Modal
Dialog with actions. 3 sizes.
import * as React from "react";
import { Button } from "@/components/ui/button";
import { Modal } from "@/components/ui/modal";
export default function Example() {
const [open, setOpen] = React.useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Place order</Button>
<Modal
open={open}
onClose={() => setOpen(false)}
title="Place this order?"
footer={<><Button variant="ghost" onClick={() => setOpen(false)}>Not yet</Button><Button onClick={() => setOpen(false)}>Place order</Button></>}
>
2 tins of Darjeeling and a clay cup, ৳1,260 in total. We will send it to House 14, Dhanmondi.
</Modal>
</>
);
}
Installation
$ npx uix-ui@latest add modalThis copies the file into components/ui/modal.tsx in your project. npx shadcn@latest add @uix/modal works too.
Usage
import { Modal } from "@/components/ui/modal";
<>
<Button onClick={() => setOpen(true)}>Place order</Button>
<Modal
open={open}
onClose={() => setOpen(false)}
title="Place this order?"
footer={<><Button variant="ghost" onClick={() => setOpen(false)}>Not yet</Button><Button onClick={() => setOpen(false)}>Place order</Button></>}
>
2 tins of Darjeeling and a clay cup, ৳1,260 in total. We will send it to House 14, Dhanmondi.
</Modal>
</>
Examples
Warning with an icon
import * as React from "react";
import { Button } from "@/components/ui/button";
import { Modal } from "@/components/ui/modal";
import { TriangleAlert } from "@/components/ui/icons";
export default function Example() {
const [open, setOpen] = React.useState(false);
return (
<>
<Button variant="destructive" onClick={() => setOpen(true)}>Cancel order</Button>
<Modal
open={open}
onClose={() => setOpen(false)}
size="sm"
headerIcon={<TriangleAlert />}
title="Cancel order #1042?"
footer={<><Button variant="outline" onClick={() => setOpen(false)}>Keep it</Button><Button variant="destructive" onClick={() => setOpen(false)}>Cancel order</Button></>}
>
The tea has already been packed. You will get your money back to bKash in 2 days.
</Modal>
</>
);
}
Large, with a form
import * as React from "react";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Modal } from "@/components/ui/modal";
export default function Example() {
const [open, setOpen] = React.useState(false);
return (
<>
<Button variant="outline" onClick={() => setOpen(true)}>Add a gift note</Button>
<Modal
open={open}
onClose={() => setOpen(false)}
size="lg"
title="Gift note"
footer={<><Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button><Button onClick={() => setOpen(false)}>Save note</Button></>}
>
<div style={{ display: "grid", gap: 12 }}>
<Input label="To" placeholder="Israt Jahan" />
<Input label="Message" placeholder="Happy birthday!" />
<Checkbox label="Hide the price on the receipt" defaultChecked />
</div>
</Modal>
</>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | sm | md | lg | "md" | |
open | boolean | – | |
onClose | () => void | – | |
title | React.ReactNode | – | |
headerIcon | React.ReactNode | – | Icon in a round badge above the title. |
showClose | boolean | true | Set to false to hide the close button in the corner. |
footer | React.ReactNode | – | Buttons, right-aligned under the content. |
Everything else is passed to the root element, so className, aria-* and event handlers work as usual.
Dependencies
Installed for you by the CLI.
class-variance-authorityclsxtailwind-merge
lib/utils.tscomponents/ui/icons.tsx