Skip to content

Commit 2f51f2d

Browse files
authored
refactor:collapse (#6266)
* refactor:collapse * fix collapse props version * docs:update & refactor: collapse type & fix collapsible
1 parent dc9987a commit 2f51f2d

File tree

14 files changed

+406
-271
lines changed

14 files changed

+406
-271
lines changed

components/collapse/Collapse.tsx

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import useConfigInject from '../config-provider/hooks/useConfigInject';
1717
import type { CollapsePanelProps } from './CollapsePanel';
1818
import collapseMotion from '../_util/collapseMotion';
1919

20+
// CSSINJS
21+
import useStyle from './style';
22+
2023
type Key = number | string;
2124

2225
function getActiveKeysArray(activeKey: Key | Key[]) {
@@ -39,7 +42,7 @@ export default defineComponent({
3942
destroyInactivePanel: false,
4043
bordered: true,
4144
openAnimation: collapseMotion('ant-motion-collapse', false),
42-
expandIconPosition: 'left',
45+
expandIconPosition: 'start',
4346
}),
4447
slots: ['expandIcon'],
4548
// emits: ['change', 'update:activeKey'],
@@ -56,12 +59,16 @@ export default defineComponent({
5659
{ deep: true },
5760
);
5861
const { prefixCls, direction } = useConfigInject('collapse', props);
62+
63+
// style
64+
const [wrapSSR, hashId] = useStyle(prefixCls);
65+
5966
const iconPosition = computed(() => {
6067
const { expandIconPosition } = props;
6168
if (expandIconPosition !== undefined) {
6269
return expandIconPosition;
6370
}
64-
return direction.value === 'rtl' ? 'right' : 'left';
71+
return direction.value === 'rtl' ? 'end' : 'start';
6572
});
6673

6774
const renderExpandIcon = (panelProps: CollapsePanelProps) => {
@@ -73,7 +80,12 @@ export default defineComponent({
7380
);
7481

7582
return (
76-
<div>
83+
<div
84+
class={`${prefixCls.value}-expand-icon`}
85+
onClick={() =>
86+
['header', 'icon'].includes(props.collapsible) && onClickItem(panelProps.panelKey)
87+
}
88+
>
7789
{isValidElement(Array.isArray(expandIcon) ? icon[0] : icon)
7890
? cloneElement(
7991
icon,
@@ -162,23 +174,26 @@ export default defineComponent({
162174

163175
return () => {
164176
const { accordion, bordered, ghost } = props;
165-
const collapseClassName = classNames({
166-
[prefixCls.value]: true,
167-
[`${prefixCls.value}-borderless`]: !bordered,
168-
[`${prefixCls.value}-icon-position-${iconPosition.value}`]: true,
169-
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
170-
[`${prefixCls.value}-ghost`]: !!ghost,
171-
[attrs.class as string]: !!attrs.class,
172-
});
173-
return (
177+
const collapseClassName = classNames(
178+
prefixCls.value,
179+
{
180+
[`${prefixCls.value}-borderless`]: !bordered,
181+
[`${prefixCls.value}-icon-position-${iconPosition.value}`]: true,
182+
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
183+
[`${prefixCls.value}-ghost`]: !!ghost,
184+
[attrs.class as string]: !!attrs.class,
185+
},
186+
hashId.value,
187+
);
188+
return wrapSSR(
174189
<div
175190
class={collapseClassName}
176191
{...getDataAndAriaProps(attrs)}
177192
style={attrs.style as CSSProperties}
178193
role={accordion ? 'tablist' : null}
179194
>
180195
{getItems()}
181-
</div>
196+
</div>,
182197
);
183198
};
184199
},

components/collapse/CollapsePanel.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export default defineComponent({
5757
const headerCls = classNames(`${prefixClsValue}-header`, {
5858
[headerClass]: headerClass,
5959
[`${prefixClsValue}-header-collapsible-only`]: collapsible === 'header',
60+
[`${prefixClsValue}-icon-collapsible-only`]: collapsible === 'icon',
6061
});
6162
const itemCls = classNames({
6263
[`${prefixClsValue}-item`]: true,
@@ -91,20 +92,19 @@ export default defineComponent({
9192
<div {...attrs} class={itemCls}>
9293
<div
9394
class={headerCls}
94-
onClick={() => collapsible !== 'header' && handleItemClick()}
95+
onClick={() => !['header', 'icon'].includes(collapsible) && handleItemClick()}
9596
role={accordion ? 'tab' : 'button'}
9697
tabindex={disabled ? -1 : 0}
9798
aria-expanded={isActive}
9899
onKeypress={handleKeyPress}
99100
>
100101
{showArrow && icon}
101-
{collapsible === 'header' ? (
102-
<span onClick={handleItemClick} class={`${prefixClsValue}-header-text`}>
103-
{header}
104-
</span>
105-
) : (
106-
header
107-
)}
102+
<span
103+
onClick={() => collapsible === 'header' && handleItemClick()}
104+
class={`${prefixClsValue}-header-text`}
105+
>
106+
{header}
107+
</span>
108108
{extra && <div class={`${prefixClsValue}-extra`}>{extra}</div>}
109109
</div>
110110
<Transition {...transitionProps}>

components/collapse/commonProps.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import type { PropType } from 'vue';
21
import type { Key } from '../_util/type';
3-
import { tuple } from '../_util/type';
2+
import { tuple, booleanType, someType, stringType, functionType } from '../_util/type';
43
import PropTypes from '../_util/vue-types';
54

6-
export type CollapsibleType = 'header' | 'disabled';
5+
export type CollapsibleType = 'header' | 'icon' | 'disabled';
76

87
export type ActiveKeyType = Array<string | number> | string | number;
98

@@ -20,38 +19,38 @@ export interface PanelProps {
2019

2120
const collapseProps = () => ({
2221
prefixCls: String,
23-
activeKey: { type: [Array, Number, String] as PropType<ActiveKeyType> },
24-
defaultActiveKey: { type: [Array, Number, String] as PropType<ActiveKeyType> },
25-
accordion: { type: Boolean, default: undefined },
26-
destroyInactivePanel: { type: Boolean, default: undefined },
27-
bordered: { type: Boolean, default: undefined },
28-
expandIcon: Function as PropType<(panelProps: PanelProps) => any>,
22+
activeKey: someType<ActiveKeyType>([Array, Number, String]),
23+
defaultActiveKey: someType<ActiveKeyType>([Array, Number, String]),
24+
accordion: booleanType(),
25+
destroyInactivePanel: booleanType(),
26+
bordered: booleanType(),
27+
expandIcon: functionType<(panelProps: PanelProps) => any>(),
2928
openAnimation: PropTypes.object,
30-
expandIconPosition: PropTypes.oneOf(tuple('left', 'right')),
31-
collapsible: { type: String as PropType<CollapsibleType> },
32-
ghost: { type: Boolean, default: undefined },
33-
onChange: Function as PropType<(key: Key | Key[]) => void>,
34-
'onUpdate:activeKey': Function as PropType<(key: Key | Key[]) => void>,
29+
expandIconPosition: PropTypes.oneOf(tuple('start', 'end')),
30+
collapsible: stringType<CollapsibleType>(),
31+
ghost: booleanType(),
32+
onChange: functionType<(key: Key | Key[]) => void>(),
33+
'onUpdate:activeKey': functionType<(key: Key | Key[]) => void>(),
3534
});
3635

3736
const collapsePanelProps = () => ({
3837
openAnimation: PropTypes.object,
3938
prefixCls: String,
4039
header: PropTypes.any,
4140
headerClass: String,
42-
showArrow: { type: Boolean, default: undefined },
43-
isActive: { type: Boolean, default: undefined },
44-
destroyInactivePanel: { type: Boolean, default: undefined },
41+
showArrow: booleanType(),
42+
isActive: booleanType(),
43+
destroyInactivePanel: booleanType(),
4544
/** @deprecated Use `collapsible="disabled"` instead */
46-
disabled: { type: Boolean, default: undefined },
47-
accordion: { type: Boolean, default: undefined },
48-
forceRender: { type: Boolean, default: undefined },
49-
expandIcon: Function as PropType<(panelProps: PanelProps) => any>,
45+
disabled: booleanType(),
46+
accordion: booleanType(),
47+
forceRender: booleanType(),
48+
expandIcon: functionType<(panelProps: PanelProps) => any>(),
5049
extra: PropTypes.any,
5150
panelKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
52-
collapsible: { type: String as PropType<CollapsibleType> },
51+
collapsible: stringType<CollapsibleType>(),
5352
role: String,
54-
onItemClick: { type: Function as PropType<(panelKey: Key) => void> },
53+
onItemClick: functionType<(panelKey: Key) => void>(),
5554
});
5655

5756
export { collapseProps, collapsePanelProps };
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<docs>
2+
---
3+
order: 7
4+
title:
5+
zh-CN: 可折叠触发区域
6+
en-US: Collapsible
7+
---
8+
9+
## zh-CN
10+
11+
通过 `collapsible` 属性,可以设置面板的可折叠触发区域。
12+
13+
## en-US
14+
15+
Specify the trigger area of collapsible by `collapsible`.
16+
17+
</docs>
18+
19+
<template>
20+
<a-space direction="vertical">
21+
<a-collapse collapsible="header" v-model:activeKey="activeKey">
22+
<a-collapse-panel header="This panel can only be collapsed by clicking text" key="1">
23+
<p>{{ text }}</p>
24+
</a-collapse-panel>
25+
</a-collapse>
26+
<a-collapse collapsible="icon" v-model:activeKey="activeKey">
27+
<a-collapse-panel header="This panel can only be collapsed by clicking icon" key="1">
28+
<p>{{ text }}</p>
29+
</a-collapse-panel>
30+
</a-collapse>
31+
<a-collapse collapsible="disabled">
32+
<a-collapse-panel header="This panel can't be collapsed" key="1">
33+
<p>{{ text }}</p>
34+
</a-collapse-panel>
35+
</a-collapse>
36+
</a-space>
37+
</template>
38+
<script lang="ts">
39+
import { defineComponent, ref } from 'vue';
40+
export default defineComponent({
41+
setup() {
42+
const activeKey = ref(['1']);
43+
const text = `A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world.`;
44+
return {
45+
activeKey,
46+
text,
47+
};
48+
},
49+
});
50+
</script>
51+
<style>
52+
.ant-space {
53+
width: 100%;
54+
}
55+
</style>

components/collapse/demo/custom.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ Customize the background, border and margin styles and icon for each panel.
1717
</docs>
1818

1919
<template>
20-
<a-collapse v-model:activeKey="activeKey" :bordered="false">
20+
<a-collapse
21+
v-model:activeKey="activeKey"
22+
:bordered="false"
23+
style="background: rgb(255, 255, 255)"
24+
>
2125
<template #expandIcon="{ isActive }">
2226
<caret-right-outlined :rotate="isActive ? 90 : 0" />
2327
</template>

components/collapse/demo/extra.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ More than one panel can be expanded at a time, the first panel is initialized to
3434
<br />
3535
<span>Expand Icon Position:</span>
3636
<a-select v-model:value="expandIconPosition">
37-
<a-select-option value="left">left</a-select-option>
38-
<a-select-option value="right">right</a-select-option>
37+
<a-select-option value="start">start</a-select-option>
38+
<a-select-option value="end">end</a-select-option>
3939
</a-select>
4040
</template>
4141
<script lang="ts">
@@ -50,7 +50,7 @@ export default defineComponent({
5050
setup() {
5151
const text = `A dog is a type of domesticated animal.Known for its loyalty and faithfulness,it can be found as a welcome guest in many households across the world.`;
5252
const activeKey = ref(['1']);
53-
const expandIconPosition = ref<CollapseProps['expandIconPosition']>('left');
53+
const expandIconPosition = ref<CollapseProps['expandIconPosition']>('start');
5454
5555
const handleClick = (event: MouseEvent) => {
5656
// If you don't want click extra trigger collapse, you can prevent this:

components/collapse/demo/index.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<Noarrow />
99
<Extra />
1010
<Ghost />
11+
<Collapsible />
1112
</demo-sort>
1213
</template>
1314

@@ -20,6 +21,7 @@ import Mix from './mix.vue';
2021
import Noarrow from './noarrow.vue';
2122
import Extra from './extra.vue';
2223
import Ghost from './ghost.vue';
24+
import Collapsible from './collapsible.vue';
2325
import CN from '../index.zh-CN.md';
2426
import US from '../index.en-US.md';
2527
@@ -35,6 +37,7 @@ export default {
3537
Noarrow,
3638
Extra,
3739
Ghost,
40+
Collapsible,
3841
},
3942
};
4043
</script>

components/collapse/index.en-US.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
category: Components
33
type: Data Display
44
title: Collapse
5-
cover: https://gw.alipayobjects.com/zos/alicdn/IxH16B9RD/Collapse.svg
5+
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*B7HKR5OBe8gAAAAAAAAAAAAADrJ8AQ/original
66
---
77

88
A content area which can be collapsed and expanded.
@@ -19,12 +19,12 @@ A content area which can be collapsed and expanded.
1919
| Property | Description | Type | Default | Version |
2020
| --- | --- | --- | --- | --- |
2121
| accordion | If `true`, `Collapse` renders as `Accordion` | boolean | `false` | |
22-
| activeKey(v-model) | Key of the active panel | string\[]\|string | No default value. In `accordion` mode, it's the key of the first panel. | |
22+
| activeKey(v-model) | Key of the active panel | string\[] \| string <br> number\[] \| number | No default value. In `accordion` mode, it's the key of the first panel. | |
2323
| bordered | Toggles rendering of the border around the collapse block | boolean | `true` | |
24-
| collapsible | Specify whether the panels of children be collapsible or the trigger area of collapsible | `header` \| `disabled` | - | 3.0 |
24+
| collapsible | Specify whether the panels of children be collapsible or the trigger area of collapsible | `header` \| `icon` \| `disabled` | - | 4.0 |
2525
| destroyInactivePanel | Destroy Inactive Panel | boolean | `false` | |
2626
| expandIcon | allow to customize collapse icon | Function(props):VNode \| v-slot:expandIcon="props" | | |
27-
| expandIconPosition | Set expand icon position: `left`, `right` | `left` | - | 1.5.0 |
27+
| expandIconPosition | Set expand icon position | `start` \| `end` | - | 4.0 |
2828
| ghost | Make the collapse borderless and its background transparent | boolean | false | 3.0 |
2929

3030
### events

components/collapse/index.zh-CN.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ category: Components
33
type: 数据展示
44
title: Collapse
55
subtitle: 折叠面板
6-
cover: https://gw.alipayobjects.com/zos/alicdn/IxH16B9RD/Collapse.svg
6+
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*B7HKR5OBe8gAAAAAAAAAAAAADrJ8AQ/original
77
---
88

99
可以折叠/展开的内容区域。
@@ -20,12 +20,12 @@ cover: https://gw.alipayobjects.com/zos/alicdn/IxH16B9RD/Collapse.svg
2020
| 参数 | 说明 | 类型 | 默认值 | 版本 |
2121
| --- | --- | --- | --- | --- |
2222
| accordion | 手风琴模式 | boolean | `false` | |
23-
| activeKey(v-model) | 当前激活 tab 面板的 key | string\[]\|string | 默认无,accordion 模式下默认第一个元素 | |
23+
| activeKey(v-model) | 当前激活 tab 面板的 key | string\[] \| string <br> number\[] \| number | 默认无,accordion 模式下默认第一个元素 | |
2424
| bordered | 带边框风格的折叠面板 | boolean | `true` | |
25-
| collapsible | 所有子面板是否可折叠或指定可折叠触发区域 | `header` \| `disabled` | - | 3.0 |
25+
| collapsible | 所有子面板是否可折叠或指定可折叠触发区域 | `header` \| `icon` \| `disabled` | - | 4.0 |
2626
| destroyInactivePanel | 销毁折叠隐藏的面板 | boolean | `false` | |
2727
| expandIcon | 自定义切换图标 | Function(props):VNode \| slot="expandIcon" slot-scope="props"\|#expandIcon="props" | | |
28-
| expandIconPosition | 设置图标位置`left`, `right` | `left` | - | 1.5.0 |
28+
| expandIconPosition | 设置图标位置 | `start` \| `end` | - | 4.0 |
2929
| ghost | 使折叠面板透明且无边框 | boolean | false | 3.0 |
3030

3131
### 事件

0 commit comments

Comments
 (0)