diff --git a/CHANGELOG.md b/CHANGELOG.md index f6424248fdc..51087f17b3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ - Converted `EuiTableRowCellCheckbox` to TS ([#1964](https://github.com/elastic/eui/pull/1964)) - Updated `caniuse-lite` version resolution ([#1970](https://github.com/elastic/eui/pull/1970)) -- Added a webpack directive for naming icon chunks ([#1944])(https://github.com/elastic/eui/pull/1944)) +- Added a webpack directive for naming icon chunks ([#1944](https://github.com/elastic/eui/pull/1944)) - Added ability to update `EuiInMemoryTable` `sorting` prop and remove columns after sorting is applied ([#1972](https://github.com/elastic/eui/pull/1972)) +- Added `onToggle` callback to `EuiAccordion` ([#1974](https://github.com/elastic/eui/pull/1974)) **Bug fixes** diff --git a/src-docs/src/views/accordion/accordion_callback.js b/src-docs/src/views/accordion/accordion_callback.js new file mode 100644 index 00000000000..aa2b204347e --- /dev/null +++ b/src-docs/src/views/accordion/accordion_callback.js @@ -0,0 +1,22 @@ +import React from 'react'; + +import { EuiAccordion, EuiText, EuiCode } from '../../../../src/components'; + +export default () => ( +
+ + console.log(`EuiAccordion is now ${isOpen ? 'open' : 'closed'}`) + } + paddingSize="l"> + +

+ Any content inside of EuiAccordion will appear + here. +

+
+
+
+); diff --git a/src-docs/src/views/accordion/accordion_example.js b/src-docs/src/views/accordion/accordion_example.js index 047954390d4..29535eb7f9b 100644 --- a/src-docs/src/views/accordion/accordion_example.js +++ b/src-docs/src/views/accordion/accordion_example.js @@ -71,6 +71,18 @@ const accordionOpenSnippet = ` `; +import AccordionCallback from './accordion_callback'; +const accordionCallbackSource = require('!!raw-loader!./accordion_callback'); +const accordionCallbackHtml = renderToHtml(AccordionCallback); +const accordionCallbackSnippet = ` handleOnToggle(isOpen)} + > + + +`; + import AccordionGrow from './accordion_grow'; const accordionGrowSource = require('!!raw-loader!./accordion_grow'); const accordionGrowHtml = renderToHtml(AccordionGrow); @@ -204,6 +216,27 @@ export const AccordionExample = { snippet: accordionOpenSnippet, demo: , }, + { + title: 'Accordion can call a function on open and close', + source: [ + { + type: GuideSectionTypes.JS, + code: accordionCallbackSource, + }, + { + type: GuideSectionTypes.HTML, + code: accordionCallbackHtml, + }, + ], + text: ( +

+ Use the onToggle prop to pass a callback method + that will be called on open and close. +

+ ), + snippet: accordionCallbackSnippet, + demo: , + }, { title: 'Accordion content can dynamically change height', source: [ diff --git a/src/components/accordion/accordion.js b/src/components/accordion/accordion.js index ca844827abf..ce183d757fc 100644 --- a/src/components/accordion/accordion.js +++ b/src/components/accordion/accordion.js @@ -50,9 +50,14 @@ export class EuiAccordion extends Component { } onToggle() { - this.setState(prevState => ({ - isOpen: !prevState.isOpen, - })); + this.setState( + prevState => ({ + isOpen: !prevState.isOpen, + }), + () => { + this.props.onToggle && this.props.onToggle(this.state.isOpen); + } + ); } setChildContentRef = node => { @@ -183,6 +188,10 @@ EuiAccordion.propTypes = { * The padding around the exposed accordion content. */ paddingSize: PropTypes.oneOf(PADDING_SIZES), + /** + * Optional callback method called on open and close with a single `isOpen` parameter + */ + onToggle: PropTypes.func, }; EuiAccordion.defaultProps = { diff --git a/src/components/accordion/accordion.test.js b/src/components/accordion/accordion.test.js index 096d1388882..e621af8fae2 100644 --- a/src/components/accordion/accordion.test.js +++ b/src/components/accordion/accordion.test.js @@ -84,5 +84,20 @@ describe('EuiAccordion', () => { expect(component).toMatchSnapshot(); }); + + it('accepts and calls an optional callback on open and close', () => { + const onToggleHandler = jest.fn(); + const component = mount( + + ); + + component.find('button').simulate('click'); + expect(onToggleHandler).toBeCalled(); + expect(onToggleHandler).toBeCalledWith(true); + + component.find('button').simulate('click'); + expect(onToggleHandler).toBeCalled(); + expect(onToggleHandler).toBeCalledWith(false); + }); }); }); diff --git a/src/components/accordion/index.d.ts b/src/components/accordion/index.d.ts index f20ce142e4f..63c0dfc9996 100644 --- a/src/components/accordion/index.d.ts +++ b/src/components/accordion/index.d.ts @@ -11,10 +11,11 @@ declare module '@elastic/eui' { buttonContent?: ReactNode; extraAction?: ReactNode; initialIsOpen?: boolean; + onToggle?: (isOpen: boolean) => void; paddingSize?: EuiAccordionSize; } export class EuiAccordion extends Component< CommonProps & HTMLAttributes & EuiAccordionProps - > {} + > {} }