Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions packages/components/switch/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>((originalProps,
defaultValue,
disabled,
loading,
shape,
size,
label,
customValue,
Expand All @@ -40,13 +41,14 @@ const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>((originalProps,
const [innerChecked, setInnerChecked] = useState(initChecked);

const contentNode = React.useMemo<React.ReactNode>(() => {
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);
Expand Down Expand Up @@ -84,6 +86,7 @@ const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>((originalProps,
const { SIZE, STATUS } = useCommonClassName();
const switchClassName = classNames(
`${classPrefix}-switch`,
`${classPrefix}-switch--shape-${shape}`,
className,
{
[STATUS.checked]: innerChecked,
Expand All @@ -104,7 +107,7 @@ const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>((originalProps,
onClick={onInternalClick}
>
<span className={`${classPrefix}-switch__handle`}>{loading && <Loading loading size="small" />}</span>
<div className={`${classPrefix}-switch__content`}>{contentNode}</div>
{shape !== 'line' && <div className={`${classPrefix}-switch__content`}>{contentNode}</div>}
Comment thread
Seeridia marked this conversation as resolved.
</button>
);
});
Expand Down
19 changes: 19 additions & 0 deletions packages/components/switch/__tests__/switch.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,25 @@ describe('Switch 组件测试', () => {
const { container } = render(<Switch size="small" />);
expect(container.firstChild.classList.contains('t-size-s')).toBeTruthy();
});
test('shape', async () => {
const { container, rerender, queryByText } = render(<Switch label={['开', '关']} />);
expect(container.firstChild.classList.contains('t-switch--shape-circle')).toBeTruthy();
expect(queryByText('关')).toBeInTheDocument();

rerender(<Switch shape="round" />);
expect(container.firstChild.classList.contains('t-switch--shape-round')).toBeTruthy();

rerender(<Switch shape="line" label={['开', '关']} size="small" loading />);
expect(container.firstChild.classList.contains('t-switch--shape-line')).toBeTruthy();
expect(container.firstChild.classList.contains('t-size-s')).toBeTruthy();
expect(container.firstChild.classList.contains('t-is-loading')).toBeTruthy();
expect(queryByText('关')).not.toBeInTheDocument();
expect(container.querySelector('.t-switch__content')).toBeFalsy();

const label = vi.fn(() => '关');
rerender(<Switch shape="line" label={label} />);
expect(label).not.toBeCalled();
});

test('disabled', async () => {
const clickFn = vi.fn();
Expand Down
12 changes: 12 additions & 0 deletions packages/components/switch/_example/shape.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { Space, Switch } from 'tdesign-react';

export default function SwitchShape() {
return (
<Space>
<Switch shape="circle" defaultValue />
<Switch shape="round" defaultValue />
<Switch shape="line" defaultValue />
</Space>
);
}
21 changes: 20 additions & 1 deletion packages/components/switch/_usage/props.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@
"defaultValue": false,
"options": []
},
{
"name": "shape",
"type": "enum",
"defaultValue": "circle",
"options": [
{
"label": "circle",
"value": "circle"
},
{
"label": "round",
"value": "round"
},
{
"label": "line",
"value": "line"
}
]
},
{
"name": "size",
"type": "enum",
Expand All @@ -36,4 +55,4 @@
"defaultValue": false,
"options": []
}
]
]
7 changes: 6 additions & 1 deletion packages/components/switch/defaultProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
};
Comment thread
Seeridia marked this conversation as resolved.
1 change: 1 addition & 0 deletions packages/components/switch/switch.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ customValue | Array | - | Typescript: `Array<SwitchValue>` | N
disabled | Boolean | - | \- | N
label | TNode | [] | Typescript: `Array<string \| TNode> \| 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 | Switch shape. `label` is not rendered when shape is `line`. 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
Expand Down
1 change: 1 addition & 0 deletions packages/components/switch/switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ customValue | Array | - | 用于自定义开关的值,[打开时的值,关
disabled | Boolean | - | 是否禁用组件,默认为 false | N
label | TNode | [] | 开关内容,[开启时内容,关闭时内容]。示例:['开', '关'] 或 (value) => value ? '开' : '关'。TS 类型:`Array<string \| TNode> \| 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
Expand Down
5 changes: 5 additions & 0 deletions packages/components/switch/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export interface TdSwitchProps<T = SwitchValue> {
* @default false
*/
loading?: boolean;
/**
* 开关形状。`line` 形态不展示开关内容 `label`
* @default circle
*/
shape?: 'circle' | 'round' | 'line';
Comment thread
Seeridia marked this conversation as resolved.
/**
* 开关尺寸
* @default medium
Expand Down
Loading