API 参考
react-snappy-modal 1.2 导出的全部内容,以及每个调用的确切行为。
导出内容
默认导出是带有静态方法的 SnappyModal 类。Provider 和 Hook 是具名导出。
1import SnappyModal, {
2 SnappyModalProvider,
3 useCurrentModal,
4 useSnappyModalState,
5} from 'react-snappy-modal';SnappyModal.show(component, options?)
将 component 渲染为新的模态框,并返回在该模态框关闭时完成的 Promise<any>。每次调用都会创建一个拥有唯一 modalId 的新模态框;如果已有模态框打开,新模态框会叠加在上面,而不是替换它。
options 会合并到下方选项表的默认值之上。
1const result = await SnappyModal.show(<MyModal />, { layer: 1 });SnappyModal.close(value?, layerOrId = 0)
关闭一个模态框,并以 value resolve 其 Promise。layerOrId 用于选择目标:数字(或数字字符串)视为层级,其他值视为 modalId。默认是层级 0。
如果目标层级上有多个模态框,关闭的是该层级中最早打开的那个,而不是最新的。没有匹配的模态框时什么也不做,也不会报错。
1SnappyModal.close('done'); // first modal on layer 0
2SnappyModal.close('done', 1); // first modal on layer 1
3SnappyModal.close('done', modalId); // one specific modalSnappyModal.throw(error?, layerOrId = 0)
与 close() 相同,但以 error reject Promise。仅在调用方需要把结果当作失败处理时使用,并始终配合 try/catch,否则会被报告为未处理的 rejection。
1try {
2 await SnappyModal.show(<UploadModal />);
3} catch (error) {
4 // SnappyModal.throw(new Error('Upload failed')) lands here
5}SnappyModal.isShow()
至少有一个模态框打开时返回 true。它只读取一次状态,不会触发重新渲染。需要响应变化的组件请使用 useSnappyModalState()。
1if (!SnappyModal.isShow()) {
2 SnappyModal.show(<Welcome />);
3}useCurrentModal()
只能在由 show() 渲染的组件内使用。返回 resolveModal(value)、rejectModal(error),以及该模态框的 layer 和 modalId。
resolveModal 和 rejectModal 按 ID 关闭渲染它们的那个模态框,因此即使同一层级有多个模态框也能准确关闭。在模态框组件内应优先使用它们,而不是静态方法。
1function Confirm() {
2 const { resolveModal, rejectModal, layer, modalId } = useCurrentModal();
3 return <button onClick={() => resolveModal(true)}>OK</button>;
4}useSnappyModalState()
订阅模态框栈,并在模态框打开或关闭时重新渲染。有模态框打开时 isShow 为 true;modalProgress 按渲染顺序列出已打开的模态框,每项包含 modalId 和合并后的 options。
1function ModalCount() {
2 const { isShow, modalProgress } = useSnappyModalState();
3 return isShow ? <span>{modalProgress.length} open</span> : null;
4}<SnappyModalProvider>
在 children 之后渲染所有已打开的模态框,并应用滚动锁定。在应用根部附近挂载且只挂载一次。
1<SnappyModalProvider>
2 <App />
3</SnappyModalProvider>选项
选项作为 show() 的第二个参数传入。每个模态框都有自己的选项。
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
allowOutsideClick | boolean | true | 为 true 时,点击内容外部会关闭模态框,并以 undefined resolve Promise。在用户必须做出选择的流程中请设为 false。 |
allowScroll | boolean | false | 为 false 时,模态框打开期间固定后面的页面,关闭时恢复滚动位置。只要任一已打开的模态框设置了 allowScroll: false,锁定就会保持。 |
backdrop | boolean | string | true | true 会使模态框后面的页面变暗,false 则去除遮罩。两种情况下全屏点击区域都存在,因此外部点击仍遵循 allowOutsideClick。 |
position | string | 'center' | 内容在 3×3 网格中的位置:top-left、top-center、top-right、center-left、center、center-right、bottom-left、bottom-center、bottom-right 之一。 |
zIndex | number | 1000 | 模态框区域的 CSS z-index。省略时使用样式表默认值 1000。 |
layer | number | 0 | 叠加分组。已打开的模态框按 layer 排序,层级越高越靠上渲染,并可通过 close(value, layer) 指定。 |
className | string | - | 添加到内容包装器(.snappy-modal-content)的类名。 |
style | React.CSSProperties | - | 应用于内容包装器的内联样式。 |
自定义背景颜色
在 1.2.1 版本中,给 backdrop 传入字符串会设置 --snappy-modal-backdrop CSS 变量,但内置样式表读取的是 --snappy-modal-backdrop-color,因此颜色不会生效。请改为在 CSS 中直接设置颜色。
1.snappy-modal-area.backdrop {
2 --snappy-modal-backdrop-color: rgba(15, 23, 42, 0.8);
3}layerOrId 的解析规则
close() 和 throw() 使用相同的规则查找目标。
- 数字和数字字符串(如
1或"1")是层级,其他字符串是modalId。 - 省略该参数时以层级
0为目标。 - 指定层级时,选择该层级中最早打开的模态框。
- 没有匹配的模态框时什么也不会发生。
为结果指定类型
show() 返回 Promise<any>。用一个小型泛型辅助函数包装它,调用方就能得到准确的结果类型。外部点击会无值 resolve,因此请在联合类型中保留 undefined。
1import type { ReactElement } from 'react';
2import SnappyModal from 'react-snappy-modal';
3
4type SnappyModalOptions = Parameters<typeof SnappyModal.show>[1];
5
6export function showModal<T>(
7 element: ReactElement,
8 options?: SnappyModalOptions,
9): Promise<T | undefined> {
10 return SnappyModal.show(element, options);
11}
12
13const confirmed = await showModal<boolean>(<Confirm />); // boolean | undefined