types(Checkbox): use tsx (#8127)

This commit is contained in:
neverland 2021-02-10 22:44:59 +08:00 committed by GitHub
parent 6d465b17a8
commit afad4ca90a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 28 deletions

View File

@ -1,21 +1,37 @@
import { watch } from 'vue'; import { PropType, watch } from 'vue';
import { createNamespace } from '../utils'; import { createNamespace } from '../utils';
import { CHECKBOX_KEY } from '../checkbox';
import { useChildren } from '@vant/use'; import { useChildren } from '@vant/use';
import { useExpose } from '../composables/use-expose'; import { useExpose } from '../composables/use-expose';
import { useLinkField } from '../composables/use-link-field'; import { useLinkField } from '../composables/use-link-field';
const [createComponent, bem] = createNamespace('checkbox-group'); const [createComponent, bem] = createNamespace('checkbox-group');
export const CHECKBOX_GROUP_KEY = 'vanCheckboxGroup';
export type CheckboxGroupDirection = 'horizontal' | 'vertical';
export type CheckboxGroupToggleAllOptions = {
checked?: boolean;
skipDisabled?: boolean;
};
export type CheckboxGroupProvide = {
props: {
max: number | string;
modelValue: any[];
};
updateModelValue: (value: unknown[]) => void;
};
export default createComponent({ export default createComponent({
props: { props: {
max: [Number, String], max: [Number, String],
disabled: Boolean, disabled: Boolean,
direction: String, direction: String as PropType<CheckboxGroupDirection>,
iconSize: [Number, String], iconSize: [Number, String],
checkedColor: String, checkedColor: String,
modelValue: { modelValue: {
type: Array, type: Array as PropType<any[]>,
default: () => [], default: () => [],
}, },
}, },
@ -23,16 +39,20 @@ export default createComponent({
emits: ['change', 'update:modelValue'], emits: ['change', 'update:modelValue'],
setup(props, { emit, slots }) { setup(props, { emit, slots }) {
const { children, linkChildren } = useChildren(CHECKBOX_KEY); const { children, linkChildren } = useChildren(CHECKBOX_GROUP_KEY);
const toggleAll = (options = {}) => { const updateModelValue = (value: unknown[]) => {
emit('update:modelValue', value);
};
const toggleAll = (options: CheckboxGroupToggleAllOptions = {}) => {
if (typeof options === 'boolean') { if (typeof options === 'boolean') {
options = { checked: options }; options = { checked: options };
} }
const { checked, skipDisabled } = options; const { checked, skipDisabled } = options;
const checkedChildren = children.filter((item) => { const checkedChildren = children.filter((item: any) => {
if (!item.props.bindGroup) { if (!item.props.bindGroup) {
return false; return false;
} }
@ -42,8 +62,8 @@ export default createComponent({
return checked ?? !item.checked.value; return checked ?? !item.checked.value;
}); });
const names = checkedChildren.map((item) => item.name); const names = checkedChildren.map((item: any) => item.name);
emit('update:modelValue', names); updateModelValue(names);
}; };
watch( watch(
@ -55,7 +75,10 @@ export default createComponent({
useExpose({ toggleAll }); useExpose({ toggleAll });
useLinkField(() => props.modelValue); useLinkField(() => props.modelValue);
linkChildren({ emit, props }); linkChildren({
props,
updateModelValue,
});
return () => <div class={bem([props.direction])}>{slots.default?.()}</div>; return () => <div class={bem([props.direction])}>{slots.default?.()}</div>;
}, },

View File

@ -1,17 +1,20 @@
import { ref, computed, defineComponent } from 'vue'; import { ref, computed, defineComponent, PropType } from 'vue';
import { addUnit } from '../utils'; import { addUnit } from '../utils';
import Icon from '../icon'; import Icon from '../icon';
export type CheckerShape = 'square' | 'round';
export type CheckerLabelPosition = 'left' | 'right';
export const checkerProps = { export const checkerProps = {
name: null, name: null as any,
disabled: Boolean, disabled: Boolean,
iconSize: [Number, String], iconSize: [Number, String],
modelValue: null, modelValue: null as any,
checkedColor: String, checkedColor: String,
labelPosition: String, labelPosition: String as PropType<CheckerLabelPosition>,
labelDisabled: Boolean, labelDisabled: Boolean,
shape: { shape: {
type: String, type: String as PropType<CheckerShape>,
default: 'round', default: 'round',
}, },
}; };
@ -20,7 +23,7 @@ export default defineComponent({
props: { props: {
...checkerProps, ...checkerProps,
role: String, role: String,
parent: Object, parent: Object as PropType<Record<string, any> | null>,
checked: Boolean, checked: Boolean,
bindGroup: { bindGroup: {
type: Boolean, type: Boolean,
@ -41,14 +44,13 @@ export default defineComponent({
if (props.parent && props.bindGroup) { if (props.parent && props.bindGroup) {
return props.parent.props[name]; return props.parent.props[name];
} }
return null;
}; };
const disabled = computed( const disabled = computed<boolean>(
() => getParentProp('disabled') || props.disabled () => getParentProp('disabled') || props.disabled
); );
const direction = computed(() => getParentProp('direction') || null); const direction = computed(() => getParentProp('direction'));
const iconStyle = computed(() => { const iconStyle = computed(() => {
const checkedColor = props.checkedColor || getParentProp('checkedColor'); const checkedColor = props.checkedColor || getParentProp('checkedColor');

View File

@ -4,11 +4,10 @@ import { useParent } from '@vant/use';
import { useExpose } from '../composables/use-expose'; import { useExpose } from '../composables/use-expose';
import { useLinkField } from '../composables/use-link-field'; import { useLinkField } from '../composables/use-link-field';
import Checker, { checkerProps } from './Checker'; import Checker, { checkerProps } from './Checker';
import { CHECKBOX_GROUP_KEY, CheckboxGroupProvide } from '../checkbox-group';
const [createComponent, bem] = createNamespace('checkbox'); const [createComponent, bem] = createNamespace('checkbox');
export const CHECKBOX_KEY = 'vanCheckbox';
export default createComponent({ export default createComponent({
props: { props: {
...checkerProps, ...checkerProps,
@ -21,11 +20,11 @@ export default createComponent({
emits: ['change', 'update:modelValue'], emits: ['change', 'update:modelValue'],
setup(props, { emit, slots }) { setup(props, { emit, slots }) {
const { parent } = useParent(CHECKBOX_KEY); const { parent } = useParent<CheckboxGroupProvide>(CHECKBOX_GROUP_KEY);
const setParentValue = (checked) => { const setParentValue = (checked: boolean) => {
const { name } = props; const { name } = props;
const { max, modelValue } = parent.props; const { max, modelValue } = parent!.props;
const value = modelValue.slice(); const value = modelValue.slice();
if (checked) { if (checked) {
@ -35,7 +34,7 @@ export default createComponent({
value.push(name); value.push(name);
if (props.bindGroup) { if (props.bindGroup) {
parent.emit('update:modelValue', value); parent!.updateModelValue(value);
} }
} }
} else { } else {
@ -45,7 +44,7 @@ export default createComponent({
value.splice(index, 1); value.splice(index, 1);
if (props.bindGroup) { if (props.bindGroup) {
parent.emit('update:modelValue', value); parent!.updateModelValue(value);
} }
} }
} }
@ -83,7 +82,6 @@ export default createComponent({
role="checkbox" role="checkbox"
parent={parent} parent={parent}
checked={checked.value} checked={checked.value}
bindGroup={props.bindGroup}
onToggle={toggle} onToggle={toggle}
{...props} {...props}
/> />

1
src/vue-shim.d.ts vendored
View File

@ -13,5 +13,6 @@ declare module 'vue' {
onClick?: EventHandler; onClick?: EventHandler;
onClosed?: EventHandler; onClosed?: EventHandler;
onChange?: EventHandler; onChange?: EventHandler;
onToggle?: EventHandler;
} }
} }