# Modal

Ready-made modals for confirmations, forms, sharing, payments and more.

Publish post confirmation

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-demo
```

This Pattern is part of [Siteplane UI Pro](/pricing), and its source comes with a [Pro license](/docs/license/#patterns). Its previews are free to view and try.

## Installation

**Pro** — Installs with a Siteplane UI Pro license key. Complete the one-time [Pro setup](/docs/installation/#siteplane-ui-pro) first. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block
```

With npm: `npx shadcn@4.18.0 add @siteplane-pro/modal-block`.

## Usage

```tsx
import { ModalBlock } from "@/siteplane/components/modal-block";

<ModalBlock
  trigger="Delete post"
  title="Delete post"
  description="Are you sure? This action cannot be undone."
  tone="error"
  confirmLabel="Delete"
  onConfirm={() => console.log("Post deleted")}
/>;
```

`ModalBlock` renders the Button that opens it, the popup with its header and actions, and the close button. Put fields and other content in `children`, and set `onSubmit` to turn the dialog into a form. To open the dialog from your own control, such as a menu item, pass `trigger={null}` and control it with `open` and `onOpenChange`.

## Composition

```text
ModalBlock
├── aside (optional)
├── media (optional)
├── header
│   ├── icon
│   ├── title
│   └── description
├── children
└── actions
    ├── footerStart (optional)
    └── Cancel and Confirm, or footer
```

Place these content parts in `children`, or use any other public component:

- Fields: `ModalTextField`, `ModalTextarea`, `ModalPasswordField`, `ModalSelect`, `ModalSearchField`, `ModalTags`, `ModalChoices`, `ModalTimeField` and `ModalVerification`, framed by `ModalFieldFrame` and `ModalFieldError`.
- Sign in: `ModalAuthFields`.
- Sharing and people: `ModalShare`, `ModalLinkField`, `ModalInviteEmails`, `ModalMemberPicker` and `ModalPeople`.
- Payment: `ModalPaymentFields`, `ModalPlanPicker`, `ModalPaymentMethods` and `ModalSeats`.
- Dates: `ModalDateRangeFields`, `ModalEventFields` and `ModalEventDetails`.
- Media and editing: `ModalMediaCarousel`, `ModalImageCrop`, `ModalUpload` and `ModalTextEditor`.
- Ready-made groups: `ModalProfileFields`, `ModalProjectFields`, `ModalCompanyFields`, `ModalExperienceFields`, `ModalUserSettings`, `ModalAppearance`, `ModalBannerAppearance`, `ModalChecklist`, `ModalAssistant` and `ModalMessage`.

Some parts have a fixed place. `ModalCardPreview` and `ModalTeamAvatars` fill `media`, `ModalConnection` fills `icon`, and `ModalCopyLink` and `ModalDateRangeInputs` fill `footerStart`. With `appearance="button"`, `ModalCopyLink` is a Button like Cancel and goes in `footer` with the other actions.

## Confirmations and alerts

`tone` colors the icon as `success`, `warning` or `error`, and an `error` tone also renders the confirm button in the destructive style. A confirmation focuses Cancel when it opens, so pressing Enter never confirms by accident. `layout="horizontal"` puts the icon beside the text, and `footerStart` adds an option such as “Don’t show again” at the start of the action row.

Delete post with a don’t-show-again option

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-destructive-example
```

When the Cancel slot carries a risky label such as Discard, set `initialFocus="confirm"` so Enter keeps the safe choice.

Unsaved changes warning

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-unsaved-changes-example
```

Mark the actions of a custom `footer` with `data-modal-action="cancel"` and `data-modal-action="confirm"` so that the dialog finds them. Without the marks, a confirmation takes the first footer button that is not an accent, destructive or inverse Button, in any of their variants, as its Cancel, so it never opens on its main or destructive action.

For a request from a person, such as a request for access, show them with `ModalPeople` in the content.

## Forms and settings

