Skip to content

Commit

Permalink
feat(switch): support beforeChange API
Browse files Browse the repository at this point in the history
  • Loading branch information
centuryPark committed Nov 1, 2024
1 parent 168c5a2 commit 86f0e1a
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 1 deletion.
39 changes: 39 additions & 0 deletions src/switch/__tests__/base.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,44 @@ describe('switch', () => {
expect(eleCls.includes('t-size-s')).toBe(true);
});
});
// test props beforeChange
describe(':props.beforeChange', () => {
it('beforeChange resolve', async () => {
const beforeChangeResolve = () =>
new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, 80);
});
const wrapper = mount({
render() {
return <Switch defaultValue={true} beforeChange={beforeChangeResolve} />;
},
});
wrapper.trigger('click');
await new Promise((resolve) => setTimeout(resolve, 100));
const ele = wrapper.find('.t-switch');
const eleCls = ele.classes();
expect(eleCls.includes('t-is-checked')).toBeFalsy();
});
it('beforeChange reject', async () => {
const beforeChangeReject = () =>
new Promise((_resolve, reject) => {
setTimeout(() => {
reject(new Error('reject'));
}, 80);
}).catch(() => {});
const wrapper = mount({
render() {
return <Switch defaultValue={false} beforeChange={beforeChangeReject} />;
},
});
wrapper.trigger('click');
await new Promise((resolve) => setTimeout(resolve, 100));
const ele = wrapper.find('.t-switch');
const eleCls = ele.classes();
expect(eleCls.includes('t-is-checked')).toBe(false);
});
});
});
});
53 changes: 53 additions & 0 deletions src/switch/_example/before-change.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<t-space>
<t-switch
v-model="resolveChecked"
:loading="loadingResolve"
:before-change="beforeChangeResolve"
@change="onChangeResolve"
/>
<t-switch
v-model="rejectChecked"
:loading="loadingReject"
:before-change="beforeChangeReject"
@change="onChangeReject"
/>
</t-space>
</template>

<script setup>
import { ref } from 'vue';
const resolveChecked = ref(true);
const rejectChecked = ref(true);
const loadingResolve = ref(false);
const loadingReject = ref(false);
const onChangeResolve = (v) => {
console.log(v);
};
const onChangeReject = (v) => {
console.log(v);
};
const beforeChangeResolve = () => {
loadingResolve.value = true;
return new Promise((resolve) => {
setTimeout(() => {
loadingResolve.value = false;
resolve(true);
}, 1000);
});
};
const beforeChangeReject = () => {
loadingReject.value = true;
return new Promise((_resolve, reject) => {
setTimeout(() => {
loadingReject.value = false;
reject(new Error('reject'));
}, 1000);
});
};
</script>
4 changes: 4 additions & 0 deletions src/switch/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { TdSwitchProps } from './type';
import { PropType } from 'vue';

export default {
/** Switch 切换状态前的回调方法,常用于需要发起异步请求的场景,回到返回值支持布尔和 Promise 类型,返回`false`或 Promise reject不继续执行change,否则则继续执行。 */
beforeChange: {
type: Function as PropType<TdSwitchProps['beforeChange']>,
},
/** 用于自定义开关的值,[打开时的值,关闭时的值]。默认为 [true, false]。示例:[1, 0]、['open', 'close'] */
customValue: {
type: Array as PropType<TdSwitchProps['customValue']>,
Expand Down
1 change: 1 addition & 0 deletions src/switch/switch.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

name | type | default | description | required
-- | -- | -- | -- | --
beforeChange | Function | - | stop checked change。Typescript:`() => boolean \| Promise<boolean>` | N
customValue | Array | - | Typescript:`Array<SwitchValue>` | N
disabled | Boolean | undefined | \- | N
label | Array / Slot / Function | [] | Typescript:`Array<string \| TNode> \| TNode<{ value: SwitchValue }>`[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N
Expand Down
1 change: 1 addition & 0 deletions src/switch/switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

名称 | 类型 | 默认值 | 说明 | 必传
-- | -- | -- | -- | --
beforeChange | Function | - | Switch 切换状态前的回调方法,常用于需要发起异步请求的场景,回到返回值支持布尔和 Promise 类型,返回`false`或 Promise reject不继续执行change,否则则继续执行。。TS 类型:`() => boolean \| Promise<boolean>` | N
customValue | Array | - | 用于自定义开关的值,[打开时的值,关闭时的值]。默认为 [true, false]。示例:[1, 0]['open', 'close']。TS 类型:`Array<SwitchValue>` | N
disabled | Boolean | undefined | 是否禁用组件。优先级:Switch.disabled > Form.disabled | N
label | Array / Slot / Function | [] | 开关内容,[开启时内容,关闭时内容]。示例:['开', '关'] 或 (value) => value ? '开' : '关'。TS 类型:`Array<string \| TNode> \| TNode<{ value: SwitchValue }>`[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N
Expand Down
14 changes: 13 additions & 1 deletion src/switch/switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,19 @@ export default defineComponent({
if (disabled.value || props.loading) {
return;
}
handleToggle(e);
if (!props.beforeChange) {
handleToggle(e);
return;
}
Promise.resolve(props.beforeChange())
.then((v) => {
if (v) {
handleToggle(e);
}
})
.catch((e) => {
throw new Error(`Switch: some error occurred: ${e}`);
});
}

// classes
Expand Down
4 changes: 4 additions & 0 deletions src/switch/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import { TNode } from '../common';

export interface TdSwitchProps<T = SwitchValue> {
/**
* Switch 切换状态前的回调方法,常用于需要发起异步请求的场景,回到返回值支持布尔和 Promise 类型,返回`false`或 Promise reject不继续执行change,否则则继续执行。
*/
beforeChange?: () => boolean | Promise<boolean>;
/**
* 用于自定义开关的值,[打开时的值,关闭时的值]。默认为 [true, false]。示例:[1, 0]、['open', 'close']
*/
Expand Down

0 comments on commit 86f0e1a

Please sign in to comment.