-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
Copy pathCheckbox.tsx
140 lines (134 loc) · 4.61 KB
/
Checkbox.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import type { CSSProperties } from 'vue';
import {
computed,
watchEffect,
onMounted,
defineComponent,
inject,
onBeforeUnmount,
ref,
} from 'vue';
import classNames from '../_util/classNames';
import VcCheckbox from '../vc-checkbox/Checkbox';
import { flattenChildren } from '../_util/props-util';
import warning from '../_util/warning';
import type { EventHandler } from '../_util/EventInterface';
import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useInjectDisabled } from '../config-provider/DisabledContext';
import type { CheckboxChangeEvent, CheckboxProps } from './interface';
import { CheckboxGroupContextKey, checkboxProps } from './interface';
// CSSINJS
import useStyle from './style';
export default defineComponent({
name: 'ACheckbox',
inheritAttrs: false,
__ANT_CHECKBOX: true,
props: checkboxProps(),
// emits: ['change', 'update:checked'],
setup(props, { emit, attrs, slots, expose }) {
const formItemContext = useInjectFormItemContext();
const formItemInputContext = FormItemInputContext.useInject();
const { prefixCls, direction, disabled } = useConfigInject('checkbox', props);
const contextDisabled = useInjectDisabled();
// style
const [wrapSSR, hashId] = useStyle(prefixCls);
const checkboxGroup = inject(CheckboxGroupContextKey, undefined);
const uniId = Symbol('checkboxUniId');
const mergedDisabled = computed(() => {
return checkboxGroup?.disabled.value || disabled.value;
});
watchEffect(() => {
if (!props.skipGroup && checkboxGroup) {
checkboxGroup.registerValue(uniId, props.value);
}
});
onBeforeUnmount(() => {
if (checkboxGroup) {
checkboxGroup.cancelValue(uniId);
}
});
onMounted(() => {
warning(
!!(props.checked !== undefined || checkboxGroup || props.value === undefined),
'Checkbox',
'`value` is not validate prop, do you mean `checked`?',
);
});
const handleChange = (event: CheckboxChangeEvent) => {
const targetChecked = event.target.checked;
emit('update:checked', targetChecked);
emit('change', event);
formItemContext.onFieldChange();
};
const checkboxRef = ref();
const focus = () => {
checkboxRef.value?.focus();
};
const blur = () => {
checkboxRef.value?.blur();
};
expose({
focus,
blur,
});
return () => {
const children = flattenChildren(slots.default?.());
const { indeterminate, skipGroup, id = formItemContext.id.value, ...restProps } = props;
const { onMouseenter, onMouseleave, onInput, class: className, style, ...restAttrs } = attrs;
const checkboxProps: CheckboxProps = {
...restProps,
id,
prefixCls: prefixCls.value,
...restAttrs,
disabled: mergedDisabled.value,
};
if (checkboxGroup && !skipGroup) {
checkboxProps.onChange = (...args) => {
emit('change', ...args);
checkboxGroup.toggleOption({ label: children, value: props.value });
};
checkboxProps.name = checkboxGroup.name.value;
checkboxProps.checked = checkboxGroup.mergedValue.value.includes(props.value);
checkboxProps.disabled = mergedDisabled.value || contextDisabled.value;
checkboxProps.indeterminate = indeterminate;
} else {
checkboxProps.onChange = handleChange;
}
const classString = classNames(
{
[`${prefixCls.value}-wrapper`]: true,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
[`${prefixCls.value}-wrapper-checked`]: checkboxProps.checked,
[`${prefixCls.value}-wrapper-disabled`]: checkboxProps.disabled,
[`${prefixCls.value}-wrapper-in-form-item`]: formItemInputContext.isFormItemInput,
},
className,
hashId.value,
);
const checkboxClass = classNames(
{
[`${prefixCls.value}-indeterminate`]: indeterminate,
},
hashId.value,
);
const ariaChecked = indeterminate ? 'mixed' : undefined;
return wrapSSR(
<label
class={classString}
style={style as CSSProperties}
onMouseenter={onMouseenter as EventHandler}
onMouseleave={onMouseleave as EventHandler}
>
<VcCheckbox
aria-checked={ariaChecked}
{...checkboxProps}
class={checkboxClass}
ref={checkboxRef}
/>
{children.length ? <span>{children}</span> : null}
</label>,
);
};
},
});