diff --git a/components/accordion/__tests__/accordion.browser-test.jsx b/components/accordion/__tests__/accordion.browser-test.jsx index 3a50ef12ab..e93e364cde 100644 --- a/components/accordion/__tests__/accordion.browser-test.jsx +++ b/components/accordion/__tests__/accordion.browser-test.jsx @@ -269,6 +269,33 @@ describe('Accordion', function describeFunction() { lastAccordionButton.getDOMNode() === document.activeElement ).to.equal(true); }); + + it('focuses the correct remaining button after a panel is removed', () => { + wrapper = mount(, { attachTo: mountNode }); + const exampleInstance = wrapper.find(AccordionExample).instance(); + + exampleInstance.setState((state) => ({ + items: state.items.filter((item) => item.id !== '2'), + })); + wrapper.update(); + + const accordionButtons = wrapper.find( + 'button.slds-accordion__summary-action' + ); + expect(accordionButtons).to.have.lengthOf(2); + + expect(() => + accordionButtons.at(0).simulate('keyDown', { + key: 'ArrowDown', + keyCode: 40, + which: 40, + }) + ).to.not.throw(); + + expect( + accordionButtons.at(1).getDOMNode() === document.activeElement + ).to.equal(true); + }); }); describe('Open panel', () => { diff --git a/components/accordion/index.jsx b/components/accordion/index.jsx index 2c239ee717..ce432c0986 100644 --- a/components/accordion/index.jsx +++ b/components/accordion/index.jsx @@ -55,7 +55,8 @@ class Accordion extends Component { componentDidUpdate(prevProps, prevState) { if ( this.state.currButtonIndex !== null && - this.state.currButtonIndex !== prevState.currButtonIndex + this.state.currButtonIndex !== prevState.currButtonIndex && + this.summaryButtons[this.state.currButtonIndex] ) { this.summaryButtons[this.state.currButtonIndex].focus(); } @@ -69,7 +70,7 @@ class Accordion extends Component { let buttonIndex = this.state.currButtonIndex; if (buttonIndex === null) { buttonIndex = this.summaryButtons.findIndex( - (el) => el.id === e.target.id + (el) => el && el.id === e.target.id ); } @@ -94,11 +95,13 @@ class Accordion extends Component { } } - addSummaryButton(button) { - const btnInArr = this.summaryButtons.find((el) => button === el); - if (button !== null && btnInArr === undefined) { + addSummaryButton(index, button) { + if (button === null) { + // eslint-disable-next-line fp/no-delete + delete this.summaryButtons[index]; + } else { // eslint-disable-next-line fp/no-mutating-methods - this.summaryButtons.push(button); + this.summaryButtons[index] = button; } } @@ -108,9 +111,9 @@ class Accordion extends Component { name={this.props.id || this.generatedId} className={classNames('slds-accordion', this.props.className)} > - {React.Children.map(this.props.children, (child) => + {React.Children.map(this.props.children, (child, index) => React.cloneElement(child, { - refs: { summaryButton: this.addSummaryButton.bind(this) }, + refs: { summaryButton: this.addSummaryButton.bind(this, index) }, onClickSummary: this.onClickSummary.bind(this), onKeyDownSummary: this.onKeyDownSummary.bind(this), })