Skip to content

Commit be1a8a3

Browse files
authored
chore: support collapsable、 remove disabled of panel and headerCollapsableOnly (#173)
* chore: 💥 remove disabled of panel and headerCollapsableOnly; feat: ✨ support collapsable prop; * chore: update readme * chore: rename collapsable to collapsible * chore: optimize code style
1 parent 6b3502b commit be1a8a3

File tree

7 files changed

+95
-44
lines changed

7 files changed

+95
-44
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ ReactDOM.render(collapse, container);
117117
<th></th>
118118
<td>specific the custom expand icon.</td>
119119
</tr>
120+
<tr>
121+
<td>collapsible</td>
122+
<td>Boolean | 'header'</td>
123+
<th>true</th>
124+
<td>specify whether the panel of children is collapsible or the area of collapsible.</td>
125+
</tr>
120126
</tbody>
121127
</table>
122128

@@ -194,9 +200,17 @@ If `accordion` is true, only one panel can be open. Opening another panel will
194200
<th></th>
195201
<td>Content to render in the right of the panel header</td>
196202
</tr>
203+
<tr>
204+
<td>collapsible</td>
205+
<td>Boolean | 'header'</td>
206+
<th>true</th>
207+
<td>specify whether the panel be collapsible or the area of collapsible.</td>
208+
</tr>
197209
</tbody>
198210
</table>
199211

212+
> `disabled` is removed since 3.0.0, please use `collapsible=false` replace it.
213+
200214
#### key
201215

202216
If `key` is not provided, the panel's index will be used instead.

assets/index.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
margin: 0 16px 0 auto;
6060
}
6161
}
62-
.@{prefixCls}-header-collapsable-only {
62+
.@{prefixCls}-header-collapsible-only {
6363
cursor: default;
6464
.@{prefixCls}-header-text {
6565
cursor: pointer;

examples/simple.tsx

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Test extends React.Component {
1818
time: random(),
1919
accordion: false,
2020
activeKey: ['4'],
21-
headerCollapsableOnly: false,
21+
collapsible: true,
2222
};
2323

2424
onChange = (activeKey: string) => {
@@ -33,7 +33,11 @@ class Test extends React.Component {
3333
for (let i = 0, len = 3; i < len; i++) {
3434
const key = i + 1;
3535
items.push(
36-
<Panel header={`This is panel header ${key}`} key={key} disabled={i === 0}>
36+
<Panel
37+
header={`This is panel header ${key}`}
38+
key={key}
39+
collapsible={i === 0 ? false : undefined}
40+
>
3741
<p>{text.repeat(this.state.time)}</p>
3842
</Panel>,
3943
);
@@ -89,19 +93,16 @@ class Test extends React.Component {
8993
});
9094
};
9195

92-
toggleHeaderCollapsableOnly = () => {
93-
const { headerCollapsableOnly } = this.state;
96+
handleCollapsibleChange = (e: any) => {
97+
const values = [true, 'header', false];
9498
this.setState({
95-
headerCollapsableOnly: !headerCollapsableOnly,
99+
collapsible: values[e.target.value],
96100
});
97101
};
98102

99103
render() {
100-
const { accordion, activeKey, headerCollapsableOnly } = this.state;
104+
const { accordion, activeKey, collapsible } = this.state;
101105
const btn = accordion ? 'Mode: accordion' : 'Mode: collapse';
102-
const headerCollapsableOnlyBtn = headerCollapsableOnly
103-
? 'headerCollapsableOnly: true'
104-
: 'headerCollapsableOnly: false';
105106
return (
106107
<div style={{ margin: 20, width: 400 }}>
107108
<button type="button" onClick={this.reRender}>
@@ -110,9 +111,14 @@ class Test extends React.Component {
110111
<button type="button" onClick={this.toggle}>
111112
{btn}
112113
</button>
113-
<button type="button" onClick={this.toggleHeaderCollapsableOnly}>
114-
{headerCollapsableOnlyBtn}
115-
</button>
114+
<p>
115+
collapsible:
116+
<select onChange={this.handleCollapsibleChange}>
117+
<option value={0}>true</option>
118+
<option value={1}>header</option>
119+
<option value={2}>false</option>
120+
</select>
121+
</p>
116122
<br />
117123
<br />
118124
<button type="button" onClick={this.setActivityKey}>
@@ -121,7 +127,7 @@ class Test extends React.Component {
121127
<br />
122128
<br />
123129
<Collapse
124-
headerCollapsableOnly={headerCollapsableOnly}
130+
collapsible={collapsible}
125131
accordion={accordion}
126132
onChange={this.onChange}
127133
activeKey={activeKey}

src/Collapse.tsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class Collapse extends React.Component<CollapseProps, CollapseState> {
2424
onChange() {},
2525
accordion: false,
2626
destroyInactivePanel: false,
27-
headerCollapsableOnly: false,
2827
};
2928

3029
static Panel = CollapsePanel;
@@ -77,24 +76,19 @@ class Collapse extends React.Component<CollapseProps, CollapseState> {
7776
if (!child) return null;
7877

7978
const { activeKey } = this.state;
80-
const {
81-
prefixCls,
82-
openMotion,
83-
accordion,
84-
destroyInactivePanel: rootDestroyInactivePanel,
85-
expandIcon,
86-
headerCollapsableOnly,
87-
} = this.props;
79+
const { prefixCls, openMotion, accordion, destroyInactivePanel: rootDestroyInactivePanel, expandIcon, collapsible } = this.props;
8880
// If there is no key provide, use the panel order as default key
8981
const key = child.key || String(index);
90-
const { header, headerClass, disabled, destroyInactivePanel } = child.props;
82+
const { header, headerClass, destroyInactivePanel, collapsible: childCollapsible } = child.props;
9183
let isActive = false;
9284
if (accordion) {
9385
isActive = activeKey[0] === key;
9486
} else {
9587
isActive = activeKey.indexOf(key) > -1;
9688
}
9789

90+
const mergeCollapsible = childCollapsible ?? collapsible;
91+
9892
const props = {
9993
key,
10094
panelKey: key,
@@ -106,9 +100,9 @@ class Collapse extends React.Component<CollapseProps, CollapseState> {
106100
openMotion,
107101
accordion,
108102
children: child.props.children,
109-
onItemClick: disabled ? null : this.onClickItem,
103+
onItemClick: mergeCollapsible === false ? null : this.onClickItem,
110104
expandIcon,
111-
headerCollapsableOnly,
105+
collapsible: mergeCollapsible,
112106
};
113107

114108
// https://github.com/ant-design/ant-design/issues/20479

src/Panel.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,19 @@ class CollapsePanel extends React.Component<CollapsePanelProps, any> {
4545
isActive,
4646
showArrow,
4747
destroyInactivePanel,
48-
disabled,
4948
accordion,
5049
forceRender,
5150
openMotion,
5251
expandIcon,
5352
extra,
54-
headerCollapsableOnly,
53+
collapsible,
5554
} = this.props;
55+
56+
const disabled = collapsible === false;
57+
5658
const headerCls = classNames(`${prefixCls}-header`, {
5759
[headerClass]: headerClass,
58-
[`${prefixCls}-header-collapsable-only`]: headerCollapsableOnly,
60+
[`${prefixCls}-header-collapsible-only`]: collapsible === 'header',
5961
});
6062
const itemCls = classNames(
6163
{
@@ -75,14 +77,14 @@ class CollapsePanel extends React.Component<CollapsePanelProps, any> {
7577
<div className={itemCls} style={style} id={id}>
7678
<div
7779
className={headerCls}
78-
onClick={() => !headerCollapsableOnly && this.handleItemClick()}
80+
onClick={() => collapsible !== 'header' && this.handleItemClick()}
7981
role={accordion ? 'tab' : 'button'}
8082
tabIndex={disabled ? -1 : 0}
8183
aria-expanded={isActive}
8284
onKeyPress={this.handleKeyPress}
8385
>
8486
{showArrow && icon}
85-
{headerCollapsableOnly ? (
87+
{collapsible === 'header' ? (
8688
<span onClick={this.handleItemClick} className={`${prefixCls}-header-text`}>
8789
{header}
8890
</span>

src/interface.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as React from 'react';
22
import { CSSMotionProps } from 'rc-motion';
33

4+
type CollapsibleType = boolean | 'header';
5+
46
export interface CollapseProps {
57
prefixCls?: string;
68
activeKey?: React.Key | React.Key[];
@@ -12,7 +14,7 @@ export interface CollapseProps {
1214
style?: object;
1315
destroyInactivePanel?: boolean;
1416
expandIcon?: (props: object) => React.ReactNode;
15-
headerCollapsableOnly?: boolean;
17+
collapsible?: CollapsibleType;
1618
}
1719

1820
export interface CollapsePanelProps {
@@ -25,7 +27,6 @@ export interface CollapsePanelProps {
2527
style?: object;
2628
isActive?: boolean;
2729
openMotion?: CSSMotionProps;
28-
disabled?: boolean;
2930
destroyInactivePanel?: boolean;
3031
accordion?: boolean;
3132
forceRender?: boolean;
@@ -34,5 +35,5 @@ export interface CollapsePanelProps {
3435
expandIcon?: (props: object) => React.ReactNode;
3536
panelKey?: string | number;
3637
role?: string;
37-
headerCollapsableOnly?: boolean;
38+
collapsible?: CollapsibleType;
3839
}

tests/index.spec.tsx

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ describe('collapse', () => {
127127

128128
const element = (
129129
<Collapse onChange={onChange} expandIcon={expandIcon}>
130-
<Panel header="collapse 1" key="1" disabled>
130+
<Panel header="collapse 1" key="1" collapsible={false}>
131131
first
132132
</Panel>
133133
<Panel header="collapse 2" key="2" extra={<span>ExtraSpan</span>}>
@@ -197,7 +197,7 @@ describe('collapse', () => {
197197
const expandIcon = () => <span>test{'>'}</span>;
198198
const element = (
199199
<Collapse onChange={onChange} expandIcon={expandIcon}>
200-
<Panel header="collapse 1" key={1} disabled>
200+
<Panel header="collapse 1" key={1} collapsible={false}>
201201
first
202202
</Panel>
203203
<Panel header="collapse 2" key={2} extra={<span>ExtraSpan</span>}>
@@ -320,7 +320,7 @@ describe('collapse', () => {
320320
it('when forceRender is not supplied it should lazy render the panel content', () => {
321321
renderCollapse(
322322
<Collapse>
323-
<Panel header="collapse 1" key="1" disabled>
323+
<Panel header="collapse 1" key="1" collapsible={false}>
324324
first
325325
</Panel>
326326
<Panel header="collapse 2" key="2">
@@ -334,7 +334,7 @@ describe('collapse', () => {
334334
it('when forceRender is FALSE it should lazy render the panel content', () => {
335335
renderCollapse(
336336
<Collapse>
337-
<Panel header="collapse 1" key="1" forceRender={false} disabled>
337+
<Panel header="collapse 1" key="1" forceRender={false} collapsible={false}>
338338
first
339339
</Panel>
340340
<Panel header="collapse 2" key="2">
@@ -348,7 +348,7 @@ describe('collapse', () => {
348348
it('when forceRender is TRUE then it should render all the panel content to the DOM', () => {
349349
renderCollapse(
350350
<Collapse>
351-
<Panel header="collapse 1" key="1" forceRender disabled>
351+
<Panel header="collapse 1" key="1" forceRender collapsible={false}>
352352
first
353353
</Panel>
354354
<Panel header="collapse 2" key="2">
@@ -377,7 +377,7 @@ describe('collapse', () => {
377377
<Panel header="collapse 2" key="2">
378378
second
379379
</Panel>
380-
<Panel header="collapse 3" key="3" disabled>
380+
<Panel header="collapse 3" key="3" collapsible={false}>
381381
second
382382
</Panel>
383383
</Collapse>,
@@ -429,7 +429,7 @@ describe('collapse', () => {
429429
const element = (
430430
<Collapse onChange={onChange} expandIcon={expandIcon}>
431431
<Fragment>
432-
<Panel header="collapse 1" key="1" disabled>
432+
<Panel header="collapse 1" key="1" collapsible={false}>
433433
first
434434
</Panel>
435435
<Panel header="collapse 2" key="2" extra={<span>ExtraSpan</span>}>
@@ -475,7 +475,7 @@ describe('collapse', () => {
475475
expect(collapse.find('.custom-child').getDOMNode().innerHTML).toBe('custom-child');
476476
});
477477

478-
describe('headerCollapsableOnly', () => {
478+
describe('collapsible', () => {
479479
it('default', () => {
480480
const collapse = mount(
481481
<Collapse>
@@ -485,10 +485,12 @@ describe('collapse', () => {
485485
</Collapse>,
486486
);
487487
expect(collapse.find('.rc-collapse-header-text').exists()).toBeFalsy();
488+
collapse.find('.rc-collapse-header').simulate('click');
489+
expect(collapse.find('.rc-collapse-item-active').length).toBe(1);
488490
});
489-
it('should work', () => {
491+
it('should work when value is header', () => {
490492
const collapse = mount(
491-
<Collapse headerCollapsableOnly>
493+
<Collapse collapsible="header">
492494
<Panel header="collapse 1" key="1">
493495
first
494496
</Panel>
@@ -500,5 +502,37 @@ describe('collapse', () => {
500502
collapse.find('.rc-collapse-header-text').simulate('click');
501503
expect(collapse.find('.rc-collapse-item-active').length).toBe(1);
502504
});
505+
506+
it('should disabled when value is false', () => {
507+
const collapse = mount(
508+
<Collapse collapsible={false}>
509+
<Panel header="collapse 1" key="1">
510+
first
511+
</Panel>
512+
</Collapse>,
513+
);
514+
expect(collapse.find('.rc-collapse-header-text').exists()).toBeFalsy();
515+
516+
expect(collapse.find('.rc-collapse-item-disabled').length).toBe(1);
517+
518+
collapse.find('.rc-collapse-header').simulate('click');
519+
expect(collapse.find('.rc-collapse-item-active').length).toBe(0);
520+
});
521+
522+
it('the value of panel should be read first', () => {
523+
const collapse = mount(
524+
<Collapse collapsible="header">
525+
<Panel collapsible={false} header="collapse 1" key="1">
526+
first
527+
</Panel>
528+
</Collapse>,
529+
);
530+
expect(collapse.find('.rc-collapse-header-text').exists()).toBeFalsy();
531+
532+
expect(collapse.find('.rc-collapse-item-disabled').length).toBe(1);
533+
534+
collapse.find('.rc-collapse-header').simulate('click');
535+
expect(collapse.find('.rc-collapse-item-active').length).toBe(0);
536+
});
503537
});
504538
});

0 commit comments

Comments
 (0)