import type { PropType, VNode } from 'vue' import { defineComponent, provide, reactive, ref, watch } from 'vue' import { getPrefixCls } from '../_utils/getPrefixCls' import { collapseGroupKey } from './context' export default defineComponent({ name: 'collapse', props: { activeKey: { type: [String, Number, Boolean, Array] as PropType< string | number | boolean | (string | number | boolean)[] >, default: undefined, }, defaultActiveKey: { type: [String, Number, Boolean, Array] as PropType< string | number | boolean | (string | number | boolean)[] >, default: undefined, }, borderLess: { type: Boolean, default: true, }, defaultExpandAll: { type: Boolean, default: true, }, disabled: { type: Boolean, default: false, }, accordion: { type: Boolean, default: true, }, expandIcon: { type: [Boolean, String, Object, Function] as PropType< boolean | string | VNode | ((args: { expanded: boolean }) => VNode) >, default: true, }, expandIconPlacement: { type: String as PropType<'left' | 'right'>, default: 'left', }, destroyOnHide: { type: Boolean, default: false, }, class: { type: [String, Array, Object], default: '', }, style: { type: Object, default: () => ({}), }, }, emits: ['update:activeKey', 'change'], setup(props, { slots, emit }) { const prefixCls = getPrefixCls('collapse-group') const _activeKey = ref(props.activeKey ?? props.defaultActiveKey ?? (!props.accordion ? [] : undefined)) watch( () => props.activeKey, (newVal) => { _activeKey.value = newVal ?? (!props.accordion ? [] : undefined) }, ) const handleChange = (val: string | number | boolean, e: Event) => { // 外部 v-model 类型决定内部 value 的类型 const isArrayMode = Array.isArray(_activeKey.value) if (isArrayMode) { const arr = [...(_activeKey.value as (string | number | boolean)[])] const idx = arr.indexOf(val) if (idx >= 0) { arr.splice(idx, 1) } else { if (props.accordion) arr.length = 0 // 单选时只保留最后一个 arr.push(val) } _activeKey.value = arr emit('update:activeKey', arr) emit('change', arr, e) } else { // 非数组模式:单选或多选时非数组 v-model const newVal = _activeKey.value === val ? undefined : val _activeKey.value = newVal emit('update:activeKey', newVal) emit('change', newVal, e) } } provide( collapseGroupKey, reactive({ name: 'AoCollapseGroup' as const, activeKey: _activeKey, disabled: props.disabled, defaultExpandAll: props.defaultExpandAll, expandIcon: props.expandIcon, expandIconPlacement: props.expandIconPlacement, destroyOnHide: props.destroyOnHide, borderLess: props.borderLess, slots, handleChange, }), ) return () => (