Dialog

Dialog is a container to display content in an overlay window.

Usage#

import { Dialog } from 'primereact/dialog';
<Dialog>
    <Dialog.Trigger />
    <Dialog.Portal>
        <Dialog.Header>
            <Dialog.Title />
            <Dialog.HeaderActions>
                <Dialog.Maximizable />
                <Dialog.Close />
            </Dialog.HeaderActions>
        </Dialog.Header>
        <Dialog.Content />
        <Dialog.Footer />
    </Dialog.Portal>
</Dialog>

Examples#

Basic#

Dialog is defined using Dialog, Dialog.Trigger, Dialog.Portal, Dialog.Header, Dialog.Content and Dialog.Footer components.

import { DialogContentInstance } from '@primereact/types/shared/dialog';
import { Button } from 'primereact/button';
import { Dialog } from 'primereact/dialog';
import { InputText } from 'primereact/inputtext';
import { Label } from 'primereact/label';
 
export default function BasicDemo() {
    return (
        <div className="card flex justify-center">
            <Dialog modal>
                <Dialog.Trigger>Show</Dialog.Trigger>
                <Dialog.Portal style={{ width: '25rem' }}>
                    <Dialog.Header>
                        <Dialog.Title>Edit Profile</Dialog.Title>
                        <Dialog.Close />
                    </Dialog.Header>
                    <Dialog.Content>
                        {(instance: DialogContentInstance) => {
                            const { dialog } = instance;
 
                            return (
                                <>
                                    <span className="text-surface-500 dark:text-surface-400 block mb-8">Update your information.</span>
                                    <div className="flex items-center gap-4 mb-4">
                                        <Label htmlFor="username" className="font-semibold w-24">
                                            Username
                                        </Label>
                                        <InputText id="username" className="flex-auto" autoComplete="off" />
                                    </div>
                                    <div className="flex items-center gap-4 mb-8">
                                        <Label htmlFor="email" className="font-semibold w-24">
                                            Email
                                        </Label>
                                        <InputText id="email" className="flex-auto" autoComplete="off" />
                                    </div>
                                    <div className="flex justify-end gap-2">
                                        <Button onClick={dialog?.close} severity="secondary">
                                            Cancel
                                        </Button>
                                        <Button onClick={dialog?.close}>Sign-In</Button>
                                    </div>
                                </>
                            );
                        }}
                    </Dialog.Content>
                </Dialog.Portal>
            </Dialog>
        </div>
    );
}

Position#

The position of the dialog can be customized with the position property. The available values are top, top-left, top-right, bottom, bottom-left, bottom-right, left, right, and center.

import { DialogChangeEvent, DialogContentInstance, DialogProps } from '@primereact/types/shared/dialog';
import { Button } from 'primereact/button';
import { Dialog } from 'primereact/dialog';
import { InputText } from 'primereact/inputtext';
import { Label } from 'primereact/label';
import * as React from 'react';
 
export default function PositionDemo() {
    const [open, setOpen] = React.useState<boolean>(false);
    const [position, setPosition] = React.useState<DialogProps['position']>('center');
 
    const openPosition = (position: DialogProps['position']) => {
        setOpen(true);
        setPosition(position);
    };
 
    return (
        <div className="card">
            <div className="flex flex-wrap justify-center gap-2 mb-2">
                <Button onClick={() => openPosition('left')} severity="secondary" style={{ minWidth: '10rem' }}>
                    Left
                    <i className="pi pi-arrow-right" />
                </Button>
                <Button onClick={() => openPosition('right')} severity="secondary" style={{ minWidth: '10rem' }}>
                    Right
                    <i className="pi pi-arrow-left" />
                </Button>
            </div>
            <div className="flex flex-wrap justify-center gap-2 mb-2">
                <Button onClick={() => openPosition('topleft')} severity="secondary" style={{ minWidth: '10rem' }}>
                    TopLeft
                    <i className="pi pi-arrow-down-right" />
                </Button>
                <Button onClick={() => openPosition('top')} severity="secondary" style={{ minWidth: '10rem' }}>
                    Top
                    <i className="pi pi-arrow-down" />
                </Button>
                <Button onClick={() => openPosition('topright')} severity="secondary" style={{ minWidth: '10rem' }}>
                    TopRight
                    <i className="pi pi-arrow-down-left" />
                </Button>
            </div>
            <div className="flex flex-wrap justify-center gap-2">
                <Button onClick={() => openPosition('bottomleft')} severity="secondary" style={{ minWidth: '10rem' }}>
                    BottomLeft
                    <i className="pi pi-arrow-up-right" />
                </Button>
                <Button onClick={() => openPosition('bottom')} severity="secondary" style={{ minWidth: '10rem' }}>
                    Bottom
                    <i className="pi pi-arrow-up" />
                </Button>
                <Button onClick={() => openPosition('bottomright')} severity="secondary" style={{ minWidth: '10rem' }}>
                    BottomRight
                    <i className="pi pi-arrow-up-left" />
                </Button>
            </div>
            <Dialog open={open} onOpenChange={(e: DialogChangeEvent) => setOpen(e.value as boolean)} modal position={position} draggable={false}>
                <Dialog.Portal style={{ width: '25rem' }}>
                    <Dialog.Header>
                        <Dialog.Title>Edit Profile</Dialog.Title>
                        <Dialog.HeaderActions>
                            <Dialog.Close />
                        </Dialog.HeaderActions>
                    </Dialog.Header>
                    <Dialog.Content>
                        {(instance: DialogContentInstance) => {
                            const { dialog } = instance;
 
                            return (
                                <>
                                    <span className="text-surface-500 dark:text-surface-400 block mb-8">Update your information.</span>
                                    <div className="flex items-center gap-4 mb-4">
                                        <Label htmlFor="username" className="font-semibold w-24">
                                            Username
                                        </Label>
                                        <InputText id="username" className="flex-auto" autoComplete="off" />
                                    </div>
                                    <div className="flex items-center gap-4 mb-8">
                                        <Label htmlFor="email" className="font-semibold w-24">
                                            Email
                                        </Label>
                                        <InputText id="email" className="flex-auto" autoComplete="off" />
                                    </div>
                                    <div className="flex justify-end gap-2">
                                        <Button type="button" severity="secondary" onClick={dialog?.close}>
                                            Cancel
                                        </Button>
                                        <Button type="button" onClick={dialog?.close}>
                                            Save
                                        </Button>
                                    </div>
                                </>
                            );
                        }}
                    </Dialog.Content>
                </Dialog.Portal>
            </Dialog>
        </div>
    );
}

