Skip to content
BigBang

Popular

    ↑↓Navigate↵OpenEscClose
    TR

    Components

    Dialog

    A modal window over the page that holds focus for one task or decision.

    Storybook
    Storybook
    Source
    Source

    The example below loads live from Storybook; open it in Storybook to use the controls.

    Live example, StorybookOpen in Storybook

    The title is required and names the dialog. The description is read with it. Actions sit at the bottom, the most important one last; the cancel button is wrapped in Dialog.Close.

    import { Button, Dialog } from '@bigbang/ui';
    export default function Default() {
    return (
    <Dialog
    trigger={<Button>Open dialog</Button>}
    title="Dialog title"
    description="Dialog description goes here."
    footer={
    <>
    <Dialog.Close>
    <Button variant="secondary">Cancel</Button>
    </Dialog.Close>
    <Dialog.Close>
    <Button>Save</Button>
    </Dialog.Close>
    </>
    }
    >
    Body content goes here. Keep the dialog to one task.
    </Dialog>
    );
    }

    size: sm 400 px, md 560 px (default), lg 720 px. Below 640 px of viewport width a dismissible dialog becomes a bottom sheet.

    import { Button, Dialog } from '@bigbang/ui';
    const sizes = [
    ['sm', 'Small dialog'],
    ['md', 'Medium dialog'],
    ['lg', 'Large dialog'],
    ] as const;
    export default function Sizes() {
    return (
    <div className="flex flex-wrap gap-sm">
    {sizes.map(([size, label]) => (
    <Dialog
    key={size}
    size={size}
    trigger={<Button variant="secondary">{label}</Button>}
    title={label}
    footer={
    <Dialog.Close>
    <Button>Save</Button>
    </Dialog.Close>
    }
    >
    Body content goes here. Keep the dialog to one task.
    </Dialog>
    ))}
    </div>
    );
    }

    When the dialog opens, focus moves to the first field in the body. The submit button sits outside the form, so its form attribute links it.

    import { Button, Dialog, TextInput } from '@bigbang/ui';
    export default function WithForm() {
    return (
    <Dialog
    trigger={<Button>Open dialog</Button>}
    title="Dialog title"
    footer={
    <>
    <Dialog.Close>
    <Button variant="secondary">Cancel</Button>
    </Dialog.Close>
    <Button type="submit" form="example-dialog-form">
    Save
    </Button>
    </>
    }
    >
    <form id="example-dialog-form" className="flex flex-col gap-lg" onSubmit={(event) => event.preventDefault()}>
    <TextInput label="Field label" description="Help text goes here." />
    </form>
    </Dialog>
    );
    }

    dismissible={false}: there is no close button, and Escape and outside presses do nothing. The footer action closes it. Use it only for unavoidable situations, such as an ended session.

    import { Button, Dialog } from '@bigbang/ui';
    export default function Blocking() {
    return (
    <Dialog
    dismissible={false}
    size="sm"
    trigger={<Button variant="secondary">Open dialog</Button>}
    title="Your session has ended"
    description="Sign in again to continue."
    footer={
    <Dialog.Close>
    <Button>Sign in again</Button>
    </Dialog.Close>
    }
    />
    );
    }

    For a layout the props do not cover, use the Dialog.Root, Dialog.Popup, Dialog.Header, Dialog.Title, Dialog.Description, Dialog.Body and Dialog.Footer parts.

    Live example, StorybookOpen in Storybook

    The panel uses color-surface-raised with a color-border-overlay hairline and the shadow-overlay shadow; color-surface-scrim dims the page behind it and blur-surface-scrim blurs it. The actions sit on a color-surface-layer-1 band.

    import { Button, Dialog } from '@bigbang/ui';
    export default function Default() {
    return (
    <Dialog
    trigger={<Button>Open dialog</Button>}
    title="Dialog title"
    description="Dialog description goes here."
    footer={
    <>
    <Dialog.Close>
    <Button variant="secondary">Cancel</Button>
    </Dialog.Close>
    <Dialog.Close>
    <Button>Save</Button>
    </Dialog.Close>
    </>
    }
    >
    Body content goes here. Keep the dialog to one task.
    </Dialog>
    );
    }