From d262fbd1eeaabd085af725df6b8f26ace01c07a4 Mon Sep 17 00:00:00 2001 From: LuckyFBB <976060700@qq.com> Date: Mon, 14 Oct 2024 16:36:40 +0800 Subject: [PATCH 1/2] fix(slidepane): add two types and close ways --- src/drawer/__tests/index.test.tsx | 26 ++++++++++++++-- src/drawer/demos/basic_mask.tsx | 36 --------------------- src/drawer/demos/basic_two.tsx | 34 ++++++++++++++++++++ src/drawer/demos/basic_type.tsx | 52 +++++++++++++++++++++++++++++++ src/drawer/index.md | 30 +++++++++--------- src/drawer/index.tsx | 39 ++++++++++++++++------- src/drawer/style.scss | 7 +++++ 7 files changed, 160 insertions(+), 64 deletions(-) delete mode 100644 src/drawer/demos/basic_mask.tsx create mode 100644 src/drawer/demos/basic_two.tsx create mode 100644 src/drawer/demos/basic_type.tsx diff --git a/src/drawer/__tests/index.test.tsx b/src/drawer/__tests/index.test.tsx index cef233e1b..902693717 100644 --- a/src/drawer/__tests/index.test.tsx +++ b/src/drawer/__tests/index.test.tsx @@ -3,7 +3,7 @@ import { fireEvent, render } from '@testing-library/react'; import { alert } from 'ant-design-testing'; import '@testing-library/jest-dom/extend-expect'; -import Drawer from '../index'; +import Drawer, { DrawerType } from '../index'; describe('test Drawer ', () => { test('snapshot match', () => { @@ -27,18 +27,23 @@ describe('test Drawer ', () => { const domLoading = document.querySelector('.ant-spin-spinning'); expect(domLoading).not.toBe(null); }); - test('should render mask correct ', () => { + test('should render mask/maskClosable correct', () => { const { unmount } = render(Hello World); const dom = document.querySelector('.dtc-drawer-mask'); expect(dom).toBe(null); unmount(); + const fn = jest.fn(); render( - + Hello World ); const domMask = document.querySelector('.dtc-drawer-mask'); + const domIcon = document.querySelector('.dtc-drawer-header--icon'); expect(domMask).not.toBe(null); + expect(domIcon).toBe(null); + fireEvent.click(domMask as Element); + expect(fn).toHaveBeenCalledTimes(1); }); test('should render width correct', () => { render( @@ -171,4 +176,19 @@ describe('test Drawer ', () => { fireEvent.click(oImg); expect(fn).toHaveBeenCalledTimes(1); }); + + test('should render from type', () => { + const fn = jest.fn(); + render( + + Hello World + + ); + const mask = document.querySelector('.dtc-drawer-mask'); + expect(mask).not.toBe(null); + const domIcon = document.querySelector('.dtc-drawer-header--icon'); + expect(domIcon).not.toBe(null); + fireEvent.click(mask as Element); + expect(fn).toHaveBeenCalledTimes(0); + }); }); diff --git a/src/drawer/demos/basic_mask.tsx b/src/drawer/demos/basic_mask.tsx deleted file mode 100644 index 99e79ff3b..000000000 --- a/src/drawer/demos/basic_mask.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { useState } from 'react'; -import { Button, Slider } from 'antd'; -import { Drawer } from 'dt-react-component'; - -export default () => { - const [visible, setVisible] = useState(false); - const [width, setWidth] = useState(80); - - return ( - <> - setWidth(value)} - /> - width:{width}% - - setVisible(false)} - title="title" - mask - > -
hello world
-
- - ); -}; diff --git a/src/drawer/demos/basic_two.tsx b/src/drawer/demos/basic_two.tsx new file mode 100644 index 000000000..dfdd8dadc --- /dev/null +++ b/src/drawer/demos/basic_two.tsx @@ -0,0 +1,34 @@ +import React, { useState } from 'react'; +import { Button } from 'antd'; +import { Drawer } from 'dt-react-component'; +import { DrawerType } from 'dt-react-component/drawer'; + +export default () => { + const [firstVisible, setFirstVisible] = useState(false); + const [secondVisible, setSecondVisible] = useState(false); + + return ( + <> + + setFirstVisible(false)} title="一级弹窗"> +
一级弹窗
+ + setSecondVisible(false)} + title="二级弹窗" + type={DrawerType.Form} + > +
一级弹窗
+
+
+ + ); +}; diff --git a/src/drawer/demos/basic_type.tsx b/src/drawer/demos/basic_type.tsx new file mode 100644 index 000000000..955843f53 --- /dev/null +++ b/src/drawer/demos/basic_type.tsx @@ -0,0 +1,52 @@ +import React, { useState } from 'react'; +import { Button, Space, Switch } from 'antd'; +import { Drawer } from 'dt-react-component'; +import { DrawerType } from 'dt-react-component/drawer'; + +export default () => { + const [visible, setVisible] = useState(false); + const [mask, setMask] = useState(false); + const [maskClosable, setMaskClosable] = useState(false); + const [type, setType] = useState(DrawerType.Normal); + + return ( + <> + + + + + + mask: + setMask(checked)} /> + maskClosable: + setMaskClosable(checked)} /> + + setVisible(false)} + title="title" + mask={mask} + maskClosable={maskClosable} + type={type} + > +
hello world
+
+ + ); +}; diff --git a/src/drawer/index.md b/src/drawer/index.md index 1126c9ace..c6cffedda 100644 --- a/src/drawer/index.md +++ b/src/drawer/index.md @@ -16,7 +16,7 @@ demo: ## 示例 - + @@ -25,6 +25,7 @@ demo: + ## API @@ -32,19 +33,20 @@ demo: [AlertProps](https://4x-ant-design.antgroup.com/components/alert-cn/#API) -| 参数 | 说明 | 类型 | 默认值 | -| ------------- | ---------------------------------- | ----------------------------------------------------- | --------- | -| activeKey | 右侧面板的内容的 Tabs 的选中项 | `string` | - | -| banner | 提示 | `React.ReactNode \| AlertProps` | - | -| bodyClassName | 内容容器的类名 | `string` | - | -| bodyStyle | 内容容器的样式 | `CSSProperties` | - | -| children | 右侧面板展示内容 | `(key: string) => React.ReactNode \| React.ReactNode` | - | -| defaultKey | 右侧面板的内容的 Tabs 的默认选中项 | `string` | - | -| footer | 右侧面板的底部内容 | `React.ReactNode` | - | -| size | 尺寸 | `small \| default \| large` | `default` | -| tabs | 右侧面板的内容的 Tabs | `{ key: string; title: React.ReactNode }[]` | - | -| title | 右侧面板的 title | `React.ReactNode` | - | -| onChange | 右侧面板的 Tabs 切换回调 | `(key: string) => void` | - | +| 参数 | 说明 | 类型 | 默认值 | +| ------------- | ---------------------------------- | ----------------------------------------------------- | ---------------------- | +| activeKey | 右侧面板的内容的 Tabs 的选中项 | `string` | - | +| banner | 提示 | `React.ReactNode \| AlertProps` | - | +| bodyClassName | 内容容器的类名 | `string` | - | +| bodyStyle | 内容容器的样式 | `CSSProperties` | - | +| children | 右侧面板展示内容 | `(key: string) => React.ReactNode \| React.ReactNode` | - | +| defaultKey | 右侧面板的内容的 Tabs 的默认选中项 | `string` | - | +| footer | 右侧面板的底部内容 | `React.ReactNode` | - | +| size | 尺寸 | `small \| default \| large` | `default` | +| tabs | 右侧面板的内容的 Tabs | `{ key: string; title: React.ReactNode }[]` | - | +| title | 右侧面板的 title | `React.ReactNode` | - | +| type | 右侧面板的类型 | `SlidePaneType.Form \| SlidePaneType.Normal` | `SlidePaneType.Normal` | +| onChange | 右侧面板的 Tabs 切换回调 | `(key: string) => void` | - | :::info 其余属性继承 [antd4.x 的 Drawer](https://4x.ant.design/components/drawer-cn/#API) diff --git a/src/drawer/index.tsx b/src/drawer/index.tsx index d583675bc..366393787 100644 --- a/src/drawer/index.tsx +++ b/src/drawer/index.tsx @@ -1,4 +1,5 @@ import React, { CSSProperties, useEffect, useState } from 'react'; +import { CloseOutlined } from '@ant-design/icons'; import { Alert, AlertProps, Spin, Tabs } from 'antd'; import classNames from 'classnames'; import { omit } from 'lodash'; @@ -16,9 +17,12 @@ type readOnlyTab = readonly Tab[]; type TabKey = T[number]['key']; +export enum DrawerType { + Form = 'form', + Normal = 'normal', +} + interface NormalDrawerProps extends Omit { - /** @deprecated */ - visible?: boolean; size?: 'small' | 'default' | 'large'; loading?: boolean; bodyClassName?: string; @@ -26,6 +30,7 @@ interface NormalDrawerProps extends Omit { bodyStyle?: CSSProperties; footer?: React.ReactNode; banner?: AlertProps['message'] | Omit; + type?: DrawerType; } interface TabsDrawerProps extends Omit { @@ -65,14 +70,15 @@ const Drawer = (props: DrawerProps) => { const slidePrefixCls = 'dtc-drawer'; const { - visible, open, loading = false, bodyClassName, mask = false, + maskClosable = true, bodyStyle, title, width, + type = DrawerType.Normal, size = 'default', footer, banner, @@ -80,16 +86,16 @@ const Drawer = (props: DrawerProps) => { ...rest } = props; - const composeOpen = open || visible; const finalWidth = width ?? getWidthFromSize(size); + const isFormType = type === DrawerType.Form; const [internalTabKey, setInternalTabKey] = useState(''); useEffect(() => { - composeOpen && + open && isTabMode(props) && setInternalTabKey(props.defaultKey ?? props.tabs?.[0]?.key ?? ''); - }, [composeOpen]); + }, [open]); const currentKey = isControlled(props) ? props.activeKey : internalTabKey; @@ -111,21 +117,32 @@ const Drawer = (props: DrawerProps) => { return ( - {!mask && renderButton()} + {!isFormType && renderButton()} - {title &&
{title}
} + {title && ( +
+ {title} + {isFormType && ( + + )} +
+ )} {banner && ( diff --git a/src/drawer/style.scss b/src/drawer/style.scss index d9c590130..8ec0a8fd6 100644 --- a/src/drawer/style.scss +++ b/src/drawer/style.scss @@ -40,12 +40,19 @@ $prefix: "dtc-drawer"; pointer-events: auto; } &-header { + display: flex; + align-items: center; + justify-content: space-between; padding: 16px; background-color: #F9F9FA; color: #3D446E; font-weight: 500; font-size: 14px; line-height: 22px; + &--icon { + color: #64698B; + font-size: 16px; + } } &-tabs { &.ant-tabs { From 9bc58cb614328ae7524e8a1a23dae0994812c3d7 Mon Sep 17 00:00:00 2001 From: LuckyFBB <976060700@qq.com> Date: Fri, 25 Oct 2024 15:12:41 +0800 Subject: [PATCH 2/2] docs(drawer): change drawer docs --- src/drawer/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drawer/index.md b/src/drawer/index.md index c6cffedda..fab536208 100644 --- a/src/drawer/index.md +++ b/src/drawer/index.md @@ -16,7 +16,7 @@ demo: ## 示例 - +