Skip to content

Commit

Permalink
Merge pull request #13 from epotockiy/feature/programmatically-expand
Browse files Browse the repository at this point in the history
Allow expand "AccordionItem" programmatically
  • Loading branch information
vincentaudebert authored Sep 13, 2017
2 parents e3be897 + fb478c7 commit 6405805
Show file tree
Hide file tree
Showing 8 changed files with 1,066 additions and 518 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ ReactDOM.render(<Example />, document.querySelector('[data-mount]'));
<td>accordion</td>
<td>CSS class(es) applied to the component</td>
</tr>
<tr>
<td>activeItems</td>
<td>Array</td>
<td>[]</td>
<td>Indexes (or custom keys) to pre expand items. Can be changed dynamically. Doesn't have the priority against `AccordionItem - expanded` on first render.</td>
</tr>
</tbody>
</table>

Expand Down Expand Up @@ -128,6 +134,12 @@ ReactDOM.render(<Example />, document.querySelector('[data-mount]'));
<td>null</td>
<td>Class name for hidden body state</td>
</tr>
<tr>
<td>customKey</td>
<td>String</td>
<td></td>
<td>Custom key to be used as a reference in `Accordion - activeItems`</td>
</tr>
</tbody>
</table>

Expand Down
4 changes: 4 additions & 0 deletions demo/css/demo.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
margin-top: 1.875rem;
}

.u-margin-right {
margin-right: 1.875rem;
}

.block {
padding: 1.25rem;
}
Expand Down
1,095 changes: 581 additions & 514 deletions demo/js/demo.js

Large diffs are not rendered by default.

242 changes: 242 additions & 0 deletions src/Accordion/__snapshots__/accordion.spec.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Accordion close accordions via accordion props props dynamicly 1`] = `
<div
className="accordion"
role="tablist"
>
<div
accordion={true}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={true}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion different className 1`] = `
<div
className="testCSSClass"
Expand All @@ -24,6 +48,119 @@ exports[`Accordion different className 1`] = `
</div>
`;

exports[`Accordion different className with the same activeItems prop 1`] = `
<div
className="test-2"
role="tablist"
>
<div
accordion={true}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={true}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion expand accordion via accordion props dynamicly 1`] = `
<div
className="accordion"
role="tablist"
>
<div
accordion={true}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={true}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion expand multiple accordions via accordion props props dynamicly 1`] = `
<div
className="accordion"
role={null}
>
<div
accordion={false}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={false}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={false}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion expand multiple accordions via accordion props props dynamicly with default
expanded on accordion items 1`] = `
<div
className="accordion"
role={null}
>
<div
accordion={false}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={false}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={false}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion handleClick function accordion false 1`] = `
<div
className="accordion"
Expand Down Expand Up @@ -168,6 +305,111 @@ exports[`Accordion handles disabled children 1`] = `
</div>
`;

exports[`Accordion pre expand accordion via accordion props 1`] = `
<div
className="accordion"
role="tablist"
>
<div
accordion={true}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={true}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion pre expand accordion via accordion props vs accordion item props. Expanded only second item. 1`] = `
<div
className="accordion"
role="tablist"
>
<div
accordion={true}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={true}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion pre expand accordion via accordion props with custom key 1`] = `
<div
className="accordion"
role="tablist"
>
<div
accordion={true}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={true}
customKey="custom"
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion pre expand multiple accordions via accordion props 1`] = `
<div
className="accordion"
role={null}
>
<div
accordion={false}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={false}
disabled={undefined}
expanded={false}
onClick={[Function]}
>
Fake Child
</div>
<div
accordion={false}
disabled={undefined}
expanded={true}
onClick={[Function]}
>
Fake Child
</div>
</div>
`;

exports[`Accordion pre expanded accordion 1`] = `
<div
className="accordion"
Expand Down
35 changes: 31 additions & 4 deletions src/Accordion/accordion.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { isArraysEqualShallow } from '../utils';

const defaultProps = {
accordion: true,
onChange: () => {},
className: 'accordion',
activeItems: [],
};

const propTypes = {
Expand All @@ -13,6 +15,10 @@ const propTypes = {
PropTypes.arrayOf(PropTypes.element),
PropTypes.object,
]).isRequired,
activeItems: PropTypes.arrayOf(PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
])),
className: PropTypes.string,
onChange: PropTypes.func,
};
Expand All @@ -28,17 +34,38 @@ class Accordion extends Component {
this.renderItems = this.renderItems.bind(this);
}

componentWillReceiveProps(nextProps) {
if (!isArraysEqualShallow(nextProps.activeItems, this.state.activeItems)) {
let newActiveItems;
if (nextProps.accordion) {
newActiveItems = nextProps.activeItems.length
? [nextProps.activeItems[0]]
: [];
} else {
newActiveItems = nextProps.activeItems.slice();
}
this.setState({
activeItems: newActiveItems,
});

nextProps.onChange(nextProps.accordion ? newActiveItems[0] : newActiveItems);
}
}

preExpandedItems() {
const activeItems = [];
let activeItems = [];
React.Children.map(this.props.children, (item, index) => {
if (item.props.expanded) {
if (this.props.accordion) {
if (activeItems.length === 0) activeItems.push(index);
if (activeItems.length === 0) activeItems.push(item.props.customKey || index);
} else {
activeItems.push(index);
activeItems.push(item.props.customKey || index);
}
}
});
if (activeItems.length === 0 && this.props.activeItems.length !== 0) {
activeItems = this.props.accordion ? [this.props.activeItems[0]] : this.props.activeItems.slice();
}
return activeItems;
}

Expand Down Expand Up @@ -68,7 +95,7 @@ class Accordion extends Component {
const { accordion, children } = this.props;

return React.Children.map(children, (item, index) => {
const key = index;
const key = item.props.customKey || index;
const expanded = (this.state.activeItems.indexOf(key) !== -1) && (!item.props.disabled);

return React.cloneElement(item, {
Expand Down
Loading

0 comments on commit 6405805

Please sign in to comment.