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 5, 2024
1 parent 37e7fb7 commit 8740abc
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 2 deletions.
55 changes: 55 additions & 0 deletions src/switch/_example/before-change.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<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>
export default {
data() {
return {
resolveChecked: true,
rejectChecked: true,
loadingResolve: false,
loadingReject: false,
};
},
methods: {
onChangeResolve(val) {
console.log('onChangeResolve', val);
},
onChangeReject(val) {
console.log('onChangeReject', val);
},
beforeChangeResolve() {
this.loadingResolve = true;
return new Promise((resolve) => {
setTimeout(() => {
this.loadingResolve = false;
resolve(true);
}, 1000);
});
},
beforeChangeReject() {
this.loadingReject = true;
return new Promise((_resolve, reject) => {
setTimeout(() => {
this.loadingReject = 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 @@ -9,6 +9,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] */
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 | - | \- | N
label | Array / Slot / Function | [] | Typescript:`Array<string \| TNode> \| TNode<{ value: SwitchValue }>`[see more ts definition](https://github.com/Tencent/tdesign-vue/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 | - | 是否禁用组件 | N
label | Array / Slot / Function | [] | 开关内容,[开启时内容,关闭时内容]。示例:['开', '关'] 或 (value) => value ? '开' : '关'。TS 类型:`Array<string \| TNode> \| TNode<{ value: SwitchValue }>`[通用类型定义](https://github.com/Tencent/tdesign-vue/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 @@ -113,7 +113,19 @@ export default mixins(classPrefixMixins).extend({
if (this.tDisabled || this.loading) {
return;
}
this.handleToggle();
if (!this.beforeChange) {
this.handleToggle();
return;
}
Promise.resolve(this.beforeChange())
.then((v) => {
if (v) {
this.handleToggle();
}
})
.catch((e) => {
throw new Error(`Switch: some error occurred: ${e}`);
});
},
},
render(): VNode {
Expand Down
6 changes: 5 additions & 1 deletion src/switch/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import { TNode } from '../common';

export interface TdSwitchProps {
/**
* Switch 切换状态前的回调方法,常用于需要发起异步请求的场景,回到返回值支持布尔和 Promise 类型,返回`false`或 Promise reject不继续执行change,否则则继续执行。
*/
beforeChange?: () => boolean | Promise<boolean>;
/**
* 开关内容,[打开时的值,关闭时的值]。默认为 [true, false]。示例:[1, 0]
*/
Expand Down Expand Up @@ -46,6 +50,6 @@ export interface TdSwitchProps {
* 数据发生变化时触发
*/
onChange?: (value: SwitchValue) => void;
};
}

export type SwitchValue = string | number | boolean;
36 changes: 36 additions & 0 deletions test/snap/__snapshots__/csr.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -100303,6 +100303,42 @@ exports[`csr snapshot test > csr test ./src/switch/_example/base.vue 1`] = `
</div>
`;

exports[`csr snapshot test > csr test ./src/switch/_example/before-change.vue 1`] = `
<div
class="t-space t-space-horizontal"
style="gap: 16px;"
>
<div
class="t-space-item"
>
<div
class="t-switch t-size-m t-is-checked"
>
<span
class="t-switch__handle"
/>
<div
class="t-switch__content t-size-m"
/>
</div>
</div>
<div
class="t-space-item"
>
<div
class="t-switch t-size-m t-is-checked"
>
<span
class="t-switch__handle"
/>
<div
class="t-switch__content t-size-m"
/>
</div>
</div>
</div>
`;

exports[`csr snapshot test > csr test ./src/switch/_example/describe.vue 1`] = `
<div
class="t-space t-space-vertical"
Expand Down
2 changes: 2 additions & 0 deletions test/snap/__snapshots__/ssr.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,8 @@ exports[`ssr snapshot test > renders ./src/swiper/_example/vertical.vue correctl

exports[`ssr snapshot test > renders ./src/switch/_example/base.vue correctly 1`] = `"<div data-server-rendered=\\"true\\" class=\\"t-space t-space-horizontal\\" style=\\"gap:16px;\\"><div class=\\"t-space-item\\"><div class=\\"t-switch t-size-l\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"></div></div></div><div class=\\"t-space-item\\"><div class=\\"t-switch t-size-l t-is-checked\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"></div></div></div></div>"`;

exports[`ssr snapshot test > renders ./src/switch/_example/before-change.vue correctly 1`] = `"<div data-server-rendered=\\"true\\" class=\\"t-space t-space-horizontal\\" style=\\"gap:16px;\\"><div class=\\"t-space-item\\"><div class=\\"t-switch t-size-m t-is-checked\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-m\\"></div></div></div><div class=\\"t-space-item\\"><div class=\\"t-switch t-size-m t-is-checked\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-m\\"></div></div></div></div>"`;

exports[`ssr snapshot test > renders ./src/switch/_example/describe.vue correctly 1`] = `"<div data-server-rendered=\\"true\\" class=\\"t-space t-space-vertical\\" style=\\"gap:16px;\\"><div class=\\"t-space-item\\"><div class=\\"tdesign-demo-block-row\\"><div class=\\"t-switch t-size-l t-is-checked\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"></div></div><div class=\\"t-switch t-size-l\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"></div></div></div></div><div class=\\"t-space-item\\"><div class=\\"tdesign-demo-block-row\\"><div class=\\"t-switch t-size-l t-is-checked\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\">开</div></div><div class=\\"t-switch t-size-l\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\">关</div></div></div></div><div class=\\"t-space-item\\"><div class=\\"tdesign-demo-block-row\\"><div class=\\"t-switch t-size-l t-is-checked\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"><svg fill=\\"none\\" viewBox=\\"0 0 24 24\\" width=\\"1em\\" height=\\"1em\\" class=\\"t-icon t-icon-check\\"><path fill=\\"currentColor\\" d=\\"M20.99 7.38l-10.61 10.6L4 11.63l1.42-1.41 4.95 4.95 9.2-9.2 1.4 1.42z\\"></path></svg></div></div><div class=\\"t-switch t-size-l\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"><svg fill=\\"none\\" viewBox=\\"0 0 24 24\\" width=\\"1em\\" height=\\"1em\\" class=\\"t-icon t-icon-close\\"><path fill=\\"currentColor\\" d=\\"M7.05 5.64L12 10.59l4.95-4.95 1.41 1.41L13.41 12l4.95 4.95-1.41 1.41L12 13.41l-4.95 4.95-1.41-1.41L10.59 12 5.64 7.05l1.41-1.41z\\"></path></svg></div></div></div></div><div class=\\"t-space-item\\"><div class=\\"tdesign-demo-block-row\\"><div class=\\"t-switch t-size-l t-is-checked\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"><svg fill=\\"none\\" viewBox=\\"0 0 24 24\\" width=\\"1em\\" height=\\"1em\\" class=\\"t-icon t-icon-check\\"><path fill=\\"currentColor\\" d=\\"M20.99 7.38l-10.61 10.6L4 11.63l1.42-1.41 4.95 4.95 9.2-9.2 1.4 1.42z\\"></path></svg></div></div><div class=\\"t-switch t-size-l\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"><svg fill=\\"none\\" viewBox=\\"0 0 24 24\\" width=\\"1em\\" height=\\"1em\\" class=\\"t-icon t-icon-close\\"><path fill=\\"currentColor\\" d=\\"M7.05 5.64L12 10.59l4.95-4.95 1.41 1.41L13.41 12l4.95 4.95-1.41 1.41L12 13.41l-4.95 4.95-1.41-1.41L10.59 12 5.64 7.05l1.41-1.41z\\"></path></svg></div></div></div></div></div>"`;

exports[`ssr snapshot test > renders ./src/switch/_example/size.vue correctly 1`] = `"<div data-server-rendered=\\"true\\" class=\\"t-space t-space-horizontal t-space--break-line\\" style=\\"gap:16px;\\"><div class=\\"t-space-item\\"><div class=\\"t-switch t-size-l t-is-checked\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-l\\"></div></div></div><div class=\\"t-space-item\\"><div class=\\"t-switch t-size-m\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-m\\"></div></div></div><div class=\\"t-space-item\\"><div class=\\"t-switch t-size-s\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content t-size-s\\"></div></div></div></div>"`;
Expand Down

0 comments on commit 8740abc

Please sign in to comment.