Skip to content

refactor:collapse #6266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions components/collapse/Collapse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { CollapsePanelProps } from './CollapsePanel';
import collapseMotion from '../_util/collapseMotion';

// CSSINJS
import useStyle from './style';

type Key = number | string;

function getActiveKeysArray(activeKey: Key | Key[]) {
Expand All @@ -39,7 +42,7 @@ export default defineComponent({
destroyInactivePanel: false,
bordered: true,
openAnimation: collapseMotion('ant-motion-collapse', false),
expandIconPosition: 'left',
expandIconPosition: 'start',
}),
slots: ['expandIcon'],
// emits: ['change', 'update:activeKey'],
Expand All @@ -56,12 +59,16 @@ export default defineComponent({
{ deep: true },
);
const { prefixCls, direction } = useConfigInject('collapse', props);

// style
const [wrapSSR, hashId] = useStyle(prefixCls);

const iconPosition = computed(() => {
const { expandIconPosition } = props;
if (expandIconPosition !== undefined) {
return expandIconPosition;
}
return direction.value === 'rtl' ? 'right' : 'left';
return direction.value === 'rtl' ? 'end' : 'start';
});

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

return (
<div>
<div
class={`${prefixCls.value}-expand-icon`}
onClick={() =>
['header', 'icon'].includes(props.collapsible) && onClickItem(panelProps.panelKey)
}
>
{isValidElement(Array.isArray(expandIcon) ? icon[0] : icon)
? cloneElement(
icon,
Expand Down Expand Up @@ -162,23 +174,26 @@ export default defineComponent({

return () => {
const { accordion, bordered, ghost } = props;
const collapseClassName = classNames({
[prefixCls.value]: true,
[`${prefixCls.value}-borderless`]: !bordered,
[`${prefixCls.value}-icon-position-${iconPosition.value}`]: true,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
[`${prefixCls.value}-ghost`]: !!ghost,
[attrs.class as string]: !!attrs.class,
});
return (
const collapseClassName = classNames(
prefixCls.value,
{
[`${prefixCls.value}-borderless`]: !bordered,
[`${prefixCls.value}-icon-position-${iconPosition.value}`]: true,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
[`${prefixCls.value}-ghost`]: !!ghost,
[attrs.class as string]: !!attrs.class,
},
hashId.value,
);
return wrapSSR(
<div
class={collapseClassName}
{...getDataAndAriaProps(attrs)}
style={attrs.style as CSSProperties}
role={accordion ? 'tablist' : null}
>
{getItems()}
</div>
</div>,
);
};
},
Expand Down
16 changes: 8 additions & 8 deletions components/collapse/CollapsePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export default defineComponent({
const headerCls = classNames(`${prefixClsValue}-header`, {
[headerClass]: headerClass,
[`${prefixClsValue}-header-collapsible-only`]: collapsible === 'header',
[`${prefixClsValue}-icon-collapsible-only`]: collapsible === 'icon',
});
const itemCls = classNames({
[`${prefixClsValue}-item`]: true,
Expand Down Expand Up @@ -91,20 +92,19 @@ export default defineComponent({
<div {...attrs} class={itemCls}>
<div
class={headerCls}
onClick={() => collapsible !== 'header' && handleItemClick()}
onClick={() => !['header', 'icon'].includes(collapsible) && handleItemClick()}
role={accordion ? 'tab' : 'button'}
tabindex={disabled ? -1 : 0}
aria-expanded={isActive}
onKeypress={handleKeyPress}
>
{showArrow && icon}
{collapsible === 'header' ? (
<span onClick={handleItemClick} class={`${prefixClsValue}-header-text`}>
{header}
</span>
) : (
header
)}
<span
onClick={() => collapsible === 'header' && handleItemClick()}
class={`${prefixClsValue}-header-text`}
>
{header}
</span>
{extra && <div class={`${prefixClsValue}-extra`}>{extra}</div>}
</div>
<Transition {...transitionProps}>
Expand Down
45 changes: 22 additions & 23 deletions components/collapse/commonProps.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { PropType } from 'vue';
import type { Key } from '../_util/type';
import { tuple } from '../_util/type';
import { tuple, booleanType, someType, stringType, functionType } from '../_util/type';
import PropTypes from '../_util/vue-types';

export type CollapsibleType = 'header' | 'disabled';
export type CollapsibleType = 'header' | 'icon' | 'disabled';

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

Expand All @@ -20,38 +19,38 @@ export interface PanelProps {

const collapseProps = () => ({
prefixCls: String,
activeKey: { type: [Array, Number, String] as PropType<ActiveKeyType> },
defaultActiveKey: { type: [Array, Number, String] as PropType<ActiveKeyType> },
accordion: { type: Boolean, default: undefined },
destroyInactivePanel: { type: Boolean, default: undefined },
bordered: { type: Boolean, default: undefined },
expandIcon: Function as PropType<(panelProps: PanelProps) => any>,
activeKey: someType<ActiveKeyType>([Array, Number, String]),
defaultActiveKey: someType<ActiveKeyType>([Array, Number, String]),
accordion: booleanType(),
destroyInactivePanel: booleanType(),
bordered: booleanType(),
expandIcon: functionType<(panelProps: PanelProps) => any>(),
openAnimation: PropTypes.object,
expandIconPosition: PropTypes.oneOf(tuple('left', 'right')),
collapsible: { type: String as PropType<CollapsibleType> },
ghost: { type: Boolean, default: undefined },
onChange: Function as PropType<(key: Key | Key[]) => void>,
'onUpdate:activeKey': Function as PropType<(key: Key | Key[]) => void>,
expandIconPosition: PropTypes.oneOf(tuple('start', 'end')),
collapsible: stringType<CollapsibleType>(),
ghost: booleanType(),
onChange: functionType<(key: Key | Key[]) => void>(),
'onUpdate:activeKey': functionType<(key: Key | Key[]) => void>(),
});

const collapsePanelProps = () => ({
openAnimation: PropTypes.object,
prefixCls: String,
header: PropTypes.any,
headerClass: String,
showArrow: { type: Boolean, default: undefined },
isActive: { type: Boolean, default: undefined },
destroyInactivePanel: { type: Boolean, default: undefined },
showArrow: booleanType(),
isActive: booleanType(),
destroyInactivePanel: booleanType(),
/** @deprecated Use `collapsible="disabled"` instead */
disabled: { type: Boolean, default: undefined },
accordion: { type: Boolean, default: undefined },
forceRender: { type: Boolean, default: undefined },
expandIcon: Function as PropType<(panelProps: PanelProps) => any>,
disabled: booleanType(),
accordion: booleanType(),
forceRender: booleanType(),
expandIcon: functionType<(panelProps: PanelProps) => any>(),
extra: PropTypes.any,
panelKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
collapsible: { type: String as PropType<CollapsibleType> },
collapsible: stringType<CollapsibleType>(),
role: String,
onItemClick: { type: Function as PropType<(panelKey: Key) => void> },
onItemClick: functionType<(panelKey: Key) => void>(),
});

export { collapseProps, collapsePanelProps };
55 changes: 55 additions & 0 deletions components/collapse/demo/collapsible.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<docs>
---
order: 7
title:
zh-CN: 可折叠触发区域
en-US: Collapsible
---

## zh-CN

通过 `collapsible` 属性,可以设置面板的可折叠触发区域。

## en-US

Specify the trigger area of collapsible by `collapsible`.

</docs>

<template>
<a-space direction="vertical">
<a-collapse collapsible="header" v-model:activeKey="activeKey">
<a-collapse-panel header="This panel can only be collapsed by clicking text" key="1">
<p>{{ text }}</p>
</a-collapse-panel>
</a-collapse>
<a-collapse collapsible="icon" v-model:activeKey="activeKey">
<a-collapse-panel header="This panel can only be collapsed by clicking icon" key="1">
<p>{{ text }}</p>
</a-collapse-panel>
</a-collapse>
<a-collapse collapsible="disabled">
<a-collapse-panel header="This panel can't be collapsed" key="1">
<p>{{ text }}</p>
</a-collapse-panel>
</a-collapse>
</a-space>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const activeKey = ref(['1']);
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.`;
return {
activeKey,
text,
};
},
});
</script>
<style>
.ant-space {
width: 100%;
}
</style>
6 changes: 5 additions & 1 deletion components/collapse/demo/custom.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ Customize the background, border and margin styles and icon for each panel.
</docs>

<template>
<a-collapse v-model:activeKey="activeKey" :bordered="false">
<a-collapse
v-model:activeKey="activeKey"
:bordered="false"
style="background: rgb(255, 255, 255)"
>
<template #expandIcon="{ isActive }">
<caret-right-outlined :rotate="isActive ? 90 : 0" />
</template>
Expand Down
6 changes: 3 additions & 3 deletions components/collapse/demo/extra.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ More than one panel can be expanded at a time, the first panel is initialized to
<br />
<span>Expand Icon Position:</span>
<a-select v-model:value="expandIconPosition">
<a-select-option value="left">left</a-select-option>
<a-select-option value="right">right</a-select-option>
<a-select-option value="start">start</a-select-option>
<a-select-option value="end">end</a-select-option>
</a-select>
</template>
<script lang="ts">
Expand All @@ -50,7 +50,7 @@ export default defineComponent({
setup() {
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.`;
const activeKey = ref(['1']);
const expandIconPosition = ref<CollapseProps['expandIconPosition']>('left');
const expandIconPosition = ref<CollapseProps['expandIconPosition']>('start');

const handleClick = (event: MouseEvent) => {
// If you don't want click extra trigger collapse, you can prevent this:
Expand Down
3 changes: 3 additions & 0 deletions components/collapse/demo/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<Noarrow />
<Extra />
<Ghost />
<Collapsible />
</demo-sort>
</template>

Expand All @@ -20,6 +21,7 @@ import Mix from './mix.vue';
import Noarrow from './noarrow.vue';
import Extra from './extra.vue';
import Ghost from './ghost.vue';
import Collapsible from './collapsible.vue';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';

Expand All @@ -35,6 +37,7 @@ export default {
Noarrow,
Extra,
Ghost,
Collapsible,
},
};
</script>
8 changes: 4 additions & 4 deletions components/collapse/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
category: Components
type: Data Display
title: Collapse
cover: https://gw.alipayobjects.com/zos/alicdn/IxH16B9RD/Collapse.svg
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*B7HKR5OBe8gAAAAAAAAAAAAADrJ8AQ/original
---

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

### events
Expand Down
8 changes: 4 additions & 4 deletions components/collapse/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ category: Components
type: 数据展示
title: Collapse
subtitle: 折叠面板
cover: https://gw.alipayobjects.com/zos/alicdn/IxH16B9RD/Collapse.svg
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*B7HKR5OBe8gAAAAAAAAAAAAADrJ8AQ/original
---

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

### 事件
Expand Down
Loading