Skip to content

Commit

Permalink
[EuiContextMenuPanel] Allow consumers to disable initial focus via `i…
Browse files Browse the repository at this point in the history
…nitialFocusedItemIndex={-1}` (#8101)
  • Loading branch information
cee-chen authored Oct 28, 2024
1 parent 040bf9a commit 90a5682
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/eui/changelogs/upcoming/8101.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Updated `EuiContextMenuPanel` to allow disabling initial focus via `initialFocusedItemIndex={-1}`
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<EuiContextMenuPanel initialFocusedItemIndex={-1}>
{children}
</EuiContextMenuPanel>
);
cy.focused().should('not.exist');
});

it('does not focus the back button if it exists', () => {
cy.mount(
<EuiContextMenuPanel
initialFocusedItemIndex={-1}
onClose={() => {}}
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(
<EuiContextMenuPanel initialFocusedItemIndex={-1} items={items} />
);
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(
<EuiContextMenuPanel
initialFocusedItemIndex={-1}
items={[
...items,
<input type="text" value="Auto focus test" autoFocus />,
]}
/>
);
cy.focused().should('have.value', 'Auto focus test');
});
});
});

describe('Keyboard navigation of items', () => {
Expand Down
17 changes: 16 additions & 1 deletion packages/eui/src/components/context_menu/context_menu_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ export type EuiContextMenuPanelProps = PropsWithChildren &
HTMLAttributes<HTMLDivElement>,
'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<void>;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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];
Expand Down

0 comments on commit 90a5682

Please sign in to comment.