From 1438ed72fdbe765ec9a9870c5cbea4ca5400a9fd Mon Sep 17 00:00:00 2001 From: liweijie0812 <674416404@qq.com> Date: Tue, 30 Jul 2024 16:35:02 +0800 Subject: [PATCH] feat(Divider): refactor (#403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(DIvider): refactor * chore: update common * chore: rename tsx * chore(site): update mobile.config * chore(husky): ci环境不运行 * chore: update snapshot * chore(site): 展示tsx 示例代码 * feat: children?: React.ReactNode * docs: sync api * feat: remove children api * docs: update --------- Co-authored-by: github-actions[bot] Co-authored-by: Y. --- .husky/commit-msg | 1 + .husky/pre-commit | 1 + site/mobile/mobile.config.js | 2 +- site/plugin-tdoc/transforms.js | 7 +- src/_common | 2 +- src/divider/Divider.tsx | 46 +- src/divider/__tests__/divider.test.tsx | 66 ++ src/divider/_example/align.jsx | 21 - src/divider/_example/base.jsx | 30 - src/divider/_example/base.tsx | 29 + src/divider/_example/{index.jsx => index.tsx} | 12 +- src/divider/_example/style/index.less | 37 +- src/divider/_example/theme.tsx | 15 + src/divider/_example/vertical.jsx | 25 - src/divider/defaultProps.ts | 7 + src/divider/divider.en-US.md | 15 + src/divider/divider.md | 4 +- src/divider/type.ts | 5 - test/snap/__snapshots__/csr.test.jsx.snap | 811 ++++++++++++++++++ test/snap/__snapshots__/ssr.test.jsx.snap | 6 + 20 files changed, 999 insertions(+), 143 deletions(-) create mode 100644 src/divider/__tests__/divider.test.tsx delete mode 100644 src/divider/_example/align.jsx delete mode 100644 src/divider/_example/base.jsx create mode 100644 src/divider/_example/base.tsx rename src/divider/_example/{index.jsx => index.tsx} (67%) create mode 100644 src/divider/_example/theme.tsx delete mode 100644 src/divider/_example/vertical.jsx create mode 100644 src/divider/defaultProps.ts create mode 100644 src/divider/divider.en-US.md diff --git a/.husky/commit-msg b/.husky/commit-msg index 4132fe04..59a2376c 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,4 +1,5 @@ #!/bin/sh +[ -n "$CI" ] && exit 0 . "$(dirname "$0")/_/husky.sh" npx commitlint -e $HUSKY_GIT_PARAMS diff --git a/.husky/pre-commit b/.husky/pre-commit index 6d395b88..7c96b908 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,5 @@ #!/bin/sh +[ -n "$CI" ] && exit 0 . "$(dirname "$0")/_/husky.sh" npm run lint:fix diff --git a/site/mobile/mobile.config.js b/site/mobile/mobile.config.js index ce2a6fec..4bb613b7 100644 --- a/site/mobile/mobile.config.js +++ b/site/mobile/mobile.config.js @@ -8,7 +8,7 @@ export default { { title: 'Divider 分割符', name: 'divider', - component: () => import('tdesign-mobile-react/divider/_example/index.jsx'), + component: () => import('tdesign-mobile-react/divider/_example/index.tsx'), }, { title: 'Icon 图标', diff --git a/site/plugin-tdoc/transforms.js b/site/plugin-tdoc/transforms.js index a3c06260..1528f49a 100644 --- a/site/plugin-tdoc/transforms.js +++ b/site/plugin-tdoc/transforms.js @@ -26,9 +26,14 @@ export default { // 替换成对应 demo 文件 source = source.replace(/\{\{\s+(.+)\s+\}\}/g, (demoStr, demoFileName) => { + const tsDemoPath = path.resolve(resourceDir, `./_example/${demoFileName}.tsx`); + if (fs.existsSync(tsDemoPath)) { + return `\n::: demo _example/${demoFileName} ${name}\n:::\n`; + } + const demoPath = path.resolve(resourceDir, `./_example/${demoFileName}.jsx`); if (!fs.existsSync(demoPath)) { - console.log('\x1B[36m%s\x1B[0m', `${name} 组件需要实现 _example/${demoFileName}.jsx 示例!`); + console.log('\x1B[36m%s\x1B[0m', `${name} 组件需要实现 _example/${demoFileName}.tsx 示例!`); return '\n

DEMO (🚧建设中)...

'; } diff --git a/src/_common b/src/_common index 1bacc8e9..05c1f59e 160000 --- a/src/_common +++ b/src/_common @@ -1 +1 @@ -Subproject commit 1bacc8e91408cca2b26a3ca7b4b13f9bb62d8af2 +Subproject commit 05c1f59ef27bea7da2fcfd09f98b0b838516d538 diff --git a/src/divider/Divider.tsx b/src/divider/Divider.tsx index d290ca38..911da7c4 100644 --- a/src/divider/Divider.tsx +++ b/src/divider/Divider.tsx @@ -1,40 +1,38 @@ -import React, { FC } from 'react'; +import React from 'react'; +import type { FC } from 'react'; import classNames from 'classnames'; import { TdDividerProps } from './type'; +import { dividerDefaultProps } from './defaultProps'; +import { StyledProps } from '../common'; import useConfig from '../_util/useConfig'; -import withNativeProps, { NativeProps } from '../_util/withNativeProps'; +import useDefaultProps from '../hooks/useDefaultProps'; -export interface DividerProps extends TdDividerProps, NativeProps {} - -const defaultProps = { - align: 'center', - dashed: false, - layout: 'horizontal', - lineColor: '', -}; +export interface DividerProps extends TdDividerProps, StyledProps { + children?: React.ReactNode; +} const Divider: FC = (props) => { - const { children, align, dashed, layout, lineColor, content } = props; + const { children, align, dashed, layout, content, style } = useDefaultProps(props, dividerDefaultProps); const { classPrefix } = useConfig(); - const name = `${classPrefix}-divider`; + const dividerClass = `${classPrefix}-divider`; const contentNode = content || children; - const classes = classNames(name, { - [`${name}-${layout}`]: layout, - [`${name}--hairline`]: true, - [`${name}--content-${align}`]: align && contentNode, - [`${name}--dashed`]: dashed, - }); + const classes = classNames([ + dividerClass, + `${dividerClass}--${layout}`, + `${dividerClass}--${align}`, + { + [`${dividerClass}--dashed`]: dashed, + }, + ]); - return withNativeProps( - props, -
- {contentNode && {contentNode}} -
, + return ( +
+
{contentNode}
+
); }; -Divider.defaultProps = defaultProps as DividerProps; Divider.displayName = 'Divider'; export default Divider; diff --git a/src/divider/__tests__/divider.test.tsx b/src/divider/__tests__/divider.test.tsx new file mode 100644 index 00000000..dd6144a3 --- /dev/null +++ b/src/divider/__tests__/divider.test.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { describe, expect, it, render, waitFor } from '@test/utils'; +import Divider from '../Divider'; +import { TdDividerProps } from '../type'; + +describe('Divider', () => { + describe('props', () => { + it(':align', async () => { + const testId = 'divider test align'; + const aligns: TdDividerProps['align'][] = ['left', 'right', 'center']; + const { getByTestId } = render( +
+ {aligns?.map((align, index) => ( + + ))} +
, + ); + + const instance = await waitFor(() => getByTestId(testId)); + + for (let index = 0; index < aligns.length; index++) { + const align = aligns[index]; + expect(() => instance.querySelector(`.t-divider--${align}`)).toBeTruthy(); + } + }); + + it(':layout', async () => { + const testId = 'divider test layout'; + const layouts: TdDividerProps['layout'][] = ['horizontal', 'vertical']; + const { getByTestId } = render( +
+ {layouts?.map((layout, index) => ( + + ))} +
, + ); + + const instance = await waitFor(() => getByTestId(testId)); + + for (let index = 0; index < layouts.length; index++) { + const layout = layouts[index]; + expect(() => instance.querySelector(`.t-divider--${layout}`)).toBeTruthy(); + } + }); + + it(':dashed', async () => { + const { container } = render(); + const dividerElement = container.firstChild; + expect(dividerElement).toHaveClass('t-divider--dashed'); + }); + + it(':content', async () => { + const content = 'DividerContent'; + const { getByText } = render(); + expect(getByText(content).textContent).toBeTruthy(); + }); + }); + + describe('slot', () => { + it(':children', async () => { + const content = 'DividerContent'; + const { getByText } = render({content}); + expect(getByText(content).textContent).toBeTruthy(); + }); + }); +}); diff --git a/src/divider/_example/align.jsx b/src/divider/_example/align.jsx deleted file mode 100644 index 09c9706e..00000000 --- a/src/divider/_example/align.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { Divider } from 'tdesign-mobile-react'; -import './style/index.less'; - -export default function Content() { - return ( -
-

文字+直线

-
- -
- -

文字+虚线

-
- - 文字信息 - -
-
- ); -} diff --git a/src/divider/_example/base.jsx b/src/divider/_example/base.jsx deleted file mode 100644 index 08a65dee..00000000 --- a/src/divider/_example/base.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { Divider } from 'tdesign-mobile-react'; - -import './style/index.less'; - -export default function Base() { - return ( -
-

直线拉通

- - -

虚线拉通

- - -

左右间距

-
- -
- -

右侧拉通

-
- -
-

自定义左侧距离

-
- -
-
- ); -} diff --git a/src/divider/_example/base.tsx b/src/divider/_example/base.tsx new file mode 100644 index 00000000..f50a24c7 --- /dev/null +++ b/src/divider/_example/base.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { Divider } from 'tdesign-mobile-react'; + +import './style/index.less'; + +export default function Base() { + return ( + <> +
水平分割线
+ + +
带文字水平分割线
+ + + + +
+ 垂直分割线 +
+
+ 文字信息 + + 文字信息 + + 文字信息 +
+ + ); +} diff --git a/src/divider/_example/index.jsx b/src/divider/_example/index.tsx similarity index 67% rename from src/divider/_example/index.jsx rename to src/divider/_example/index.tsx index 12183f28..dc9629ac 100644 --- a/src/divider/_example/index.jsx +++ b/src/divider/_example/index.tsx @@ -1,20 +1,20 @@ import React from 'react'; import TDemoBlock from '../../../site/mobile/components/DemoBlock'; import TDemoHeader from '../../../site/mobile/components/DemoHeader'; -import Vertical from './vertical'; import BaseDemo from './base'; -import AlignDemo from './align'; +import ThemeDemo from './theme'; import './style/index.less'; -export default function Base() { +export default function DividerDemo() { return (
- + - - + + +
); diff --git a/src/divider/_example/style/index.less b/src/divider/_example/style/index.less index 01a345bb..3ccc2562 100644 --- a/src/divider/_example/style/index.less +++ b/src/divider/_example/style/index.less @@ -1,34 +1,17 @@ .tdesign-mobile-demo { background-color: #fff; - padding-bottom: 16px; - - .divider-demo-container { - h3 { - font-size: 12px; - font-weight: 400; - font-family: 'PingFang SC'; - color: #a9a9a9; - padding: 16px; - } - } -} - -.t-demo1 { - margin: 0 16px; } -.t-demo2 { - margin-left: 16px; +.divider-demo__title { + font-size: 14px; + color: var(--td-text-color-secondary, rgba(0, 0, 0, 0.6)); + padding: 8px 16px; + line-height: 20px; } - -.t-demo3 { - margin-left: 76px; -} - -.vertical-panel { +.divider-wrapper { display: flex; - height: 20px; - margin: 0 16px; - font-size: 12px; - color: rgba(0, 0, 0, 0.4); + align-items: center; + font-size: 14px; + color: var(--td-text-color-primary, rgba(0, 0, 0, 0.9)); + padding-left: 16px; } diff --git a/src/divider/_example/theme.tsx b/src/divider/_example/theme.tsx new file mode 100644 index 00000000..950b55a0 --- /dev/null +++ b/src/divider/_example/theme.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { Divider } from 'tdesign-mobile-react'; +import './style/index.less'; + +export default function Theme() { + return ( +
+
虚线样式
+ + + + +
+ ); +} diff --git a/src/divider/_example/vertical.jsx b/src/divider/_example/vertical.jsx deleted file mode 100644 index ef1e7e5e..00000000 --- a/src/divider/_example/vertical.jsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import { Divider } from 'tdesign-mobile-react'; -import './style/index.less'; - -export default function Vertical() { - return ( -
-

纯文字

-
- - 没有更多了~ - -
- -

垂直分割

-
- 文字信息 - - 文字信息 - - 文字信息 -
-
- ); -} diff --git a/src/divider/defaultProps.ts b/src/divider/defaultProps.ts new file mode 100644 index 00000000..5d7b1c94 --- /dev/null +++ b/src/divider/defaultProps.ts @@ -0,0 +1,7 @@ +/** + * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC + * */ + +import { TdDividerProps } from './type'; + +export const dividerDefaultProps: TdDividerProps = { align: 'center', dashed: false, layout: 'horizontal' }; diff --git a/src/divider/divider.en-US.md b/src/divider/divider.en-US.md new file mode 100644 index 00000000..f1f34f0c --- /dev/null +++ b/src/divider/divider.en-US.md @@ -0,0 +1,15 @@ +:: BASE_DOC :: + +## API + +### Divider Props + +name | type | default | description | required +-- | -- | -- | -- | -- +className | String | - | className of component | N +style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N +align | String | center | options: left/right/center | N +children | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +content | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +dashed | Boolean | false | \- | N +layout | String | horizontal | options: horizontal/vertical | N diff --git a/src/divider/divider.md b/src/divider/divider.md index 690eea32..87e28ad5 100644 --- a/src/divider/divider.md +++ b/src/divider/divider.md @@ -1,8 +1,9 @@ :: BASE_DOC :: ## API + ### Divider Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- className | String | - | 类名 | N style | Object | - | 样式,TS 类型:`React.CSSProperties` | N @@ -11,4 +12,3 @@ children | TNode | - | 子元素,同 content。TS 类型:`string | TNode`。 content | TNode | - | 子元素。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N dashed | Boolean | false | 是否虚线(仅在水平分割线有效) | N layout | String | horizontal | 分隔线类型有两种:水平和垂直。可选项:horizontal/vertical | N -lineColor | String | - | 分隔线颜色 | N diff --git a/src/divider/type.ts b/src/divider/type.ts index 919d7c76..a0b0408e 100644 --- a/src/divider/type.ts +++ b/src/divider/type.ts @@ -30,9 +30,4 @@ export interface TdDividerProps { * @default horizontal */ layout?: 'horizontal' | 'vertical'; - /** - * 分隔线颜色 - * @default '' - */ - lineColor?: string; } diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index 6c885976..5e98494d 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -1,5 +1,810 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`csr snapshot test > csr test src/divider/_example/base.tsx 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+ 水平分割线 +
+