diff --git a/CHANGELOG.md b/CHANGELOG.md index 108d3c2aa085..cfbf8b08ce1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## [`master`](https://github.com/elastic/eui/tree/master) +- Added `initialFocusedItemIndex` support to `EuiContextMenuPanelDescriptor` ([#4223](https://github.com/elastic/eui/pull/4223)) + **Bug fixes** - Fixed a condition in `EuiInMemoryTable` to avoid mistaken assignment of `sortName` ([#4138](https://github.com/elastic/eui/pull/4138)) diff --git a/src-docs/src/views/context_menu/context_menu.js b/src-docs/src/views/context_menu/context_menu.js index 9747121cc88c..90973c95a23b 100644 --- a/src-docs/src/views/context_menu/context_menu.js +++ b/src-docs/src/views/context_menu/context_menu.js @@ -68,6 +68,7 @@ export default () => { }, { id: 1, + initialFocusedItemIndex: 1, title: 'Nest panels', items: [ { diff --git a/src/components/context_menu/context_menu.tsx b/src/components/context_menu/context_menu.tsx index cb19ad796c2e..9018eb65bc31 100644 --- a/src/components/context_menu/context_menu.tsx +++ b/src/components/context_menu/context_menu.tsx @@ -65,6 +65,7 @@ export interface EuiContextMenuPanelDescriptor { items?: EuiContextMenuPanelItemDescriptor[]; content?: ReactNode; width?: number; + initialFocusedItemIndex?: number; } export type EuiContextMenuProps = CommonProps & @@ -227,9 +228,10 @@ export class EuiContextMenu extends Component { if (nextPanelId) { if (this.state.isUsingKeyboardToNavigate) { - this.setState({ - focusedItemIndex: 0, - }); + this.setState(({ idToPanelMap }) => ({ + focusedItemIndex: + idToPanelMap[nextPanelId].initialFocusedItemIndex ?? 0, + })); } this.showPanel(nextPanelId, 'next'); @@ -388,7 +390,7 @@ export class EuiContextMenu extends Component { initialFocusedItemIndex={ this.state.isUsingKeyboardToNavigate ? this.state.focusedItemIndex - : undefined + : panel.initialFocusedItemIndex } onUseKeyboardToNavigate={this.onUseKeyboardToNavigate} showNextPanel={this.showNextPanel} diff --git a/src/components/context_menu/context_menu_panel.test.tsx b/src/components/context_menu/context_menu_panel.test.tsx index 780727b61b73..b4d10250b877 100644 --- a/src/components/context_menu/context_menu_panel.test.tsx +++ b/src/components/context_menu/context_menu_panel.test.tsx @@ -173,6 +173,16 @@ describe('EuiContextMenuPanel', () => { document.activeElement ); }); + + it('sets focus on the panel when set to `-1`', async () => { + const component = mount( + + ); + + await tick(20); + + expect(component.getDOMNode()).toBe(document.activeElement); + }); }); describe('onUseKeyboardToNavigate', () => { diff --git a/src/components/context_menu/context_menu_panel.tsx b/src/components/context_menu/context_menu_panel.tsx index fbb193dcc71a..5ff4d5e8d2ee 100644 --- a/src/components/context_menu/context_menu_panel.tsx +++ b/src/components/context_menu/context_menu_panel.tsx @@ -228,6 +228,14 @@ export class EuiContextMenuPanel extends Component { return; } + // `focusedItemIndex={-1}` specifies that the panel itself should be focused. + // This should only be used when the panel does not have `item`s + // and preventing autofocus is desired, which is an uncommon case. + if (this.panel && this.state.focusedItemIndex === -1) { + this.panel.focus(); + return; + } + // If there aren't any items then this is probably a form or something. if (!this.state.menuItems.length) { // If we've already focused on something inside the panel, everything's fine.