Komponenter
Dialog
Dialog lar deg lage modale og ikke-modale dialoger basert på HTML-elementet dialog.
React
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
- 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) |
| 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. |
Bruk
For å legge til egen lukk knapp, kan du enten bruke ref og Dialog.close() på en knapp du lager selv, eller legge på data-command="close" på en knapp inni dialogen.
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.
data-command er inspirert av Invoker Commands (mozilla.org).
Eksempel
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().
React
const WithRef = () => { const dialogRef = useRef<HTMLDialogElement>(null); return ( <> <Button 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
const WithForm = () => { const dialogRef = useRef<HTMLDialogElement>(null); const [input, setInput] = useState(''); return ( <Dialog.TriggerContext> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog ref={dialogRef} onClose={() => setInput('')} closedby='any'> <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 onClick={() => { window.alert(`Du har sendt inn skjema med navn: ${input}`); dialogRef.current?.close(); }} > Send inn skjema </Button> <Button variant='secondary' data-color='danger' data-command='close'> 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
const WithBlocks = () => { return ( <Dialog.TriggerContext> <Dialog.Trigger>Open Dialog</Dialog.Trigger> <Dialog> <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' data-command='close'> 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.
Dette fungerer kun når modal={true}, fordi en ikke-modal dialog ikke har noe :backdrop.
React
const CloseWithClickOutside = () => { return ( <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, og håndtere åpning og lukking av dialogen med JavaScript.
Merk at knappen som åpner dialogen bør ha aria-haspopup="dialog"-attributtet.
Vi har utvidet Dialog i React til å støtte data-command for lukk-knapp, og closedby-attributtet for å lukke dialogen ved klikk utenfor.
Dette må selv implementeres i HTML/JavaScript dersom du ikke bruker React-komponenten.
closedby er støtta i nokre nettlesarar (mozilla.org)
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) |
| Navn | Verdi |
|---|---|
| data-command | close |