Overlay 通用浮层
#
使用场景通用的浮层组件。<Overlay />
是一个较为底层的组件,一般不会单独进行使用。
Overlay 提供了 对话框、抽屉、弹层 等上层组件所需的共同能力,包括:
- 浮层容器
usePortal
&portalContainer
- 出现消失动画
animation
- 浮层生命周期
beforeOpen
&onOpen
... - 关闭操作与安全节点
canCloseBy*
&safeNodes
- 禁止容器滚动
disableScroll
- 背景层
hasBackdrop
很多上层组件(例如对话框)继承了来自 Overlay 的 props 和相应功能,所以本页下方的特性介绍也适用这些上层组件。
注意 Overlay 并没有提供 定位 的能力。
#
特性介绍#
浮层容器浮层组件默认会使用 React Portal 并配合 absolute 或 fix 定位方式将内容渲染到 document.body
中。如果指定了 props.portalContainer
,组件会将内容渲染到对应的容器中。rexd 组件库也提供了 OverlayBehaviorContext
用于设置浮层默认挂载节点。
在一些特殊情况下,例如「上层元素的 overflow=hidden 需要作用于浮层内容」,此时可以设置 usePortal={false}
来禁用 React Portal,组件会用常规方式来渲染浮层内容。
#
出现消失动画Overlay 封装了内容出现和消失的动画,默认动画如下:
Overlay.animations
提供了 Overlay 默认支持的动画效果,例如 Overlay.animations.fadeIn
。完整列表可以在 Overlay 源码中进行查看。rexd 中的动画效果与 animate.css 相兼容,你也可以引入 animate.css,然后使用 animate.css 提供的动画效果。例如:
你可以使用与 animate.css 相同的方式来指定动画的时长和延迟:
如果不需要使用动画,可以设置 animation={false}
。
#
浮层生命周期围绕浮层的打开和关闭,Overlay 提供了以下六个声明周期回调:
beforeOpen
浮层即将被打开时的回调- 该回调函数可以返回一个类型为
{ animation: { in: xx, out: yy } }
的 Promise 来设置「本次打开所使用的动画效果」 - 如果函数没有返回值,则使用
props.animation.in
作为「本次打开所使用的动画效果」
- 该回调函数可以返回一个类型为
onOpen
浮层打开时的回调,此时相关 DOM 元素中已经设置了 CSS animation,动画即将开始afterOpen
浮层打开后的回调,此时动画效果已经结束beforeClose
浮层即将被关闭时的回调- 该回调函数可以返回一个类型为
{ animation: { in: xx, out: yy } }
的 普通对象 来设置「本次关闭所使用的动画效果」 - 如果函数没有返回值,则使用
props.animation.out
作为「本次关闭所使用的动画效果」
- 该回调函数可以返回一个类型为
onClose
浮层关闭时的回调,此时相关 DOM 元素中已经设置了 CSS animation,动画即将开始afterClose
浮层关闭后的回调,此时动画效果已经结束- 如果浮层组件在打开状态下发生了卸载(unmount),afterClose 将不被调用
#
关闭操作与安全节点除了在上层主动控制浮层的显示或隐藏之外,浮层也提供了以下额外的关闭操作:
- 设置
canCloseByEsc={true}
后,按下 ESC 键关闭最近打开的浮层 - 设置
canCloseByOutSideClick={true}
后,点击浮层外节点关闭最近打开的浮层- 如果想让某个节点点击后不关闭浮层弹层(如:触发浮层打开的按钮),请将该节点加入到
safeNodes
中。
- 如果想让某个节点点击后不关闭浮层弹层(如:触发浮层打开的按钮),请将该节点加入到
注意:
- canClose* 需要配合 onRequestClose 才能关闭弹层
- canClose* 一次只能关闭一个浮层,同时关闭多个浮层需要通过其他方式
#
禁止容器滚动设置了 disableScroll={true}
的浮层被打开后,会给 portalContainer
追加额外的样式来禁用容器上的滚动。
多个浮层被同时打开时,只要有一个浮层设置了 disableScroll={true}
,容器的滚动就会被禁止。
如果容器没有按照预期禁用滚动,可以设置 disableScroll="force"
,此时组件将为容器附加 overflow: hidden !important;
的 CSS 样式。
#
背景层设置了 hasBackdrop={true}
的浮层被打开后,会在 portalContainer
上渲染传一个额外的背景层。
所有浮层的「背景层」和「浮层内容」的 z-index 默认值均为 1000,多个浮层被同时打开时,新打开的浮层会展示在已有浮层之上。
#
API字段 | 描述 | |
---|---|---|
overlayKey | string | |
visible* | boolean 是否显示弹层 | |
onRequestClose | (reason: any) => void 弹层请求关闭时触发事件的回调函数 | |
className | string 弹层的根节点的样式类 | |
style | CSSProperties 弹层的根节点的内联样式 | |
children | ReactNode 弹层内容 | |
renderChildren | (pass: { ref: RefObject<Element>; children: ReactNode; }) => ReactNode = Overlay.defaultRenderChildren使用 render prop 的形式指定弹层内容,用于精确控制 DOM 结构 | |
wrapperRef | Ref<HTMLDivElement> | |
safeNodes | (Node | (() => Node))[] = [] | |
attachOverlayManager | boolean = true是否关联到 portalContainer 上的 overlay manager. 该属性一般保持默认即可。 | |
浮层交互 | ||
canCloseByEsc | boolean = true是否支持 esc 按键关闭弹层 | |
canCloseByOutSideClick | boolean = true点击弹层外部区域是否关闭弹层(注意背景层也被认为是外部) | |
浮层生命周期 | ||
beforeOpen | (state?: any) => Promise<IOverlayAnimationProps> 浮层即将被打开时的回调 | |
onOpen | () => void 浮层打开时的回调 | |
afterOpen | () => void 浮层打开时的回调 | |
beforeClose | () => IOverlayAnimationProps 浮层即将被关闭时的回调 | |
onClose | () => void 浮层关闭时的回调 | |
afterClose | () => void 浮层关闭后的回调 | |
背景层 | ||
hasBackdrop | boolean 是否展示背景层 | |
backdropStyle | CSSProperties | |
backdropClassName | string | |
浮层动画 | ||
animationDuration | string = 200ms动画持续时间(注意该 prop 会作为 CSS 变量的值,使用时要带上单位,例如 `'500ms'`) | |
animation | false | { in: string | Keyframes; out: string | Keyframes; } = { in: animations.fadeIn, out: animations.fadeOut }弹层的出现和消失的动画,可以用 Overlay.animations.{name} 来引用弹层组件内置的动画效果 | |
浮层容器 | ||
usePortal | boolean = true是否使用 portal 来渲染弹层内容 | |
portalContainer | HTMLElement | "DOCUMENT_BODY" 渲染组件的容器 | |
disableScroll | boolean | "force" = false是否禁用容器的滚动 |