Dialog
Display a modal dialog box.
#
Documentation
#
#
Usage
#
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogFooter,
DialogHeader,
DialogTrigger,
} from "@optiaxiom/react";
export function App() {
return (
<Dialog>
<DialogTrigger>Open Dialog</DialogTrigger>
<DialogContent>
<DialogHeader>Modal Title</DialogHeader>
<DialogBody>This is the modal body</DialogBody>
<DialogFooter>
<DialogClose appearance="primary">Close</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
#
Controlled
#
Use the open
and defaultOpen
props to toggle between controlled and uncontrolled usage. And combine it with onOpenChange
to listen for changes to the state.
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogFooter,
DialogHeader,
DialogTrigger,
} from "@optiaxiom/react";
import { useState } from "react";
export function App() {
const [open, setOpen] = useState(false);
return (
<Dialog onOpenChange={setOpen} open={open}>
<DialogTrigger>Open Dialog</DialogTrigger>
<DialogContent>
<DialogHeader>Modal Title</DialogHeader>
<DialogBody>This is the modal body</DialogBody>
<DialogFooter>
<DialogClose appearance="primary">Close</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
#
Sizes
#
Use the size
prop to change the size of the dialog box.
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogFooter,
DialogHeader,
DialogTrigger,
} from "@optiaxiom/react";
import { type ComponentPropsWithRef } from "react";
export function App({
size,
}: Pick<ComponentPropsWithRef<typeof DialogContent>, "size">) {
return (
<Dialog>
<DialogTrigger>Open Dialog</DialogTrigger>
<DialogContent size={size}>
<DialogHeader>Modal Title</DialogHeader>
<DialogBody>This is the modal body</DialogBody>
<DialogFooter>
<DialogClose appearance="primary">Close</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
#
Description
#
You can add accessible description to the modal using the description
prop on DialogHeader
component.
import {
Dialog,
DialogClose,
DialogContent,
DialogFooter,
DialogHeader,
DialogTrigger,
} from "@optiaxiom/react";
export function App() {
return (
<Dialog>
<DialogTrigger>Open Dialog</DialogTrigger>
<DialogContent>
<DialogHeader description="This is additional description of the modal">
Modal Title
</DialogHeader>
<DialogFooter>
<DialogClose>Close</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
#
Customize trigger
#
By default we use the Button
component for the dialog trigger which accepts all of the existing button props.
We can also completely change the trigger by using asChild
and passing our own component.
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogFooter,
DialogHeader,
DialogTrigger,
} from "@optiaxiom/react";
import { IconRefresh } from "@tabler/icons-react";
export function App() {
return (
<Dialog>
<DialogTrigger
appearance="primary"
aria-label="Re-publish changes"
icon={<IconRefresh />}
/>
<DialogContent>
<DialogHeader>Modal Title</DialogHeader>
<DialogBody>This is the modal body</DialogBody>
<DialogFooter>
<DialogClose appearance="primary">Close</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
#
Form dialogs
#
Wrap DialogBody
and DialogFooter
with the DialogForm
component to use forms in dialogs.
import {
Button,
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogFooter,
DialogForm,
DialogHeader,
DialogTrigger,
Field,
Input,
Textarea,
} from "@optiaxiom/react";
import { useState } from "react";
export function App() {
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false);
return (
<Dialog onOpenChange={loading ? undefined : setOpen} open={open}>
<DialogTrigger>Create new issue</DialogTrigger>
<DialogContent size="sm">
<DialogHeader>Create new issue</DialogHeader>
<DialogForm
onSubmit={(event) => {
event.preventDefault();
setLoading(true);
// use form data to perform a server action
setTimeout(() => {
setLoading(false);
setOpen(false);
}, 3000);
}}
>
<DialogBody>
<Field label="Title">
<Input autoFocus name="title" required />
</Field>
<Field label="Description">
<Textarea name="description" required />
</Field>
</DialogBody>
<DialogFooter>
<DialogClose disabled={loading}>Cancel</DialogClose>
<Button
appearance="primary"
disabled={loading}
loading={loading}
type="submit"
>
Save
</Button>
</DialogFooter>
</DialogForm>
</DialogContent>
</Dialog>
);
}
#
Nested dialogs
#
Combine dialogs to show nested dialogs.
import {
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogFooter,
DialogHeader,
DialogTrigger,
} from "@optiaxiom/react";
export function App() {
return (
<Dialog>
<DialogTrigger>Open Dialog</DialogTrigger>
<DialogContent size="sm">
<DialogHeader>Modal Title</DialogHeader>
<DialogBody>This is the modal body</DialogBody>
<DialogFooter>
<Dialog>
<DialogTrigger mr="auto">Open nested dialog</DialogTrigger>
<DialogContent size="sm">
<DialogHeader>Modal Title</DialogHeader>
<DialogBody>This is the modal body</DialogBody>
<DialogFooter>
<Dialog>
<DialogTrigger mr="auto">Open nested dialog</DialogTrigger>
<DialogContent size="sm">
<DialogHeader>Modal Title</DialogHeader>
<DialogBody>This is the modal body</DialogBody>
<DialogFooter>
<DialogClose appearance="primary">Close</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
<DialogClose appearance="primary">Close</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
<DialogClose appearance="primary">Close</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
#
Nested alert dialogs
#
Combine Dialog
with AlertDialog
to show nested confirmation dialogs.
Use the onOpenChange
handler to trigger the nested callback instead of an explicit trigger.
Type something into the text field and then attempt to close the dialog:
import {
AlertDialog,
AlertDialogAction,
AlertDialogBody,
AlertDialogCancel,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
Button,
Dialog,
DialogBody,
DialogClose,
DialogContent,
DialogFooter,
DialogForm,
DialogHeader,
DialogTrigger,
Textarea,
} from "@optiaxiom/react";
import { useRef, useState } from "react";
export function App() {
const [open, setOpen] = useState(false);
const [alertOpen, setAlertOpen] = useState(false);
const textRef = useRef<HTMLTextAreaElement>(null);
return (
<Dialog
onOpenChange={(open) => {
if (!open && textRef.current?.value) {
setAlertOpen(true);
} else {
setOpen(open);
}
}}
open={open}
>
<DialogTrigger>Create new issue</DialogTrigger>
<DialogContent size="sm">
<DialogHeader>Create new issue</DialogHeader>
<DialogForm
onSubmit={(event) => {
event.preventDefault();
setOpen(false);
}}
>
<DialogBody>
<Textarea autoFocus ref={textRef} required />
</DialogBody>
<DialogFooter>
<DialogClose>Cancel</DialogClose>
<Button appearance="primary">Save</Button>
</DialogFooter>
</DialogForm>
</DialogContent>
<AlertDialog onOpenChange={setAlertOpen} open={alertOpen}>
<AlertDialogContent onCloseAutoFocus={() => textRef.current?.focus()}>
<AlertDialogHeader>Discard issue?</AlertDialogHeader>
<AlertDialogBody>All unsaved changes will be lost.</AlertDialogBody>
<AlertDialogFooter>
<AlertDialogCancel>No, keep editing</AlertDialogCancel>
<AlertDialogAction onClick={() => setOpen(false)}>
Yes, discard
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</Dialog>
);
}
#
Related
#
AlertDialog
Display a modal with important content that expects confirmation from the user.
#
Props
#
#
Dialog
#
Doesn't render its own HTML element.
Prop |
---|
defaultOpen The initial open state in uncontrolled mode.
|
onOpenChange Handler that is called when the open state changes.
|
open The open state in controlled mode.
|
#
DialogTrigger
#
Supports all Button props in addition to its own. Renders a <button>
element.
Prop |
---|
addonAfter Display content inside the button after
|
addonBefore Display content inside the button before
|
appearance Control the appearance by selecting between the different button types.
|
asChild Change the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
disabled Whether the button is disabled.
|
icon Display an icon before or after the button content or omit
|
iconPosition Control whether to show the icon before or after the button content.
|
loading Whether to show loading spinner inside the button.
|
size Control the size of the button.
|
square Whether button should have square shape.
|
#
DialogContent
#
Supports all Box props in addition to its own. Renders a <div>
element.
Prop |
---|
asChild Change the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
onCloseAutoFocus Event handler called when auto-focusing on close. Can be prevented.
|
onEscapeKeyDown Event handler called when the escape key is down. Can be prevented.
|
onFocusOutside Event handler called when the focus moves outside of the
|
onInteractOutside Event handler called when an interaction happens outside the
|
onOpenAutoFocus Event handler called when auto-focusing on open. Can be prevented.
|
onPointerDownOutside Event handler called when the a
|
size
Default: |
transitionType
Default: |
#
DialogHeader
#
Supports all Box props in addition to its own. Renders a <div>
element.
Prop |
---|
addonAfter
|
asChild Change the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
description
|
#
DialogForm
#
Supports all Box props in addition to its own. Renders a <form>
element.
Prop |
---|
asChild Change the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
DialogBody
#
Supports all Box props in addition to its own. Renders a <div>
element.
Prop |
---|
asChild Change the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
DialogFooter
#
Supports all Box props in addition to its own. Renders a <div>
element.
Prop |
---|
asChild Change the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
DialogClose
#
Supports all Button props in addition to its own. Renders a <button>
element.
Prop |
---|
addonAfter Display content inside the button after
|
addonBefore Display content inside the button before
|
appearance Control the appearance by selecting between the different button types.
Default: |
asChild Change the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
disabled Whether the button is disabled.
|
icon Display an icon before or after the button content or omit
|
iconPosition Control whether to show the icon before or after the button content.
|
loading Whether to show loading spinner inside the button.
|
size Control the size of the button.
|
square Whether button should have square shape.
|
#
Changelog
#
#
0.1.0
#
- Added component