Skip to content

Commit 068862c

Browse files
feat(Collapse): sfc changed to tsx (#1308)
* feat(Collapse): sfc changed to tsx * feat(Collapse): use usePrefixClass() to calculate the class prefix * docs: sync api --------- Co-authored-by: 黎伟杰 <674416404@qq.com>
1 parent e2d344c commit 068862c

File tree

9 files changed

+637
-440
lines changed

9 files changed

+637
-440
lines changed

src/collapse/__test__/__snapshots__/demo.test.jsx.snap

Lines changed: 484 additions & 264 deletions
Large diffs are not rendered by default.

src/collapse/collapse-panel-props.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default {
1616
default: {
1717
type: [String, Function] as PropType<TdCollapsePanelProps['default']>,
1818
},
19-
/** 当前面板处理折叠状态时,是否销毁面板内容 */
19+
/** 【暂不支持】当前面板处理折叠状态时,是否销毁面板内容 */
2020
destroyOnCollapse: Boolean,
2121
/** 禁止当前面板展开,优先级大于 Collapse 的同名属性 */
2222
disabled: {

src/collapse/collapse-panel.tsx

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { ref, computed, nextTick, watch, onMounted, inject, defineComponent, getCurrentInstance } from 'vue';
2+
import { ChevronDownIcon, ChevronUpIcon } from 'tdesign-icons-vue-next';
3+
import TCell from '../cell';
4+
import props from './collapse-panel-props';
5+
import config from '../config';
6+
import { findIndex } from './util';
7+
import { useTNodeJSX, useContent } from '../hooks/tnode';
8+
import { usePrefixClass } from '../hooks/useClass';
9+
import { CollapseProvide } from './collapse';
10+
11+
const { prefix } = config;
12+
const name = `${prefix}-collapse-panel`;
13+
14+
export default defineComponent({
15+
name,
16+
components: { TCell },
17+
props,
18+
setup(props, { slots }) {
19+
const renderTNodeJSX = useTNodeJSX();
20+
const renderContent = useContent();
21+
22+
const componentName = usePrefixClass('collapse-panel');
23+
24+
const parent = inject<CollapseProvide>('collapse');
25+
const renderParentTNode: Function = inject('renderParentTNode');
26+
27+
const disabled = computed(() => parent?.disabled.value || props.disabled);
28+
const rootClass = computed(() => ({
29+
[`${componentName.value}`]: true,
30+
[`${componentName.value}--${props.placement}`]: true,
31+
[`${componentName.value}--active`]: isActive.value,
32+
[`${componentName.value}--disabled`]: disabled.value,
33+
}));
34+
const isActive = computed(() => findIndex(props.value, parent?.activeValue.value) > -1);
35+
const updatePanelValue = (args?: any) => {
36+
if (props.value != null) {
37+
parent?.onPanelChange(props.value, args);
38+
}
39+
};
40+
41+
const handleClick = (e: MouseEvent) => {
42+
e?.stopPropagation();
43+
if (disabled.value) {
44+
return;
45+
}
46+
updatePanelValue({ e });
47+
};
48+
49+
// 设置折叠/展开高度过渡
50+
const bodyRef = ref();
51+
const wrapRef = ref();
52+
const headRef = ref();
53+
const wrapperHeight = ref('');
54+
const updatePanelState = () => {
55+
nextTick(() => {
56+
if (!wrapRef.value) {
57+
return;
58+
}
59+
const { height: headHeight } = headRef.value.getBoundingClientRect();
60+
if (!isActive.value) {
61+
wrapperHeight.value = `${headHeight}px`;
62+
return;
63+
}
64+
const { height: bodyHeight } = bodyRef.value.getBoundingClientRect();
65+
const height = headHeight + bodyHeight;
66+
wrapperHeight.value = `${height}px`;
67+
});
68+
};
69+
70+
watch(
71+
isActive,
72+
() => {
73+
nextTick(() => updatePanelState());
74+
},
75+
{
76+
immediate: true,
77+
},
78+
);
79+
80+
onMounted(() => {
81+
if (parent?.defaultExpandAll) {
82+
updatePanelValue();
83+
}
84+
});
85+
86+
const renderDefaultIcon = () => {
87+
if (props.placement === 'bottom') {
88+
return isActive.value ? <ChevronUpIcon /> : <ChevronDownIcon />;
89+
}
90+
return isActive.value ? <ChevronDownIcon /> : <ChevronUpIcon />;
91+
};
92+
const panelExpandIcon = computed(() => slots.expandIcon || props.expandIcon);
93+
const renderRightIcon = () => {
94+
const tNodeRender = panelExpandIcon.value === undefined ? renderParentTNode : renderTNodeJSX;
95+
return <div class={`${componentName.value}__header-icon`}>{tNodeRender('expandIcon', renderDefaultIcon())}</div>;
96+
};
97+
98+
return () => {
99+
const panelContent = renderContent('default', 'content');
100+
const headerContent = renderTNodeJSX('header');
101+
const noteContent = renderTNodeJSX('headerRightContent');
102+
const leftIcon = renderTNodeJSX('headerLeftIcon');
103+
104+
return (
105+
<div ref={wrapRef} class={rootClass.value} style={{ height: wrapperHeight.value }}>
106+
<div ref={headRef} class={`${componentName.value}__title`} onClick={handleClick}>
107+
<TCell
108+
class={[
109+
`${componentName.value}__header`,
110+
`${componentName.value}__header--${props.placement}`,
111+
{ [`${componentName.value}__header--expanded`]: isActive.value },
112+
]}
113+
v-slots={{
114+
leftIcon: () => leftIcon,
115+
title: () => headerContent,
116+
note: () => noteContent,
117+
rightIcon: () => renderRightIcon(),
118+
}}
119+
></TCell>
120+
</div>
121+
<div ref={bodyRef} class={`${componentName.value}__content`}>
122+
{panelContent}
123+
</div>
124+
</div>
125+
);
126+
};
127+
},
128+
});

src/collapse/collapse-panel.vue

Lines changed: 0 additions & 148 deletions
This file was deleted.

src/collapse/collapse.en-US.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
:: BASE_DOC ::
22

33
## API
4+
45
### Collapse Props
56

67
name | type | default | description | required
@@ -20,6 +21,7 @@ name | params | description
2021
-- | -- | --
2122
change | `(value: CollapseValue, context: { e: MouseEvent })` | \-
2223

24+
2325
### CollapsePanel Props
2426

2527
name | type | default | description | required
@@ -35,8 +37,8 @@ headerRightContent | String / Slot / Function | - | Typescript:`string \| TNod
3537
placement | String | bottom | options: bottom/top | N
3638
value | String / Number | - | \- | N
3739

40+
### CSS 变量
3841

39-
### CSS Variables
4042
The component provides the following CSS variables, which can be used to customize styles.
4143
Name | Default Value | Description
4244
-- | -- | --
@@ -49,4 +51,4 @@ Name | Default Value | Description
4951
--td-collapse-header-text-color | @font-gray-1 | -
5052
--td-collapse-header-text-disabled-color | @font-gray-4 | -
5153
--td-collapse-panel-bg-color | @bg-color-container | -
52-
--td-collapse-title-font-size | @font-size-m | -
54+
--td-collapse-title-font-size | @font-size-m | -

src/collapse/collapse.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
:: BASE_DOC ::
22

33
## API
4+
45
### Collapse Props
56

6-
名称 | 类型 | 默认值 | 说明 | 必传
7+
名称 | 类型 | 默认值 | 描述 | 必传
78
-- | -- | -- | -- | --
89
defaultExpandAll | Boolean | false | 默认是否展开全部 | N
910
disabled | Boolean | - | 是否禁用面板展开/收起操作 | N
@@ -20,9 +21,10 @@ onChange | Function | | TS 类型:`(value: CollapseValue, context: { e: Mouse
2021
-- | -- | --
2122
change | `(value: CollapseValue, context: { e: MouseEvent })` | 切换面板时触发,返回变化的值
2223

24+
2325
### CollapsePanel Props
2426

25-
名称 | 类型 | 默认值 | 说明 | 必传
27+
名称 | 类型 | 默认值 | 描述 | 必传
2628
-- | -- | -- | -- | --
2729
content | String / Slot / Function | - | 折叠面板内容。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
2830
default | String / Slot / Function | - | 折叠面板内容,同 content。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
@@ -35,8 +37,8 @@ headerRightContent | String / Slot / Function | - | 面板头的右侧区域,
3537
placement | String | bottom | 选项卡内容的位置。可选项:bottom/top | N
3638
value | String / Number | - | 当前面板唯一标识,如果值为空则取当前面下标兜底作为唯一标识 | N
3739

38-
3940
### CSS 变量
41+
4042
组件提供了下列 CSS 变量,可用于自定义样式。
4143
名称 | 默认值 | 描述
4244
-- | -- | --
@@ -49,4 +51,4 @@ value | String / Number | - | 当前面板唯一标识,如果值为空则取
4951
--td-collapse-header-text-color | @font-gray-1 | -
5052
--td-collapse-header-text-disabled-color | @font-gray-4 | -
5153
--td-collapse-panel-bg-color | @bg-color-container | -
52-
--td-collapse-title-font-size | @font-size-m | -
54+
--td-collapse-title-font-size | @font-size-m | -

0 commit comments

Comments
 (0)