Skip to content

Commit deefeae

Browse files
authored
upgrade to react-accessible-accordion@5 (#871)
* upgrade to react-accessible-accordion@5 * Migrate to react-accessible-accordion@5 * refactor to functional component * bump version * format * update unit test
1 parent e2ecb5d commit deefeae

File tree

5 files changed

+73
-92
lines changed

5 files changed

+73
-92
lines changed

package-lock.json

Lines changed: 3 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "clever-components",
3-
"version": "2.234.1",
3+
"version": "2.235.0",
44
"description": "A library of helpful React components and less styles",
55
"repository": {
66
"type": "git",
@@ -33,7 +33,7 @@
3333
"moment": "^2.18.1",
3434
"numeral": "^2.0.4",
3535
"prop-types": "^15.5.10",
36-
"react-accessible-accordion": "^1.0.2",
36+
"react-accessible-accordion": "^5.0.1",
3737
"react-autosize-textarea": "^7.0.0",
3838
"react-bootstrap": "0.32.1",
3939
"react-copy-to-clipboard": "^5.1.0",

src/InfoPanel/InfoPanel.less

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,21 @@
6666

6767
// classes picked up by react-accessible-accordion to show
6868
// and hide content
69-
.accordion__body {
69+
.accordion__panel {
7070
display: block;
71-
animation: fadein 0.35s ease-in;
71+
animation: accordion_panel_fadein 0.35s ease-in;
72+
73+
&[hidden] {
74+
display: none;
75+
}
7276
}
7377

74-
.accordion__body--hidden {
75-
display: none;
76-
opacity: 0;
77-
animation: fadein 0.35s ease-in;
78+
@keyframes accordion_panel_fadein {
79+
0% {
80+
opacity: 0;
81+
}
82+
83+
100% {
84+
opacity: 1; /* Fade in */
85+
}
7886
}

src/InfoPanel/InfoPanel.tsx

Lines changed: 52 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import classnames from "classnames";
22
import * as React from "react";
3-
import * as PropTypes from "prop-types";
43
import * as FontAwesome from "react-fontawesome";
54
import {
65
Accordion,
76
AccordionItem,
8-
AccordionItemTitle,
9-
AccordionItemBody,
7+
AccordionItemHeading,
8+
AccordionItemButton,
9+
AccordionItemPanel,
1010
} from "react-accessible-accordion";
1111
import "./InfoPanel.less";
1212

@@ -20,20 +20,6 @@ export interface Props {
2020
defaultOpen?: boolean;
2121
}
2222

23-
interface State {
24-
isCollapsed: boolean;
25-
}
26-
27-
const propTypes = {
28-
children: PropTypes.node,
29-
className: PropTypes.string,
30-
title: PropTypes.node,
31-
hideTitle: PropTypes.bool,
32-
footer: PropTypes.node,
33-
collapsible: PropTypes.bool,
34-
defaultOpen: PropTypes.bool,
35-
};
36-
3723
export const cssClass = {
3824
CONTAINER: "InfoPanel",
3925
FOOTER: "InfoPanel--footer",
@@ -45,66 +31,62 @@ export const cssClass = {
4531
COLLAPSIBLE_HEADER: "InfoPanel--collapsibleHeader",
4632
};
4733

34+
const ACCORDION_ITEM_KEY = "info-panel-accordion-item";
35+
4836
/**
4937
* Base presentational component for the displaying information in paneled format.
5038
*/
51-
export default class InfoPanel extends React.Component<Props, State> {
52-
static propTypes = propTypes;
53-
54-
constructor(props: Props) {
55-
super(props);
56-
this.state = {
57-
isCollapsed: !props.defaultOpen,
58-
};
59-
}
60-
61-
toggleArrow(keys) {
62-
this.setState({ isCollapsed: !(typeof keys !== "undefined") });
63-
}
64-
65-
render() {
66-
const { children, className, hideTitle, title, footer, collapsible } = this.props;
67-
const { isCollapsed } = this.state;
68-
if (!collapsible) {
69-
return (
70-
<div className={classnames(cssClass.CONTAINER, className)}>
71-
{!hideTitle && (
72-
<div className={cssClass.HEADER}>
73-
<h4 className={cssClass.TITLE}>{title}</h4>
74-
</div>
75-
)}
76-
<div className={cssClass.CONTENT}>{children}</div>
77-
{footer && <div className={cssClass.FOOTER}>{footer}</div>}
78-
</div>
79-
);
80-
}
39+
const InfoPanel = ({
40+
children,
41+
className,
42+
hideTitle,
43+
title,
44+
footer,
45+
collapsible,
46+
defaultOpen,
47+
}: Props) => {
48+
const [isCollapsed, setIsCollapsed] = React.useState(!defaultOpen);
8149

82-
let collapseArrow;
83-
if (isCollapsed) {
84-
collapseArrow = "caret-right";
85-
} else {
86-
collapseArrow = "caret-down";
87-
}
50+
const preExpanded = collapsible && defaultOpen ? [ACCORDION_ITEM_KEY] : [];
8851

52+
if (!collapsible) {
8953
return (
9054
<div className={classnames(cssClass.CONTAINER, className)}>
91-
<Accordion onChange={(keys) => this.toggleArrow(keys)}>
92-
<AccordionItem expanded={!isCollapsed}>
93-
<AccordionItemTitle className={cssClass.COLLAPSIBLE_HEADER}>
94-
<div>
95-
<div className={cssClass.COLLAPSE_ARROW}>
96-
<FontAwesome name={collapseArrow} />
97-
</div>
98-
<div className={cssClass.COLLAPSIBLE_TITLE}>{title}</div>
99-
</div>
100-
</AccordionItemTitle>
101-
<AccordionItemBody>
102-
<div className={cssClass.CONTENT}>{children}</div>
103-
{footer && <div className={cssClass.FOOTER}>{footer}</div>}
104-
</AccordionItemBody>
105-
</AccordionItem>
106-
</Accordion>
55+
{!hideTitle && (
56+
<div className={cssClass.HEADER}>
57+
<h4 className={cssClass.TITLE}>{title}</h4>
58+
</div>
59+
)}
60+
<div className={cssClass.CONTENT}>{children}</div>
61+
{footer && <div className={cssClass.FOOTER}>{footer}</div>}
10762
</div>
10863
);
10964
}
110-
}
65+
66+
return (
67+
<div className={classnames(cssClass.CONTAINER, className)}>
68+
<Accordion
69+
allowZeroExpanded
70+
preExpanded={preExpanded}
71+
onChange={(_) => setIsCollapsed(!isCollapsed)}
72+
>
73+
<AccordionItem uuid={ACCORDION_ITEM_KEY}>
74+
<AccordionItemHeading className={cssClass.COLLAPSIBLE_HEADER}>
75+
<AccordionItemButton>
76+
<div className={cssClass.COLLAPSE_ARROW}>
77+
<FontAwesome name={isCollapsed ? "caret-right" : "caret-down"} />
78+
</div>
79+
<div className={cssClass.COLLAPSIBLE_TITLE}>{title}</div>
80+
</AccordionItemButton>
81+
</AccordionItemHeading>
82+
<AccordionItemPanel>
83+
<div className={cssClass.CONTENT}>{children}</div>
84+
{footer && <div className={cssClass.FOOTER}>{footer}</div>}
85+
</AccordionItemPanel>
86+
</AccordionItem>
87+
</Accordion>
88+
</div>
89+
);
90+
};
91+
92+
export default InfoPanel;

test/InfoPanel_test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe("InfoPanel", () => {
2727
{content}
2828
</InfoPanel>,
2929
);
30-
assert(panel.find(".accordion__body").hasClass("accordion__body--hidden"));
30+
assert(panel.find(".accordion__panel[hidden]").length > 0);
3131
});
3232

3333
it("shows collapsible content when defaultOpen is true", () => {
@@ -37,6 +37,6 @@ describe("InfoPanel", () => {
3737
{content}
3838
</InfoPanel>,
3939
);
40-
assert(!panel.find(".accordion__body").hasClass("accordion__body--hidden"));
40+
assert(panel.find(".accordion__panel[hidden]").length === 0);
4141
});
4242
});

0 commit comments

Comments
 (0)