Maximizable#

A dialog can be maximized by clicking the Dialog.Maximizable button.

import { Dialog } from 'primereact/dialog';
 
export default function MaximizableDemo() {
    return (
        <div className="card flex justify-center">
            <Dialog modal>
                <Dialog.Trigger>Show</Dialog.Trigger>
                <Dialog.Portal style={{ width: '50rem' }}>
                    <Dialog.Header>
                        <Dialog.Title>Header</Dialog.Title>
                        <Dialog.HeaderActions>
                            <Dialog.Maximizable />
                            <Dialog.Close />
                        </Dialog.HeaderActions>
                    </Dialog.Header>
                    <Dialog.Content>
                        <p>
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
                            consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
                            laborum.
                        </p>
                    </Dialog.Content>
                </Dialog.Portal>
            </Dialog>
        </div>
    );
}

Without Modal#

Mask layer behind the Dialog is configured with the modal property. By default, no modal layer is added.

import { DialogContentInstance } from '@primereact/types/shared/dialog';
import { Button } from 'primereact/button';
import { Dialog } from 'primereact/dialog';
import { InputText } from 'primereact/inputtext';
import { Label } from 'primereact/label';
 
export default function WithoutModalDemo() {
    return (
        <div className="card flex justify-center">
            <Dialog>
                <Dialog.Trigger>Show</Dialog.Trigger>
                <Dialog.Portal style={{ width: '25rem' }}>
                    <Dialog.Header>
                        <Dialog.Title>Edit Profile</Dialog.Title>
                        <Dialog.HeaderActions>
                            <Dialog.Close />
                        </Dialog.HeaderActions>
                    </Dialog.Header>
                    <Dialog.Content>
                        {(instance: DialogContentInstance) => {
                            const { dialog } = instance;
 
                            return (
                                <>
                                    <span className="text-surface-500 dark:text-surface-400 block mb-8">Update your information.</span>
                                    <div className="flex items-center gap-4 mb-4">
                                        <Label htmlFor="username" className="font-semibold w-24">
                                            Username
                                        </Label>
                                        <InputText id="username" className="flex-auto" autoComplete="off" />
                                    </div>
                                    <div className="flex items-center gap-4 mb-8">
                                        <Label htmlFor="email" className="font-semibold w-24">
                                            Email
                                        </Label>
                                        <InputText id="email" className="flex-auto" autoComplete="off" />
                                    </div>
                                    <div className="flex justify-end gap-2">
                                        <Button type="button" severity="secondary" onClick={dialog?.close}>
                                            Cancel
                                        </Button>
                                        <Button type="button" onClick={dialog?.close}>
                                            Save
                                        </Button>
                                    </div>
                                </>
                            );
                        }}
                    </Dialog.Content>
                </Dialog.Portal>
            </Dialog>
        </div>
    );
}

Accessibility#

Screen Reader#

Dialog component uses dialog role along with aria-labelledby referring to the header element however any attribute is passed to the root element so you may use aria-labelledby to override this default behavior. In addition aria-modal is added since focus is kept within the popup.

Trigger element also has aria-expanded and aria-controls to be handled explicitly.

Overlay Keyboard Support#

KeyFunction
tabMoves focus to the next the focusable element within the dialog if modal is true. Otherwise, the focusable element in the page tab sequence.
shift + tabMoves focus to the previous the focusable element within the dialog if modal is true. Otherwise, the focusable element in the page tab sequence.
escapeCloses the dialog if closeOnEscape is true.

Close Button Keyboard Support#

KeyFunction
enterCloses the dialog.
spaceCloses the dialog.