feat: update collapse (#2539)
parent
80599668df
commit
41e3630f8d
|
@ -79,3 +79,7 @@ tabList[{scopedSlots}] -> tabList[{slots}]
|
|||
## rate
|
||||
|
||||
v-model -> v-model:value
|
||||
|
||||
## Collapse
|
||||
|
||||
v-model -> v-model:activeKey
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { inject } from 'vue';
|
||||
import animation from '../_util/openAnimation';
|
||||
import {
|
||||
getOptionProps,
|
||||
initDefaultProps,
|
||||
getComponentFromProp,
|
||||
getComponent,
|
||||
isValidElement,
|
||||
getListeners,
|
||||
getSlot,
|
||||
} from '../_util/props-util';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import VcCollapse, { collapseProps } from '../vc-collapse';
|
||||
|
@ -13,21 +14,19 @@ import { ConfigConsumerProps } from '../config-provider';
|
|||
|
||||
export default {
|
||||
name: 'ACollapse',
|
||||
model: {
|
||||
prop: 'activeKey',
|
||||
event: 'change',
|
||||
},
|
||||
props: initDefaultProps(collapseProps(), {
|
||||
bordered: true,
|
||||
openAnimation: animation,
|
||||
expandIconPosition: 'left',
|
||||
}),
|
||||
inject: {
|
||||
configProvider: { default: () => ConfigConsumerProps },
|
||||
setup() {
|
||||
return {
|
||||
configProvider: inject('configProvider', ConfigConsumerProps),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
renderExpandIcon(panelProps, prefixCls) {
|
||||
const expandIcon = getComponentFromProp(this, 'expandIcon', panelProps);
|
||||
const expandIcon = getComponent(this, 'expandIcon', panelProps);
|
||||
const icon = expandIcon || <RightOutlined rotate={panelProps.isActive ? 90 : undefined} />;
|
||||
return isValidElement(Array.isArray(expandIcon) ? icon[0] : icon)
|
||||
? cloneElement(icon, {
|
||||
|
@ -46,14 +45,12 @@ export default {
|
|||
[`${prefixCls}-icon-position-${expandIconPosition}`]: true,
|
||||
};
|
||||
const rcCollapeProps = {
|
||||
props: {
|
||||
...getOptionProps(this),
|
||||
prefixCls,
|
||||
expandIcon: panelProps => this.renderExpandIcon(panelProps, prefixCls),
|
||||
},
|
||||
...getOptionProps(this),
|
||||
prefixCls,
|
||||
expandIcon: panelProps => this.renderExpandIcon(panelProps, prefixCls),
|
||||
class: collapseClassName,
|
||||
on: getListeners(this),
|
||||
};
|
||||
return <VcCollapse {...rcCollapeProps}>{this.$slots.default}</VcCollapse>;
|
||||
|
||||
return <VcCollapse {...rcCollapeProps}>{getSlot(this)}</VcCollapse>;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { getOptionProps, getComponentFromProp, getListeners } from '../_util/props-util';
|
||||
import { inject } from 'vue';
|
||||
import { getOptionProps, getComponent, getSlot } from '../_util/props-util';
|
||||
import VcCollapse, { panelProps } from '../vc-collapse';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
|
||||
|
@ -7,8 +8,10 @@ export default {
|
|||
props: {
|
||||
...panelProps(),
|
||||
},
|
||||
inject: {
|
||||
configProvider: { default: () => ConfigConsumerProps },
|
||||
setup() {
|
||||
return {
|
||||
configProvider: inject('configProvider', ConfigConsumerProps),
|
||||
};
|
||||
},
|
||||
render() {
|
||||
const { prefixCls: customizePrefixCls, showArrow = true } = this;
|
||||
|
@ -18,21 +21,14 @@ export default {
|
|||
const collapsePanelClassName = {
|
||||
[`${prefixCls}-no-arrow`]: !showArrow,
|
||||
};
|
||||
|
||||
const rcCollapePanelProps = {
|
||||
props: {
|
||||
...getOptionProps(this),
|
||||
prefixCls,
|
||||
extra: getComponentFromProp(this, 'extra'),
|
||||
},
|
||||
...getOptionProps(this),
|
||||
header: getComponent(this, 'header'),
|
||||
prefixCls,
|
||||
extra: getComponent(this, 'extra'),
|
||||
class: collapsePanelClassName,
|
||||
on: getListeners(this),
|
||||
};
|
||||
const header = getComponentFromProp(this, 'header');
|
||||
return (
|
||||
<VcCollapse.Panel {...rcCollapePanelProps}>
|
||||
{this.$slots.default}
|
||||
{header ? <template slot="header">{header}</template> : null}
|
||||
</VcCollapse.Panel>
|
||||
);
|
||||
return <VcCollapse.Panel {...rcCollapePanelProps}>{getSlot(this)}</VcCollapse.Panel>;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
exports[`Collapse should support remove expandIcon 1`] = `
|
||||
<div class="ant-collapse ant-collapse-icon-position-left">
|
||||
<div role="tablist" class="ant-collapse-item">
|
||||
<div role="button" tabindex="0" class="ant-collapse-header"><span role="img" aria-label="right" class="anticon anticon-right ant-collapse-arrow"><svg viewBox="64 64 896 896" focusable="false" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" class=""><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span>header</div>
|
||||
<div class="ant-collapse-item" role="tablist">
|
||||
<div class="ant-collapse-header" role="button" tabindex="0" aria-expanded="false"><span class="anticon anticon-right ant-collapse-arrow" role="img" aria-label="right"><svg class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896" focusable="false"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span>header
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import Collapse from './Collapse';
|
||||
import CollapsePanel from './CollapsePanel';
|
||||
import Base from '../base';
|
||||
|
||||
Collapse.Panel = CollapsePanel;
|
||||
|
||||
/* istanbul ignore next */
|
||||
Collapse.install = function(Vue) {
|
||||
Vue.use(Base);
|
||||
Vue.component(Collapse.name, Collapse);
|
||||
Vue.component(CollapsePanel.name, CollapsePanel);
|
||||
Collapse.install = function(app) {
|
||||
app.component(Collapse.name, Collapse);
|
||||
app.component(CollapsePanel.name, CollapsePanel);
|
||||
};
|
||||
|
||||
export default Collapse;
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import BaseMixin from '../../_util/BaseMixin';
|
||||
import { hasProp, getPropsData, isEmptyElement, initDefaultProps } from '../../_util/props-util';
|
||||
import {
|
||||
hasProp,
|
||||
getPropsData,
|
||||
isEmptyElement,
|
||||
initDefaultProps,
|
||||
getSlot,
|
||||
} from '../../_util/props-util';
|
||||
import { cloneElement } from '../../_util/vnode';
|
||||
import openAnimationFactory from './openAnimationFactory';
|
||||
import { collapseProps } from './commonProps';
|
||||
|
@ -14,10 +20,6 @@ function _toArray(activeKey) {
|
|||
export default {
|
||||
name: 'Collapse',
|
||||
mixins: [BaseMixin],
|
||||
model: {
|
||||
prop: 'activeKey',
|
||||
event: 'change',
|
||||
},
|
||||
props: initDefaultProps(collapseProps(), {
|
||||
prefixCls: 'rc-collapse',
|
||||
accordion: false,
|
||||
|
@ -84,32 +86,30 @@ export default {
|
|||
let panelEvents = {};
|
||||
if (!disabled && disabled !== '') {
|
||||
panelEvents = {
|
||||
itemClick: this.onClickItem,
|
||||
onItemClick: this.onClickItem,
|
||||
};
|
||||
}
|
||||
|
||||
const props = {
|
||||
key,
|
||||
props: {
|
||||
panelKey: key,
|
||||
header,
|
||||
headerClass,
|
||||
isActive,
|
||||
prefixCls,
|
||||
destroyInactivePanel,
|
||||
openAnimation: this.currentOpenAnimations,
|
||||
accordion,
|
||||
expandIcon,
|
||||
},
|
||||
on: panelEvents,
|
||||
panelKey: key,
|
||||
header,
|
||||
headerClass,
|
||||
isActive,
|
||||
prefixCls,
|
||||
destroyInactivePanel,
|
||||
openAnimation: this.currentOpenAnimations,
|
||||
accordion,
|
||||
expandIcon,
|
||||
...panelEvents,
|
||||
};
|
||||
|
||||
return cloneElement(child, props);
|
||||
},
|
||||
getItems() {
|
||||
const newChildren = [];
|
||||
this.$slots.default &&
|
||||
this.$slots.default.forEach((child, index) => {
|
||||
getSlot(this) &&
|
||||
getSlot(this).forEach((child, index) => {
|
||||
newChildren.push(this.getNewChild(child, index));
|
||||
});
|
||||
return newChildren;
|
||||
|
@ -117,6 +117,7 @@ export default {
|
|||
setActiveKey(activeKey) {
|
||||
this.setState({ stateActiveKey: activeKey });
|
||||
this.$emit('change', this.accordion ? activeKey[0] : activeKey);
|
||||
this.$emit('update:activeKey', this.accordion ? activeKey[0] : activeKey);
|
||||
},
|
||||
},
|
||||
render() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import PanelContent from './PanelContent';
|
||||
import { initDefaultProps, getComponentFromProp } from '../../_util/props-util';
|
||||
import { initDefaultProps, getComponent, getSlot } from '../../_util/props-util';
|
||||
import { panelProps } from './commonProps';
|
||||
import { Transition } from 'vue';
|
||||
|
||||
export default {
|
||||
name: 'Panel',
|
||||
|
@ -35,20 +36,18 @@ export default {
|
|||
expandIcon,
|
||||
extra,
|
||||
} = this.$props;
|
||||
const { $slots } = this;
|
||||
|
||||
const transitionProps = {
|
||||
props: Object.assign({
|
||||
appear: true,
|
||||
css: false,
|
||||
}),
|
||||
on: { ...openAnimation },
|
||||
appear: true,
|
||||
css: false,
|
||||
...openAnimation,
|
||||
};
|
||||
const headerCls = {
|
||||
[`${prefixCls}-header`]: true,
|
||||
[headerClass]: headerClass,
|
||||
};
|
||||
const header = getComponentFromProp(this, 'header');
|
||||
|
||||
const header = getComponent(this, 'header');
|
||||
const itemCls = {
|
||||
[`${prefixCls}-item`]: true,
|
||||
[`${prefixCls}-item-active`]: isActive,
|
||||
|
@ -58,11 +57,24 @@ export default {
|
|||
if (showArrow && typeof expandIcon === 'function') {
|
||||
icon = expandIcon(this.$props);
|
||||
}
|
||||
|
||||
const panelContent = (
|
||||
<PanelContent
|
||||
vShow={isActive}
|
||||
prefixCls={prefixCls}
|
||||
isActive={isActive}
|
||||
destroyInactivePanel={destroyInactivePanel}
|
||||
forceRender={forceRender}
|
||||
role={accordion ? 'tabpanel' : null}
|
||||
>
|
||||
{getSlot(this)}
|
||||
</PanelContent>
|
||||
);
|
||||
return (
|
||||
<div class={itemCls} role="tablist">
|
||||
<div
|
||||
class={headerCls}
|
||||
onClick={this.handleItemClick.bind(this)}
|
||||
onClick={this.handleItemClick}
|
||||
onKeypress={this.handleKeyPress}
|
||||
role={accordion ? 'tab' : 'button'}
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
|
@ -72,18 +84,7 @@ export default {
|
|||
{header}
|
||||
{extra && <div class={`${prefixCls}-extra`}>{extra}</div>}
|
||||
</div>
|
||||
<transition {...transitionProps}>
|
||||
<PanelContent
|
||||
v-show={isActive}
|
||||
prefixCls={prefixCls}
|
||||
isActive={isActive}
|
||||
destroyInactivePanel={destroyInactivePanel}
|
||||
forceRender={forceRender}
|
||||
role={accordion ? 'tabpanel' : null}
|
||||
>
|
||||
{$slots.default}
|
||||
</PanelContent>
|
||||
</transition>
|
||||
<Transition {...transitionProps}>{panelContent}</Transition>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import PropTypes from '../../_util/vue-types';
|
||||
import { getSlot } from '../../_util/props-util';
|
||||
|
||||
export default {
|
||||
name: 'PanelContent',
|
||||
|
@ -20,14 +21,13 @@ export default {
|
|||
return null;
|
||||
}
|
||||
const { prefixCls, isActive, destroyInactivePanel, forceRender, role } = this.$props;
|
||||
const { $slots } = this;
|
||||
const contentCls = {
|
||||
[`${prefixCls}-content`]: true,
|
||||
[`${prefixCls}-content-active`]: isActive,
|
||||
};
|
||||
const child =
|
||||
!forceRender && !isActive && destroyInactivePanel ? null : (
|
||||
<div class={`${prefixCls}-content-box`}>{$slots.default}</div>
|
||||
<div class={`${prefixCls}-content-box`}>{getSlot(this)}</div>
|
||||
);
|
||||
return (
|
||||
<div class={contentCls} role={role}>
|
||||
|
|
Loading…
Reference in New Issue