Skip to content

Commit 26496ba

Browse files
authored
refactor: checkbox (#5091)
* style: remove not use pkg * refactor: vc-checkbox * refactor: checkbox * fix: radio type
1 parent 620214d commit 26496ba

31 files changed

+491
-943
lines changed

components/checkbox/Checkbox.tsx

Lines changed: 85 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,107 @@
1-
import type { ExtractPropTypes } from 'vue';
2-
import { defineComponent, inject, nextTick } from 'vue';
3-
import PropTypes from '../_util/vue-types';
1+
import { watchEffect, onMounted, defineComponent, inject, onBeforeUnmount, ref } from 'vue';
42
import classNames from '../_util/classNames';
5-
import VcCheckbox from '../vc-checkbox';
6-
import hasProp, { getOptionProps, getSlot } from '../_util/props-util';
7-
import { defaultConfigProvider } from '../config-provider';
3+
import VcCheckbox from '../vc-checkbox/Checkbox';
4+
import { flattenChildren } from '../_util/props-util';
85
import warning from '../_util/warning';
96
import type { RadioChangeEvent } from '../radio/interface';
107
import type { EventHandler } from '../_util/EventInterface';
118
import { useInjectFormItemContext } from '../form/FormItemContext';
12-
function noop() {}
9+
import useConfigInject from '../_util/hooks/useConfigInject';
1310

14-
export const checkboxProps = () => {
15-
return {
16-
prefixCls: PropTypes.string,
17-
defaultChecked: PropTypes.looseBool,
18-
checked: PropTypes.looseBool,
19-
disabled: PropTypes.looseBool,
20-
isGroup: PropTypes.looseBool,
21-
value: PropTypes.any,
22-
name: PropTypes.string,
23-
id: PropTypes.string,
24-
indeterminate: PropTypes.looseBool,
25-
type: PropTypes.string.def('checkbox'),
26-
autofocus: PropTypes.looseBool,
27-
onChange: PropTypes.func,
28-
'onUpdate:checked': PropTypes.func,
29-
skipGroup: PropTypes.looseBool,
30-
};
31-
};
32-
33-
export type CheckboxProps = Partial<ExtractPropTypes<ReturnType<typeof checkboxProps>>>;
11+
import type { CheckboxProps } from './interface';
12+
import { CheckboxGroupContextKey, checkboxProps } from './interface';
3413

3514
export default defineComponent({
3615
name: 'ACheckbox',
3716
inheritAttrs: false,
3817
__ANT_CHECKBOX: true,
3918
props: checkboxProps(),
4019
emits: ['change', 'update:checked'],
41-
setup() {
20+
setup(props, { emit, attrs, slots, expose }) {
4221
const formItemContext = useInjectFormItemContext();
43-
return {
44-
formItemContext,
45-
configProvider: inject('configProvider', defaultConfigProvider),
46-
checkboxGroupContext: inject('checkboxGroupContext', undefined),
47-
};
48-
},
22+
const { prefixCls, direction } = useConfigInject('checkbox', props);
23+
const checkboxGroup = inject(CheckboxGroupContextKey, undefined);
24+
const uniId = Symbol('checkboxUniId');
4925

50-
watch: {
51-
value(value, prevValue) {
52-
if (this.skipGroup) {
53-
return;
26+
watchEffect(() => {
27+
if (!props.skipGroup && checkboxGroup) {
28+
checkboxGroup.registerValue(uniId, props.value);
5429
}
55-
nextTick(() => {
56-
const { checkboxGroupContext: checkboxGroup = {} } = this;
57-
if (checkboxGroup.registerValue && checkboxGroup.cancelValue) {
58-
checkboxGroup.cancelValue(prevValue);
59-
checkboxGroup.registerValue(value);
60-
}
61-
});
62-
},
63-
},
64-
65-
mounted() {
66-
const { value, checkboxGroupContext: checkboxGroup = {} } = this;
67-
if (checkboxGroup.registerValue) {
68-
checkboxGroup.registerValue(value);
69-
}
30+
});
31+
onBeforeUnmount(() => {
32+
if (checkboxGroup) {
33+
checkboxGroup.cancelValue(uniId);
34+
}
35+
});
36+
onMounted(() => {
37+
warning(
38+
props.checked !== undefined || checkboxGroup || props.value === undefined,
39+
'Checkbox',
40+
'`value` is not validate prop, do you mean `checked`?',
41+
);
42+
});
7043

71-
warning(
72-
hasProp(this, 'checked') || this.checkboxGroupContext || !hasProp(this, 'value'),
73-
'Checkbox',
74-
'`value` is not validate prop, do you mean `checked`?',
75-
);
76-
},
77-
beforeUnmount() {
78-
const { value, checkboxGroupContext: checkboxGroup = {} } = this;
79-
if (checkboxGroup.cancelValue) {
80-
checkboxGroup.cancelValue(value);
81-
}
82-
},
83-
methods: {
84-
handleChange(event: RadioChangeEvent) {
44+
const handleChange = (event: RadioChangeEvent) => {
8545
const targetChecked = event.target.checked;
86-
this.$emit('update:checked', targetChecked);
87-
// this.$emit('input', targetChecked);
88-
this.$emit('change', event);
89-
},
90-
focus() {
91-
(this.$refs.vcCheckbox as HTMLInputElement).focus();
92-
},
93-
blur() {
94-
(this.$refs.vcCheckbox as HTMLInputElement).blur();
95-
},
96-
},
97-
98-
render() {
99-
const props = getOptionProps(this);
100-
const { checkboxGroupContext: checkboxGroup, $attrs } = this;
101-
const children = getSlot(this);
102-
const {
103-
indeterminate,
104-
prefixCls: customizePrefixCls,
105-
skipGroup,
106-
id = this.formItemContext.id.value,
107-
...restProps
108-
} = props;
109-
const getPrefixCls = this.configProvider.getPrefixCls;
110-
const prefixCls = getPrefixCls('checkbox', customizePrefixCls);
111-
const {
112-
onMouseenter = noop,
113-
onMouseleave = noop,
114-
onInput,
115-
class: className,
116-
style,
117-
...restAttrs
118-
} = $attrs;
119-
const checkboxProps: any = {
120-
...restProps,
121-
id,
122-
prefixCls,
123-
...restAttrs,
46+
emit('update:checked', targetChecked);
47+
emit('change', event);
12448
};
125-
if (checkboxGroup && !skipGroup) {
126-
checkboxProps.onChange = (...args) => {
127-
this.$emit('change', ...args);
128-
this.formItemContext.onFieldChange();
129-
checkboxGroup.toggleOption({ label: children, value: props.value });
130-
};
131-
checkboxProps.name = checkboxGroup.name;
132-
checkboxProps.checked = checkboxGroup.sValue.indexOf(props.value) !== -1;
133-
checkboxProps.disabled = props.disabled || checkboxGroup.disabled;
134-
checkboxProps.indeterminate = indeterminate;
135-
} else {
136-
checkboxProps.onChange = this.handleChange;
137-
}
138-
const classString = classNames(
139-
{
140-
[`${prefixCls}-wrapper`]: true,
141-
[`${prefixCls}-wrapper-checked`]: checkboxProps.checked,
142-
[`${prefixCls}-wrapper-disabled`]: checkboxProps.disabled,
143-
},
144-
className,
145-
);
146-
const checkboxClass = classNames({
147-
[`${prefixCls}-indeterminate`]: indeterminate,
49+
const checkboxRef = ref();
50+
const focus = () => {
51+
checkboxRef.value?.focus();
52+
};
53+
const blur = () => {
54+
checkboxRef.value?.blur();
55+
};
56+
expose({
57+
focus,
58+
blur,
14859
});
149-
return (
150-
<label
151-
class={classString}
152-
style={style}
153-
onMouseenter={onMouseenter as EventHandler}
154-
onMouseleave={onMouseleave as EventHandler}
155-
>
156-
<VcCheckbox {...checkboxProps} class={checkboxClass} ref="vcCheckbox" />
157-
{children.length ? <span>{children}</span> : null}
158-
</label>
159-
);
60+
return () => {
61+
const children = flattenChildren(slots.default?.());
62+
const { indeterminate, skipGroup, id = formItemContext.id.value, ...restProps } = props;
63+
const { onMouseenter, onMouseleave, onInput, class: className, style, ...restAttrs } = attrs;
64+
const checkboxProps: CheckboxProps = {
65+
...restProps,
66+
id,
67+
prefixCls: prefixCls.value,
68+
...restAttrs,
69+
};
70+
if (checkboxGroup && !skipGroup) {
71+
checkboxProps.onChange = (...args) => {
72+
emit('change', ...args);
73+
checkboxGroup.toggleOption({ label: children, value: props.value });
74+
};
75+
checkboxProps.name = checkboxGroup.name.value;
76+
checkboxProps.checked = checkboxGroup.mergedValue.value.indexOf(props.value) !== -1;
77+
checkboxProps.disabled = props.disabled || checkboxGroup.disabled.value;
78+
checkboxProps.indeterminate = indeterminate;
79+
} else {
80+
checkboxProps.onChange = handleChange;
81+
}
82+
const classString = classNames(
83+
{
84+
[`${prefixCls.value}-wrapper`]: true,
85+
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
86+
[`${prefixCls.value}-wrapper-checked`]: checkboxProps.checked,
87+
[`${prefixCls.value}-wrapper-disabled`]: checkboxProps.disabled,
88+
},
89+
className,
90+
);
91+
const checkboxClass = classNames({
92+
[`${prefixCls.value}-indeterminate`]: indeterminate,
93+
});
94+
return (
95+
<label
96+
class={classString}
97+
style={style}
98+
onMouseenter={onMouseenter as EventHandler}
99+
onMouseleave={onMouseleave as EventHandler}
100+
>
101+
<VcCheckbox {...checkboxProps} class={checkboxClass} ref={checkboxRef} />
102+
{children.length ? <span>{children}</span> : null}
103+
</label>
104+
);
105+
};
160106
},
161107
});

0 commit comments

Comments
 (0)