diff --git a/packages/common b/packages/common index 17b62abaed..76de6c3a78 160000 --- a/packages/common +++ b/packages/common @@ -1 +1 @@ -Subproject commit 17b62abaedb8f4d2bac8e2aad53bc17bc68d5fd9 +Subproject commit 76de6c3a786aaf5eb6a5b1fc1aa3692f00cef8d5 diff --git a/packages/components/switch/Switch.tsx b/packages/components/switch/Switch.tsx index 65268cac68..a73499cc90 100644 --- a/packages/components/switch/Switch.tsx +++ b/packages/components/switch/Switch.tsx @@ -26,6 +26,7 @@ const Switch = React.forwardRef((originalProps, defaultValue, disabled, loading, + shape, size, label, customValue, @@ -40,13 +41,15 @@ const Switch = React.forwardRef((originalProps, const [innerChecked, setInnerChecked] = useState(initChecked); const contentNode = React.useMemo(() => { + // line 形态不展示开关内容 + if (shape === 'line') return null; if (Array.isArray(label)) { const [activeContent = '', inactiveContent = ''] = label; const content = innerChecked ? activeContent : inactiveContent; return parseTNode(content, { value }); } return parseTNode(label, { value }); - }, [label, innerChecked, value]); + }, [label, innerChecked, shape, value]); const handleChange = (e: React.MouseEvent) => { !isControlled && setInnerChecked(!innerChecked); @@ -84,6 +87,7 @@ const Switch = React.forwardRef((originalProps, const { SIZE, STATUS } = useCommonClassName(); const switchClassName = classNames( `${classPrefix}-switch`, + `${classPrefix}-switch--shape-${shape}`, className, { [STATUS.checked]: innerChecked, @@ -104,7 +108,7 @@ const Switch = React.forwardRef((originalProps, onClick={onInternalClick} > {loading && } -
{contentNode}
+ {shape !== 'line' &&
{contentNode}
} ); }); diff --git a/packages/components/switch/__tests__/switch.test.tsx b/packages/components/switch/__tests__/switch.test.tsx index 9f92b92410..e6a0ed6ed9 100644 --- a/packages/components/switch/__tests__/switch.test.tsx +++ b/packages/components/switch/__tests__/switch.test.tsx @@ -27,6 +27,31 @@ describe('Switch 组件测试', () => { expect(container.children[0].classList.contains('t-size-s')).toBeTruthy(); }); + test('shape default is circle', async () => { + const { container } = render(); + expect(container.firstChild.classList.contains('t-switch--shape-circle')).toBeTruthy(); + }); + + test('shape round', async () => { + const { container } = render(); + expect(container.firstChild.classList.contains('t-switch--shape-round')).toBeTruthy(); + }); + + test('shape line does not render content', async () => { + const { container, queryByText } = render(); + expect(container.firstChild.classList.contains('t-switch--shape-line')).toBeTruthy(); + expect(container.firstChild.querySelector('.t-switch__content')).toBeNull(); + expect(queryByText('关')).not.toBeInTheDocument(); + }); + + test('shape line onChange still works', async () => { + const clickFn = vi.fn(); + const { container } = render(); + fireEvent.click(container.firstChild); + expect(clickFn).toBeCalledTimes(1); + expect(container.firstChild.classList.contains('t-is-checked')).toBeTruthy(); + }); + test('disabled', async () => { const clickFn = vi.fn(); const { container } = render(); diff --git a/packages/components/switch/_example/shape.tsx b/packages/components/switch/_example/shape.tsx new file mode 100644 index 0000000000..29b7e89bf9 --- /dev/null +++ b/packages/components/switch/_example/shape.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { Space, Switch } from 'tdesign-react'; + +export default function SwitchShape() { + return ( + + + circle(默认胶囊形态) + + + + round(圆角矩形形态) + + + + line(线性形态) + + + + ); +} diff --git a/packages/components/switch/defaultProps.ts b/packages/components/switch/defaultProps.ts index 57ceba6db3..0ed2aedef5 100644 --- a/packages/components/switch/defaultProps.ts +++ b/packages/components/switch/defaultProps.ts @@ -4,4 +4,9 @@ import type { TdSwitchProps } from './type'; -export const switchDefaultProps: TdSwitchProps = { label: [], loading: false, size: 'medium' }; +export const switchDefaultProps: TdSwitchProps = { + label: [], + loading: false, + shape: 'circle', + size: 'medium', +}; diff --git a/packages/components/switch/switch.en-US.md b/packages/components/switch/switch.en-US.md index 94e6d529fd..ebbdbc6309 100644 --- a/packages/components/switch/switch.en-US.md +++ b/packages/components/switch/switch.en-US.md @@ -12,6 +12,7 @@ customValue | Array | - | Typescript: `Array` | N disabled | Boolean | - | \- | N label | TNode | [] | Typescript: `Array \| TNode<{ value: SwitchValue }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N loading | Boolean | false | \- | N +shape | String | circle | shape of switch。`line` shape does not render switch content `label`。options: circle/round/line | N size | String | medium | options:small/medium/large | N value | String / Number / Boolean | - | Typescript: `T` `type SwitchValue = string \| number \| boolean`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/switch/type.ts) | N defaultValue | String / Number / Boolean | - | uncontrolled property。Typescript: `T` `type SwitchValue = string \| number \| boolean`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/switch/type.ts) | N diff --git a/packages/components/switch/switch.md b/packages/components/switch/switch.md index b0eb603947..5d4e14f60f 100644 --- a/packages/components/switch/switch.md +++ b/packages/components/switch/switch.md @@ -12,6 +12,7 @@ customValue | Array | - | 用于自定义开关的值,[打开时的值,关 disabled | Boolean | - | 是否禁用组件,默认为 false | N label | TNode | [] | 开关内容,[开启时内容,关闭时内容]。示例:['开', '关'] 或 (value) => value ? '开' : '关'。TS 类型:`Array \| TNode<{ value: SwitchValue }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N loading | Boolean | false | 是否处于加载中状态 | N +shape | String | circle | 开关形状。`line` 形态不展示开关内容 `label`。可选项:circle/round/line | N size | String | medium | 开关尺寸。可选项:small/medium/large | N value | String / Number / Boolean | - | 开关值。TS 类型:`T` `type SwitchValue = string \| number \| boolean`。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/switch/type.ts) | N defaultValue | String / Number / Boolean | - | 开关值。非受控属性。TS 类型:`T` `type SwitchValue = string \| number \| boolean`。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/switch/type.ts) | N diff --git a/packages/components/switch/type.ts b/packages/components/switch/type.ts index 3a1b76e8b6..be839a99c9 100644 --- a/packages/components/switch/type.ts +++ b/packages/components/switch/type.ts @@ -29,6 +29,11 @@ export interface TdSwitchProps { * @default false */ loading?: boolean; + /** + * 开关形状。`line` 形态不展示开关内容 `label` + * @default circle + */ + shape?: 'circle' | 'round' | 'line'; /** * 开关尺寸 * @default medium diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index e7669177f2..072af7eec7 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -153756,6 +153756,397 @@ exports[`csr snapshot test > csr test packages/components/upload/_example/single `; +exports[`csr snapshot test > csr test packages\\components\\switch\\_example\\base.tsx 1`] = ` +
+
+
+ +
+
+ +
+
+
+`; + +exports[`csr snapshot test > csr test packages\\components\\switch\\_example\\beforeChange.tsx 1`] = ` +
+
+
+ +
+
+ +
+
+
+`; + +exports[`csr snapshot test > csr test packages\\components\\switch\\_example\\describe.tsx 1`] = ` +
+
+
+ +
+
+ +
+
+
+`; + +exports[`csr snapshot test > csr test packages\\components\\switch\\_example\\shape.tsx 1`] = ` +
+
+
+
+
+ + circle(默认胶囊形态) + +
+
+ +
+
+
+
+
+
+ + round(圆角矩形形态) + +
+
+ +
+
+
+
+
+
+ + line(线性形态) + +
+
+ +
+
+
+
+
+`; + +exports[`csr snapshot test > csr test packages\\components\\switch\\_example\\size.tsx 1`] = ` +
+
+
+ +
+
+ +
+
+ +
+
+
+`; + +exports[`csr snapshot test > csr test packages\\components\\switch\\_example\\status.tsx 1`] = ` +
+
+
+ +
+
+