Expects two child components.
Prop | Required? | Type | Default | Description |
---|---|---|---|---|
open | Yes | bool | show second child | |
additionalClass | No | string | class added to parent element second child component | |
showPlus | No | bool | show a + or - icon indicating second child's visibility | |
expandedContentId | No | string | id for ReactCSSTransitionGroup |
<div id="reactMount" data-tpl="expandinggroup">
<div><button>Toggle Expanding Group</button>
<div class="form-expanding-group form-expanding-group-open">
<div>visible child</div><span><div><div>hidden child</div></div></span></div>
</div>
</div>
<script>
window.currentProps = {
"package": {
"name": "department-of-veteran-affairs/jean-pants",
"version": "0.1.0"
},
"assetPath": "/design-system/",
"isProduction": true,
"componentSourcePath": "./ExpandingGroup.jsx",
"open": true,
"expandedContentId": "expandedContentId"
}
</script>
import React from 'react';
import ExpandingGroup from './ExpandingGroup';
class Toggler extends React.Component {
constructor(props) {
super(props);
this.state = props;
}
render() {
return (
<div>
<button
onClick={() => this.setState({
open: !this.state.open
})}
>
Toggle Expanding Group
</button>
<ExpandingGroup
open={this.state.open}
>
<div>visible child</div>
<div>hidden child</div>
</ExpandingGroup>
</div>
);
}
}
export default function ExpandingGroupExample(props) {
return (
<Toggler
{...props}
/>
);
}
package:
name: department-of-veteran-affairs/jean-pants
version: 0.1.0
assetPath: /design-system/
isProduction: true
componentSourcePath: ./ExpandingGroup.jsx
open: true
expandedContentId: expandedContentId
import PropTypes from 'prop-types';
import React from 'react';
import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';
import classnames from 'classnames';
/*
* Component that expands to show a hidden child element with a fade in/slide down animation
*
* Props:
* children - expects 2 children, the first is always shown, the second is shown if open is true
* open - determines if the second child is displayed
* additionalClass - A string added as a class to the parent element of the second child
* showPlus - Boolean to display a "+" or "-" icon based on open status
*/
export default function ExpandingGroup({
children, open, showPlus, additionalClass, expandedContentId
}) {
const classNames = classnames(
'form-expanding-group',
{ 'form-expanding-group-open': open },
{ 'form-expanding-group-plus': showPlus }
);
return (
<div className={classNames}>
{children[0]}
<ReactCSSTransitionGroup id={expandedContentId} transitionName="form-expanding-group-inner" transitionEnterTimeout={700} transitionLeave={false}>
{open
? <div key="removable-group" className={additionalClass}>
{children[1]}
</div>
: null}
</ReactCSSTransitionGroup>
</div>
);
}
ExpandingGroup.propTypes = {
/**
* show second child
*/
open: PropTypes.bool.isRequired,
/**
* class added to parent element second child component
*/
additionalClass: PropTypes.string,
/**
* show a + or - icon indicating second child's visibility
*/
showPlus: PropTypes.bool,
/**
* id for ReactCSSTransitionGroup
*/
expandedContentId: PropTypes.string
};
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { axeCheck } from '../../../../../lib/testing/helpers';
import ExpandingGroup from './ExpandingGroup.jsx';
describe('<ExpandingGroup>', () => {
it('renders only first child when open is false', () => {
const wrapper = shallow(<ExpandingGroup open={false}><first/><second/></ExpandingGroup>);
const first = wrapper.find('first');
const second = wrapper.find('second');
expect(first).to.have.lengthOf(1);
expect(second).to.have.lengthOf(0);
});
it('renders both children when open is true', () => {
const wrapper = shallow(<ExpandingGroup open><first/><second/></ExpandingGroup>);
const first = wrapper.find('first');
const second = wrapper.find('second');
expect(first).to.have.lengthOf(1);
expect(second).to.have.lengthOf(1);
});
it('passes aXe check when only first child is rendered', () => {
const check = axeCheck(<ExpandingGroup open={false}><first/><second/></ExpandingGroup>);
return check;
});
it('passes aXe check when both children are rendered', () => {
const check = axeCheck(<ExpandingGroup open><first/><second/></ExpandingGroup>);
return check;
});
});