11import classnames from "classnames" ;
22import * as React from "react" ;
3- import * as PropTypes from "prop-types" ;
43import * as FontAwesome from "react-fontawesome" ;
54import {
65 Accordion ,
76 AccordionItem ,
8- AccordionItemTitle ,
9- AccordionItemBody ,
7+ AccordionItemHeading ,
8+ AccordionItemButton ,
9+ AccordionItemPanel ,
1010} from "react-accessible-accordion" ;
1111import "./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-
3723export 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 ;
0 commit comments