mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
110 lines
2.5 KiB
TypeScript
110 lines
2.5 KiB
TypeScript
import {
|
|
watch,
|
|
PropType,
|
|
InjectionKey,
|
|
defineComponent,
|
|
ExtractPropTypes,
|
|
ComponentPublicInstance,
|
|
} from 'vue';
|
|
|
|
// Utils
|
|
import { createNamespace } from '../utils';
|
|
|
|
// Composables
|
|
import { useChildren } from '@vant/use';
|
|
import { useExpose } from '../composables/use-expose';
|
|
import { useLinkField } from '../composables/use-link-field';
|
|
|
|
// Types
|
|
import { CheckerParent, CheckerDirection } from '../checkbox/Checker';
|
|
|
|
const [name, bem] = createNamespace('checkbox-group');
|
|
|
|
const props = {
|
|
max: [Number, String],
|
|
disabled: Boolean,
|
|
direction: String as PropType<CheckerDirection>,
|
|
iconSize: [Number, String],
|
|
checkedColor: String,
|
|
modelValue: {
|
|
type: Array as PropType<unknown[]>,
|
|
default: () => [],
|
|
},
|
|
};
|
|
|
|
export type CheckboxGroupToggleAllOptions =
|
|
| boolean
|
|
| {
|
|
checked?: boolean;
|
|
skipDisabled?: boolean;
|
|
};
|
|
|
|
type CheckboxGroupProps = ExtractPropTypes<typeof props>;
|
|
|
|
type CheckboxGroupExpose = {
|
|
toggleAll: (options?: CheckboxGroupToggleAllOptions) => void;
|
|
};
|
|
|
|
export type CheckboxGroupInstance = ComponentPublicInstance<
|
|
CheckboxGroupProps,
|
|
CheckboxGroupExpose
|
|
>;
|
|
|
|
export type CheckboxGroupProvide = CheckerParent & {
|
|
props: CheckboxGroupProps;
|
|
updateValue: (value: unknown[]) => void;
|
|
};
|
|
|
|
export const CHECKBOX_GROUP_KEY: InjectionKey<CheckboxGroupProvide> = Symbol(
|
|
name
|
|
);
|
|
|
|
export default defineComponent({
|
|
name,
|
|
|
|
props,
|
|
|
|
emits: ['change', 'update:modelValue'],
|
|
|
|
setup(props, { emit, slots }) {
|
|
const { children, linkChildren } = useChildren(CHECKBOX_GROUP_KEY);
|
|
|
|
const updateValue = (value: unknown[]) => emit('update:modelValue', value);
|
|
|
|
const toggleAll = (options: CheckboxGroupToggleAllOptions = {}) => {
|
|
if (typeof options === 'boolean') {
|
|
options = { checked: options };
|
|
}
|
|
|
|
const { checked, skipDisabled } = options;
|
|
|
|
const checkedChildren = children.filter((item: any) => {
|
|
if (!item.props.bindGroup) {
|
|
return false;
|
|
}
|
|
if (item.props.disabled && skipDisabled) {
|
|
return item.checked.value;
|
|
}
|
|
return checked ?? !item.checked.value;
|
|
});
|
|
|
|
const names = checkedChildren.map((item: any) => item.name);
|
|
updateValue(names);
|
|
};
|
|
|
|
watch(
|
|
() => props.modelValue,
|
|
(value) => emit('change', value)
|
|
);
|
|
|
|
useExpose<CheckboxGroupExpose>({ toggleAll });
|
|
useLinkField(() => props.modelValue);
|
|
linkChildren({
|
|
props,
|
|
updateValue,
|
|
});
|
|
|
|
return () => <div class={bem([props.direction])}>{slots.default?.()}</div>;
|
|
},
|
|
});
|