diff --git a/packages/eui/src/components/context_menu/context_menu_panel.spec.tsx b/packages/eui/src/components/context_menu/context_menu_panel.spec.tsx
index 9e41fb7d6db..425c72998c0 100644
--- a/packages/eui/src/components/context_menu/context_menu_panel.spec.tsx
+++ b/packages/eui/src/components/context_menu/context_menu_panel.spec.tsx
@@ -231,6 +231,52 @@ describe('EuiContextMenuPanel', () => {
cy.focused().should('have.attr', 'data-test-subj', 'popoverToggle');
});
});
+
+ describe('disabling auto focus', () => {
+ it('does not focus anything if initialFocusedItemIndex is set to -1', () => {
+ cy.mount(
+
+ {children}
+
+ );
+ cy.focused().should('not.exist');
+ });
+
+ it('does not focus the back button if it exists', () => {
+ cy.mount(
+ {}}
+ title="Test"
+ items={items}
+ />
+ );
+ cy.focused().should('not.exist');
+ });
+
+ it('still allows for manually tabbing to the panel and using up/down key navigation', () => {
+ cy.realMount(
+
+ );
+ cy.realPress('Tab');
+ cy.focused().should('have.attr', 'data-test-subj', 'itemA');
+ cy.realPress('{downarrow}');
+ cy.focused().should('have.attr', 'data-test-subj', 'itemB');
+ });
+
+ it('other children with `autoFocus` should take focus', () => {
+ cy.mount(
+ ,
+ ]}
+ />
+ );
+ cy.focused().should('have.value', 'Auto focus test');
+ });
+ });
});
describe('Keyboard navigation of items', () => {
diff --git a/packages/eui/src/components/context_menu/context_menu_panel.tsx b/packages/eui/src/components/context_menu/context_menu_panel.tsx
index 578d42cd49c..fba84f9f41b 100644
--- a/packages/eui/src/components/context_menu/context_menu_panel.tsx
+++ b/packages/eui/src/components/context_menu/context_menu_panel.tsx
@@ -46,6 +46,12 @@ export type EuiContextMenuPanelProps = PropsWithChildren &
HTMLAttributes,
'onKeyDown' | 'tabIndex' | 'onAnimationEnd' | 'title'
> & {
+ /**
+ * Determines the initially focused menu item for keyboard and screen reader users.
+ *
+ * Can be set to `-1` to prevent autofocus (an uncommon case that must have
+ * keyboard accessibility accounted for manually if used)
+ */
initialFocusedItemIndex?: number;
items?: ReactElement[];
onClose?: NoArgCallback;
@@ -99,7 +105,9 @@ export class EuiContextMenuPanelClass extends Component<
},
menuItems: [],
focusedItemIndex:
- props.onClose && props.initialFocusedItemIndex != null
+ props.onClose &&
+ props.initialFocusedItemIndex != null &&
+ props.initialFocusedItemIndex !== -1
? props.initialFocusedItemIndex + 1 // Account for panel title back button
: props.initialFocusedItemIndex,
currentHeight: undefined,
@@ -257,6 +265,13 @@ export class EuiContextMenuPanelClass extends Component<
return;
}
+ // `initialFocusedItemIndex={-1}` should only be used when preventing initial item focus is desired
+ if (this.state.focusedItemIndex === -1) {
+ // Resetting the focusedItemIndex to 0 allows keyboard up/down behavior to
+ // still work correctly later if the panel is manually tabbed into
+ return this.setState({ tookInitialFocus: true, focusedItemIndex: 0 });
+ }
+
// If an item should be focused, focus it (if it exists)
if (this.state.focusedItemIndex != null && this.state.menuItems.length) {
const focusedItem = this.state.menuItems[this.state.focusedItemIndex];