From 3b9058a5251bf202464fcc75e6cc47c3170cb1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Thu, 19 Sep 2024 23:00:57 +0800 Subject: [PATCH] feat(switch): update label api --- src/switch/__test__/index.test.jsx | 31 +++++++++++++++++++++-- src/switch/props.ts | 4 +-- src/switch/switch.en-US.md | 2 +- src/switch/switch.md | 2 +- src/switch/switch.tsx | 40 ++++++++++++++++++++++-------- src/switch/type.ts | 4 +-- 6 files changed, 65 insertions(+), 18 deletions(-) diff --git a/src/switch/__test__/index.test.jsx b/src/switch/__test__/index.test.jsx index 611a80f0f..824b062fb 100644 --- a/src/switch/__test__/index.test.jsx +++ b/src/switch/__test__/index.test.jsx @@ -1,7 +1,7 @@ +import { ref } from 'vue'; import { mount } from '@vue/test-utils'; import { describe, it, expect, vi } from 'vitest'; import Switch from '../switch'; -import { ref } from 'vue'; describe('switch', () => { describe('props', () => { @@ -21,7 +21,7 @@ describe('switch', () => { expect(value.value).toBe(0); }); - it(':label', async () => { + it(':label=Array', async () => { const wrapper = mount(Switch, { props: { label: ['open', 'close'], @@ -34,6 +34,32 @@ describe('switch', () => { expect($label.text()).toBe('open'); }); + it(':label=Array', async () => { + const TNodeOpen = () => open; + const TNodeClose = () => close; + const label = [TNodeOpen, TNodeClose]; + const wrapper = mount({ + render() { + return ; + }, + }); + const contentEle = wrapper.find('.t-switch__label'); + const text = contentEle.find('#switch_close').element.innerHTML; + expect(text === 'close').toBe(true); + }); + + it(':label={TNode}', () => { + const label = (val) => (val ? open : close); + const wrapper = mount({ + render() { + return ; + }, + }); + const contentEle = wrapper.find('.t-switch__label'); + const text = contentEle.find('#switch_open').element.innerHTML; + expect(text === 'open').toBe(true); + }); + it(':disabled', async () => { const wrapper = mount(Switch, { props: { @@ -62,6 +88,7 @@ describe('switch', () => { expect(wrapper.classes()).toContain('t-switch--small'); }); }); + describe('event', () => { it(': onChange', async () => { const onChange = vi.fn(); diff --git a/src/switch/props.ts b/src/switch/props.ts index f43717695..3da7c68c9 100644 --- a/src/switch/props.ts +++ b/src/switch/props.ts @@ -22,9 +22,9 @@ export default { type: Array as PropType, default: (): TdSwitchProps['icon'] => [], }, - /** 开关的标签;[打开时的标签,关闭时的标签] */ + /** 开关内容,[开启时内容,关闭时内容]。示例:['开', '关'] 或 (value) => value ? '开' : '关' */ label: { - type: Array as PropType, + type: [Array, Function] as PropType, default: (): TdSwitchProps['label'] => [], }, /** 是否处于加载中状态 */ diff --git a/src/switch/switch.en-US.md b/src/switch/switch.en-US.md index 5937e5385..02bd392b3 100644 --- a/src/switch/switch.en-US.md +++ b/src/switch/switch.en-US.md @@ -9,7 +9,7 @@ name | type | default | description | required customValue | Array | - | Typescript:`Array` | N disabled | Boolean | undefined | \- | N icon | Array | [] | Typescript:`TNode[]`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N -label | Array | [] | Typescript:`string[]` | N +label | Array / Slot / Function | [] | Typescript:`Array \| TNode<{ value: SwitchValue }>`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N loading | Boolean | false | \- | N size | String | medium | options: small/medium/large | N value | String / Number / Boolean | - | `v-model` and `v-model:value` is supported。Typescript:`T` `type SwitchValue = string \| number \| boolean`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/switch/type.ts) | N diff --git a/src/switch/switch.md b/src/switch/switch.md index bcc6e9478..11ebdca37 100644 --- a/src/switch/switch.md +++ b/src/switch/switch.md @@ -9,7 +9,7 @@ customValue | Array | - | 用于自定义开关的值,[打开时的值,关闭时的值]。默认为 [true, false]。示例:[1, 0]、['open', 'close']。TS 类型:`Array` | N disabled | Boolean | undefined | 是否禁用组件。优先级:Switch.disabled > Form.disabled | N icon | Array | [] | 开关的图标;[打开时的图标,关闭时的图标]。TS 类型:`TNode[]`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N -label | Array | [] | 开关的标签;[打开时的标签,关闭时的标签]。TS 类型:`string[]` | N +label | Array / Slot / Function | [] | 开关内容,[开启时内容,关闭时内容]。示例:['开', '关'] 或 (value) => value ? '开' : '关'。TS 类型:`Array \| TNode<{ value: SwitchValue }>`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N loading | Boolean | false | 是否处于加载中状态 | N size | String | medium | 开关尺寸。可选项:small/medium/large | N value | String / Number / Boolean | - | 开关值。支持语法糖 `v-model` 或 `v-model:value`。TS 类型:`T` `type SwitchValue = string \| number \| boolean`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/switch/type.ts) | N diff --git a/src/switch/switch.tsx b/src/switch/switch.tsx index 51a4a934d..63c9d4f7d 100644 --- a/src/switch/switch.tsx +++ b/src/switch/switch.tsx @@ -1,4 +1,7 @@ -import { computed, defineComponent } from 'vue'; +import { computed, defineComponent, h } from 'vue'; +import isArray from 'lodash/isArray'; +import isFunction from 'lodash/isFunction'; +import isString from 'lodash/isString'; import TLoading from '../loading'; import { useToggle, useDefault } from '../shared'; import config from '../config'; @@ -57,20 +60,37 @@ export default defineComponent({ innerValue.value = state.value; } - return () => { - const readerContent = () => { - if (props.loading) { - return ; + + const renderContent = () => { + if (props.loading) { + return ; + } + + if (isArray(props.label) && props.label.length === 2) { + const label = checked.value ? props.label[0] : props.label[1]; + if (isString(label)) { + return label; } - if (props.label.length === 2) { - return checked.value ? props.label[0] : props.label[1]; + if (isFunction(label)) { + return label(h); } - return iconContent.value; - }; + } + + if (isFunction(props.label)) { + return props.label(h, { value: innerValue.value }); + } + if (context.slots.label) { + return context.slots.label({ value: innerValue.value }); + } + + return iconContent.value; + }; + + return () => { return (
-
{readerContent()}
+
{renderContent()}
); diff --git a/src/switch/type.ts b/src/switch/type.ts index 173ea99d5..e85c27cf8 100644 --- a/src/switch/type.ts +++ b/src/switch/type.ts @@ -21,10 +21,10 @@ export interface TdSwitchProps { */ icon?: TNode[]; /** - * 开关的标签;[打开时的标签,关闭时的标签] + * 开关内容,[开启时内容,关闭时内容]。示例:['开', '关'] 或 (value) => value ? '开' : '关' * @default [] */ - label?: string[]; + label?: Array | TNode<{ value: SwitchValue }>; /** * 是否处于加载中状态 * @default false