Pass `onSubmit` to make the dialog a form. The content sits in a Form, the confirm button submits it and Enter in a field submits it. Fields are validated first and show their error inline; `onSubmit` receives the `FormData` once every field is valid. The dialog stays open until you close it, so close it after your request succeeds.

New project form

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-form-example
```

Set `dividers` to read a long form as three bands: header, fields and actions. Fields placed in `footerStart` belong to the form too, so their values arrive in the same `FormData`.

Display preference with dividers

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-settings-example
```

The ready-made field groups `ModalExperienceFields`, `ModalCompanyFields`, `ModalProfileFields`, `ModalProjectFields` and `ModalUserSettings` cover common profile and project forms. `ModalChoices` lists checkboxes, switches or radio options, optionally as cards. Its `defaultValue` takes an id or a list of ids in every mode. A radio group starts on the first id, or on the first option when there is none. For a checkbox or a switch, an option's own `checked` decides for that option when it is set. `ModalTags` collects labels, `ModalSeats` a seat count with its price and `ModalTextEditor` formatted text. The editor's `tools` choose the tools of its toolbar, such as `["bold", "italic", "bulletList", "link"]` for a short note; the toolbar keeps its own order, and without `tools` it shows all of them.

## Pending and failed requests

`onConfirm` and `onSubmit` may return a promise. Until it settles, the confirm button shows its spinner and ignores a second press, and Enter in a form field submits nothing. Cancel and Escape still close the dialog. A dialog without `onSubmit` closes once the promise of `onConfirm` resolves and stays open when it rejects. A form dialog stays open either way, so close it through `open` after the request succeeds. When your application tracks the request itself, set `confirmLoading` instead.

Show a failure with `confirmError`. The message appears under the content as an alert, so screen readers announce it, and it opens and closes with motion. Clear it when the person tries again.

```tsx
const [error, setError] = useState<string>();

<ModalBlock
  trigger="Delete project"
  title="Delete project"
  tone="error"
  confirmLabel="Delete"
  confirmError={error}
  onConfirm={async () => {
    setError(undefined);
    try {
      await deleteProject();
    } catch (cause) {
      setError("The project could not be deleted. Try again.");
      // A rejected promise keeps the dialog open.
      throw cause;
    }
  }}
/>;
```

The second argument of `onOpenChange` is a `ModalBlockChangeDetails` object. Its `reason` says why the dialog changes, such as `escape-key`, `outside-press` or `close-press`, and `eventDetails.cancel()` keeps the dialog as it is, for example until a request has finished. The argument is missing when the confirm button closes the dialog.

## Sharing and invites

`ModalShare` combines a copyable link with a permission menu and a searchable list of people. Use `ModalInviteEmails` for a list of addresses, `ModalMemberPicker` to add people from a list, and `ModalLinkField` or `ModalCopyLink` for a link on its own. `ModalTeamAvatars` works well as `media` when welcoming new members.

Share project with a link and people

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-share-example
```

## Sign in and verification

A dialog that brings its own submit button sets `hideFooter`. `ModalAuthFields` renders a login or sign-up form that fits the `xs` width, with an optional forgot-password link and further actions such as single sign-on. `mode` switches between `login`, `signup` and `signup-social`.

Sign in with single sign-on

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-sign-in-example
```

`ModalVerification` renders a one-time code with a field for each digit. `layout="centered"` gathers it under a centered header; `layout="stacked"` fits a left-aligned header and spreads six cells over the full width. Put a resend link in `description`. `ModalPasswordField` adds a masked field with a show toggle for a password prompt.

Email verification code

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-verification-example
```

## Payment and plans

`ModalPaymentFields` formats the card number and expiry while people type and reports every change through `onValueChange`, so a `ModalCardPreview` in `media` can mirror the card. With the card at the top, the close button is off by default; Cancel, Escape and a click outside close the dialog. `ModalPlanPicker` (compact or `rich`), `ModalPaymentMethods` and `ModalSeats` cover plan changes, saved cards and seat counts.

Payment method with a live card preview

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-payment-example
```

## Media

