import { ref, computed, PropType, defineComponent } from 'vue'; import { addUnit, extend, unknownProp, truthProp } from '../utils'; import { Icon } from '../icon'; export type CheckerShape = 'square' | 'round'; export type CheckerDirection = 'horizontal' | 'vertical'; export type CheckerLabelPosition = 'left' | 'right'; export type CheckerParent = { props: { disabled?: boolean; iconSize?: number | string; direction?: CheckerDirection; checkedColor?: string; }; }; export const checkerProps = { name: unknownProp, disabled: Boolean, iconSize: [Number, String], modelValue: unknownProp, checkedColor: String, labelPosition: String as PropType, labelDisabled: Boolean, shape: { type: String as PropType, default: 'round', }, }; export default defineComponent({ props: extend({}, checkerProps, { role: String, parent: Object as PropType, checked: Boolean, bindGroup: truthProp, bem: { type: Function, required: true as const, }, }), emits: ['click', 'toggle'], setup(props, { emit, slots }) { const iconRef = ref(); const getParentProp = (name: T) => { if (props.parent && props.bindGroup) { return props.parent.props[name]; } }; const disabled = computed( () => getParentProp('disabled') || props.disabled ); const direction = computed(() => getParentProp('direction')); const iconStyle = computed(() => { const checkedColor = props.checkedColor || getParentProp('checkedColor'); if (checkedColor && props.checked && !disabled.value) { return { borderColor: checkedColor, backgroundColor: checkedColor, }; } }); const onClick = (event: MouseEvent) => { const { target } = event; const icon = iconRef.value; const iconClicked = icon === target || icon!.contains(target as Node); if (!disabled.value && (iconClicked || !props.labelDisabled)) { emit('toggle'); } emit('click', event); }; const renderIcon = () => { const { bem, shape, checked } = props; const iconSize = props.iconSize || getParentProp('iconSize'); return (
{slots.icon ? ( slots.icon({ checked, disabled: disabled.value }) ) : ( )}
); }; const renderLabel = () => { if (slots.default) { return ( {slots.default()} ); } }; return () => { const nodes: (JSX.Element | undefined)[] = [renderIcon()]; if (props.labelPosition === 'left') { nodes.unshift(renderLabel()); } else { nodes.push(renderLabel()); } return (
{nodes}
); }; }, });