import BaseMixin from '../../_util/BaseMixin'; import { hasProp, getPropsData, isEmptyElement, initDefaultProps, getSlot, } from '../../_util/props-util'; import { cloneElement } from '../../_util/vnode'; import openAnimationFactory from './openAnimationFactory'; import { collapseProps } from './commonProps'; import { getDataAndAriaProps } from '../../_util/util'; function _toArray(activeKey) { let currentActiveKey = activeKey; if (!Array.isArray(currentActiveKey)) { currentActiveKey = currentActiveKey ? [currentActiveKey] : []; } return currentActiveKey.map(key => String(key)); } export default { name: 'Collapse', mixins: [BaseMixin], inheritAttrs: false, props: initDefaultProps(collapseProps(), { prefixCls: 'rc-collapse', accordion: false, destroyInactivePanel: false, }), data() { const { activeKey, defaultActiveKey, openAnimation, prefixCls } = this.$props; let currentActiveKey = defaultActiveKey; if (hasProp(this, 'activeKey')) { currentActiveKey = activeKey; } const currentOpenAnimations = openAnimation || openAnimationFactory(prefixCls); return { currentOpenAnimations, stateActiveKey: _toArray(currentActiveKey), }; }, watch: { activeKey(val) { this.setState({ stateActiveKey: _toArray(val), }); }, openAnimation(val) { this.setState({ currentOpenAnimations: val, }); }, }, methods: { onClickItem(key) { let activeKey = this.stateActiveKey; if (this.accordion) { activeKey = activeKey[0] === key ? [] : [key]; } else { activeKey = [...activeKey]; const index = activeKey.indexOf(key); const isActive = index > -1; if (isActive) { // remove active state activeKey.splice(index, 1); } else { activeKey.push(key); } } this.setActiveKey(activeKey); }, getNewChild(child, index) { if (isEmptyElement(child)) return; const activeKey = this.stateActiveKey; const { prefixCls, accordion, destroyInactivePanel, expandIcon } = this.$props; // If there is no key provide, use the panel order as default key const key = child.key || String(index); const { header, headerClass, disabled } = getPropsData(child); let isActive = false; if (accordion) { isActive = activeKey[0] === key; } else { isActive = activeKey.indexOf(key) > -1; } let panelEvents = {}; if (!disabled && disabled !== '') { panelEvents = { onItemClick: this.onClickItem, }; } const props = { key, panelKey: key, header, headerClass, isActive, prefixCls, destroyInactivePanel, openAnimation: this.currentOpenAnimations, accordion, expandIcon, ...panelEvents, }; return cloneElement(child, props); }, getItems() { const newChildren = []; const children = getSlot(this); children && children.forEach((child, index) => { newChildren.push(this.getNewChild(child, index)); }); return newChildren; }, setActiveKey(activeKey) { if (!hasProp(this, 'activeKey')) { this.setState({ stateActiveKey: activeKey }); } this.__emit('change', this.accordion ? activeKey[0] : activeKey); }, }, render() { const { prefixCls, accordion } = this.$props; const { class: className, style } = this.$attrs; const collapseClassName = { [prefixCls]: true, [className]: className, }; return (