You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ant-design-vue/components/vc-collapse/src/Collapse.jsx

146 lines
3.8 KiB

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 (
<div
class={collapseClassName}
{...getDataAndAriaProps(this.$attrs)}
style={style}
role={accordion ? 'tablist' : null}
>
{this.getItems()}
</div>
);
},
};