Files
lingxiao865 c5af079d8c first commit
2026-02-10 08:05:03 +08:00

239 lines
6.1 KiB
Vue

<template>
<view
:style="tools._style([customStyle])"
:class="[
classPrefix + ' ' + classPrefix + '--' + placement,
tClass
]"
>
<view
:class="classPrefix + '__title'"
aria-role="button"
:aria-expanded="expanded"
:aria-disabled="ultimateDisabled"
@click="onClick"
>
<t-cell
:title="header"
:note="headerRightContent"
bordered
:left-icon="headerLeftIcon"
:right-icon="ultimateExpandIcon ? (expanded ? 'chevron-up' : 'chevron-down') : ''"
:t-class="tools.cls(classPrefix + '__header', [placement, ['expanded', expanded]]) + ' ' + tClassHeader"
:t-class-title="'class-title ' + (ultimateDisabled ? 'class-title--disabled' : '')"
:t-class-note="'class-note ' + (ultimateDisabled ? 'class-note--disabled' : '')"
:t-class-left-icon="'class-left-icon ' + (ultimateDisabled ? 'class-left-icon--disabled' : '')"
:t-class-right-icon="'class-right-icon ' + classPrefix + '__arrow--' + placement + ' ' + (ultimateDisabled ? 'class-right-icon--disabled' : '')"
t-class-hover="class-header-hover"
:title-style="titleCustomStyle"
:note-style="noteCustomStyle"
:right-icon-style="rightIconCustomStyle"
>
<template
#left-icon
>
<slot
name="header-left-icon"
/>
</template>
<template
#title
>
<slot
name="header"
/>
</template>
<template
#note
>
<slot
name="header-right-content"
/>
</template>
<template
#right-icon
>
<slot
name="expand-icon"
/>
</template>
</t-cell>
</view>
<view
:class="classPrefix + '__wrapper'"
:animation="animation"
:aria-hidden="expanded ? '' : true"
>
<view :class="tools.cls(classPrefix + '__content', [['disabled', ultimateDisabled], ['expanded', expanded], placement]) + ' ' + tClassContent">
{{ content }}
<slot />
<slot name="content" />
</view>
</view>
</view>
</template>
<script>
import TCell from '../cell/cell';
import { uniComponent } from '../common/src/index';
import { prefix } from '../common/config';
import props from './props';
import { getRect } from '../common/utils';
import tools from '../common/utils.wxs';
import { ChildrenMixin, RELATION_MAP } from '../common/relation';
const name = `${prefix}-collapse-panel`;
const DISABLED_COLOR = 'var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, .26)))';
export default uniComponent({
name,
options: {
styleIsolation: 'shared',
},
externalClasses: [
`${prefix}-class`,
`${prefix}-class-content`,
`${prefix}-class-header`,
],
mixins: [ChildrenMixin(RELATION_MAP.CollapsePanel)],
components: {
TCell,
},
props: {
...props,
},
data() {
return {
prefix,
expanded: false,
classPrefix: name,
classBasePrefix: prefix,
ultimateExpandIcon: false,
ultimateDisabled: false,
tools,
animation: null,
};
},
computed: {
titleCustomStyle() {
return tools._style({
fontSize: 'var(--td-collapse-title-font-size, var(--td-font-size-m, 16px))',
color: this.ultimateDisabled && DISABLED_COLOR,
});
},
noteCustomStyle() {
return tools._style({
color: this.ultimateDisabled && DISABLED_COLOR,
});
},
rightIconCustomStyle() {
return tools._style({
color: this.ultimateDisabled && DISABLED_COLOR,
});
},
},
watch: {
disabled: {
handler(e) {
this.ultimateDisabled = !!e;
},
immediate: true,
},
},
methods: {
updateExpanded(activeValues = []) {
if (!this[RELATION_MAP.CollapsePanel]) {
return;
}
const { value } = this;
const { defaultExpandAll } = this[RELATION_MAP.CollapsePanel];
const expanded = defaultExpandAll ? !this.expanded : activeValues?.includes(value);
if (expanded === this.expanded) return;
this.expanded = expanded;
this.updateStyle(expanded);
},
updateStyle(expanded) {
return getRect(this, `.${name}__content`)
.then(rect => rect.height)
.then((height) => {
const animation = uni.createAnimation({
duration: 0,
timingFunction: 'ease-in-out',
});
if (expanded) {
animation
.height(height)
.top(0)
.step({ duration: 300 })
.height('auto')
.step();
} else {
let doAnimation = false;
// #ifdef H5 || APP-PLUS
animation
.height(height)
.top(1)
.step({ duration: 17 })
.height(0)
.step({ duration: 300 });
doAnimation = true;
// #endif
if (!doAnimation) {
animation
.height(height)
.top(1)
.step({ duration: 1 })
.height(0)
.step({ duration: 300 });
}
}
this.animation = animation.export();
});
},
onClick() {
const { ultimateDisabled } = this;
const { value } = this;
if (ultimateDisabled) return;
if (this[RELATION_MAP.CollapsePanel].defaultExpandAll) {
this.updateExpanded();
} else {
this[RELATION_MAP.CollapsePanel].switch(value);
}
},
innerAfterLinked() {
const { dataValue, expandIcon, disabled } = this[RELATION_MAP.CollapsePanel];
this.ultimateExpandIcon = this.expandIcon == null ? expandIcon : this.expandIcon;
this.ultimateDisabled = this.disabled == null ? disabled : this.disabled;
let interval = 0;
// #ifdef APP-PLUS
interval = 33;
// #endif
setTimeout(() => {
this.updateExpanded(dataValue);
}, interval);
},
},
});
</script>
<style scoped>
@import './collapse-panel.css';
</style>