Skip to content

Commit

Permalink
[EuiAccordion] Allow external control (#3614)
Browse files Browse the repository at this point in the history
* call onToggle

* test it

* onToggle returns expected state after click

* invert isOpen for docs
  • Loading branch information
thompsongl authored Jun 16, 2020
1 parent e5f54e6 commit 2c47d9c
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 18 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- Updated `logoElastic` to meet brand guidelines ([#3613](https://github.com/elastic/eui/pull/3613))
- Allowed user to enter hexcode for colors in `EuiStat` ([#3617](https://github.com/elastic/eui/pull/3617))
- Extended `CommonProps` in `EuiColorPalettePickerPaletteTextProps`, `EuiColorPalettePickerPaletteFixedProps` and `EuiColorPalettePickerPaletteGradientProps` types ([#3616](https://github.com/elastic/eui/pull/3616))

- Updated `onToggle` callback in `EuiAccordion` to allow for external state control ([#3614](https://github.com/elastic/eui/pull/3614))

**Bug fixes**

Expand Down
5 changes: 3 additions & 2 deletions src-docs/src/views/accordion/accordion_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ export const AccordionExample = {
demo: <AccordionForm />,
},
{
title: 'Force accordion state',
title: 'External state control',
source: [
{
type: GuideSectionTypes.JS,
Expand All @@ -346,7 +346,8 @@ export const AccordionExample = {
text: (
<p>
Use the <EuiCode>forceState</EuiCode> prop to control open and close
state.
state. The <EuiCode>onToggle</EuiCode> callback prop can still be used
to update external state or perform side effects.
</p>
),
snippet: accordionForceStateSnippet,
Expand Down
7 changes: 7 additions & 0 deletions src-docs/src/views/accordion/accordion_forceState.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export default () => {
setID(id);
};

const onToggle = isOpen => {
const newState = isOpen ? 'open' : 'closed';
setTrigger(newState);
setID(`${idPrefix}--${newState}`);
};

return (
<div>
<EuiButtonGroup
Expand All @@ -41,6 +47,7 @@ export default () => {
<EuiAccordion
id="accordion--forceState"
forceState={trigger}
onToggle={onToggle}
buttonContent="I am controlled via prop">
<EuiText>
<p>
Expand Down
12 changes: 6 additions & 6 deletions src/components/accordion/__snapshots__/accordion.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`EuiAccordion behavior closes when clicked twice 1`] = `
<EuiAccordion
arrowDisplay="left"
id="9"
id="10"
initialIsOpen={false}
paddingSize="none"
>
Expand All @@ -14,7 +14,7 @@ exports[`EuiAccordion behavior closes when clicked twice 1`] = `
className="euiAccordion__triggerWrapper"
>
<button
aria-controls="9"
aria-controls="10"
aria-expanded={false}
className="euiAccordion__button"
onClick={[Function]}
Expand Down Expand Up @@ -42,7 +42,7 @@ exports[`EuiAccordion behavior closes when clicked twice 1`] = `
</div>
<div
className="euiAccordion__childWrapper"
id="9"
id="10"
>
<EuiResizeObserver
onResize={[Function]}
Expand All @@ -61,7 +61,7 @@ exports[`EuiAccordion behavior closes when clicked twice 1`] = `
exports[`EuiAccordion behavior opens when clicked once 1`] = `
<EuiAccordion
arrowDisplay="left"
id="8"
id="9"
initialIsOpen={false}
paddingSize="none"
>
Expand All @@ -72,7 +72,7 @@ exports[`EuiAccordion behavior opens when clicked once 1`] = `
className="euiAccordion__triggerWrapper"
>
<button
aria-controls="8"
aria-controls="9"
aria-expanded={true}
className="euiAccordion__button"
onClick={[Function]}
Expand Down Expand Up @@ -100,7 +100,7 @@ exports[`EuiAccordion behavior opens when clicked once 1`] = `
</div>
<div
className="euiAccordion__childWrapper"
id="8"
id="9"
>
<EuiResizeObserver
onResize={[Function]}
Expand Down
15 changes: 15 additions & 0 deletions src/components/accordion/accordion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ describe('EuiAccordion', () => {

expect(component).toMatchSnapshot();
});

it('accepts and calls an optional callback on click', () => {
const onToggleHandler = jest.fn();
const component = mount(
<EuiAccordion
id={getId()}
onToggle={onToggleHandler}
forceState="closed"
/>
);

component.find('button').simulate('click');
expect(onToggleHandler).toBeCalled();
expect(onToggleHandler).toBeCalledWith(true);
});
});
});

Expand Down
22 changes: 13 additions & 9 deletions src/components/accordion/accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,19 @@ export class EuiAccordion extends Component<

onToggle = () => {
const { forceState } = this.props;
if (forceState) return this.setState({ isOpen: forceState === 'open' });
this.setState(
prevState => ({
isOpen: !prevState.isOpen,
}),
() => {
this.props.onToggle && this.props.onToggle(this.state.isOpen);
}
);
if (forceState) {
this.props.onToggle &&
this.props.onToggle(forceState === 'open' ? false : true);
} else {
this.setState(
prevState => ({
isOpen: !prevState.isOpen,
}),
() => {
this.props.onToggle && this.props.onToggle(this.state.isOpen);
}
);
}
};

setChildContentRef = (node: HTMLDivElement | null) => {
Expand Down

0 comments on commit 2c47d9c

Please sign in to comment.