@leafygreen-ui/modal
v20.3.3
Published
LeafyGreen UI Kit Modal
Downloads
257,327
Keywords
Readme
Modal
View on MongoDB.design
Installation
PNPM
pnpm add @leafygreen-ui/modalYarn
yarn add @leafygreen-ui/modalNPM
npm install @leafygreen-ui/modalExample
v20+
import { css } from '@leafygreen-ui/emotion';
import Modal from '@leafygreen-ui/modal';
const customModalStyles = css`
// modal root styles
&::backdrop {
// modal backdrop styles
}
`;
function ExampleComponent() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(curr => !curr)}>Open Modal</button>
<Modal open={open} setOpen={setOpen} className={customModalStyles}>
<h2>Modal title</h2>
<p>More modal content</p>
<button onClick={() => {}} autoFocus>
Modal action
</button>
</Modal>
</>
);
}Pre-v20
import { css } from '@leafygreen-ui/emotion';
import Modal from '@leafygreen-ui/modal';
const customModalRootStyles = css`
// modal root styles
`;
const customBackdropStyles = css`
// modal backdrop styles
`;
function ExampleComponent() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(curr => !curr)}>Open Modal</button>
<Modal
open={open}
setOpen={setOpen}
className={customBackdropStyles}
contentClassName={customModalRootStyles}
initialFocus="#init-focus-el"
>
<h2>Modal title</h2>
<p>More modal content</p>
<button id="init-focus-el" onClick={() => {}}>
Modal action
</button>
</Modal>
</>
);
}Properties
| Prop | Type | Description | Default |
| ----------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| children | ReactNode | Content that will appear inside of the Modal component. | |
| closeIconColor (optional) | 'default' \| 'dark' \| 'light' | Determines the color of the close icon. | 'default' |
| darkMode (optional) | boolean | Determines if the component will appear in dark mode. | false |
| id (optional) | string | Unique identifier for the Modal. | |
| initialFocus (optional) | 'auto' \| string \| React.RefObject<HTMLElement> \| null | Specifies which element should receive focus when the modal opens. See Initial focus behavior for details. | 'auto' |
| open (optional) | boolean | Determines the open state of the modal. | false |
| setOpen (optional) | (open: boolean) => void \| React.Dispatch<SetStateAction<boolean>> | Callback to change the open state of the Modal. | () => {} |
| shouldClose (optional) | () => boolean | Callback to determine whether or not Modal should close when user tries to close it. | () => true |
| size (optional) | 'small' \| 'default' \| 'large' | Specifies the size of the Modal. | 'default' |
v20+
| Prop | Type | Description | Default |
| -------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| className (optional) | string | Applies a className to the Modal root element. | |
| backdropClassName (optional) | string | @deprecated (optional) Applies a className to the Modal backdrop. Use CSS ::backdrop pseudo-element instead. This prop will be removed in a future version. | |
pre-v20
| Prop | Type | Description | Default |
| ------------------------------- | -------- | -------------------------------------------------------- | ------- |
| className (optional) | string | Applies a className to the Modal backdrop. | |
| contentClassName (optional) | string | Applies a className to the Modal content wrapper element | |
Additional notes
Popover children elements
When using popover elements (tooltips, selects, etc.) inside a Modal, it is recommended that they use the top layer to ensure proper stacking and avoid rendering issues.
For LeafyGreen UI popover components, this is handled automatically in the latest versions as they default to renderMode="top-layer". If you're using custom popover implementations or need to explicitly set the render mode, ensure they use the top layer.
Initial focus behavior
When a Modal opens, it automatically manages focus to ensure proper accessibility. You can control this behavior using the initialFocus prop.
Focus Priority Order
initialFocusprop: The specified element receives focus- String selector:
initialFocus="#submit-button" - React ref:
initialFocus={submitButtonRef}(recommended over string selector for better type safety)
- String selector:
autoFocusattribute: If any child element has theautoFocusattribute, that element receives focus- First focusable element: If
initialFocusis"auto"and no child element has theautoFocusattribute, the first focusable element receives focus - No focus: If
initialFocusisnull, no automatic focus occurs
Using Clipboard.js inside Modal
To directly use the Clipboard.js library inside of Modal, rather than using the Copyable component, the reference value of the Modal should be used as the container when Clipboard.js is instantiated. You can get the reference value by consuming the usePopoverPortalContainer hook:
import { usePopoverPortalContainer } from '@leafygreen-ui/leafygreen-provider';
function ExampleComponent() {
const { portalContainer } = usePopoverPortalContainer();
const clipboard = new ClipboardJS(buttonRef, {
container: portalContainer,
});
}Backdrop styling
The preferred approach for styling the modal backdrop is to use the native CSS ::backdrop pseudo-element:
.my-modal::backdrop {
background-color: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(4px);
}The deprecated backdropClassName prop exists only to ease migration from previous Modal implementations and will be removed in a future version.
