There are no notes for this item.
Prop | Required? | Type | Default | Description |
---|---|---|---|---|
panelName | Yes | string |
<div id="reactMount" data-tpl="collapsiblepanel">
<div>
<div class="usa-accordion-bordered form-review-panel">
<div name="collapsible-panel-11-scroll-element"></div>
<div class="accordion-header clearfix"><button class="usa-accordion-button usa-button-unstyled" aria-expanded="false" aria-controls="collapsible-11">Collapsible Panel</button></div>
<div id="collapsible-11"></div>
</div>
<div class="usa-accordion-bordered form-review-panel">
<div name="collapsible-panel-12-scroll-element"></div>
<div class="accordion-header clearfix"><button class="usa-accordion-button usa-button-unstyled" aria-expanded="true" aria-controls="collapsible-12">Collapsible Panel</button></div>
<div id="collapsible-12">
<div class="usa-accordion-content" aria-hidden="false">
<div>This panel defaults to open.</div>
</div>
</div>
</div>
</div>
</div>
<script>
window.currentProps = {
"package": {
"name": "department-of-veteran-affairs/jean-pants",
"version": "0.1.0"
},
"assetPath": "/design-system/",
"isProduction": true,
"componentSourcePath": "CollapsiblePanel.jsx",
"panelName": "Collapsible Panel"
}
</script>
import React from 'react';
import CollapsiblePanel from './CollapsiblePanel.jsx';
export default function CollapsiblePanelExample(props) {
return (
<div>
<CollapsiblePanel
panelName={props.panelName}>
<div>This panel defaults to closed.</div>
</CollapsiblePanel>
<CollapsiblePanel
panelName={props.panelName} startOpen>
<div>This panel defaults to open.</div>
</CollapsiblePanel>
</div>
);
}
package:
name: department-of-veteran-affairs/jean-pants
version: 0.1.0
assetPath: /design-system/
isProduction: true
componentSourcePath: CollapsiblePanel.jsx
panelName: Collapsible Panel
import PropTypes from 'prop-types';
import React from 'react';
import Scroll from 'react-scroll';
import _ from 'lodash/fp';
const Element = Scroll.Element;
const scroller = Scroll.scroller;
class CollapsiblePanel extends React.Component {
constructor(props) {
super(props);
this.state = { open: !!(props.startOpen) };
this.toggleChapter = this.toggleChapter.bind(this);
this.scrollToTop = this.scrollToTop.bind(this);
}
componentWillMount() {
this.id = _.uniqueId();
}
scrollToTop() {
// console.log('undefined?', window.VetsGov.scroll);
scroller.scrollTo(`collapsible-panel-${this.id}-scroll-element`, {
duration: 500,
delay: 2,
smooth: true,
});
}
toggleChapter() {
const isOpening = !this.state.open;
this.setState((prevState) => ({ open: !prevState.open }), () => {
if (isOpening) {
this.scrollToTop();
}
});
}
render() {
let pageContent = null;
if (this.state.open) {
pageContent = (
<div className="usa-accordion-content" aria-hidden="false">
{this.props.children}
</div>
);
}
return (
<div className="usa-accordion-bordered form-review-panel">
<Element name={`collapsible-panel-${this.id}-scroll-element`}/>
<div className="accordion-header clearfix">
<button
className="usa-accordion-button usa-button-unstyled"
aria-expanded={this.state.open ? 'true' : 'false'}
aria-controls={`collapsible-${this.id}`}
onClick={this.toggleChapter}>
{this.props.panelName}
</button>
</div>
<div id={`collapsible-${this.id}`}>
{pageContent}
</div>
</div>
);
}
}
CollapsiblePanel.propTypes = {
/* panel label */
panelName: PropTypes.string.isRequired
};
export default CollapsiblePanel;
import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';
import sinon from 'sinon';
import { axeCheck } from '../../../lib/testing/helpers';
import CollapsiblePanel from './CollapsiblePanel';
describe('<CollapsiblePanel>', () => {
it('should render the correct panel header', () => {
const testHeaderText = 'Test panel';
const wrapper = shallow(<CollapsiblePanel panelName={testHeaderText}/>);
const renderedHeaderText = wrapper.find('.usa-accordion-button').render().text();
expect(renderedHeaderText).to.equal(testHeaderText);
});
it('should handle toggling chapter', () => {
const wrapper = shallow(<CollapsiblePanel panelName={'Test panel'}><div>Some content goes here.</div></CollapsiblePanel>);
const toggleButton = wrapper.find('button');
expect(wrapper.find('.usa-accordion-content').length).to.equal(0);
toggleButton.simulate('click');
expect(wrapper.find('.usa-accordion-content').length).to.equal(1);
toggleButton.simulate('click');
expect(wrapper.find('.usa-accordion-content').length).to.equal(0);
});
it('should default to open if startOpen prop is true', () => {
const wrapper = shallow(<CollapsiblePanel panelName={'Test'} startOpen><div>Some content goes here.</div></CollapsiblePanel>);
const toggleButton = wrapper.find('button');
expect(wrapper.find('.usa-accordion-content').length).to.equal(1);
toggleButton.simulate('click');
expect(wrapper.find('.usa-accordion-content').length).to.equal(0);
toggleButton.simulate('click');
expect(wrapper.find('.usa-accordion-content').length).to.equal(1);
});
it('should call scrollToTop on toggle open', () => {
const scrollSpy = sinon.spy();
CollapsiblePanel.prototype.scrollToTop = scrollSpy;
const wrapper = shallow(<CollapsiblePanel panelName={'Test'}/>);
const button = wrapper.find('button');
expect(scrollSpy.called).to.be.false;
button.simulate('click');
expect(scrollSpy.calledOnce).to.be.true;
});
it('should pass aXe check when closed', () => {
return axeCheck(<CollapsiblePanel panelName={'Test'}/>);
});
it('should pass aXe check when open', () => {
return axeCheck(<CollapsiblePanel panelName={'Test'} startOpen/>);
});
});