`ModalMediaCarousel` pages through slides with a caption, dots and Back, Next and Skip actions. A slide can be a video: it rests on its poster behind a Play button. The carousel brings its own actions, so the dialog sets `hideFooter`, and as its pictures start the content, `showCloseButton={false}` lets them begin 24 px from the top edge. Keep a visible way to close the dialog, here Skip and the last slide’s button. `ModalImageCrop` adds a movable crop frame over a choice of images. The whole picture shows inside its 16:9 area, so a tall photo can be framed from top to bottom. The selected thumbnail shows what the frame holds. The crop `value` is measured in the picture, from 0 to 1 across its width and height, and `onImageLoad` reports the picture’s size in pixels.

Welcome tour with a picture carousel

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-carousel-example
```

A single picture goes in `media`. It starts 24 px from the top edge and keeps its own 24 px from the sides, as in this example. With media the close button is off by default, as Cancel, Escape and a click outside close the dialog. Set `showCloseButton` to show it: it sits over the top-end corner of the picture as an opaque button that reads on any image.

Published post with a picture

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-media-example
```

## Dates

Combine `dividers` and `width="lg"` for a range picker. In the content, `ModalDateRangeFields` with `twoMonths` shows two months from the `lg` breakpoint up, and its `presets` are the Calendar's own shortcuts above them. `showFields={false}` leaves out its date fields, because `ModalDateRangeInputs` in `footerStart` puts the range next to the actions: a [Date Range Picker](/docs/components/date-range-picker/) without its calendar button, since the calendar in the dialog is the picker. `ModalEventFields` adds a calendar with shortcuts, times and a location for creating an event, and `ModalEventDetails` shows an invitation.

