Komponenter
Dialog
Det er to typer dialoger, en modal og en ikke-modal. En modal dialog tvinger brukerne til å ta stilling til noe før de kan fortsette å bruke siden. En Ikke-modal dialog lar brukerne fortsette å bruke siden, selv om dialogen er åpen.
React
Unable to parse html
const Preview = () => { return ( <Dialog.TriggerContext> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog> <Heading style={{ marginBottom: 'var(--ds-size-2)' }}> Dialog header </Heading> <Paragraph style={{ marginBottom: 'var(--ds-size-2)' }}> Lorem ipsum dolor sit, amet consectetur adipisicing elit. Blanditiis doloremque obcaecati assumenda odio ducimus sunt et. </Paragraph> <Paragraph data-size='sm'>Dialog footer</Paragraph> </Dialog> </Dialog.TriggerContext> ); }; render(<Preview />)
- closeButton
- Description
Screen reader label of close button. Set false to hide the close button.
- Type
string | false- Default
Lukk dialogvindu
- closedby
- Description
Light dismiss behavior, allowing to close on backdrop click by setting `closedby="any"`. @see [mdn closedBy](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/closedBy)
- Type
"none" | "closerequest" | "any"- Default
'closerequest'
- placement
- Description
When not center, displays dialog as a "drawer" from the specified side.
- Type
"center" | "left" | "right" | "top" | "bottom"- Default
center
- modal
- Description
Toogle modal and non-modal dialog. @see [mdn modal dialog](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog#creating_a_modal_dialog)
- Type
boolean- Default
true
- open
- Description
@note Unlike standard html, where the open attribute always opens a non-modal dialog, Dialog's open prop uses the `modal` prop to determine whether the Dialog is modal or non-modal
- Type
boolean
- onClose
- Description
Callback that is called when the dialog is closed.
- Type
((event: Event) => void)
- asChild
- Description
Change the default rendered element for the one passed as a child, merging their props and behavior. @deprecated Will be removed in the next major version. Should always be a `<dialog>` element
- Type
boolean- Default
false
| Name | Type | Default | Description |
|---|---|---|---|
| closeButton | string | false | Lukk dialogvindu | Screen reader label of close button. Set false to hide the close button. |
| closedby | "none" | "closerequest" | "any" | 'closerequest' | Light dismiss behavior, allowing to close on backdrop click by setting `closedby="any"`. @see [mdn closedBy](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/closedBy) |
| placement | "center" | "left" | "right" | "top" | "bottom" | center | When not center, displays dialog as a "drawer" from the specified side. |
| modal | boolean | true | Toogle modal and non-modal dialog. @see [mdn modal dialog](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog#creating_a_modal_dialog) |
| open | boolean | - | @note Unlike standard html, where the open attribute always opens a non-modal dialog, Dialog's open prop uses the `modal` prop to determine whether the Dialog is modal or non-modal |
| onClose | ((event: Event) => void) | - | Callback that is called when the dialog is closed. |
| asChild | boolean | false | Change the default rendered element for the one passed as a child, merging their props and behavior. @deprecated Will be removed in the next major version. Should always be a `<dialog>` element |
DialogBlock
- asChild
- Description
Change the default rendered element for the one passed as a child, merging their props and behavior.
- Type
boolean- Default
false
| Name | Type | Default | Description |
|---|---|---|---|
| asChild | boolean | false | Change the default rendered element for the one passed as a child, merging their props and behavior. |
DialogTrigger
- type
- Description
Specify the type of button. Unset when `asChild` is true
- Type
"submit" | "reset" | "button"- Default
'button'
- command
- Type
string
- commandfor
- Type
string
- variant
- Description
Specify which variant to use
- Type
"primary" | "secondary" | "tertiary"- Default
'primary'
- icon
- Description
Toggle icon only styling, pass icon as children When combined with loading, the loading-icon will be shown instead of the icon.
- Type
boolean- Default
false
- loading
- Description
Toggle loading state. Pass an element if you want to display a custom loader.
- Type
ReactNode- Default
false
- asChild
- Description
Change the default rendered element for the one passed as a child, merging their props and behavior.
- Type
boolean- Default
false
| Name | Type | Default | Description |
|---|---|---|---|
| type | "submit" | "reset" | "button" | 'button' | Specify the type of button. Unset when `asChild` is true |
| command | string | - | - |
| commandfor | string | - | - |
| variant | "primary" | "secondary" | "tertiary" | 'primary' | Specify which variant to use |
| icon | boolean | false | Toggle icon only styling, pass icon as children When combined with loading, the loading-icon will be shown instead of the icon. |
| loading | ReactNode | false | Toggle loading state. Pass an element if you want to display a custom loader. |
| asChild | boolean | false | Change the default rendered element for the one passed as a child, merging their props and behavior. |
Bruk
For å legge til egen lukk knapp, kan du enten bruke command="close" commandfor="DIALOG-ID" ellr ref og Dialog.close() på en knapp du lager selv.
Dersom knappen er tom vil den få et ikon.
Dersom knappen er direkte barn av dialogen og første element, vil den flyte til topp høyre.
Attributtene command (developer.mozilla.org) og commandfor er en relativt ny del av web-standarden som lar knapper utføre handlinger på andre elementer deklarativt. Vi legger automatisk til invokers-polyfill (npmjs.com) for å støtte eldre nettlesere.
Eksempel
Med command og uten context
Dersom du ikke vil bruke Dialog.TriggerContext, kan du bruke command="show-modal" eller command="--show-non-modal" og commandfor="DIALOG-ID" for å åpne dialogen fra en ekstern trigger.
React
Unable to parse html
const WithCommand = () => ( <> <Button command='show-modal' commandfor='my-dialog-commant'> Open Dialog with ref </Button> <Dialog id='my-dialog-commant'> <Heading style={{ marginBottom: 'var(--ds-size-2)' }}> Dialog header </Heading> <Paragraph style={{ marginBottom: 'var(--ds-size-2)' }}> Lorem ipsum dolor sit, amet consectetur adipisicing elit. Blanditiis doloremque obcaecati assumenda odio ducimus sunt et. </Paragraph> </Dialog> </> ); render(<WithCommand />)
Med ref og uten context
Dersom du ikke vil bruke Dialog.TriggerContext, kan du bruke ref for å åpne dialogen fra en ekstern trigger.
Du bruker da native metoder på <dialog>-elementet, som showModal() eller show().
Merk at knappen som åpner dialogen da bør ha aria-haspopup="dialog"-attributtet.
React
Unable to parse html
const WithRef = () => { const dialogRef = useRef<HTMLDialogElement>(null); return ( <> <Button aria-haspopup='dialog' onClick={() => dialogRef.current?.showModal()} > Open Dialog with ref </Button> <Dialog ref={dialogRef}> <Heading style={{ marginBottom: 'var(--ds-size-2)' }}> Dialog header </Heading> <Paragraph style={{ marginBottom: 'var(--ds-size-2)' }}> Lorem ipsum dolor sit, amet consectetur adipisicing elit. Blanditiis doloremque obcaecati assumenda odio ducimus sunt et. </Paragraph> </Dialog> </> ); }; render(<WithRef />)
Med skjema og fokus
Dersom du vil at et felt i et skjema inni dialogen skal få fokus når dialogen åpnes, kan du bruke native autofocus-attributtet på input-elementet.
Når du bruker dette med React, må du skrive det med små bokstaver som autofocus, ikke autoFocus.
Denne prop-en eksistere ikke i React sine typedefinisjoner, så vi har ignorert feilen med en @ts-expect-error-kommentar i eksempelet under.
React
Unable to parse html
const WithForm = () => { const [input, setInput] = useState(''); return ( <Dialog.TriggerContext> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog onClose={() => setInput('')} closedby='any' id='my-dialog-form'> <Heading style={{ marginBottom: 'var(--ds-size-2)' }}> Dialog med skjema </Heading> <Textfield label='Navn' value={input} onChange={(e) => setInput(e.target.value)} // @ts-expect-error We want the native "autofocus" and Reacts onMount smartness (see https://react.dev/reference/react-dom/components/input#input) autofocus='true' /> <div style={{ display: 'flex', gap: 'var(--ds-size-4)', marginTop: 'var(--ds-size-4)', }} > <Button command='close' commandfor='my-dialog-form' onClick={() => alert(`Du har sendt inn skjema med navn: ${input}`)} > Send inn skjema </Button> <Button variant='secondary' data-color='danger' command='close' commandfor='my-dialog-form' > Avbryt </Button> </div> </Dialog> </Dialog.TriggerContext> ); }; render(<WithForm />)
Med blokker
Bruk flere Dialog.Block hvis du vil dele opp dialogen med skillelinjer til for eksempel topp- og bunn-område. Merk at innhold kan ikke plasseres direkte i Dialog dersom du bruker Dialog.Block; da burde alt innholdet være inni en av av dialogens Dialog.Block-seksjoner.
React
Unable to parse html
const WithBlocks = () => ( <Dialog.TriggerContext> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog id='my-dialog-blocks'> <Dialog.Block> <Paragraph data-size='sm'>Dialog subtitle</Paragraph> <Heading>Dialog with dividers</Heading> </Dialog.Block> <Dialog.Block> <Paragraph> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sodales eros justo. </Paragraph> </Dialog.Block> <Dialog.Block> <Button variant='secondary' command='close' commandfor='my-dialog-blocks' > Lukk </Button> </Dialog.Block> </Dialog> </Dialog.TriggerContext> ); render(<WithBlocks />)
Lukk ved klikk utenfor
Vi bruker closedby="any" for å lukke dialogen når brukeren klikker utenfor.
Vi legger til polyfill så closedby="any" også fungerer i eldre Safari.
React
Unable to parse html
const CloseWithClickOutside = () => ( <Dialog.TriggerContext> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog closedby='any'> <Heading>Click outside to close</Heading> </Dialog> </Dialog.TriggerContext> ); render(<CloseWithClickOutside />)
HTML
Hovedklassenavnet er ds-dialog, som blir plassert på <dialog>-elementet.
Blokker inne i dialogen får klassenavn som ds-dialog__block.
I HTML må du selv koble <dialog>-elementet til en trigger via command="show-modal" eller command="--show-non-modal" og commandfor="DIALOG-ID".
CSS variabler og data-attributter
Alle CSS variabler brukt av ds-dialog__block er satt på ds-dialog.
| Navn | Verdi |
|---|---|
| --dsc-dialog-backdrop-background | rgba(0,0,0,.5) |
| --dsc-dialog-background | var(--ds-color-neutral-surface-default) |
| --dsc-dialog-icon-spacing | var(--ds-size-3) |
| --dsc-dialog-icon-url | url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' fill='none' viewBox='0 0 24 24'%3E%3Cpath fill='currentColor' d='M6.53 5.47a.75.75 0 0 0-1.06 1.06L10.94 12l-5.47 5.47a.75.75 0 1 0 1.06 1.06L12 13.06l5.47 5.47a.75.75 0 1 0 1.06-1.06L13.06 12l5.47-5.47a.75.75 0 0 0-1.06-1.06L12 10.94z'/%3E%3C/svg%3E") |
| --dsc-dialog-color | var(--ds-color-neutral-text-default) |
| --dsc-dialog-divider-border-width | var(--ds-border-width-default) |
| --dsc-dialog-divider-border-style | solid |
| --dsc-dialog-divider-border-color | var(--ds-color-neutral-border-subtle) |
| --dsc-dialog-border-width | var(--ds-border-width-default) |
| --dsc-dialog-border-style | solid |
| --dsc-dialog-border-color | var(--ds-color-neutral-border-subtle) |
| --dsc-dialog-max-height | 80vh |
| --dsc-dialog-max-width | 40rem |
| --dsc-dialog-spacing | var(--ds-size-6) |
| --dsc-dialog-placement-inline-max-width | 40rem |
| --dsc-dialog-placement-block-max-width | 100% |
| --dsc-dialog-transition-duration | 300ms |
| Navn | Verdi |
|---|---|
| data-placement | bottom, top, left, right |
| data-command | close |