Skip to content
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

Feature/collapse transition #72

Merged
merged 14 commits into from
Jul 8, 2024
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"copy-to-clipboard": "^3.3.3",
"lodash": "~4.17.15",
"omi": "7.6.7",
"omi-transition": "^0.1.7",
"omi-transition": "^0.1.8",
"tailwind-merge": "^2.2.1"
},
"devDependencies": {
Expand Down
14 changes: 9 additions & 5 deletions src/collapse/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ spline: data

### CollapsePanel Props

| 名称 | 类型 | 默认值 | 说明 | 必传 |
| ----------------- | --------------- | --------- | ---------------------------------------------------------------- | ---- |
| destroyOnCollapse | Boolean | false | 当前面板处理折叠状态时,是否销毁面板内容 | N |
| disabled | Boolean | undefined | 禁止当前面板展开,优先级大于 Collapse 的同名属性 | N |
| value | String / Number | - | 必需。当前面板唯一标识,如果值为空则取当前面下标兜底作为唯一标识 | Y |
| 名称 | 类型 | 默认值 | 说明 | 必传 |
| ------------------ | ------------------------- | --------- | -------------------------------------------------------------------- | ---- |
| destroyOnCollapse | Boolean | false | 当前面板处理折叠状态时,是否销毁面板内容 | N |
| disabled | Boolean | undefined | 禁止当前面板展开,优先级大于 Collapse 的同名属性 | N |
| value | String / Number | - | 必需。当前面板唯一标识,如果值为空则取当前面下标兜底作为唯一标识 | Y |
| expandIcon | Boolean / Slot / Function | undefined | 当前折叠面板展开图标。TS 类型:`boolean \| TNode`。 | N |
| header | String / Slot / Function | - | 面板头内容。TS 类型:`string \| TNode`。 | N |
| headerRightContent | String / Slot / Function | - | 面板头的右侧区域,一般用于呈现面板操作。TS 类型:`string \| TNode`。 | N |
| content | String / Slot / Function | - | 折叠面板内容。TS 类型:`string \| TNode`。 | N |
30 changes: 21 additions & 9 deletions src/collapse/_example/base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,27 @@ export default class Demo extends Component {

render() {
return (
<t-collapse onChange={this.onChange}>
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel destroyOnCollapse={true}>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse onChange={this.onChange} value={[1]}>
<t-collapse-panel
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
<t-collapse-panel
destroyOnCollapse={true}
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
<t-collapse-panel
header="嵌套折叠面板"
content={
<t-collapse default-expand-all>
<t-collapse-panel header="子面板1" content="这是子面板1" />
<t-collapse-panel header="子面板1" content="这是子面板2" />
<t-collapse-panel header="子面板1" content="这是子面板3" />
<t-collapse-panel header="子面板1" content="这是子面板4" />
</t-collapse>
}
/>
</t-collapse>
);
}
Expand Down
58 changes: 42 additions & 16 deletions src/collapse/_example/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,56 @@ import { bind, Component, signal } from 'omi';
export default class Demo extends Component {
checked = signal(true);

isLeftIcon = signal(true);

expandOnRowClick = signal(true);

@bind
onChange(value) {
console.log('onChange.value', value);
}

render() {
return (
<t-space direction={'vertical'}>
<t-collapse onChange={this.onChange} expand-icon-placement="left">
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel>
<div slot="header">自定义图标</div>
<t-icon name="user-checked" slot="expandIcon"></t-icon>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel>
<div slot="header">自定义图标</div>
<t-icon name="add" slot="expandIcon"></t-icon>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-space direction={'vertical'} style={{ width: '100%' }}>
<t-collapse
onChange={this.onChange}
expandIconPlacement={this.isLeftIcon.value ? 'left' : 'right'}
expandOnRowClick={this.expandOnRowClick.value}
>
<t-collapse-panel
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
<t-collapse-panel
header="自定义图标"
expandIcon={<t-icon name="user-checked"></t-icon>}
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
<t-collapse-panel
header="自定义图标"
expandIcon={<t-icon name="add"></t-icon>}
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
</t-collapse>
<div class="button-area">
<div>
<span class="button-text">图标是否在左侧</span>
<t-switch
size="small"
value={this.isLeftIcon.value}
onChange={() => (this.isLeftIcon.value = !this.isLeftIcon.value)}
/>
</div>
<div>
<span class="button-text">是否仅图标响应点击</span>
<t-switch
size="small"
value={!this.expandOnRowClick.value}
onChange={() => (this.expandOnRowClick.value = !this.expandOnRowClick.value)}
/>
</div>
</div>
</t-space>
);
}
Expand Down
34 changes: 17 additions & 17 deletions src/collapse/_example/mutex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@ export default class Demo extends Component {

render() {
return (
<t-space direction={'vertical'}>
<t-space direction={'vertical'} style={{ width: '100%' }}>
<t-collapse expand-mutex onChange={this.onChange}>
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
<t-collapse-panel
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
<t-collapse-panel
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
<t-collapse-panel
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
</t-collapse>
<div style="margin-top: 10px">当前展开项:{this.currentItem.value}</div>
</t-space>
Expand Down
30 changes: 20 additions & 10 deletions src/collapse/_example/other.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,18 @@ export default class Demo extends Component {
render() {
const { borderless, expandIcon, disabled } = this;
return (
<t-space direction={'vertical'}>
<t-collapse borderless={borderless.value} expandIcon={expandIcon.value} disabled={disabled.value}>
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-space direction={'vertical'} style={{ width: '100%' }}>
<t-collapse borderless={borderless.value} disabled={disabled.value}>
<t-collapse-panel
expandIcon={expandIcon.value}
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
<t-collapse-panel
expandIcon={expandIcon.value}
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
/>
</t-collapse>
<div class="button-area">
<div>
Expand All @@ -47,6 +49,14 @@ export default class Demo extends Component {
<span class="button-text">无边框</span>
<t-switch size="small" onChange={() => (this.borderless.value = !this.borderless.value)} />
</div>
<div>
<span class="button-text">显示 Icon</span>
<t-switch
size="small"
value={expandIcon.value}
onChange={() => (this.expandIcon.value = !this.expandIcon.value)}
/>
</div>
</div>
</t-space>
);
Expand Down
28 changes: 15 additions & 13 deletions src/collapse/_example/rightSlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,27 @@ export default class Demo extends Component {

render() {
return (
<t-collapse borderless={true} expandMutex={true} expandOnRowClick={true} onChange={this.onChange}>
<t-collapse-panel>
<div slot="header">这是一个折叠标题</div>
<div slot="headerRightContent">
<t-collapse onChange={this.onChange}>
<t-collapse-panel
header="这是一个折叠标题"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
headerRightContent={
<t-button size="small" style={{ marginLeft: '8px' }}>
操作
</t-button>
</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
<t-collapse-panel destroyOnCollapse={true} disabled>
<div slot="header">禁用状态</div>
<div slot="headerRightContent">
}
/>
<t-collapse-panel
destroyOnCollapse={true}
disabled
header="禁用状态"
content="这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。"
headerRightContent={
<t-button size="small" style={{ marginLeft: '8px' }}>
操作
</t-button>
</div>
这部分是每个折叠面板折叠或展开的内容,可根据不同业务或用户的使用诉求,进行自定义填充。可以是纯文本、图文、子列表等内容形式。
</t-collapse-panel>
}
/>
</t-collapse>
);
}
Expand Down
52 changes: 52 additions & 0 deletions src/collapse/collapse-animation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* eslint-disable no-param-reassign */
export function getCollapseAnimation() {
const beforeEnter = (el: HTMLElement) => {
el.dataset.oldPaddingTop = el.style.paddingTop;
el.dataset.oldPaddingBottom = el.style.paddingBottom;

el.style.height = '0';
el.style.paddingTop = '0';
el.style.paddingBottom = '0';
};
const enter = (el: HTMLElement) => {
el.dataset.oldOverflow = el.style.overflow;
el.style.height = `${el.scrollHeight}px`;
el.style.paddingTop = el.dataset.oldPaddingTop;
el.style.paddingBottom = el.dataset.oldPaddingBottom;
el.style.overflow = 'hidden';
};
const afterEnter = (el: HTMLElement) => {
el.style.height = '';
el.style.overflow = el.dataset.oldOverflow;
};
const beforeLeave = (el: HTMLElement) => {
el.dataset.oldPaddingTop = el.style.paddingTop;
el.dataset.oldPaddingBottom = el.style.paddingBottom;
el.dataset.oldOverflow = el.style.overflow;

el.style.height = `${el.scrollHeight}px`;
el.style.overflow = 'hidden';
};
const leave = (el: HTMLElement) => {
if (el.scrollHeight !== 0) {
el.style.height = '0';
el.style.paddingTop = '0';
el.style.paddingBottom = '0';
}
};
const afterLeave = (el: HTMLElement) => {
el.style.height = '';
el.style.overflow = el.dataset.oldOverflow;
el.style.paddingTop = el.dataset.oldPaddingTop;
el.style.paddingBottom = el.dataset.oldPaddingBottom;
};

return {
beforeEnter,
enter,
afterEnter,
beforeLeave,
leave,
afterLeave,
};
}
Loading
Loading