From ee54e86c14dfc58b77c6dac88a6a3736efbefbcf Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Wed, 21 Aug 2024 14:57:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(popup):=20popup=E5=AF=B9=E9=BD=90vue=20mob?= =?UTF-8?q?ile=20(#449)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(popup): 对齐vue mobile fix #407 * refactor(popup): demo调整 * refactor(popup): useDefaultProps 使用 * fix(popup): 修复button编译报错问题,popup demo改tsx * refactor(popup): 更新overlay 使用;动画改用 CSSTransition * refactor(popup): portal 应用 * test: update csr and ssr snap --------- Co-authored-by: anlyyao --- site/mobile/mobile.config.js | 2 +- site/web/main.jsx | 2 +- src/_common | 2 +- src/popup/Popup.tsx | 156 ++++++---- src/popup/_example/base.jsx | 65 ---- src/popup/_example/base.tsx | 48 +++ src/popup/_example/custom-close.tsx | 35 +++ src/popup/_example/index.tsx | 142 +++++++++ src/popup/_example/placement-bottom.jsx | 23 -- src/popup/_example/placement-center.jsx | 23 -- src/popup/_example/placement-left.jsx | 23 -- src/popup/_example/placement-right.jsx | 23 -- src/popup/_example/placement-top.jsx | 23 -- src/popup/_example/style/index.less | 65 ++-- src/popup/_example/with-title.tsx | 32 ++ src/popup/defaultProps.ts | 5 +- src/popup/popup.en-US.md | 24 ++ src/popup/popup.md | 23 +- src/popup/style/index.js | 2 +- src/popup/type.ts | 46 ++- test/snap/__snapshots__/csr.test.jsx.snap | 363 ++++++++++++++++++++++ test/snap/__snapshots__/ssr.test.jsx.snap | 8 + 22 files changed, 848 insertions(+), 287 deletions(-) delete mode 100644 src/popup/_example/base.jsx create mode 100644 src/popup/_example/base.tsx create mode 100644 src/popup/_example/custom-close.tsx create mode 100644 src/popup/_example/index.tsx delete mode 100644 src/popup/_example/placement-bottom.jsx delete mode 100644 src/popup/_example/placement-center.jsx delete mode 100644 src/popup/_example/placement-left.jsx delete mode 100644 src/popup/_example/placement-right.jsx delete mode 100644 src/popup/_example/placement-top.jsx create mode 100644 src/popup/_example/with-title.tsx create mode 100644 src/popup/popup.en-US.md diff --git a/site/mobile/mobile.config.js b/site/mobile/mobile.config.js index 4dc0fc04..2cf97c94 100644 --- a/site/mobile/mobile.config.js +++ b/site/mobile/mobile.config.js @@ -43,7 +43,7 @@ export default { { title: 'Popup 弹出层', name: 'popup', - component: () => import('tdesign-mobile-react/popup/_example/base.jsx'), + component: () => import('tdesign-mobile-react/popup/_example/index.tsx'), }, { title: 'Progress 进度条', diff --git a/site/web/main.jsx b/site/web/main.jsx index 2ea5f040..9b9be49d 100644 --- a/site/web/main.jsx +++ b/site/web/main.jsx @@ -2,7 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; -import '@common/style/mobile/index.less'; +// import '@common/style/mobile/index.less'; import 'tdesign-site-components'; import 'tdesign-site-components/lib/styles/style.css'; diff --git a/src/_common b/src/_common index cfcad47f..41d40c78 160000 --- a/src/_common +++ b/src/_common @@ -1 +1 @@ -Subproject commit cfcad47f9c27eaf31ad50de07347f8c07685a090 +Subproject commit 41d40c788e2793b7707ee1ca0719d3d66bba838d diff --git a/src/popup/Popup.tsx b/src/popup/Popup.tsx index a7dd811b..aba1bbe3 100644 --- a/src/popup/Popup.tsx +++ b/src/popup/Popup.tsx @@ -1,92 +1,130 @@ -import React, { FC, useState } from 'react'; +import React, { forwardRef, useMemo, useRef, useState } from 'react'; import classnames from 'classnames'; -import { useSpring, animated } from 'react-spring'; +import { CloseIcon } from 'tdesign-icons-react'; +import { CSSTransition } from 'react-transition-group'; +import { CSSTransitionClassNames } from 'react-transition-group/CSSTransition'; import Overlay from '../overlay'; import useDefault from '../_util/useDefault'; import withNativeProps, { NativeProps } from '../_util/withNativeProps'; import { TdPopupProps } from './type'; -import useConfig from '../_util/useConfig'; import { popupDefaultProps } from './defaultProps'; +import useDefaultProps from '../hooks/useDefaultProps'; +import parseTNode from '../_util/parseTNode'; +import { usePrefixClass } from '../hooks/useClass'; +import Portal from '../common/Portal'; export interface PopupProps extends TdPopupProps, NativeProps {} enum PopupSourceEnum { OVERLAY = 'overlay', + CLOSEBTN = 'close-btn', } -enum PlacementEnum { - TOP = 'top', - BOTTOM = 'bottom', - LEFT = 'left', - RIGHT = 'right', - CENTER = 'center', -} +const Popup = forwardRef((props) => { + const { + children, + placement, + showOverlay, + visible, + defaultVisible, + zIndex, + overlayProps, + preventScrollThrough, + attach, + destroyOnClose, + closeBtn, + closeOnOverlayClick, + onClose, + onClosed, + onOpen, + onOpened, + onVisibleChange, + } = useDefaultProps(props, popupDefaultProps); -const Popup: FC = (props) => { - const { children, placement, showOverlay, visible, defaultVisible, zIndex, overlayProps, onVisibleChange } = props; + const duration = 300; - const { classPrefix } = useConfig(); + const name = usePrefixClass('popup'); - const name = `${classPrefix}-popup`; + const contentRef = useRef(null); const [show, setShow] = useDefault(visible, defaultVisible, onVisibleChange); const [active, setActive] = useState(show); - const handleOverlayClick = () => { + const handleOverlayClick = (e) => { + if (!closeOnOverlayClick) return; + onClose?.(e); setShow(false, PopupSourceEnum.OVERLAY); }; - const { progress, opacity } = useSpring({ - progress: show ? 0 : 100, - opacity: show ? 1 : 0, - onStart: () => { - setActive(true); - }, - onRest: () => { - setActive(show); - }, - }); - - const contentStyle = { - transform: progress.to((p) => { - if (placement === PlacementEnum.BOTTOM) { - return `translateY(${p}%)`; - } - if (placement === PlacementEnum.TOP) { - return `translateY(-${p}%)`; - } - if (placement === PlacementEnum.LEFT) { - return `translateX(-${p}%)`; - } - if (placement === PlacementEnum.RIGHT) { - return `translateX(${p}%)`; - } + const handleCloseClick = (e) => { + onClose?.(e); + setShow(false, PopupSourceEnum.CLOSEBTN); + }; + + const contentStyle = useMemo( + () => ({ + zIndex, + display: active ? null : 'none', + animationFillMode: 'forwards', }), - opacity: opacity.to((o) => { - if (placement === PlacementEnum.CENTER) { - return o; - } + [zIndex, active], + ); + + const classNames = useMemo( + () => ({ + enterActive: placement === 'center' ? 'fade-zoom-enter-active' : `slide-${placement}-enter-active`, + exitActive: placement === 'center' ? 'fade-zoom-leave-active' : `slide-${placement}-leave-active`, }), - }; + [placement], + ); - const rootStyles = { - zIndex, - display: active ? 'block' : 'none', - }; + const closeBtnNode = !closeBtn ? null : ( +
+ {parseTNode(closeBtn, props, )} +
+ ); - return withNativeProps( - props, -
- {showOverlay && } - - {active && children} - -
, + const node = ( + <> + + { + onOpen?.(); + setActive(true); + }} + onEntered={() => { + onOpened?.(); + }} + onExited={() => { + onClosed?.(); + setActive(false); + }} + > + {withNativeProps( + props, +
+ {closeBtnNode} + {parseTNode(children)} +
, + )} +
+ ); -}; + return {node}; +}); Popup.displayName = 'Popup'; -Popup.defaultProps = popupDefaultProps; export default Popup; diff --git a/src/popup/_example/base.jsx b/src/popup/_example/base.jsx deleted file mode 100644 index 101bc0b3..00000000 --- a/src/popup/_example/base.jsx +++ /dev/null @@ -1,65 +0,0 @@ -import React, { useState } from 'react'; -import { Popup, Button } from 'tdesign-mobile-react'; -import TDemoBlock from '../../../site/mobile/components/DemoBlock'; -import TDemoHeader from '../../../site/mobile/components/DemoHeader'; -import './style/index.less' - -export default function Base() { - - const [visible1, setVisible1] = useState(false) - const [visible2, setVisible2] = useState(false) - const [visible3, setVisible3] = useState(false) - const [visible4, setVisible4] = useState(false) - const [visible5, setVisible5] = useState(false) - - const handleVisible1Change = (visible) => { - setVisible1(visible); - } - const handleVisible2Change = (visible) => { - setVisible2(visible); - } - - const handleVisible3Change = (visible) => { - setVisible3(visible); - } - - const handleVisible4Change = (visible) => { - setVisible4(visible); - } - - const handleVisible5Change = (visible) => { - setVisible5(visible); - } - - return ( -
- - -
-
- - - - - -
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- ); -} diff --git a/src/popup/_example/base.tsx b/src/popup/_example/base.tsx new file mode 100644 index 00000000..a4219680 --- /dev/null +++ b/src/popup/_example/base.tsx @@ -0,0 +1,48 @@ +import React, { useState } from 'react'; +import Button from '../../button'; +import Popup from '..'; + +const placementList = [ + { value: 'top', text: '顶部弹出' }, + { value: 'left', text: '左侧弹出' }, + { value: 'center', text: '中间弹出' }, + { value: 'bottom', text: '底部弹出' }, + { value: 'right', text: '右侧弹出' }, +] as const; + +type PlacementValue = (typeof placementList)[number]['value']; + +export default function Base() { + const [visible, setVisible] = useState(false); + const [placement, setPlacement] = useState('top'); + const onClick = (value) => { + setPlacement(value); + setVisible(true); + }; + const handleVisibleChange = (visible) => { + setVisible(visible); + }; + return ( +
+ {placementList.map((item) => ( + + ))} + +
+ ); +} diff --git a/src/popup/_example/custom-close.tsx b/src/popup/_example/custom-close.tsx new file mode 100644 index 00000000..67bbd65f --- /dev/null +++ b/src/popup/_example/custom-close.tsx @@ -0,0 +1,35 @@ +import React, { useState } from 'react'; +import { CloseCircleIcon } from 'tdesign-icons-react'; +import { Popup, Button } from 'tdesign-mobile-react'; + +export default function CustomClose() { + const [visible, setVisible] = useState(false); + + const handleVisibleChange = (visible) => { + setVisible(visible); + }; + + const onHide = () => setVisible(false); + + return ( + <> + + + + + + + ); +} diff --git a/src/popup/_example/index.tsx b/src/popup/_example/index.tsx new file mode 100644 index 00000000..3602cc11 --- /dev/null +++ b/src/popup/_example/index.tsx @@ -0,0 +1,142 @@ +import React, { useState } from 'react'; +import TDemoBlock from '../../../site/mobile/components/DemoBlock'; +import TDemoHeader from '../../../site/mobile/components/DemoHeader'; +import './style/index.less'; +import WithTitle from './with-title'; +import CustomClose from './custom-close'; +import Button from '../../button'; +import Popup from '..'; + +function PlacementBottom() { + const [visible, setVisible] = useState(false); + + const handleVisibleChange = (visible) => { + setVisible(visible); + }; + + return ( + <> + + + + + ); +} + +function PlacementTop() { + const [visible, setVisible] = useState(false); + + const handleVisibleChange = (visible) => { + setVisible(visible); + }; + + return ( + <> + + + + + ); +} + +function PlacementLeft() { + const [visible, setVisible] = useState(false); + + const handleVisibleChange = (visible) => { + setVisible(visible); + }; + + return ( + <> + + + + + ); +} + +function PlacementRight() { + const [visible, setVisible] = useState(false); + + const handleVisibleChange = (visible) => { + setVisible(visible); + }; + + return ( + <> + + + + + ); +} + +function PlacementCenter() { + const [visible, setVisible] = useState(false); + + const handleVisibleChange = (visible) => { + setVisible(visible); + }; + + return ( + <> + + + + + ); +} + +export default function Index() { + return ( +
+ + + + + + + + + + + + +
+ ); +} diff --git a/src/popup/_example/placement-bottom.jsx b/src/popup/_example/placement-bottom.jsx deleted file mode 100644 index 27473acc..00000000 --- a/src/popup/_example/placement-bottom.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, { useState } from 'react'; -import { Popup, Button } from 'tdesign-mobile-react'; -import './style/index.less' - -export default function Base() { - - const [visible, setVisible] = useState(false) - - const handleVisibleChange = (visible) => { - setVisible(visible); - } - - return ( -
-
- -
- -
-
-
- ); -} diff --git a/src/popup/_example/placement-center.jsx b/src/popup/_example/placement-center.jsx deleted file mode 100644 index 085ec390..00000000 --- a/src/popup/_example/placement-center.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, { useState } from 'react'; -import { Popup, Button } from 'tdesign-mobile-react'; -import './style/index.less' - -export default function Base() { - - const [visible, setVisible] = useState(false) - - const handleVisibleChange = (visible) => { - setVisible(visible); - } - - return ( -
-
- -
- -
-
-
- ); -} diff --git a/src/popup/_example/placement-left.jsx b/src/popup/_example/placement-left.jsx deleted file mode 100644 index 9b00d3d3..00000000 --- a/src/popup/_example/placement-left.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, { useState } from 'react'; -import { Popup, Button } from 'tdesign-mobile-react'; -import './style/index.less' - -export default function Base() { - - const [visible, setVisible] = useState(false) - - const handleVisibleChange = (visible) => { - setVisible(visible); - } - - return ( -
-
- -
- -
-
-
- ); -} diff --git a/src/popup/_example/placement-right.jsx b/src/popup/_example/placement-right.jsx deleted file mode 100644 index 182142f3..00000000 --- a/src/popup/_example/placement-right.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, { useState } from 'react'; -import { Popup, Button } from 'tdesign-mobile-react'; -import './style/index.less' - -export default function Base() { - - const [visible, setVisible] = useState(false) - - const handleVisibleChange = (visible) => { - setVisible(visible); - } - - return ( -
-
- -
- -
-
-
- ); -} diff --git a/src/popup/_example/placement-top.jsx b/src/popup/_example/placement-top.jsx deleted file mode 100644 index efbf6b2e..00000000 --- a/src/popup/_example/placement-top.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, { useState } from 'react'; -import { Popup, Button } from 'tdesign-mobile-react'; -import './style/index.less' - -export default function Base() { - - const [visible, setVisible] = useState(false) - - const handleVisibleChange = (visible) => { - setVisible(visible); - } - - return ( -
-
- -
- -
-
-
- ); -} diff --git a/src/popup/_example/style/index.less b/src/popup/_example/style/index.less index 2498b967..3991b236 100644 --- a/src/popup/_example/style/index.less +++ b/src/popup/_example/style/index.less @@ -1,35 +1,38 @@ -.tdesign-mobile-demo { - background-color: #ffffff; +.tdesign-mobile-popup-demo { + background-color: #ffffff; + flex: 1; + padding-bottom: 16px; - .vertical { - height: 240px; - background-color: #fff; - } - - .horizontal { - width: 307px; - height: 100%; - background-color: #fff; - } - - .center { - width: 88px; - height: 88px; - border-radius: 4px; - background-color: #fff; - } - - &__button-group { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; + button + button { + margin-top: 16px; + } +} + +.tdesign-mobile-popup-demo__with-title.header { + display: flex; + align-items: center; + .btn { + font-size: 16px; + padding: 16px; + &--cancel { + color: var(--td-text-color-secondary, rgba(0, 0, 0, 0.6)); } - - &__button { - width: 343px; - height: 44px; - border-radius: 4px; - margin-bottom: 16px; + &--confirm { + color: #0052d9; } + } + .title { + flex: 1; + text-align: center; + font-weight: 600; + font-size: 18px; + color: var(--td-text-color-primary, rgba(0, 0, 0, 0.9)); + } +} + +.design-mobile-popup-demo__custom-close.close-btn { + position: absolute; + left: 50%; + margin-left: -16px; + bottom: -56px; } diff --git a/src/popup/_example/with-title.tsx b/src/popup/_example/with-title.tsx new file mode 100644 index 00000000..c4c2749d --- /dev/null +++ b/src/popup/_example/with-title.tsx @@ -0,0 +1,32 @@ +import React, { useState } from 'react'; +import { Popup, Button } from 'tdesign-mobile-react'; + +export default function WithTitle() { + const [visible, setVisible] = useState(false); + + const handleVisibleChange = (visible) => { + setVisible(visible); + }; + + const onHide = () => setVisible(false); + + return ( + <> + + + +
+
+ 取消 +
+
标题文字
+
+ 确定 +
+
+
+ + ); +} diff --git a/src/popup/defaultProps.ts b/src/popup/defaultProps.ts index 0203bd6e..41f3cc40 100644 --- a/src/popup/defaultProps.ts +++ b/src/popup/defaultProps.ts @@ -5,8 +5,11 @@ import { TdPopupProps } from './type'; export const popupDefaultProps: TdPopupProps = { + attach: 'body', + closeOnOverlayClick: true, + destroyOnClose: false, overlayProps: {}, placement: 'top', + preventScrollThrough: true, showOverlay: true, - visible: false, }; diff --git a/src/popup/popup.en-US.md b/src/popup/popup.en-US.md new file mode 100644 index 00000000..5e24d03d --- /dev/null +++ b/src/popup/popup.en-US.md @@ -0,0 +1,24 @@ +:: BASE_DOC :: + +## API + +### Popup Props + +name | type | default | description | required +-- | -- | -- | -- | -- +attach | String / Function | 'body' | Typescript:`AttachNode`。[see more ts definition](https://github.com/TDesignOteam/tdesign-mobile-react/blob/develop/src/common.ts) | N +children | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/TDesignOteam/tdesign-mobile-react/blob/develop/src/common.ts) | N +closeBtn | TNode | - | Typescript:`boolean \| TNode`。[see more ts definition](https://github.com/TDesignOteam/tdesign-mobile-react/blob/develop/src/common.ts) | N +closeOnOverlayClick | Boolean | true | \- | N +destroyOnClose | Boolean | false | \- | N +overlayProps | Object | {} | Typescript:`OverlayProps`,[Overlay API Documents](./overlay?tab=api)。[see more ts definition](https://github.com/TDesignOteam/tdesign-mobile-react/tree/develop/src/popup/type.ts) | N +placement | String | top | options: top/left/right/bottom/center | N +preventScrollThrough | Boolean | true | \- | N +showOverlay | Boolean | true | \- | N +visible | Boolean | - | Typescript:`boolean` | N +zIndex | Number | - | \- | N +onClose | Function | | Typescript:`(context: { e: MouseEvent }) => void`
| N +onClosed | Function | | Typescript:`() => void`
| N +onOpen | Function | | Typescript:`() => void`
| N +onOpened | Function | | Typescript:`() => void`
| N +onVisibleChange | Function | | Typescript:`(visible: boolean, trigger: PopupSource) => void`
[see more ts definition](https://github.com/TDesignOteam/tdesign-mobile-react/tree/develop/src/popup/type.ts)。
`type PopupSource = 'close-btn' \| 'overlay'`
| N diff --git a/src/popup/popup.md b/src/popup/popup.md index 9e75cdbb..0802f43c 100644 --- a/src/popup/popup.md +++ b/src/popup/popup.md @@ -1,17 +1,24 @@ :: BASE_DOC :: ## API + ### Popup Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- -className | String | - | 类名 | N -style | Object | - | 样式,TS 类型:`React.CSSProperties` | N -children | TNode | - | 触发元素,同 triggerElement。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N -overlayProps | Object | {} | 遮罩层的属性,透传至 overlay | N +attach | String / Function | 'body' | 制定挂载节点。数据类型为 String 时,会被当作选择器处理,进行节点查询。示例:'body' 或 () => document.body。TS 类型:`AttachNode`。[通用类型定义](https://github.com/TDesignOteam/tdesign-mobile-react/blob/develop/src/common.ts) | N +children | TNode | - | 触发元素,同 triggerElement。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/TDesignOteam/tdesign-mobile-react/blob/develop/src/common.ts) | N +closeBtn | TNode | - | 是否展示关闭按钮,值为 `true` 显示默认关闭按钮;值为 `false` 则不显示关闭按钮;也可以自定义关闭按钮。TS 类型:`boolean \| TNode`。[通用类型定义](https://github.com/TDesignOteam/tdesign-mobile-react/blob/develop/src/common.ts) | N +closeOnOverlayClick | Boolean | true | 点击遮罩层是否关闭 | N +destroyOnClose | Boolean | false | 是否在关闭浮层时销毁浮层 | N +overlayProps | Object | {} | 遮罩层的属性,透传至 overlay。TS 类型:`OverlayProps`,[Overlay API Documents](./overlay?tab=api)。[详细类型定义](https://github.com/TDesignOteam/tdesign-mobile-react/tree/develop/src/popup/type.ts) | N placement | String | top | 浮层出现位置。可选项:top/left/right/bottom/center | N +preventScrollThrough | Boolean | true | 是否阻止背景滚动 | N showOverlay | Boolean | true | 是否显示遮罩层 | N -visible | Boolean | false | 是否显示浮层。TS 类型:`boolean` | N -defaultVisible | Boolean | false | 是否显示浮层。非受控属性。TS 类型:`boolean` | N +visible | Boolean | - | 是否显示浮层。TS 类型:`boolean` | N zIndex | Number | - | 组件层级,Web 侧样式默认为 5500,移动端和小程序样式默认为 1500 | N -onVisibleChange | Function | | TS 类型:`(visible: boolean, trigger: PopupSource) => void`
当浮层隐藏或显示时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/popup/type.ts)。
`type PopupSource = 'close-btn' | 'overlay'`
| N +onClose | Function | | TS 类型:`(context: { e: MouseEvent }) => void`
组件准备关闭时触发 | N +onClosed | Function | | TS 类型:`() => void`
组件关闭且动画结束后执行 | N +onOpen | Function | | TS 类型:`() => void`
组件准备展示时触发 | N +onOpened | Function | | TS 类型:`() => void`
组件展示且动画结束后执行 | N +onVisibleChange | Function | | TS 类型:`(visible: boolean, trigger: PopupSource) => void`
当浮层隐藏或显示时触发。[详细类型定义](https://github.com/TDesignOteam/tdesign-mobile-react/tree/develop/src/popup/type.ts)。
`type PopupSource = 'close-btn' \| 'overlay'`
| N diff --git a/src/popup/style/index.js b/src/popup/style/index.js index 52b4cca6..762249d7 100644 --- a/src/popup/style/index.js +++ b/src/popup/style/index.js @@ -1 +1 @@ -import '../../_common/style/mobile/components/popup/_index.less'; +import '../../_common/style/mobile/components/popup/v2/_index.less'; diff --git a/src/popup/type.ts b/src/popup/type.ts index ddb8c3c4..82298b21 100644 --- a/src/popup/type.ts +++ b/src/popup/type.ts @@ -4,15 +4,34 @@ * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC * */ -import { TNode } from '../common'; - import { OverlayProps } from '../overlay'; +import { TNode, AttachNode } from '../common'; +import { MouseEvent } from 'react'; export interface TdPopupProps { + /** + * 制定挂载节点。数据类型为 String 时,会被当作选择器处理,进行节点查询。示例:'body' 或 () => document.body + * @default 'body' + */ + attach?: AttachNode; /** * 触发元素,同 triggerElement */ children?: TNode; + /** + * 是否展示关闭按钮,值为 `true` 显示默认关闭按钮;值为 `false` 则不显示关闭按钮;也可以自定义关闭按钮 + */ + closeBtn?: TNode; + /** + * 点击遮罩层是否关闭 + * @default true + */ + closeOnOverlayClick?: boolean; + /** + * 是否在关闭浮层时销毁浮层 + * @default false + */ + destroyOnClose?: boolean; /** * 遮罩层的属性,透传至 overlay * @default {} @@ -23,6 +42,11 @@ export interface TdPopupProps { * @default top */ placement?: 'top' | 'left' | 'right' | 'bottom' | 'center'; + /** + * 是否阻止背景滚动 + * @default true + */ + preventScrollThrough?: boolean; /** * 是否显示遮罩层 * @default true @@ -30,18 +54,32 @@ export interface TdPopupProps { showOverlay?: boolean; /** * 是否显示浮层 - * @default false */ visible?: boolean; /** * 是否显示浮层,非受控属性 - * @default false */ defaultVisible?: boolean; /** * 组件层级,Web 侧样式默认为 5500,移动端和小程序样式默认为 1500 */ zIndex?: number; + /** + * 组件准备关闭时触发 + */ + onClose?: (context: { e: MouseEvent }) => void; + /** + * 组件关闭且动画结束后执行 + */ + onClosed?: () => void; + /** + * 组件准备展示时触发 + */ + onOpen?: () => void; + /** + * 组件展示且动画结束后执行 + */ + onOpened?: () => void; /** * 当浮层隐藏或显示时触发 */ diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index fe16d4e4..8131c420 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -8826,6 +8826,361 @@ exports[`csr snapshot test > csr test src/overlay/_example/index.tsx 1`] = ` `; +exports[`csr snapshot test > csr test src/popup/_example/base.tsx 1`] = ` +
+
+ + + + + + +
+`; + +exports[`csr snapshot test > csr test src/popup/_example/custom-close.tsx 1`] = ` +
+ + +
+`; + +exports[`csr snapshot test > csr test src/popup/_example/index.tsx 1`] = ` +
+
+
+

+ Popup 弹窗层 +

+

+ 由其他控件触发,屏幕滑出或弹出一块自定义内容区域 +

+
+
+
+

+ 01 组件类型 +

+

+ 基础弹出层 +

+
+
+ +