From b8d3acad776a1a1531b14cc47ca69b3fb8676edc Mon Sep 17 00:00:00 2001 From: John Date: Tue, 6 Jul 2021 18:18:12 +0800 Subject: [PATCH 1/5] refactor(switch): support customize checked value #4329 --- components/switch/index.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/components/switch/index.tsx b/components/switch/index.tsx index 4febcce829..fff9f9365d 100644 --- a/components/switch/index.tsx +++ b/components/switch/index.tsx @@ -31,6 +31,8 @@ const switchProps = { autofocus: PropTypes.looseBool, loading: PropTypes.looseBool, checked: PropTypes.looseBool, + trueValue: PropTypes.any.def(true), + falseValue: PropTypes.any.def(false), onChange: PropTypes.func, onClick: PropTypes.func, onKeydown: PropTypes.func, @@ -59,12 +61,15 @@ const Switch = defineComponent({ '`value` is not validate prop, do you mean `checked`?', ); }); - const checked = ref(props.checked !== undefined ? !!props.checked : !!attrs.defaultChecked); + const checked = ref(props.checked !== undefined ? props.checked : attrs.defaultChecked); + const checkedStatus = computed(() => { + return checked.value === props.trueValue; + }); watch( () => props.checked, () => { - checked.value = !!props.checked; + checked.value = props.checked; }, ); @@ -92,29 +97,26 @@ const Switch = defineComponent({ }); }); - const setChecked = (check: boolean, e: MouseEvent | KeyboardEvent) => { + const setChecked = (check: any, e: MouseEvent | KeyboardEvent) => { if (props.disabled) { return; } - if (props.checked === undefined) { - checked.value = check; - } emit('update:checked', check); emit('change', check, e); }; const handleClick = (e: MouseEvent) => { focus(); - const newChecked = !checked.value; + const newChecked = checkedStatus.value ? props.falseValue : props.trueValue; setChecked(newChecked, e); emit('click', newChecked, e); }; const handleKeyDown = (e: KeyboardEvent) => { if (e.keyCode === KeyCode.LEFT) { - setChecked(false, e); + setChecked(props.falseValue, e); } else if (e.keyCode === KeyCode.RIGHT) { - setChecked(true, e); + setChecked(props.trueValue, e); } emit('keydown', e); }; @@ -133,6 +135,8 @@ const Switch = defineComponent({ 'checked', 'autofocus', 'defaultChecked', + 'trueValue', + 'falseValue', ])} {...attrs} onKeydown={handleKeyDown} @@ -147,7 +151,7 @@ const Switch = defineComponent({ [prefixCls.value]: true, [`${prefixCls.value}-small`]: props.size === 'small', [`${prefixCls.value}-loading`]: props.loading, - [`${prefixCls.value}-checked`]: checked.value, + [`${prefixCls.value}-checked`]: checkedStatus.value, [`${prefixCls.value}-disabled`]: props.disabled, }} ref={refSwitchNode} From ab4d502f4cfc91d05d6e527f58cb338d52ad2f7c Mon Sep 17 00:00:00 2001 From: John Date: Tue, 6 Jul 2021 18:35:43 +0800 Subject: [PATCH 2/5] test: add test case --- components/switch/__tests__/index.test.js | 28 +++++++++++++++++++++++ components/switch/index.tsx | 6 ++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/components/switch/__tests__/index.test.js b/components/switch/__tests__/index.test.js index 73061036fc..6f45738c46 100644 --- a/components/switch/__tests__/index.test.js +++ b/components/switch/__tests__/index.test.js @@ -4,6 +4,7 @@ import focusTest from '../../../tests/shared/focusTest'; import { resetWarned } from '../../_util/warning'; import mountTest from '../../../tests/shared/mountTest'; import { ref } from 'vue'; +import { asyncExpect } from '@/tests/utils'; describe('Switch', () => { focusTest(Switch); @@ -42,4 +43,31 @@ describe('Switch', () => { ); errorSpy.mockRestore(); }); + + it('customize checked value should work', async () => { + resetWarned(); + const checked = ref(1); + const onUpdate = val => (checked.value = val); + const wrapper = mount({ + render() { + return ( + + ); + }, + }); + await asyncExpect(() => { + wrapper.find('button').trigger('click'); + }); + expect(checked.value).toBe(2); + + await asyncExpect(() => { + wrapper.find('button').trigger('click'); + }); + expect(checked.value).toBe(1); + }); }); diff --git a/components/switch/index.tsx b/components/switch/index.tsx index fff9f9365d..f4aac78a21 100644 --- a/components/switch/index.tsx +++ b/components/switch/index.tsx @@ -30,7 +30,7 @@ const switchProps = { tabindex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), autofocus: PropTypes.looseBool, loading: PropTypes.looseBool, - checked: PropTypes.looseBool, + checked: PropTypes.any, trueValue: PropTypes.any.def(true), falseValue: PropTypes.any.def(false), onChange: PropTypes.func, @@ -62,9 +62,7 @@ const Switch = defineComponent({ ); }); const checked = ref(props.checked !== undefined ? props.checked : attrs.defaultChecked); - const checkedStatus = computed(() => { - return checked.value === props.trueValue; - }); + const checkedStatus = computed(() => checked.value === props.trueValue); watch( () => props.checked, From 38de9211de7c8ed6452188ced4593cb39a511fcc Mon Sep 17 00:00:00 2001 From: John Date: Wed, 7 Jul 2021 10:34:12 +0800 Subject: [PATCH 3/5] refactor: update props name --- components/switch/__tests__/index.test.js | 4 ++-- components/switch/index.tsx | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/switch/__tests__/index.test.js b/components/switch/__tests__/index.test.js index 6f45738c46..55980437b9 100644 --- a/components/switch/__tests__/index.test.js +++ b/components/switch/__tests__/index.test.js @@ -54,8 +54,8 @@ describe('Switch', () => { ); }, diff --git a/components/switch/index.tsx b/components/switch/index.tsx index f4aac78a21..d8e3adff9c 100644 --- a/components/switch/index.tsx +++ b/components/switch/index.tsx @@ -1,4 +1,4 @@ -import type { ExtractPropTypes } from 'vue'; +import type { ExtractPropTypes, PropType } from 'vue'; import { defineComponent, inject, @@ -62,7 +62,7 @@ const Switch = defineComponent({ ); }); const checked = ref(props.checked !== undefined ? props.checked : attrs.defaultChecked); - const checkedStatus = computed(() => checked.value === props.trueValue); + const checkedStatus = computed(() => checked.value === props.checkedValue); watch( () => props.checked, @@ -105,16 +105,16 @@ const Switch = defineComponent({ const handleClick = (e: MouseEvent) => { focus(); - const newChecked = checkedStatus.value ? props.falseValue : props.trueValue; + const newChecked = checkedStatus.value ? props.uncheckedValue : props.checkedValue; setChecked(newChecked, e); emit('click', newChecked, e); }; const handleKeyDown = (e: KeyboardEvent) => { if (e.keyCode === KeyCode.LEFT) { - setChecked(props.falseValue, e); + setChecked(props.uncheckedValue, e); } else if (e.keyCode === KeyCode.RIGHT) { - setChecked(props.trueValue, e); + setChecked(props.checkedValue, e); } emit('keydown', e); }; @@ -133,8 +133,8 @@ const Switch = defineComponent({ 'checked', 'autofocus', 'defaultChecked', - 'trueValue', - 'falseValue', + 'checkedValue', + 'uncheckedValue', ])} {...attrs} onKeydown={handleKeyDown} From 7823984d94df7210cef782aab4c60d80ee21d8fc Mon Sep 17 00:00:00 2001 From: John Date: Wed, 7 Jul 2021 10:35:30 +0800 Subject: [PATCH 4/5] refactor: update ts --- components/switch/index.tsx | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/components/switch/index.tsx b/components/switch/index.tsx index d8e3adff9c..162b7d2643 100644 --- a/components/switch/index.tsx +++ b/components/switch/index.tsx @@ -19,7 +19,7 @@ import { tuple, withInstall } from '../_util/type'; import { getPropsSlot } from '../_util/props-util'; import Omit from 'omit.js'; -export const SwitchSizes = tuple('small', 'default', 'large'); +export const SwitchSizes = tuple('small', 'default'); const switchProps = { prefixCls: PropTypes.string, @@ -31,13 +31,23 @@ const switchProps = { autofocus: PropTypes.looseBool, loading: PropTypes.looseBool, checked: PropTypes.any, - trueValue: PropTypes.any.def(true), - falseValue: PropTypes.any.def(false), - onChange: PropTypes.func, - onClick: PropTypes.func, - onKeydown: PropTypes.func, - onMouseup: PropTypes.func, - 'onUpdate:checked': PropTypes.func, + checkedValue: PropTypes.any.def(true), + uncheckedValue: PropTypes.any.def(false), + onChange: { + type: Function as PropType<(checked: any, e: Event) => void>, + }, + onClick: { + type: Function as PropType<(checked: any, e: Event) => void>, + }, + onKeydown: { + type: Function as PropType<(e: Event) => void>, + }, + onMouseup: { + type: Function as PropType<(e: Event) => void>, + }, + 'onUpdate:checked': { + type: Function as PropType<(checked: any) => void>, + }, }; export type SwitchProps = Partial>; @@ -48,7 +58,7 @@ const Switch = defineComponent({ inheritAttrs: false, props: switchProps, emits: ['update:checked', 'mouseup', 'change', 'click', 'keydown'], - setup(props: SwitchProps, { attrs, slots, expose, emit }) { + setup(props, { attrs, slots, expose, emit }) { onBeforeMount(() => { warning( !('defaultChecked' in attrs), From 0020e709b063e7751e9f482a7ff01aef93932fff Mon Sep 17 00:00:00 2001 From: John Date: Wed, 7 Jul 2021 10:50:08 +0800 Subject: [PATCH 5/5] refactor: optimize --- components/switch/index.tsx | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/components/switch/index.tsx b/components/switch/index.tsx index 162b7d2643..647b3961f0 100644 --- a/components/switch/index.tsx +++ b/components/switch/index.tsx @@ -25,8 +25,8 @@ const switchProps = { prefixCls: PropTypes.string, size: PropTypes.oneOf(SwitchSizes), disabled: PropTypes.looseBool, - checkedChildren: PropTypes.any, - unCheckedChildren: PropTypes.any, + checkedChildren: PropTypes.VNodeChild, + unCheckedChildren: PropTypes.VNodeChild, tabindex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), autofocus: PropTypes.looseBool, loading: PropTypes.looseBool, @@ -133,6 +133,13 @@ const Switch = defineComponent({ refSwitchNode.value?.blur(); emit('mouseup', e); }; + + const classNames = computed(() => ({ + [`${prefixCls.value}-small`]: props.size === 'small', + [`${prefixCls.value}-loading`]: props.loading, + [`${prefixCls.value}-checked`]: checkedStatus.value, + [`${prefixCls.value}-disabled`]: props.disabled, + })); return () => (