Demos
How to import
import { Modal } from '@fibrous/semi-ui-react';
Basic Usage
Code
import { useState } from 'react';
import { Modal, Button } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [visible, setVisible] = useState(false);
const showDialog = () => {
setVisible(true);
};
const handleOk = () => {
setVisible(false);
console.log('Ok button clicked');
};
const handleCancel = () => {
setVisible(false);
console.log('Cancel button clicked');
};
const handleAfterClose = () => {
console.log('After Close callback executed');
};
return (
<>
<Button onClick={showDialog}>打开弹窗</Button>
<Modal title="基本对话框" visible={visible} onOk={handleOk} afterClose={handleAfterClose} onCancel={handleCancel} closeOnEsc>
This is the content of a basic modal.
<br />
More content...
</Modal>
</>
);
}Bottom Button Fill up
Set footerFill to true to make the bottom buttons of the Modal footer fill up the arrangement.
Mask Closable
You can set maskClosable={false} to prevent modal from closing when clicking on the mask.
Code
import { useState } from 'react';
import { Modal, Button } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [visible, setVisible] = useState(false);
const showDialog = () => {
setVisible(true);
};
const handleOk = () => {
setVisible(false);
};
const handleCancel = () => {
setVisible(false);
};
return (
<>
<Button onClick={showDialog}>点击遮罩层不可关闭</Button>
<Modal title="对话框标题" visible={visible} onOk={handleOk} onCancel={handleCancel} maskClosable={false}>
<p>This is a modal that cannot be closed by clicking on the mask.</p>
<p>More content...</p>
</Modal>
</>
);
}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
Code
import { useState } from 'react';
import { Modal, Button } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [visible, setVisible] = useState(false);
const showDialog = () => {
setVisible(true);
};
const handleOk = () => {
setVisible(false);
};
const handleCancel = () => {
setVisible(false);
};
return (
<>
<Button onClick={showDialog}>自定义按钮文字</Button>
<Modal title="自定义按钮文字" visible={visible} onOk={handleOk} onCancel={handleCancel} okText="Sounds great!" cancelText="No, thanks.">
<p>This is a modal with customized button texts.</p>
<p>More content...</p>
</Modal>
</>
);
}Custom Button Properties
You can set button properties using okButtonProps and cancelButtonProps. Their onClick runs before the built-in handling and does not replace it.
Code
import { useState } from 'react';
import { Modal, Button } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [visible, setVisible] = useState(false);
const showDialog = () => {
setVisible(true);
};
const handleOk = () => {
setVisible(false);
};
const handleCancel = () => {
setVisible(false);
};
return (
<>
<Button onClick={showDialog}>自定义按钮属性</Button>
<Modal title="自定义按钮属性" visible={visible} onOk={handleOk} onCancel={handleCancel} okButtonProps={{ size: 'small', type: 'warning' }} cancelButtonProps={{ size: 'small', disabled: true }}>
<p>This is a modal with customized button props.</p>
<p>More content...</p>
</Modal>
</>
);
}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.
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.
Code
import { useState } from 'react';
import { Modal, Button } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [visible, setVisible] = useState(false);
const showDialog = () => {
setVisible(true);
};
const handleOk = () => {
setVisible(false);
};
const handleCancel = () => {
setVisible(false);
};
return (
<>
<Button onClick={showDialog}>自定义对话框样式</Button>
<Modal title="自定义样式" visible={visible} onOk={handleOk} onCancel={handleCancel} centered bodyStyle={{ overflow: 'auto', height: 200 }}>
<p style={{ lineHeight: 1.8 }}>Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。</p>
<p style={{ lineHeight: 1.8 }}>区别于其他的设计系统而言,Semi Design 以用户中心、内容优先、设计人性化为设计理念,具有以下优势:</p>
<ul>
<li>
<p>Semi Design 以内容优先进行设计。</p>
</li>
<li>
<p>更容易地自定义主题。</p>
</li>
<li>
<p>适用国际化场景。</p>
</li>
<li>
<p>效率场景加入人性化关怀</p>
</li>
</ul>
</Modal>
</>
);
}Custom Modal
By using header, footer, etc, you could create any modal to your needs.
Code
import { useState } from 'react';
import { IconVigoLogo, IconSemiLogo } from '@fibrous/semi-icons-react';
import { Modal, Button, List } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [visible, setVisible] = useState(false);
const showDialog = () => {
setVisible(true);
};
const handleOk = () => {
setVisible(false);
};
const handleCancel = () => {
setVisible(false);
};
const data = [
{
icon: <IconSemiLogo style={{ fontSize: 48 }} />,
title: 'Boost new feature adoption with Integration',
content: 'Sample data is prepared for you to demonstrate how Integration may be useful for your team',
},
{
icon: <IconVigoLogo style={{ fontSize: 48 }} />,
title: 'Introducing Dark Mode',
content: 'Sample data is prepared for you to demonstrate how Integration may be useful for your team',
},
{
icon: <IconSemiLogo style={{ fontSize: 48 }} />,
title: 'New List Component',
content: 'Sample data is prepared for you to demonstrate how Integration may be useful for your team',
},
];
const btnStyle = {
width: 240,
margin: '4px 50px',
};
const footer = (
<div style={{ textAlign: 'center' }}>
<Button type="primary" theme="solid" onClick={handleOk} style={btnStyle}>
Continue
</Button>
<Button type="primary" theme="borderless" onClick={handleCancel} style={btnStyle}>
Learn more features
</Button>
</div>
);
return (
<>
<Button onClick={showDialog}>自定义对话框</Button>
<Modal header={null} visible={visible} onOk={handleOk} onCancel={handleCancel} footer={footer}>
<h3 style={{ textAlign: 'center', fontSize: 24, margin: 40 }}>Semi Design New Features</h3>
<List
dataSource={data}
split={false}
renderItem={(item) => (
<List.Item
header={item.icon}
main={
<div>
<h6 style={{ margin: 0, fontSize: 16 }}>{item.title}</h6>
<p style={{ marginTop: 4, color: 'var(--semi-color-text-1)' }}>{item.content}</p>
</div>
}
/>
)}
/>
</Modal>
</>
);
}Full Screen Modal
set fullScreen={true} can use full screen Modal
Code
import { useState } from 'react';
import { Modal, Button } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [visible, setVisible] = useState(false);
const onClose = () => {
setVisible(false);
};
return (
<>
<Button onClick={() => setVisible(true)}>打开全屏弹窗</Button>
<Modal title="全屏对话框标题" fullScreen visible={visible} onOk={onClose} onCancel={onClose}>
<p>This is a full screen modal</p>
<p>More content...</p>
</Modal>
</>
);
}Confirm Modal
You could use static methods to create a confirm Modal. Use icon to customize icon.
Code
import { IconSend } from '@fibrous/semi-icons-react';
import { Modal, Button } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
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: <IconSend />,
cancelButtonProps: { theme: 'borderless' },
okButtonProps: { theme: 'solid' },
});
}
return (
<div>
<Button onClick={info}>Info</Button>
<br />
<br />
<Button onClick={success}>Success</Button>
<br />
<br />
<Button onClick={error} type="danger">
Error
</Button>
<br />
<br />
<Button onClick={warning} type="warning">
Warning
</Button>
<br />
<br />
<Button onClick={confirm} type="primary">
Confirm
</Button>
<br />
<br />
<Button onClick={custom}>Custom</Button>
</div>
);
}useModal Hooks
You could use Modal.useModal to create a contextHolder that could access context.
Code
import en_GB from '@fibrous/semi-foundation/locale/source/en_GB';
import { ConfigProvider, Button, Modal } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [modal, contextHolder] = Modal.useModal();
const config = { title: 'This is a success message', content: 'Context consumer' };
return (
<ConfigProvider locale={en_GB}>
<div>
<Button
onClick={() => {
modal.confirm(config);
}}
>
Confirm Modal
</Button>
</div>
{contextHolder}
</ConfigProvider>
);
}Draggable Modal
The modal content is rendered customly through modalRender, and the draggable Modal is implemented through the DragMove component.
Code
import { useState } from 'react';
import { Button, Modal, DragMove } from '@fibrous/semi-ui-react';
export default function ModalDemo() {
const [visible, setVisible] = useState(false);
return (
<div>
<Button onClick={() => setVisible(true)}>Open Modal</Button>
<Modal title="可拖拽Modal" visible={visible} centered onCancel={() => setVisible(false)} modalRender={(modal) => <DragMove positionStrategy="relative">{modal}</DragMove>}>
<p>This is the content of a basic sidesheet.</p>
<p>Here is more content...</p>
</Modal>
</div>
);
}API Reference
Modal
Props
| Property | Description | Type | Default |
|---|---|---|---|
| afterClose | Called after the dialog has fully closed. It is also called once when the dialog is unmounted while shown, or when a subtree holding it is hidden by Activity. | Type() => void | - |
| bodyStyle | Style of the dialog body. | CSSProperties | - |
| cancelButtonProps | Props of the cancel button, the same as Button. It is focused on open unless autoFocus is false. onClick runs before the built-in cancel handling, which still runs. | ButtonProps | - |
| cancelLoading | Whether the cancel button is loading. When omitted it follows the Promise returned by onCancel; pass false to turn that off. | boolean | - |
| cancelText | Cancel button text. Defaults to the locale entry Modal.cancel. | string | - |
| centered | Whether the dialog is vertically centered. | boolean | false |
| children | Body of the dialog. | React.ReactNode | - |
| className | Class name of the outermost element inside the portal. | string | - |
| closable | Whether the close button in the corner is shown. | boolean | true |
| closeIcon | Icon of the close button. null falls back to the default icon; to hide the close button, use closable={false}. | ReactNode | - |
| closeOnEsc | Whether Esc cancels the dialog. | boolean | true |
| confirmLoading | Whether the ok button is loading. When omitted it follows the Promise returned by onOk; pass false to turn that off. | boolean | - |
| content | The component does not render it; write the dialog content as children. It is used only by the options of the imperative methods such as Modal.info. | ReactNode | - |
| direction | Text direction, overriding the ConfigProvider. Without it, the ConfigProvider at the position decides. | 'ltr' | 'rtl' | - |
| footer | Replaces the default footer buttons. null hides the footer area. | ReactNode | - |
| footerFill | Whether the two buttons of the default footer fill the row. Defaults to false. | boolean | - |
| fullScreen | Whether the dialog fills the screen. width and height are ignored. | boolean | false |
| getPopupContainer | Parent element the dialog is rendered into. Without it, the getPopupContainer of the ConfigProvider is used, and document.body when that is absent too. A custom container needs position: relative; it changes where the dialog sits in the DOM, not where it is shown. | Type() => HTMLElement | - |
| hasCancel | Whether the default footer shows the cancel button. | boolean | true |
| header | Replaces the whole default header: icon, title and close button. null hides the header area. | ReactNode | - |
| height | Height of the dialog. A number is in pixels; a string is any valid CSS length. | string | number | - |
| icon | Icon before the title. | ReactNode | - |
| keepDOM | Whether the dialog content stays mounted while closed. | boolean | false |
| lazyRender | Used with keepDOM. When true, the dialog is not rendered until it is first shown. | boolean | true |
| mask | Whether the mask is shown. | boolean | true |
| maskClosable | Whether a click on the mask cancels the dialog. | boolean | true |
| maskFixed | Whether a mask confined to a custom container still covers the viewport with fixed positioning and is treated as modal (aria-modal, inert page, Tab lock, body scroll lock). | boolean | false |
| maskStyle | Style of the mask. | CSSProperties | - |
| modalContentClass | Class name of the dialog content element. | string | - |
| modalRender | Custom rendering of the dialog itself. The argument is the role="dialog" element, which the returned node must contain, for example wrapped in DragMove. | Type(node: ReactNode) => ReactNode | - |
| motion | Whether the enter and leave animations run. | boolean | true |
| okButtonProps | Props of the ok button, the same as Button. autoFocus focuses it on open. onClick runs before the built-in ok handling, which still runs. | ButtonProps | - |
| okText | Ok button text. Defaults to the locale entry Modal.confirm. | string | - |
| okType | Type of the ok button, the same as the type of Button. | OKType | "primary" |
| onCancel | Called by the cancel button, the close button, the mask and Esc; the argument is a native KeyboardEvent for Esc. A returned Promise keeps the cancel button loading until it settles. The dialog never closes itself; the caller sets visible to false. | Type(e: React.MouseEvent | KeyboardEvent) => void | Promise<any> | - |
| onOk | Called when the ok button is clicked, with the click event. A returned Promise keeps the ok button loading until it settles. The dialog never closes itself; the caller sets visible to false. | Type(e: React.MouseEvent) => void | Promise<any> | - |
| preventScroll | Whether the focus calls made by the component avoid scrolling the focused element into view. Focus calls made by the caller are not affected. Without it, the focused element is scrolled into view. | boolean | - |
| ref | Reference to the outermost div element inside the portal; null while nothing is rendered. | TypeReact.Ref<HTMLDivElement> | - |
| role | role of the dialog element, dialog by default. The imperative methods use alertdialog. | 'dialog' | 'alertdialog' | - |
| size | Width preset of the dialog: small is 448px, medium 684px, large 920px, full-width 100vw - 64px. | Size | "small" |
| style | Style of the .semi-modal dialog box. | CSSProperties | - |
| title | Title of the dialog. Without aria-label or a custom header, the title names the dialog. | ReactNode | - |
| visible | Whether the dialog is visible, controlled by the caller. | boolean | false |
| width | Width of the dialog. A number is in pixels; a string is any valid CSS length. When omitted, size decides. | string | number | - |
| zIndex | z-index of the outer layer. | number | 1000 |
role and every aria-* attribute land on the role="dialog" element, style lands on the .semi-modal dialog box, and className and other native attributes (such as id and data-*) land on the outermost element inside the portal.
The Modal component does not render content; put the dialog content in children. content is only for the static methods below.
Static Method
Modal.infoModal.successModal.errorModal.warningModal.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; when unset it follows the pending state of the Promise returned by onOk, pass false to turn that off | boolean | - |
| footer | Footer | ReactNode | - |
| header | Header | ReactNode | - |
| height | Height | string | 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 | - |
| modalContentClass | The class name that can be used to set the style of the dialog content | string | - |
| modalRender | Custom rendering Modal | (modal: ReactNode) => ReactNode | - |
| motion | Animation switch; changing it with update takes effect too | boolean | true |
| okButtonProps | Properties for confirm button; its onClick runs before the built-in handling and does not replace it | 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) | string | 'small' |
| style | Inline style | CSSProperties | - |
| title | Title | ReactNode | - |
| width | Width; when unset, size decides (448 for small) | string | number | - |
| zIndex | Z-index value for mask | number | 1000 |
| onCancel | Callback function when clicking cancel button; closing with Esc passes the native KeyboardEvent | (e: React.MouseEvent | KeyboardEvent) => void | Promise<any> | - |
| onOk | Callback function when clicking confirm button | (e: any) => void | Promise<any> | - |
Creating modal with the above methods will return a reference to the instance. You could use it to update or close the modal. update takes the same props as the methods above (ModalProps) and merges them into the current config; it does not take type.
const modal = Modal.info();
modal.update({
title: 'Updated Title',
content: 'Updated Content',
});
modal.destroy();
Modal.destroyAll
You could use Modal.destroyAll() to destroy Modal that created by methods above e.g. .info()
Modal.useModal
When you need access Context, you could useModal.useModalto create acontextHolderand insert to corresponding DOM tree. Modal created by hooks will be able to access the context wherecontextHolderis inserted. Hook modal shares the same methods with Modal.method.
Accessibility
ARIA
WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
- The Modal component has role
dialog, following the APG Dialog (Modal) pattern - Confirm dialogs (
Modal.confirm,info,success,warning,error, and the same-nameduseModalmethods) have rolealertdialog, andaria-describedbypoints to the message, following the APG Alert Dialog pattern - aria-modal is set to true when the dialog is modal. A dialog is modal when it has a mask (
mask) and is mounted in the body (judged by the actual container, so thegetPopupContainerof ConfigProvider counts) or hasmaskFixed. Withmask={false}, or a mask confined to a custom container, the page behind stays usable and aria-modal is omitted - aria-labelledby corresponds to the dialog title; it is not generated when
aria-labelor a custom header is given - The Modal component does not set aria-describedby by default: when the body holds a form, a list or several paragraphs, reading it out whole gets in the way. Pass it yourself when needed
roleand everyaria-*attribute passed by the caller land on the element that carries the role- The close button's aria-label comes from the current locale ('Close' in English, '关闭' in Simplified Chinese)
Keyboard and focus
- Modal automatically gets the focus when it is popped up. An element with
autoFocus(autofocusin Vue) inside the dialog gets the focus first; otherwise the cancel button does by default, which can be controlled by passing autoFocus in cancelButtonProps or okButtonProps. WithkeepDOM, opening it again gives the same result; withkeepDOMandlazyRender={false}that starts hidden, anautoFocuselement cannot take focus underdisplay: none, so later openings land on the default button. - When a modal dialog is closed, the focus automatically returns to the element before it was opened. Keyboard users can use the
Tabkey andShift + Tabto move the focus in a loop within the Modal, including the Modal's own close button and OK cancel button. At this time, the page behind the Modal cannot be interacted with or tab-focused. - A non-modal dialog (
mask={false}, or a mask confined to a custom container withoutmaskFixed) also takes focus when opened, but does not lock Tab and the rest of the page stays usable. When closed, focus is returned only if it is still inside the dialog or has fallen to the body; focus the user has moved elsewhere on the page stays. A Modal in the body withmask={false}does not lock body scrolling. - 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
| Sass variable | Value | Usage |
|---|---|---|
| $animation_duration-modal-show | 120ms | 弹窗打开-动画持续时间 |
| $animation_function-modal-show | cubic-bezier(0.215, 0.61, 0.355, 1) | 弹窗打开-过渡曲线 |
| $animation_delay-modal-show | 0ms | 弹窗打开-延迟时间 |
| $animation_duration-modal-hide | 120ms | 弹窗关闭-动画持续时间 |
| $animation_function-modal-hide | cubic-bezier(0.215, 0.61, 0.355, 1) | 弹窗关闭-过渡曲线 |
| $animation_delay-modal-hide | 0ms | 弹窗关闭-延迟时间 |
| $animation_duration-modal_mask-show | 90ms | 弹窗打开时-蒙层颜色-动画持续时间 |
| $animation_function-modal_mask-show | cubic-bezier(0.215, 0.61, 0.355, 1) | 弹窗打开时-蒙层颜色-过渡曲线 |
| $animation_delay-modal_mask-show | 0ms | 弹窗打开时-蒙层颜色-延迟时间 |
| $animation_duration-modal_mask-hide | 90ms | 弹窗关闭时-蒙层颜色-动画持续时间 |
| $animation_function-modal_mask-hide | cubic-bezier(0.215, 0.61, 0.355, 1) | 弹窗关闭时-蒙层颜色-过渡曲线 |
| $animation_delay-modal_mask-hide | 0ms | 弹窗关闭时-蒙层颜色-延迟时间 |
| $animation_transform_scale-modal_content-open | 0.7 | 弹窗打开时-缩放比例 |
| $animation_opacity-modal_content-open | 0 | 弹窗打开时-起始透明度 |
| $animation_transform_scale-modal_content-close | 0.7 | 弹窗关闭时-缩放比例 |
| $animation_opacity-modal_content-close | 0 | 弹窗关闭时-起始透明度 |
| $animation_opacity-modal_mask-open | 0 | 弹窗打开时-蒙层起始透明度 |
| $animation_opacity-modal_mask-close | 0 | 弹窗关闭时-蒙层起始透明度 |
| $color-modal-bg | var(--semi-color-bg-2) | 模态框背景颜色 |
| $color-modal_mask-bg | var(--semi-color-overlay-bg) | 模态框蒙层颜色 |
| $color-modal_main-text | var(--semi-color-text-0) | 模态框文字颜色 |
| $color-modal_info-icon | var(--semi-color-info) | 模态框信息图标颜色 |
| $color-modal_primary-icon | var(--semi-color-primary) | 模态框主要图标颜色 |
| $color-modal_success-icon | var(--semi-color-success) | 模态框成功图标颜色 |
| $color-modal_danger-icon | var(--semi-color-danger) | 模态框危险图标颜色 |
| $color-modal_warning-icon | var(--semi-color-warning) | 模态框警告图标颜色 |
| $color-modal_content-border | var(--semi-color-border) | 模态框描边颜色 |
| $color-modal_header-bg | transparent | 模态框 header 背景填充色 |
| $color-modal_footer-bg | transparent | 模态框 footer 背景填充色 |
| $spacing-modal-marginY | 80px | 模态框距容器顶部外边距 |
| $spacing-modal-marginX | auto | 模态框水平外边距(默认居中) |
| $spacing-modal_mask-top | 0 | 模态框蒙层顶部位置 |
| $spacing-modal_mask-right | 0 | 模态框蒙层右侧位置 |
| $spacing-modal_mask-bottom | 0 | 模态框蒙层底部位置 |
| $spacing-modal_mask-left | 0 | 模态框蒙层左侧位置 |
| $spacing-modal_content_withicon-marginLeft | 36px | 模态框蒙层左侧位置 |
| $spacing-modal_icon_wrapper-marginRight | $spacing-base-tight | 模态框图标右侧外边距 |
| $spacing-modal_wrap-top | 0 | |
| $spacing-modal_wrap-right | 0 | |
| $spacing-modal_wrap-bottom | 0 | |
| $spacing-modal_wrap-left | 0 | |
| $spacing-modal_title-margin | 0 | 模态框标题外边距 |
| $spacing-modal_content-paddingY | 0 | 模态框内容垂直内边距 |
| $spacing-modal_content-paddingX | 24px | 模态框内容水平内边距 |
| $spacing-modal_header-marginY | 24px | 模态框标题垂直外边距 |
| $spacing-modal_header-marginX | 0 | 模态框标题水平外边距 |
| $spacing-modal_header-paddingY | 0 | |
| $spacing-modal_header-paddingX | 0 | |
| $spacing-modal_body_wrapper-marginY | 24px | |
| $spacing-modal_body_wrapper-marginX | 0 | |
| $spacing-modal_body-margin | 0 | 模态框 body 外边距 |
| $spacing-modal_body-padding | 0 | 模态框 内容外Padding |
| $spacing-modal_footer-marginY | 24px | 模态框 footer 垂直外边距 |
| $spacing-modal_footer-marginX | 0 | 模态框 footer 水平外边距 |
| $spacing-modal_footer-paddingY | 0 | |
| $spacing-modal_footer-paddingX | 0 | |
| $spacing-modal_footer_button-marginLeft | $spacing-base-tight | 模态框 footer 按钮左侧外边距 |
| $spacing-modal_confirm_header-marginBottom | 8px | 命令式调用模态框 header 底部外边距 |
| $spacing-modal_confirm_icon_wrapper-marginRight | $spacing-base-tight | 命令式调用模态框图标右侧外边距 |
| $spacing-modal_content_fullscreen-top | 0px | 模态框内容全屏顶部位置 |
| $width-modal_title | 100% | 模态框标题宽度 |
| $width-modal_content | 100% | 模态框内容宽度 |
| $height-modal_content | max-content | 模态框内容高度 |
| $width-modal_content-border | 1px | 模态框内容描边宽度 |
| $width-modal_small | 448px | 模态框宽度 - 小 |
| $width-modal_medium | 684px | 模态框宽度 - 中 |
| $width-modal_large | 920px | 模态框宽度 - 大 |
| $width-modal_full_width | calc(100vw - 64px) | 模态框宽度 - 全屏 |
| $radius-modal_content | var(--semi-border-radius-large) | 模态框圆角大小 |
| $radius-modal_content_fullscreen | 0 | 模态框圆角大小 - 全屏 |
| $radius-modal_footer | 0 0 5px 5px | 模态框 footer 圆角大小 |
| $font-modal_header-fontSize | $font-size-regular | 模态框 title 字号 |
| $font-modal_header-fontWeight | $font-weight-bold | 模态框 title 字重 |
| $color-modal_header-border | transparent | 模态框 header 底部描边颜色 |
| $width-modal_header-border | 0 | 模态框 header 底部描边宽度 |
| $color-modal_footer-border | transparent | 模态框 footer 顶部描边颜色 |
| $width-modal_footer-border | 0 | 模态框 footer 顶部描边宽度 |
| $shadow-modal_content | var(--semi-shadow-elevated) | |
| $filter-modal_mask-bg | none | |
| $filter-modal_content-bg | none |
FAQ
-
Why the button texts in Modal.confirm are not internationalized even when I use LocaleProvider?
You could use
Modal.useModalto create acontextHolderthat is accessible to config from ConfigProvider or LocaleProvider.If you don't want to use Hooks, you could also use
okTextandcancelTextto set i18 texts at this moment. -
Why is the spacing between title and content different under imperative and non-imperative calls?
In the imperative call scenario, the title and content are more closely related, so expressing this strong correlation with a closer distance is in line with expectations. If users don't want this effect, they can do their own style overrides.