refactor: collapse
parent
740ba04c02
commit
af182533c1
|
@ -0,0 +1,143 @@
|
|||
import { isEmptyElement, initDefaultProps, flattenChildren } from '../_util/props-util';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import openAnimationFactory from './openAnimationFactory';
|
||||
import { collapseProps, CollapsibleType } from './commonProps';
|
||||
import { getDataAndAriaProps } from '../_util/util';
|
||||
import { computed, defineComponent, ref, watch } from 'vue';
|
||||
import firstNotUndefined from '../_util/firstNotUndefined';
|
||||
import classNames from '../_util/classNames';
|
||||
|
||||
type Key = number | string;
|
||||
|
||||
function getActiveKeysArray(activeKey: Key | Key[]) {
|
||||
let currentActiveKey = activeKey;
|
||||
if (!Array.isArray(currentActiveKey)) {
|
||||
const activeKeyType = typeof currentActiveKey;
|
||||
currentActiveKey =
|
||||
activeKeyType === 'number' || activeKeyType === 'string' ? [currentActiveKey] : [];
|
||||
}
|
||||
return currentActiveKey.map(key => String(key));
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Collapse',
|
||||
inheritAttrs: false,
|
||||
props: initDefaultProps(collapseProps(), {
|
||||
prefixCls: 'rc-collapse',
|
||||
accordion: false,
|
||||
destroyInactivePanel: false,
|
||||
}),
|
||||
slots: ['expandIcon'],
|
||||
emits: ['change'],
|
||||
setup(props, { attrs, slots, emit }) {
|
||||
const stateActiveKey = ref<Key[]>(
|
||||
getActiveKeysArray(firstNotUndefined([props.activeKey, props.defaultActiveKey])),
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.activeKey,
|
||||
() => {
|
||||
stateActiveKey.value = getActiveKeysArray(props.activeKey);
|
||||
},
|
||||
);
|
||||
const currentOpenAnimations = computed(
|
||||
() => props.openAnimation || openAnimationFactory(props.prefixCls),
|
||||
);
|
||||
|
||||
const setActiveKey = (activeKey: Key[]) => {
|
||||
if (props.activeKey === undefined) {
|
||||
stateActiveKey.value = activeKey;
|
||||
}
|
||||
emit('change', props.accordion ? activeKey[0] : activeKey);
|
||||
};
|
||||
const onClickItem = (key: Key) => {
|
||||
let activeKey = stateActiveKey.value;
|
||||
if (props.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);
|
||||
}
|
||||
}
|
||||
setActiveKey(activeKey);
|
||||
};
|
||||
|
||||
const getNewChild = (child, index) => {
|
||||
if (isEmptyElement(child)) return;
|
||||
const activeKey = stateActiveKey.value;
|
||||
const {
|
||||
prefixCls,
|
||||
accordion,
|
||||
destroyInactivePanel,
|
||||
expandIcon = slots.expandIcon,
|
||||
collapsible,
|
||||
} = props;
|
||||
|
||||
// If there is no key provide, use the panel order as default key
|
||||
const key = String(child.key ?? index);
|
||||
const {
|
||||
header = child.children?.header?.(),
|
||||
headerClass,
|
||||
collapsible: childCollapsible,
|
||||
disabled,
|
||||
} = child.props || {};
|
||||
let isActive = false;
|
||||
|
||||
if (accordion) {
|
||||
isActive = activeKey[0] === key;
|
||||
} else {
|
||||
isActive = activeKey.indexOf(key) > -1;
|
||||
}
|
||||
|
||||
let mergeCollapsible: CollapsibleType = childCollapsible ?? collapsible;
|
||||
// legacy 2.x
|
||||
if (disabled || disabled === '') {
|
||||
mergeCollapsible = 'disabled';
|
||||
}
|
||||
const newProps = {
|
||||
key,
|
||||
panelKey: key,
|
||||
header,
|
||||
headerClass,
|
||||
isActive,
|
||||
prefixCls,
|
||||
destroyInactivePanel,
|
||||
openAnimation: currentOpenAnimations.value,
|
||||
accordion,
|
||||
onItemClick: mergeCollapsible === 'disabled' ? null : onClickItem,
|
||||
expandIcon,
|
||||
collapsible: mergeCollapsible,
|
||||
};
|
||||
|
||||
return cloneElement(child, newProps);
|
||||
};
|
||||
|
||||
const getItems = () => {
|
||||
return flattenChildren(slots.default?.()).map(getNewChild);
|
||||
};
|
||||
|
||||
return () => {
|
||||
const { prefixCls, accordion } = props;
|
||||
const collapseClassName = classNames({
|
||||
[prefixCls]: true,
|
||||
[attrs.class as string]: !!attrs.class,
|
||||
});
|
||||
return (
|
||||
<div
|
||||
class={collapseClassName}
|
||||
{...getDataAndAriaProps(attrs)}
|
||||
style={attrs.style}
|
||||
role={accordion ? 'tablist' : null}
|
||||
>
|
||||
{getItems()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
|
@ -0,0 +1,109 @@
|
|||
import PanelContent from './PanelContent';
|
||||
import { initDefaultProps } from '../_util/props-util';
|
||||
import { panelProps } from './commonProps';
|
||||
import { defineComponent } from 'vue';
|
||||
import Transition from '../_util/transition';
|
||||
import classNames from '../_util/classNames';
|
||||
import devWarning from '../vc-util/devWarning';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Panel',
|
||||
props: initDefaultProps(panelProps(), {
|
||||
showArrow: true,
|
||||
isActive: false,
|
||||
onItemClick() {},
|
||||
headerClass: '',
|
||||
forceRender: false,
|
||||
}),
|
||||
slots: ['expandIcon', 'extra', 'header'],
|
||||
emits: ['itemClick'],
|
||||
setup(props, { slots, emit }) {
|
||||
devWarning(
|
||||
!('disabled' in props),
|
||||
'Collapse.Panel',
|
||||
'`disabled` is deprecated. Please use `collapsible="disabled"` instead.',
|
||||
);
|
||||
const handleItemClick = () => {
|
||||
emit('itemClick', props.panelKey);
|
||||
};
|
||||
const handleKeyPress = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter' || e.keyCode === 13 || e.which === 13) {
|
||||
handleItemClick();
|
||||
}
|
||||
};
|
||||
return () => {
|
||||
const {
|
||||
prefixCls,
|
||||
header = slots.header?.(),
|
||||
headerClass,
|
||||
isActive,
|
||||
showArrow,
|
||||
destroyInactivePanel,
|
||||
accordion,
|
||||
forceRender,
|
||||
openAnimation,
|
||||
expandIcon = slots.expandIcon,
|
||||
extra = slots.extra?.(),
|
||||
collapsible,
|
||||
} = props;
|
||||
const disabled = collapsible === 'disabled';
|
||||
|
||||
const headerCls = classNames(`${prefixCls}-header`, {
|
||||
[headerClass]: headerClass,
|
||||
[`${prefixCls}-header-collapsible-only`]: collapsible === 'header',
|
||||
});
|
||||
const itemCls = classNames({
|
||||
[`${prefixCls}-item`]: true,
|
||||
[`${prefixCls}-item-active`]: isActive,
|
||||
[`${prefixCls}-item-disabled`]: disabled,
|
||||
});
|
||||
|
||||
let icon = <i class="arrow" />;
|
||||
if (showArrow && typeof expandIcon === 'function') {
|
||||
icon = expandIcon(props);
|
||||
}
|
||||
|
||||
const panelContent = (
|
||||
<PanelContent
|
||||
v-show={isActive}
|
||||
prefixCls={prefixCls}
|
||||
isActive={isActive}
|
||||
forceRender={forceRender}
|
||||
role={accordion ? 'tabpanel' : null}
|
||||
v-slots={{ default: slots.default }}
|
||||
></PanelContent>
|
||||
);
|
||||
const transitionProps = {
|
||||
appear: true,
|
||||
css: false,
|
||||
...openAnimation,
|
||||
};
|
||||
|
||||
return (
|
||||
<div class={itemCls}>
|
||||
<div
|
||||
class={headerCls}
|
||||
onClick={() => collapsible !== 'header' && handleItemClick()}
|
||||
role={accordion ? 'tab' : 'button'}
|
||||
tabindex={disabled ? -1 : 0}
|
||||
aria-expanded={isActive}
|
||||
onKeypress={handleKeyPress}
|
||||
>
|
||||
{showArrow && icon}
|
||||
{collapsible === 'header' ? (
|
||||
<span onClick={handleItemClick} class={`${prefixCls}-header-text`}>
|
||||
{header}
|
||||
</span>
|
||||
) : (
|
||||
header
|
||||
)}
|
||||
{extra && <div class={`${prefixCls}-extra`}>{extra}</div>}
|
||||
</div>
|
||||
<Transition {...transitionProps}>
|
||||
{!destroyInactivePanel || isActive ? panelContent : null}
|
||||
</Transition>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
import { defineComponent, ref, watchEffect } from 'vue';
|
||||
import { panelProps } from './commonProps';
|
||||
import classNames from '../_util/classNames';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PanelContent',
|
||||
props: panelProps(),
|
||||
setup(props, { slots }) {
|
||||
const rendered = ref(false);
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.isActive || props.forceRender) {
|
||||
rendered.value = true;
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
if (!rendered.value) return null;
|
||||
const { prefixCls, isActive, role } = props;
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
class={classNames(`${prefixCls}-content`, {
|
||||
[`${prefixCls}-content-active`]: isActive,
|
||||
[`${prefixCls}-content-inactive`]: !isActive,
|
||||
})}
|
||||
role={role}
|
||||
>
|
||||
<div class={`${prefixCls}-content-box`}>{slots.default?.()}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
|
@ -1,100 +0,0 @@
|
|||
@prefixCls: rc-collapse;
|
||||
@text-color: #666;
|
||||
@borderStyle: 1px solid #d9d9d9;
|
||||
|
||||
#arrow {
|
||||
.common() {
|
||||
width: 0;
|
||||
height: 0;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
}
|
||||
.right(@w, @h, @color) {
|
||||
border-top: @w solid transparent;
|
||||
border-bottom: @w solid transparent;
|
||||
border-left: @h solid @color;
|
||||
}
|
||||
|
||||
.bottom(@w, @h, @color) {
|
||||
border-left: @w solid transparent;
|
||||
border-right: @w solid transparent;
|
||||
border-top: @h solid @color;
|
||||
}
|
||||
}
|
||||
|
||||
.@{prefixCls} {
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 3px;
|
||||
border: @borderStyle;
|
||||
|
||||
&-anim-active {
|
||||
transition: height 0.2s ease-out;
|
||||
}
|
||||
|
||||
& > &-item {
|
||||
border-top: @borderStyle;
|
||||
&:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
> .@{prefixCls}-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 22px;
|
||||
padding: 10px 16px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
.arrow {
|
||||
display: inline-block;
|
||||
content: '\20';
|
||||
#arrow > .common();
|
||||
#arrow > .right(3px, 4px, #666);
|
||||
vertical-align: middle;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.@{prefixCls}-extra {
|
||||
margin: 0 16px 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > &-item-disabled > .@{prefixCls}-header {
|
||||
cursor: not-allowed;
|
||||
color: #999;
|
||||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
&-content {
|
||||
overflow: hidden;
|
||||
color: @text-color;
|
||||
padding: 0 16px;
|
||||
background-color: #fff;
|
||||
|
||||
& > &-box {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&-inactive {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-item:last-child {
|
||||
> .@{prefixCls}-content {
|
||||
border-radius: 0 0 3px 3px;
|
||||
}
|
||||
}
|
||||
|
||||
& > &-item-active {
|
||||
> .@{prefixCls}-header {
|
||||
.arrow {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
#arrow > .bottom(3px, 4px, #666);
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
import PropTypes from '../../_util/vue-types';
|
||||
import type { PropType } from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
|
||||
export type CollapsibleType = 'header' | 'disabled';
|
||||
|
||||
const collapseProps = () => ({
|
||||
prefixCls: PropTypes.string,
|
||||
|
@ -19,6 +22,7 @@ const collapseProps = () => ({
|
|||
openAnimation: PropTypes.object,
|
||||
expandIconPosition: PropTypes.oneOf(['left', 'right']),
|
||||
onChange: PropTypes.func,
|
||||
collapsible: { type: String as PropType<CollapsibleType> },
|
||||
});
|
||||
|
||||
const panelProps = () => ({
|
||||
|
@ -34,7 +38,10 @@ const panelProps = () => ({
|
|||
forceRender: PropTypes.looseBool,
|
||||
expandIcon: PropTypes.func,
|
||||
extra: PropTypes.any,
|
||||
panelKey: PropTypes.any,
|
||||
panelKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
collapsible: { type: String as PropType<CollapsibleType> },
|
||||
role: String,
|
||||
onItemClick: { type: Function as PropType<(panelKey: string | number) => void> },
|
||||
});
|
||||
|
||||
export { collapseProps, panelProps };
|
|
@ -1,9 +0,0 @@
|
|||
// based on rc-collapse 1.11.8
|
||||
import CollapsePanel from './src/Panel';
|
||||
import Collapse from './src/Collapse';
|
||||
import { collapseProps, panelProps } from './src/commonProps';
|
||||
|
||||
Collapse.Panel = CollapsePanel;
|
||||
|
||||
export { collapseProps, panelProps };
|
||||
export default Collapse;
|
|
@ -0,0 +1,9 @@
|
|||
// based on rc-collapse 3.1.1
|
||||
import CollapsePanel from './Panel';
|
||||
import Collapse from './Collapse';
|
||||
import { collapseProps, panelProps } from './commonProps';
|
||||
|
||||
Collapse.Panel = CollapsePanel;
|
||||
|
||||
export { collapseProps, panelProps };
|
||||
export default Collapse;
|
|
@ -1,14 +1,14 @@
|
|||
import cssAnimation from '../../_util/css-animation';
|
||||
import cssAnimation from '../_util/css-animation';
|
||||
|
||||
function animate(node, show, transitionName, done) {
|
||||
let height;
|
||||
function animate(node: HTMLElement, show: boolean, transitionName: string, done: () => void) {
|
||||
let height: number;
|
||||
return cssAnimation(node, transitionName, {
|
||||
start() {
|
||||
if (!show) {
|
||||
node.style.height = `${node.offsetHeight}px`;
|
||||
} else {
|
||||
height = node.offsetHeight;
|
||||
node.style.height = 0;
|
||||
node.style.height = '0px';
|
||||
}
|
||||
},
|
||||
active() {
|
||||
|
@ -21,12 +21,12 @@ function animate(node, show, transitionName, done) {
|
|||
});
|
||||
}
|
||||
|
||||
function animation(prefixCls) {
|
||||
function animation(prefixCls: string) {
|
||||
return {
|
||||
onEnter(node, done) {
|
||||
onEnter(node: HTMLElement, done: () => void) {
|
||||
return animate(node, true, `${prefixCls}-anim`, done);
|
||||
},
|
||||
onLeave(node, done) {
|
||||
onLeave(node: HTMLElement, done: () => void) {
|
||||
return animate(node, false, `${prefixCls}-anim`, done);
|
||||
},
|
||||
};
|
|
@ -1,148 +0,0 @@
|
|||
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';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
function _toArray(activeKey) {
|
||||
let currentActiveKey = activeKey;
|
||||
if (!Array.isArray(currentActiveKey)) {
|
||||
const activeKeyType = typeof currentActiveKey;
|
||||
currentActiveKey =
|
||||
activeKeyType === 'number' || activeKeyType === 'string' ? [currentActiveKey] : [];
|
||||
}
|
||||
return currentActiveKey.map(key => String(key));
|
||||
}
|
||||
export default defineComponent({
|
||||
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 = String(child.key ?? 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>
|
||||
);
|
||||
},
|
||||
});
|
|
@ -1,94 +0,0 @@
|
|||
import PanelContent from './PanelContent';
|
||||
import { initDefaultProps, getComponent, getSlot } from '../../_util/props-util';
|
||||
import { panelProps } from './commonProps';
|
||||
import { defineComponent } from 'vue';
|
||||
import BaseMixin from '../../_util/BaseMixin';
|
||||
import Transition from '../../_util/transition';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Panel',
|
||||
mixins: [BaseMixin],
|
||||
props: initDefaultProps(panelProps(), {
|
||||
showArrow: true,
|
||||
isActive: false,
|
||||
destroyInactivePanel: false,
|
||||
headerClass: '',
|
||||
forceRender: false,
|
||||
}),
|
||||
methods: {
|
||||
handleItemClick() {
|
||||
this.__emit('itemClick', this.panelKey);
|
||||
},
|
||||
handleKeyPress(e) {
|
||||
if (e.key === 'Enter' || e.keyCode === 13 || e.which === 13) {
|
||||
this.handleItemClick();
|
||||
}
|
||||
},
|
||||
},
|
||||
render() {
|
||||
const {
|
||||
prefixCls,
|
||||
headerClass,
|
||||
isActive,
|
||||
showArrow,
|
||||
destroyInactivePanel,
|
||||
disabled,
|
||||
openAnimation,
|
||||
accordion,
|
||||
forceRender,
|
||||
expandIcon,
|
||||
extra,
|
||||
} = this.$props;
|
||||
|
||||
const transitionProps = {
|
||||
appear: true,
|
||||
css: false,
|
||||
...openAnimation,
|
||||
};
|
||||
const headerCls = {
|
||||
[`${prefixCls}-header`]: true,
|
||||
[headerClass]: headerClass,
|
||||
};
|
||||
|
||||
const header = getComponent(this, 'header');
|
||||
const itemCls = {
|
||||
[`${prefixCls}-item`]: true,
|
||||
[`${prefixCls}-item-active`]: isActive,
|
||||
[`${prefixCls}-item-disabled`]: disabled,
|
||||
};
|
||||
let icon = <i class="arrow" />;
|
||||
if (showArrow && typeof expandIcon === 'function') {
|
||||
icon = expandIcon(this.$props);
|
||||
}
|
||||
|
||||
const panelContent = (
|
||||
<PanelContent
|
||||
v-show={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}
|
||||
onKeypress={this.handleKeyPress}
|
||||
role={accordion ? 'tab' : 'button'}
|
||||
tabindex={disabled ? -1 : 0}
|
||||
aria-expanded={isActive}
|
||||
>
|
||||
{showArrow && icon}
|
||||
{header}
|
||||
{extra && <div class={`${prefixCls}-extra`}>{extra}</div>}
|
||||
</div>
|
||||
<Transition {...transitionProps}>{panelContent}</Transition>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
|
@ -1,39 +0,0 @@
|
|||
import PropTypes from '../../_util/vue-types';
|
||||
import { getSlot } from '../../_util/props-util';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PanelContent',
|
||||
props: {
|
||||
prefixCls: PropTypes.string,
|
||||
isActive: PropTypes.looseBool,
|
||||
destroyInactivePanel: PropTypes.looseBool,
|
||||
forceRender: PropTypes.looseBool,
|
||||
role: PropTypes.any,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
_isActive: undefined,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
this._isActive = this.forceRender || this._isActive || this.isActive;
|
||||
if (!this._isActive) {
|
||||
return null;
|
||||
}
|
||||
const { prefixCls, isActive, destroyInactivePanel, forceRender, role } = this.$props;
|
||||
const contentCls = {
|
||||
[`${prefixCls}-content`]: true,
|
||||
[`${prefixCls}-content-active`]: isActive,
|
||||
};
|
||||
const child =
|
||||
!forceRender && !isActive && destroyInactivePanel ? null : (
|
||||
<div class={`${prefixCls}-content-box`}>{getSlot(this)}</div>
|
||||
);
|
||||
return (
|
||||
<div class={contentCls} role={role}>
|
||||
{child}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
// base rc-steps 3.5.0
|
||||
// base rc-steps 4.1.3
|
||||
import Steps from './Steps';
|
||||
import Step from './Step';
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import { defineComponent } from 'vue';
|
||||
import demo from '../v2-doc/src/docs/timeline/demo/index.vue';
|
||||
import demo from '../v2-doc/src/docs/collapse/demo/index.vue';
|
||||
// import Affix from '../components/affix';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
|
2
v2-doc
2
v2-doc
|
@ -1 +1 @@
|
|||
Subproject commit 3a14ef175850d1fcb3ccd002c3afd1f871dc3257
|
||||
Subproject commit c703df2dd803ee5097b414e2a32482b8fc2225d7
|
Loading…
Reference in New Issue