diff --git a/components/switch/__tests__/index.test.js b/components/switch/__tests__/index.test.js
index 73061036fc..55980437b9 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 4febcce829..647b3961f0 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,
@@ -19,23 +19,35 @@ 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,
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,
- checked: PropTypes.looseBool,
- onChange: PropTypes.func,
- onClick: PropTypes.func,
- onKeydown: PropTypes.func,
- onMouseup: PropTypes.func,
- 'onUpdate:checked': PropTypes.func,
+ checked: PropTypes.any,
+ 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>;
@@ -46,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),
@@ -59,12 +71,13 @@ 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(() => checked.value === props.checkedValue);
watch(
() => props.checked,
() => {
- checked.value = !!props.checked;
+ checked.value = props.checked;
},
);
@@ -92,29 +105,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.uncheckedValue : props.checkedValue;
setChecked(newChecked, e);
emit('click', newChecked, e);
};
const handleKeyDown = (e: KeyboardEvent) => {
if (e.keyCode === KeyCode.LEFT) {
- setChecked(false, e);
+ setChecked(props.uncheckedValue, e);
} else if (e.keyCode === KeyCode.RIGHT) {
- setChecked(true, e);
+ setChecked(props.checkedValue, e);
}
emit('keydown', e);
};
@@ -123,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 () => (