--- localeCode: en-US order: 55 category: Show title: Modal subTitle: Modal icon: doc-modal brief: Modals are used to wait for the user to interact, inform the user of important information, or display more information without losing context. --- ## Demos ### How to import ```jsx import import { Modal } from '@douyinfe/semi-ui'; ``` ### Basic Usage ```jsx live=true import React from 'react'; import { Modal, Button } from '@douyinfe/semi-ui'; class modalDemo extends React.Component { constructor() { super(); this.state = {visible: false}; this.showDialog = this.showDialog.bind(this); this.handleOk = this.handleOk.bind(this); this.handleCancel = this.handleCancel.bind(this); } showDialog() { this.setState({ visible: true }); } handleOk(e) { this.setState({ visible: false }); console.log('Ok button clicked'); } handleAfterClose(){ console.log('After Close callback executed'); } handleCancel(e) { this.setState({ visible: false }); console.log('Cancel button clicked'); } render() { return ( <> = 1.16.0 onCancel={this.handleCancel} closeOnEsc={true} > This is the content of a basic modal.
More content...
); } } ``` ### Mask Closable You can set `maskClosable={false}` to prevent modal from closing when clicking on the mask. ```jsx live=true import React from 'react'; import { Modal, Button } from '@douyinfe/semi-ui'; class modalDemo extends React.Component { constructor() { super(); this.state = {visible: false}; this.showDialog = this.showDialog.bind(this); this.handleOk = this.handleOk.bind(this); this.handleCancel = this.handleCancel.bind(this); } showDialog() { this.setState({ visible: true }); } handleOk(e) { this.setState({ visible: false }); } handleCancel(e) { this.setState({ visible: false }); } render() { return ( <>

This is a modal that cannot be closed by clicking on the mask.

More content...

); } } ``` ### Custom Button Text You can set button text using `okText` and `cancelText`. > In the case of creating a modal with static methods, you will have to use these two properties to set i18 texts at this moment. Because we cannot modify the React component tree, imperatively inserted components cannot consume Locale-related Context ```jsx live=true import React from 'react'; import { Modal, Button } from '@douyinfe/semi-ui'; class modalDemo extends React.Component { constructor() { super(); this.state = {visible: false}; this.showDialog = this.showDialog.bind(this); this.handleOk = this.handleOk.bind(this); this.handleCancel = this.handleCancel.bind(this); } showDialog() { this.setState({ visible: true }); } handleOk(e) { this.setState({ visible: false }); } handleCancel(e) { this.setState({ visible: false }); } render() { return ( <>

This is a modal with customized button texts.

More content...

); } } ``` ### Custom Button Properties You can set button properties using `okButtonProps` and `cancelButtonProps`. ```jsx live=true import React from 'react'; import { Modal, Button } from '@douyinfe/semi-ui'; class modalDemo extends React.Component { constructor() { super(); this.state = {visible: false}; this.showDialog = this.showDialog.bind(this); this.handleOk = this.handleOk.bind(this); this.handleCancel = this.handleCancel.bind(this); } showDialog() { this.setState({ visible: true }); } handleOk(e) { this.setState({ visible: false }); } handleCancel(e) { this.setState({ visible: false }); } render() { return ( <>

This is a modal with customized button props.

More content...

); } } ``` ### Custom Header & Footer For more customized modal, you could use `header` and `footer`. Set `header={null}` if you do not want header area, or `footer={null}` to remove footer area including buttons. ```jsx live=true import React from 'react'; import { Modal, Button } from '@douyinfe/semi-ui'; class modalDemo extends React.Component { constructor() { super(); this.state = {visible: false}; this.showDialog = this.showDialog.bind(this); this.handleOk = this.handleOk.bind(this); this.handleCancel = this.handleCancel.bind(this); } showDialog() { this.setState({ visible: true }); } handleOk(e) { this.setState({ visible: false }); } handleCancel(e) { this.setState({ visible: false }); } render() { return ( <> Yes, I Understand } >

This is a modal with a customized footer.

More content...

); } } ``` ### Custom Style You can use `style` to customize styling or position e.g. `style.top = '30vh'`, or use `centered` to center modal. Also, you could use `maskStyle` to customize mask style or `bodyStyle` for content style. ```jsx live=true import React from 'react'; import { Modal, Button } from '@douyinfe/semi-ui'; class modalDemo extends React.Component { constructor() { super(); this.state = {visible: false}; this.showDialog = this.showDialog.bind(this); this.handleOk = this.handleOk.bind(this); this.handleCancel = this.handleCancel.bind(this); } showDialog() { this.setState({ visible: true }); } handleOk(e) { this.setState({ visible: false }); } handleCancel(e) { this.setState({ visible: false }); } render() { return ( <>

Semi Design is a design system developed and maintained by IES Front-end Team and UED Team

Semi Design create a consistent, good-looking, easy-to-use, and efficient user experience with a user-centric, content-first, and human-friendly design system.

); } } ``` ### Custom Modal By using `header`, `footer`, etc, you could create any modal to your needs. ```jsx live=true import React from 'react'; import { Modal, Button, List } from '@douyinfe/semi-ui'; import { IconVigoLogo, IconSemiLogo } from '@douyinfe/semi-icons'; class modalDemo extends React.Component { constructor() { super(); this.state = {visible: false}; this.showDialog = this.showDialog.bind(this); this.handleOk = this.handleOk.bind(this); this.handleCancel = this.handleCancel.bind(this); } showDialog() { this.setState({ visible: true }); } handleOk(e) { this.setState({ visible: false }); } handleCancel(e) { this.setState({ visible: false }); } render() { const data = [ { icon: , title: 'Boost new feature adoption with Integration', content: 'Sample data is prepared for you to demostrate how Integration may be useful for your team' }, { icon: , title: 'Introducing Dark Mode', content: 'Sample data is prepared for you to demostrate how Integration may be useful for your team' }, { icon: , title: 'New List Component', content: 'Sample data is prepared for you to demostrate how Integration may be useful for your team' }, ]; const btnStyle = { width: 240, margin: '4px 50px', }; const footer = (
); return ( <>

Semi Design New Features

(
{item.title}

{item.content}

} />) } />
); } } ``` ### Full Screen Modal set `fullScreen={true}` can use full screen Modal ```jsx live=true import React from 'react'; import { Modal, Button } from '@douyinfe/semi-ui'; () => { const [visible, setVisible] = useState(false); const onClose = () => { setVisible(false); }; return ( <>

This is a full screen modal

More content...

); }; ``` ### Confirm Modal You could use static methods to create a confirm Modal. Use `icon` to customize icon. ```jsx live=true hideInDSM import React from 'react'; import { Modal, Button } from '@douyinfe/semi-ui'; import { IconSend } from '@douyinfe/semi-icons'; ModalComponent = function(props) { function success() { Modal.success({ 'title': 'This is a success message', 'content': 'bla bla bla...'}); } function info() { Modal.info({ 'title': 'Here is some info', 'content': 'bla bla bla...' }); } function error() { Modal.error({ 'title': 'Unfortunately, there is an error', 'content': 'bla bla bla...' }); } function warning() { Modal.warning({ 'title': 'Warning: be cautious ahead', 'content': 'bla bla bla...' }); } function confirm() { Modal.confirm({ 'title': 'Are you sure ?', 'content': 'bla bla bla...' }); } function custom() { Modal.info({ 'title': 'This is a custom modal', 'content': 'bla bla bla...', icon: , cancelButtonProps: { theme: 'borderless' }, okButtonProps: { theme: 'solid' }, }); } return (










); }; ``` ### useModal Hooks You could use `Modal.useModal` to create a `contextHolder` that could access context. ```jsx live=true hideInDSM import React from 'react'; import { ConfigProvider, Modal, Button } from '@douyinfe/semi-ui'; import en_GB from '@douyinfe/semi-ui/lib/es/locale/source/en_GB'; function Demo(props = {}) { const [modal, contextHolder] = Modal.useModal(); const config = { 'title': 'This is a success message', 'content': 'Context consumer' }; return (
{contextHolder}
); } ``` ## API Reference ### Modal | Properties | Instructions | type | Default | | ----------------- | -------------------------------------------------- | -- | ------- | | afterClose | Callback function when modal closed completely
**>= v1.16.0** | () => void | - | | bodyStyle | Content style | CSSProperties | - | | cancelButtonProps | Properties for cancel button | [ButtonProps](/en-US/input/button#API-reference) | - | | cancelText | Text for cancel button | string | - | | centered | Toggle whether to center modal | boolean | false | | closable | Toggle whether to show close button | boolean | true | | closeIcon | Icon for close button
**>= v1.0.0** | ReactNode | | | closeOnEsc | Toggle whether to allow close modal by keyboard event Esc
**>= v1.0.0** | boolean | true | | confirmLoading | Toggle loading state of confirm button | boolean | false | | content | Content | ReactNode | - | | footer | Footer | ReactNode | - | | fullScreen | Is modal FullScreen(will override width and height)
**>= v1.18.0** | boolean | false | | getPopupContainer | Specifies the parent DOM, and the bullet layer will be rendered to the DOM, you need to set 'position: relative`
** >= v0.33.0 ** | () => HTMLElement |() => document.body | | hasCancel | Toggle whether to show cancal button | boolean | true | | header | Header | ReactNode | - | | height | Height | number | - | | icon | Custom icon
**v1.1.0** | ReactNode | - | | keepDOM | Keep dom tree when close modal
**>= v1.0.0** | boolean | false | | lazyRender | Lazy render modal, used with `keepDOM`
**>=v1.0.0** | boolean | true | | mask | Toggle whether to show mask | boolean | true | | maskClosable | Toggle whether to allow closing when clicking mask | boolean | true | | maskStyle | Mask style | CSSProperties | - | | motion | animation switch | boolean | true | | okButtonProps | Properties for confirm button | [ButtonProps](/en-US/input/button#API-reference) | - | | okText | Text for confirm button | string | - | | okType | Type for confirm button, optional: 'primary'、'secondary'、'tertiary'、'warning'、'danger' | string | primary | | preventScroll | Indicates whether the browser should scroll the document to display the newly focused element, acting on the focus method inside the component, excluding the component passed in by the user | boolean | | | | size | Size of modal, one of `small`(448px), `medium`(684px), `large`(920px), `full-width`(100vw - 64px)
**>= v1.0.0** | string | 'small' | | style | Inline style | CSSProperties | - | | title | Title | ReactNode | - | | visible | Toggle visibility of the modal | boolean | false | | width | Width | number | 448 | | zIndex | Z-index value for mask | number | 1000 | | onCancel | Callback function when clicking cancel button | (e: any) => void \| Promise | - | | onOk | Callback function when clicking confirm button | (e: any) => void \| Promise | - | ### Static Method - `Modal.info` - `Modal.success` - `Modal.error` - `Modal.warning` - `Modal.confirm` | Properties | Instructions | type | Default | | ----------------- | -------------------------------------------------- | ----------------- | ------- | | bodyStyle | Content style | CSSProperties | - | | cancelButtonProps | Properties for cancel button | ButtonProps | - | | cancelText | Text for cancel button | string | - | | centered | Toggle whether to center modal | boolean | false | | closable | Toggle whether to show close button | boolean | true | | content | Content | ReactNode | - | | confirmLoading | Toggle loading state of confirm button | boolean | false | | footer | Footer | ReactNode | - | | header | Header | ReactNode | - | | height | Height | number | - | | icon | Customized icon | ReactNode | - | | mask | Toggle whether to show mask | boolean | true | | maskClosable | Toggle whether to allow closing when clicking mask | boolean | true | | maskStyle | Mask style | CSSProperties | - | | okButtonProps | Properties for confirm button | ButtonProps | - | | okText | Text for confirm button | string | - | | okType | Type for confirm button | string | primary | | size | Size of modal, one of `small`(448px), `medium`(684px), `large`(920px), `full-width`(100vw - 64px)
**v >= 0.33.0** | string | 'small' | | style | Inline style | CSSProperties | - | | title | Title | ReactNode | - | | width | Width | number | 520 | | zIndex | Z-index value for mask | number | 1000 | | onCancel | Callback function when clicking cancel button | (e: any) => void \| Promise | - | | onOk | Callback function when clicking confirm button | (e: any) => void \| Promise | - | Creating modal with the above methods will return a reference to the instance. You could use it to update or close the modal.| ``` const modal = Modal.info(); modal.update({ title: 'Updated Title', content: 'Updated Content', }); modal.destroy(); ``` - `Modal.destroyAll` **v>=0.37.0** You could use Modal.destroyAll() to destroy Modal that created by methods above e.g. `.info()` - `Modal.useModal` **v>=1.2.0** When you need access Context, you could use `Modal.useModal` to create a `contextHolder` and insert to corresponding DOM tree. Modal created by hooks will be able to access the context where `contextHolder` is inserted. Hook modal shares the same methods with Modal.method. ## Accessibility ### ARIA WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/ - Modal role set to `dialog` - aria-modal is set to true - aria-labelledby corresponds to Modal header - aria-describedby corresponds to Modal body ### Keyboard and focus - Modal automatically gets the focus when it is popped up, and when it is closed, the focus automatically returns to the element before it was opened. - Keyboard users can use the `Tab` key and `Shift + Tab` to move the focus within the Modal, including the Modal's own close button and OK cancel button. At this time, the elements behind the Modal cannot be tab-focused. - When Modal is opened, the focus is on the cancel button by default, which can be controlled by passing autoFocus in cancelButtonProps or okButtonProps. - By adding autoFocus to the form element that needs to be focused in the Modal content, the Modal can automatically focus on the element when it is opened (the autoFocus of cancelButtonProps needs to be set to false at the same time). - Modify the default value of closeOnEsc to true, allowing users to directly close Modal through the keyboard for a better experience ## Content Guidelines - Imperative Modal and Default Modal The title of the two modal dialogs uses the format of verb + noun, whether it is a declarative sentence or a question sentence | ✅ Recommended usage | ❌ Deprecated usage | | --- | --- | | Edit ticket | Edit | | Delete form? | Are you sure you want to delete form? | - The operation buttons of the two modal dialog boxes only need to use the verbs in the title under the premise of ensuring that the title description is clear | ✅ Recommended usage | ❌ Deprecated usage | | --- | --- | | Edit | Edit ticket | - Text specification for imperative Modal - Give a specific explanation to the title, do not repeat the information of the title - Make sure users know how to act if necessary ## Design Tokens ## FAQ - Why the button texts in Modal.confirm are not internationalized even when I use LocaleProvider? In version >= 1.2.0, you could use `Modal.useModal` to create a `contextHolder` that is accessible to config from ConfigProvider or LocaleProvider. For version before 1.2 or if you don't want to use Hooks, you could also use `okText` and `cancelText` to set i18 texts at this moment.