Date range with presets

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-date-range-example
```

## Uploads

`ModalUpload` wraps File Upload. Your application owns the `files` state and starts the transfer in `onFilesSelected`. Set `avatar` to show a picture beside the dropzone, as in a profile dialog, and `compact` for the row of a labeled form. `ModalUpload` sets the hint in the dropzone through its own `description`, “Choose files or drop them here.” by default. Its `labels` reach the [File Upload](/docs/patterns/file-upload/) inside, for the upload prompt, the file states, the actions and the rejection messages. Each word left out keeps File Upload's English default.

Attach files with upload progress

**Pro** — This example installs with a Siteplane UI Pro license key. Get a license on the [Pro page](/pricing).

```bash
pnpm dlx shadcn@4.18.0 add @siteplane-pro/modal-block-upload-example
```

## Assistants, messages and integrations

`ModalAssistant` fills a centered dialog with prompt suggestions and a composer, and `ModalMessage` is a complete compose form with recipients, subject, text and attachments. For an integration, pass `ModalConnection` as the `icon` and list what it may access with `ModalChecklist`. These parts take their callbacks as props, so connect them to your own actions.

## API reference

### ModalBlock

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| title | ReactNode | required | Dialog title and accessible name. With hideHeader it stays available to assistive technology. |
| description | ReactNode | unset | Text under the title; also the accessible description. |
| icon | ReactNode | unset | Decorative icon above the title, or beside it in the horizontal layout. tone colors it. |
| children | ReactNode | unset | Content between the header and the actions, in a scrollable panel with 16 px between children. |
| layout | stacked \| horizontal \| centered | stacked | Header arrangement: icon above a left-aligned title, icon beside the text, or everything centered. |
| tone | neutral \| success \| warning \| error | neutral | Colors the icon. error also renders the confirm button in the destructive style. The earlier names default and destructive still work as deprecated aliases of neutral and error. |
| width | xs \| sm \| md \| lg | sm | Popup width from the sm breakpoint up: 400, 440, 600 and 880 px. Smaller screens show a full-width bottom sheet at every step. |
| trigger | ReactNode | Open dialog | Content of the Button that opens the dialog. null or false renders no Button, for a dialog that your application opens through open. |
| confirmLabel | ReactNode | Confirm | Text of the primary action; an icon may lead it. |
| cancelLabel | ReactNode | Cancel | Text of the secondary action, which closes the dialog; an icon may lead it. |
| footerStart | ReactNode | unset | Content at the start of the action row, such as a checkbox, a link or a secondary Button. In a form dialog it belongs to the form. |
| footer | ReactNode | unset | Replaces the Cancel and Confirm buttons. Close the dialog from your own actions through open and onOpenChange, and mark them with data-modal-action="cancel" and data-modal-action="confirm" for the initial focus. |
| media | ReactNode | unset | Picture or illustration above the header, 24 px from the top edge; it keeps its own 24 px from the sides. Turns the close button off by default. |
| open | boolean | uncontrolled | Controlled open state. |
| defaultOpen | boolean | false | Initial open state when uncontrolled. |
| onOpenChange | (open: boolean, eventDetails?: ModalBlockChangeDetails) => void | unset | Called when the dialog asks to open or close. eventDetails gives the reason, such as escape-key or close-press, and its cancel() keeps the dialog as it is. It is missing when the confirm button closes the dialog. |
| onSubmit | (data: FormData) => void \| Promise<unknown> | unset | Makes the dialog a form. The content sits in a Form, the confirm button submits it and Enter in a field submits it. Called with the form data once every field is valid. A returned promise keeps the confirm button loading until it settles, and the dialog stays open until you close it. Without onSubmit there is no Form. |
| onConfirm | () => void \| Promise<unknown> | unset | Called when the confirm button is pressed in a dialog without onSubmit. The dialog then closes, or, for a returned promise, closes once it resolves and stays open when it rejects. |
| confirmLoading | boolean | false | Shows the spinner of the confirm button and blocks it, for a request that your application tracks itself. |
| confirmError | ReactNode | unset | Message under the content when the confirm action did not work. It is an alert, so screen readers announce it. Clear it when the person tries again. |
| hideFooter | boolean | false | Omits the action row, for content that brings its own actions. |
| actionLayout | fill \| end | fill or end | fill lets the buttons share the row; end aligns them to the end at their own width. The default is fill for the xs and sm widths unless the layout is horizontal, and end otherwise. Links keep their own width, and so do the buttons beside a footerStart, so fill has no effect there. |
| hideHeader | boolean | false | Hides the header visually. Title and description stay available to assistive technology. |
| aside | ReactNode | unset | A rail at the start of the dialog, as tall as the dialog and divided by a vertical line, such as the presets of a date range. On small screens it sits above the content with a horizontal line. |
| closeLabel | string | Close | Accessible name of the close button. |
| showCloseButton | boolean | true, false with media | Shows the close button. Without media it sits in the top-end corner of the dialog; with media it sits over the top-end corner of the media as an opaque button. Escape and a click on the backdrop always close the dialog, so keep a visible close action without it. |
| dividers | boolean | false | Draws a full-width divider under the header and another above the actions. A divider only appears between two parts that are shown. |
| initialFocus | auto \| cancel \| confirm | auto | Control that takes focus on open. auto picks the first empty text field, then Cancel in a confirmation, then the first field or choice, then the primary action, which a confirmation replaces with the dialog itself. cancel without a safe action also focuses the dialog. Set confirm when Cancel carries a risky label such as Discard. |
`ModalBlock` composes Dialog, Form, Button and Separator, so it inherits their
focus handling, motion and portal. The types `ModalBlockProps`,
`ModalBlockChangeDetails`, the second argument of `onOpenChange`, and
`ModalBlockTone`, with `ModalBlockDeprecatedTone` for the earlier names, are
exported with the component.

### Parts

In this table, Prop is the part, Type lists the props it requires and the ones you need most, Default a notable default and Description what the part is for. The installed source has the complete props.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ModalTextField | label, hint, icon | — | Labeled text input. |
| ModalTextarea | label, help, layout | — | Labeled textarea. |
| ModalPasswordField | label, icon, labels | — | Masked field with toggle. |
| ModalSelect | label, name, options, icon | — | Labeled select. |
| ModalSelectOptionLabel | icon, children | — | Option with icon. |
| ModalSearchField | label, name, items | — | Searchable field. |
| ModalChoices | options, label, mode, defaultValue | mode: checkbox | Choice list. |
| ModalTags | label, options, layout | — | Multi-value chip field. |
| ModalTimeField | label, name, defaultValue, labels | — | Time of day field. |
| ModalVerification | label, length | length: 6 | One-time code input. |
| ModalFieldFrame | label, htmlFor | — | Frame for your own control. |
| ModalFieldError | label, minLength | — | Inline validation message. |
| ModalAuthFields | mode, labels | mode: login | Login or sign-up. |
| ModalShare | people, link, permissionOptions, searchLabel, linkLabel, copyLabel, copiedLabel, failedLabel, accessLabel, accessHint, permissionLabel | — | Sharing panel. |
| ModalLinkField | label, value | — | Read-only link with copy. |
| ModalCopyLink | value, appearance | appearance: link | Copy action. |
| ModalInviteEmails | label, addLabel | — | Email address list. |
| ModalMemberPicker | people, defaultSelected | — | Pick people. |
| ModalPeople | people, onRemove | — | People list with roles. |
| ModalTeamAvatars | people | — | Overlapping avatars. |
| ModalPaymentFields | defaultValue, onValueChange | — | Card fields. |
| ModalCardPreview | name, number, expiry, brand | — | Card preview. |
| ModalPlanPicker | plans, rich | rich: false | Plan choice list. |
| ModalPaymentMethods | methods, onEdit, onSetDefault | — | Card list. |
| ModalSeats | price, formatPrice | — | Seat count with total. |
| ModalDateRangeFields | value, onValueChange, presets | — | Range calendar; presets show as its shortcuts. |
| ModalDateRangePresets | presets, onValueChange | — | Deprecated preset buttons; pass presets to ModalDateRangeFields. Works until 2.0. |
| ModalDateRangeInputs | value, onValueChange, label, startLabel, endLabel | label: Date range | Footer range: a Date Range Picker without its calendar button. |
| ModalEventFields | range, onRangeChange, presets, labels | — | Create-event fields. |
| ModalEventDetails | date, time, reminder, organizer, attendees, status, onAddGuest, labels | — | Invitation details. |
| ModalMediaCarousel | slides, onFinish, onSkip | — | Slide carousel. |
| ModalImageCrop | images, value, onValueChange | — | Image crop frame. |
| ModalUpload | files, onFilesSelected, labels | — | Dropzone with files. |
| ModalTextEditor | label, name, defaultText, onValueChange, tools, labels | — | Rich text field. |
| ModalProfileFields | upload, termsHref | — | Profile fields. |
| ModalProjectFields | upload, teams, tags | — | Project fields. |
| ModalCompanyFields | upload, usernamePrefix, labels | — | Company fields. |
| ModalExperienceFields | companies, locations, employment, labels | — | Work experience. |
| ModalUserSettings | user, countries, stats, banner, onArchive, onEdit, labels | — | Profile settings. |
| ModalAppearance | defaultColor, onColorChange, labels | — | Color and theme. |
| ModalAppearancePreview | mode, banner | — | App illustration. |
| ModalBannerAppearance | options, onEditCss | — | Banner choices. |
| ModalConnection | from, to | — | Icon for two linked apps. |
| ModalChecklist | title, items | — | Heading with checked list. |
| ModalAssistant | prompts, user, users, onPromptSelect, onMore, onDictate, onAttach, onShortcuts, labels | — | Prompts and composer. |
| ModalMessage | recipients, sender, defaultTo, onAttach, onRemoveAttachment, onDiscard, onSave, onSchedule, onSnippet, labels | — | Message composer. |
`ModalTextField`, `ModalTextarea` and `ModalPasswordField` also pass native
input attributes through. Parts that submit a value name it, so a form dialog
collects the values in the `FormData` that `onSubmit` receives. The messages of
fields read in English.

Parts with words of their own take them as props. The `labels` of
`ModalAppearance`, `ModalCompanyFields`, `ModalEventDetails`,
`ModalEventFields`, `ModalExperienceFields`, `ModalUserSettings`,
`ModalAssistant`, `ModalMessage`, `ModalTextEditor`, `ModalPasswordField`,
`ModalTimeField` and `ModalUpload` take any of their words and keep the English
default for the others. `ModalPasswordField` names its show and hide toggle
with `show` and `hide`, `ModalTimeField` passes its words to the time field
and its selector, and `ModalUpload` passes File Upload's `labels` on. `ModalAuthFields`,
`ModalPaymentFields`, `ModalPaymentMethods`, `ModalMediaCarousel`,
`ModalProfileFields` and `ModalProjectFields` take a complete `labels` object.
Other parts take single props, such as `copyLabel` and `accessLabel` on
`ModalShare` or `removeLabel` on `ModalPeople`.

The types `ModalPerson`, `ModalOption`, `ModalSelectOption`,
`ModalFieldLayout`, `ModalPaymentValue`, `ModalPlan`, `ModalDateRange` and
`ModalCrop` are exported, as is `ModalTextEditorTool`, the name of a toolbar tool, and so are the label types, such as
`ModalMessageLabels`, `ModalPasswordFieldLabels` and `ModalTimeFieldLabels`,
which name every key; the installed source has the English defaults. A
`ModalDateRange` is `{ from: Date; to: Date }`, the range shape of
[Calendar](/docs/components/calendar/). The date range parts,
`ModalImageCrop` and `ModalTextEditor` report a change through
`onValueChange`; their earlier `onChange` still works as a deprecated alias.

## Usage notes

Every modal needs a `title`, even with `hideHeader`; the header then stays available to assistive technology. Icons passed as `icon` are decorative and hidden from assistive technology, so state the meaning in the title or the description as well.

On open, focus goes to the first empty text field. Without one, a confirmation, meaning a `warning` or `error` dialog or one with nothing to interact with, focuses Cancel. Without either, the first field or choice takes focus, and without that the primary action; a confirmation never opens on its primary action and focuses the dialog itself instead. Touch devices focus the popup itself so the on-screen keyboard stays closed. Use `initialFocus` to choose another target.

Escape, a click on the backdrop and Cancel close the dialog. Without the close button, after `showCloseButton={false}` or with media by default, keep a visible action that closes the dialog. For a decision that must be made before continuing, use [Alert Dialog](/docs/components/alert-dialog/) instead.

A form dialog never closes itself on submit, so keep it open while a request is pending or has failed and close it when it succeeds. Return a promise from `onSubmit` or `onConfirm`, or set `confirmLoading`, so the confirm button shows that the request is running, and show a failure with `confirmError`.

Default labels and the built-in validation messages are in English. The parts take most of their words as props, but a few words have no prop and stay in English. Among them are the corner names of the `ModalImageCrop` handles, the Edit CSS action of `ModalBannerAppearance`, the terms message of `ModalProfileFields`, the name of the help button beside a field label, the copy failure message of `ModalLinkField` and the carousel role description of `ModalMediaCarousel`, as well as the placeholders “MM/YY” in the expiry field of `ModalPaymentFields` and “name@example.com” in `ModalInviteEmails`. Kit components inside a part also keep their own English defaults where the part does not pass words on, such as the color controls of `ModalAppearance`. For another language, change these in the installed source. The date parts, `ModalDateRangeFields`, `ModalDateRangeInputs` and the calendar of `ModalEventFields`, show dates in the `en-US` format.

Below the `sm` breakpoint the dialog is a full-width bottom sheet at every `width`, and an `aside` rail moves above the content. Long content scrolls inside the panel while the header and actions stay in view.

To open a modal from a menu item or another control, pass `trigger={null}` and control the dialog with `open` and `onOpenChange`.

`ModalMediaCarousel`, `ModalImageCrop` and `ModalTextEditor` ship inside this pattern; they are not separate components.
