handleClick(event)}
+ {...rest}
>
{children ? (
children
diff --git a/src/packages/overlay/demo.scss b/src/packages/overlay/demo.scss
new file mode 100644
index 0000000..e5e8fd4
--- /dev/null
+++ b/src/packages/overlay/demo.scss
@@ -0,0 +1,16 @@
+.wrapper {
+ display: flex;
+ height: 100%;
+ align-items: center;
+ justify-content: center;
+ .content {
+ display: flex;
+ width: 150px;
+ height: 150px;
+ background: #fff;
+ border-radius: 8px;
+ align-items: center;
+ justify-content: center;
+ color: red;
+ }
+}
diff --git a/src/packages/overlay/demo.tsx b/src/packages/overlay/demo.tsx
new file mode 100644
index 0000000..55c7408
--- /dev/null
+++ b/src/packages/overlay/demo.tsx
@@ -0,0 +1,48 @@
+import React, { useState } from 'react'
+import { Overlay } from './overlay'
+import Cell from '@/packages/cell'
+import Button from '@/packages/button'
+import './demo.scss'
+
+const OverlayDemo = () => {
+ const [visible, setVisible] = useState(false)
+ const [visible2, setVisible2] = useState(false)
+ const handleToggleShow = () => {
+ setVisible(true)
+ }
+ const handleToggleShow2 = () => {
+ setVisible2(true)
+ }
+ const onClose = () => {
+ setVisible(false)
+ }
+ const onClose2 = () => {
+ setVisible2(false)
+ }
+ return (
+ <>
+
+
基础用法
+
+
+
+ |
+
嵌套内容
+
+
+
+
+
+ |
+
+ >
+ )
+}
+
+export default OverlayDemo
diff --git a/src/packages/overlay/doc.md b/src/packages/overlay/doc.md
new file mode 100644
index 0000000..cf7712f
--- /dev/null
+++ b/src/packages/overlay/doc.md
@@ -0,0 +1,49 @@
+# Overlay 组件
+
+### 介绍
+
+创建一个遮罩层,通常用于阻止用户进行其他操作
+
+### 安装
+
+
+``` javascript
+import { OverLay } from '@nutui/nutui';
+```
+
+## 代码演示
+
+### 基础用法
+
+```tsx
+
+```
+
+### 嵌套内容
+
+```tsx
+
+
+
+```
+
+## API
+
+### Props
+
+| 参数 | 说明 | 类型 | 默认值 |
+| ---------------------- | ---------------- | -------------- | ------ |
+| visible | 当前组件是否显示 | Boolean | `false` |
+| zIndex | 遮罩层级 | Number | 2000 |
+| duration | 动画时长,单位秒 | Number | 0.3 |
+| overlayClass | 自定义遮罩类名 | String | - |
+| overlayStyle | 自定义遮罩样式 | CSSProperties | - |
+| closeOnClickOverlay | 是否点击遮罩关闭 | Boolean | `true` |
+
+### Events
+
+| 事件名 | 说明 | 回调参数 |
+| ------ | ---------- | ------------ |
+| onClick | 点击时触发 | event: Event |
diff --git a/src/packages/overlay/index.ts b/src/packages/overlay/index.ts
new file mode 100644
index 0000000..7d7ebdf
--- /dev/null
+++ b/src/packages/overlay/index.ts
@@ -0,0 +1,2 @@
+import { Overlay } from './overlay'
+export default Overlay
diff --git a/src/packages/overlay/overlay.scss b/src/packages/overlay/overlay.scss
new file mode 100644
index 0000000..c4b2843
--- /dev/null
+++ b/src/packages/overlay/overlay.scss
@@ -0,0 +1,47 @@
+.nut-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: $overlay-bg-color;
+}
+.overlay-fade-enter-active {
+ animation: nut-fade-in;
+}
+.overlay-fade-leave-active {
+ animation: nut-fade-out;
+}
+.first-render {
+ display: none;
+}
+.hidden-render {
+ display: none;
+}
+@keyframes nut-fade-in {
+ 0% {
+ opacity: 0;
+ }
+
+ 1% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+@keyframes nut-fade-out {
+ 0% {
+ opacity: 1;
+ }
+
+ 1% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ }
+}
diff --git a/src/packages/overlay/overlay.tsx b/src/packages/overlay/overlay.tsx
new file mode 100644
index 0000000..6f6ceeb
--- /dev/null
+++ b/src/packages/overlay/overlay.tsx
@@ -0,0 +1,75 @@
+import React, { FunctionComponent, MouseEventHandler, useEffect, useRef, useState } from 'react'
+import bem from '@/utils/bem'
+import classNames from 'classnames'
+import './overlay.scss'
+
+export interface OverlayProps {
+ zIndex: number
+ duration: number
+ overlayClass: string
+ overlayStyle: React.CSSProperties
+ closeOnClickOverlay: boolean
+ visible: boolean
+}
+const defaultProps = {
+ zIndex: 2000,
+ duration: 0.3,
+ overlayClass: '',
+ closeOnClickOverlay: true,
+ visible: false,
+} as OverlayProps
+export const Overlay: FunctionComponent<
+ Partial
& React.HTMLAttributes
+> = (props) => {
+ const [show, setShow] = useState(false)
+ const renderRef = useRef(true)
+ const intervalRef = useRef(0)
+ const { children, zIndex, duration, overlayClass, closeOnClickOverlay, visible, ...rest } = {
+ ...defaultProps,
+ ...props,
+ }
+ useEffect(() => {
+ setShow(false)
+ }, [visible])
+ useEffect(() => {
+ return () => {
+ clearTimeout(intervalRef.current)
+ }
+ }, [])
+ const b = bem('overlay')
+ const classes = classNames(
+ {
+ [overlayClass]: true,
+ 'overlay-fade-leave-active': !renderRef.current && !visible,
+ 'overlay-fade-enter-active': visible,
+ 'first-render': renderRef.current && !visible,
+ 'hidden-render': show,
+ },
+ b('')
+ )
+ const styles = {
+ zIndex: zIndex,
+ animationDuration: `${props.duration}s`,
+ ...props.overlayStyle,
+ }
+ const handleClick: MouseEventHandler = (e) => {
+ renderRef.current = false
+ let id = setTimeout(() => {
+ setShow(true)
+ }, duration * 1000 * 0.8)
+ intervalRef.current = id
+ if (props.onClick) {
+ props.onClick(e)
+ }
+ }
+ return (
+
+
+ {children}
+
+
+ )
+}
+
+Overlay.defaultProps = defaultProps
+Overlay.displayName = 'NutOverlay'
--
GitLab