Modal
⟦Módál díálóg búílt óñ thé ñátívé díálóg éléméñt.~~~~~~~~~~~~~~~~~⟧
- ⟦Brówšérš~~~⟧
- Chrome 123+Firefox 121+Safari 17.5+
- ⟦Tíér~~⟧
- 0
- ⟦Búñdlé çómpréššéd~~~~~~⟧
- 944 B
- ⟦Fórçéd láýóút búdgét~~~~~~~⟧
- 0 ms
- ⟦Áxé búdgét~~~~⟧
- 0
- ⟦ŠŠR çómpátíblé~~~~~⟧
- ⟦Ýéš~~⟧
- ⟦Búílt óñ~~~⟧
- elements/dialog
- ⟦Públíšhéd çóñtráçt~~~~~~~⟧
- ⟦Téšt hárñéšš~~~~~⟧
⟦Pláýgróúñd~~~~⟧
Modal
Closed
Controlled
Changes: , state:
⟦Éxámpléš~~~⟧
Sizes
size writes data-size: sm 24rem, md (default) 28rem, lg 40rem, full fills the viewport. On a phone every size except full is a bottom sheet.
import { Modal } from "@gunkin/uiify";
export default function Example() {
return (
<>
<Modal id="size-sm" size="sm" title="Small" trigger="Small">
<p>24rem wide.</p>
</Modal>
<Modal id="size-lg" size="lg" title="Large" trigger="Large">
<p>40rem wide.</p>
</Modal>
</>
);
}Long content
The title, content and footer share one scroll area. Compose the parts inside ModalBody for a document-style dialog.
import { ModalTrigger, ModalContent, ModalBody, ModalHeader, ModalTitle, ModalClose, ModalFooter } from "@gunkin/uiify";
export default function Example() {
return <>
<ModalTrigger target="terms">Read terms</ModalTrigger>
<ModalContent id="terms" aria-labelledby="terms-title">
<ModalBody>
<ModalHeader><ModalTitle id="terms-title">Terms of service</ModalTitle><ModalClose aria-label="Close" target="terms">×</ModalClose></ModalHeader>
{Array.from({ length: 30 }, (_, index) => <p key={index}>Clause {index + 1}: text that makes the document taller than the screen.</p>)}
<ModalFooter><ModalClose target="terms">Done</ModalClose></ModalFooter>
</ModalBody>
</ModalContent>
</>;
}Opening a modal from a modal
Render the child Modal inside the parent. It opens on top, Escape closes only the child, focus returns to the button that opened it, and the page is dimmed once.
import { Modal, ModalClose } from "@gunkin/uiify";
export default function Example() {
return (
<Modal
id="editor"
trigger="Edit profile"
title="Edit profile"
description="Unsaved changes are lost when you close."
>
<Modal
id="discard"
trigger="Discard changes"
title="Discard changes?"
description="This cannot be undone."
footer={<ModalClose target="discard">Keep editing</ModalClose>}
/>
</Modal>
);
}⟦ÁPÍ~~⟧
Modal
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
id* | string | — | ⟦Úñíqúé díálóg íd thát thé tríggér áñd çlóšé búttóñ tárgét, šó thé díálóg ópéñš áñd çlóšéš béfóré hýdrátíóñ.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
trigger* | ReactNode | — | ⟦Çóñtéñt óf thé búttóñ thát ópéñš thé díálóg.~~~~~~~~~~~~~~~~⟧ |
title* | ReactNode | — | ⟦Héádíñg réñdéréd íñšídé thé díálóg áñd úšéd áš ítš áççéššíblé ñámé.~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
description | ReactNode | — | ⟦Šúppórtíñg téxt réñdéréd úñdér thé títlé áñd référéñçéd bý áríá-déšçríbédbý.~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
children | ReactNode | — | ⟦Bódý çóñtéñt, réñdéréd íñ thé šçróllíñg MódálBódý.~~~~~~~~~~~~~~~~~~⟧ |
closeLabel | string | "Close" | ⟦Áççéššíblé ñámé óf thé çlóšé íçóñ íñ thé héádér.~~~~~~~~~~~~~~~~~⟧ |
footer | ReactNode | — | ⟦Áçtíóñš rów píññéd úñdér thé bódý. Pút á MódálÇlóšé héré fór á bóttóm Çlóšé búttóñ.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
size | "sm" | "md" | "lg" | "full" | "md" | ⟦Wídth štép (24, 28, 40rém). fúll fíllš thé víéwpórt. Wríttéñ tó dátá-šížé; óvérrídé --úíífý-módál-íñlíñé-šížé fór á çúštóm wídth.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
align | "center" | "start" | "center" | ⟦Vértíçál póšítíóñ óñ táblét áñd déšktóp. Phóñéš gét á bóttóm šhéét úñléšš šížé íš fúll.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
dismiss | "any" | "closerequest" | "none" | "any" | ⟦çlóšédbý: áñý áddš báçkdróp tápš, çlóšéréqúéšt állówš óñlý Éšçápé, ñóñé óñlý ýóúr çóñtrólš. Šáfárí láçkš çlóšédbý, šó Éšçápé álwáýš çlóšéš; ÚÍÉñháñçé háñdléš báçkdróp tápš (áñý) áñd šhéét šwípé (ñót ñóñé).~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
backdrop | "opaque" | "blur" | "none" | "opaque" | ⟦Báçkdróp tréátméñt. Wríttéñ tó dátá-báçkdróp.~~~~~~~~~~~~~~~~⟧ |
className | string | — | ⟦Çlášš ápplíéd tó thé díálóg éléméñt.~~~~~~~~~~~~~⟧ |
ModalTrigger
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
target* | string | — | ⟦Íd óf thé MódálÇóñtéñt thíš búttóñ ópéñš; thé brówšér réšólvéš ít át çlíçk tímé, šó ñó JáváŠçrípt óf óúrš rúñš.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
children | ReactNode | — | ⟦Çóñtéñt óf thé tríggér búttóñ.~~~~~~~~~~~⟧ |
as | TAs & NativeButtonAs<TAs> | "button" | ⟦Á çómpóñéñt thát fórwárdš própš áñd réf tó á ñátívé búttóñ; óthér tágš áré réjéçtéd, béçáúšé íñvókér çómmáñdš ñééd á réál búttóñ.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
ModalContent
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
id* | string | — | ⟦Úñíqúé íd šúpplíéd bý thé çóñšúmér; référéñçéd bý thé tríggér áñd çlóšé tárgét.~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
size | "sm" | "md" | "lg" | "full" | "md" | ⟦Wídth štép (24, 28, 40rém). fúll fíllš thé víéwpórt. Wríttéñ tó dátá-šížé; óvérrídé --úíífý-módál-íñlíñé-šížé fór á çúštóm wídth.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
align | "center" | "start" | "center" | ⟦Vértíçál póšítíóñ óñ táblét áñd déšktóp. Phóñéš gét á bóttóm šhéét úñléšš šížé íš fúll.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
dismiss | "any" | "closerequest" | "none" | "any" | ⟦çlóšédbý: áñý áddš báçkdróp tápš, çlóšéréqúéšt állówš óñlý Éšçápé, ñóñé óñlý ýóúr çóñtrólš. Šáfárí láçkš çlóšédbý, šó Éšçápé álwáýš çlóšéš; ÚÍÉñháñçé háñdléš báçkdróp tápš (áñý) áñd šhéét šwípé (ñót ñóñé).~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
backdrop | "opaque" | "blur" | "none" | "opaque" | ⟦Báçkdróp tréátméñt. Wríttéñ tó dátá-báçkdróp.~~~~~~~~~~~~~~~~⟧ |
children | ReactNode | — | ⟦Çóñtéñt óf thé díálóg.~~~~~~~~⟧ |
ModalClose
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
target* | string | — | ⟦Íd óf thé MódálÇóñtéñt thíš búttóñ çlóšéš.~~~~~~~~~~~~~~~⟧ |
children | ReactNode | — | ⟦Çóñtéñt óf thé çlóšé búttóñ.~~~~~~~~~~⟧ |
as | TAs & NativeButtonAs<TAs> | "button" | ⟦Á çómpóñéñt thát fórwárdš própš áñd réf tó á ñátívé búttóñ; óthér tágš áré réjéçtéd, béçáúšé íñvókér çómmáñdš ñééd á réál búttóñ.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
ModalHeader
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
children | ReactNode | — | ⟦Píññéd tóp rów hóldíñg thé títlé, déšçríptíóñ áñd çlóšé çóñtról.~~~~~~~~~~~~~~~~~~~~~~~⟧ |
ModalTitle
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
children | ReactNode | — | ⟦Thé díálóg'š áççéššíblé ñámé; référéñçé ítš íd fróm áríá-lábéllédbý.~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
ModalDescription
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
children | ReactNode | — | ⟦Šúppórtíñg téxt; référéñçé ítš íd fróm áríá-déšçríbédbý.~~~~~~~~~~~~~~~~~~~~⟧ |
ModalBody
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
children | ReactNode | — | ⟦Thé šçróllíñg régíóñ bétwééñ héádér áñd fóótér.~~~~~~~~~~~~~~~~~⟧ |
ModalFooter
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
children | ReactNode | — | ⟦Áçtíóñš rów píññéd úñdér thé bódý.~~~~~~~~~~~~⟧ |
ModalGrabber
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
children | ReactNode | — | ⟦Déçórátívé drág háñdlé óñ thé móbílé šhéét; thé šwípé štártš héré.~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
ModalClientContent (@gunkin/uiify/components/modal/client)
| ⟦Próp~~⟧ | ⟦Týpé~~⟧ | ⟦Défáúlt~~~⟧ | ⟦Déšçríptíóñ~~~~⟧ |
|---|---|---|---|
id* | string | — | ⟦Úñíqúé íd šúpplíéd bý thé çóñšúmér; référéñçéd bý thé tríggér áñd çlóšé.~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
open | boolean | — | ⟦Çóñtrólléd ópéñ štáté, áúthórítátívé áftér hýdrátíóñ.~~~~~~~~~~~~~~~~~~~⟧ |
defaultOpen | boolean | — | ⟦Úñçóñtrólléd íñítíál štáté, ápplíéd wíth šhówMódál() áftér hýdrátíóñ; thé šérvér márkúp štáýš çlóšéd.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
onOpenChange | (open: boolean) => void | — | ⟦Fíréš óñçé pér ñátívé ór prógrámmátíç çháñgé wíth thé ñéw štáté, íñçlúdíñg óñçé át móúñt íf thé brówšér ópéñéd ít béfóré hýdrátíóñ.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
onOpenChangeComplete | (open: boolean) => void | — | ⟦Fíréš óñçé pér ópéñ ór çlóšé tráñšítíóñ áftér ítš ÇŠŠ tráñšítíóñš fíñíšh, ór ímmédíátélý wíthóút áñý, íñçlúdíñg thé défáúltÓpéñ tráñšítíóñ áftér hýdrátíóñ; ñévér fór áñ úñçháñgéd díálóg.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
size | "sm" | "md" | "lg" | "full" | "md" | ⟦Wídth štép (24, 28, 40rém). fúll fíllš thé víéwpórt. Wríttéñ tó dátá-šížé; óvérrídé --úíífý-módál-íñlíñé-šížé fór á çúštóm wídth.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
align | "center" | "start" | "center" | ⟦Vértíçál póšítíóñ óñ táblét áñd déšktóp. Phóñéš gét á bóttóm šhéét úñléšš šížé íš fúll.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
dismiss | "any" | "closerequest" | "none" | "any" | ⟦çlóšédbý: áñý áddš báçkdróp tápš, çlóšéréqúéšt állówš óñlý Éšçápé, ñóñé óñlý ýóúr çóñtrólš. Šáfárí láçkš çlóšédbý, šó Éšçápé álwáýš çlóšéš; ÚÍÉñháñçé háñdléš báçkdróp tápš (áñý) áñd šhéét šwípé (ñót ñóñé).~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧ |
backdrop | "opaque" | "blur" | "none" | "opaque" | ⟦Báçkdróp tréátméñt. Wríttéñ tó dátá-báçkdróp.~~~~~~~~~~~~~~~~⟧ |
children | ReactNode | — | ⟦Çóñtéñt óf thé díálóg.~~~~~~~~⟧ |
⟦Kéýbóárd~~~⟧
| ⟦Kéý~~⟧ | ⟦Áçtíóñ~~~⟧ |
|---|---|
| Escape | ⟦Çlóšé (óñlý thé tópmóšt módál whéñ ñéštéd)~~~~~~~~~~~~~~~⟧ |
| Tab | ⟦Çýçlé fóçúš íñšídé módál~~~~~~~~~⟧ |
| Shift+Tab | ⟦Révéršé táb órdér~~~~~~⟧ |
⟦Áççéššíbílítý~~~~~⟧
⟦Ñátívé <díálóg> ópéñéd bý á çómmáñd="šhów-módál" íñvókér béfóré áñý JáváŠçrípt rúñš. Thé brówšér ówñš módálítý, fóçúš çóñtáíñméñt, Éšçápé áñd fóçúš rétúrñ; çlóšíñg úšéš réqúéšt-çlóšé šó óñÇáñçél çáñ vétó. Thé héádér çlóšé íçóñ íš álwáýš préšéñt. Óñ phóñéš thé módál íš á bóttóm šhéét; šwípíñg ít dówñ áñd táppíñg thé báçkdróp áré šhórtçútš, ñévér thé óñlý wáý óút.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧
⟦Štýlíñg hóókš~~~~~⟧
data-uiify-modaldata-part="trigger|content|header|title|description|body|footer|grabber|close"data-size="sm|lg|full"data-align="start"data-backdrop="blur|none"--uiify-trigger-open (inside [data-uiify-modal][data-part="root"])--uiify-modal-inline-size (dialog width)