From 50c8975489f9de595f71e31c6295bc95ace5c030 Mon Sep 17 00:00:00 2001 From: Randall Krauskopf Date: Wed, 1 May 2024 11:23:01 -0500 Subject: [PATCH] Account for the {Space} key event --- packages/react/src/TreeView/TreeView.test.tsx | 96 +++++++++++++++++++ packages/react/src/TreeView/TreeView.tsx | 2 +- packages/react/src/TreeView/useTypeahead.ts | 2 +- 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/packages/react/src/TreeView/TreeView.test.tsx b/packages/react/src/TreeView/TreeView.test.tsx index 00f076da368..ff48cbde3b6 100644 --- a/packages/react/src/TreeView/TreeView.test.tsx +++ b/packages/react/src/TreeView/TreeView.test.tsx @@ -981,6 +981,102 @@ describe('Keyboard interactions', () => { }) }) + describe('Space', () => { + it('calls onSelect function if provided and checks if the item has been selected', () => { + const onSelect = jest.fn() + const {getByRole} = renderWithTheme( + + + Parent 1 + + + Child 1 + + + + + Parent 2 + + + Child2 + + + + + Parent 3 + + + Child 3 + + + + , + ) + const itemChild = getByRole('treeitem', {name: 'Child2'}) + + act(() => { + // Focus first item + itemChild.focus() + }) + + // Press Enter + fireEvent.keyDown(document.activeElement || document.body, {key: ' '}) + + // onSelect should have been called + expect(onSelect).toHaveBeenCalledTimes(1) + + onSelect.mockClear() + + // Press middle click + fireEvent.click(document.activeElement?.firstChild || document.body, {button: 1}) + + // onSelect should have been called + expect(onSelect).toHaveBeenCalledTimes(1) + }) + + it('toggles expanded state if no onSelect function is provided', () => { + const {getByRole, queryByRole} = renderWithTheme( + + + Parent + + Child 1 + Child 2 + + + , + ) + + const parent = getByRole('treeitem', {name: 'Parent'}) + + act(() => { + // Focus first item + parent.focus() + }) + + // aria-expanded should be false + expect(parent).toHaveAttribute('aria-expanded', 'false') + + // Press Enter + fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'}) + + // aria-expanded should now be true + expect(parent).toHaveAttribute('aria-expanded', 'true') + + // Subtree should be visible + expect(queryByRole('group')).toBeVisible() + + // Press Enter + fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'}) + + // aria-expanded should now be false + expect(parent).toHaveAttribute('aria-expanded', 'false') + + // Subtree should no longer be visible + expect(queryByRole('group')).not.toBeInTheDocument() + }) + }) + describe('Typeahead', () => { it('moves focus to the next item that matches the typed character', () => { const {getByRole} = renderWithTheme( diff --git a/packages/react/src/TreeView/TreeView.tsx b/packages/react/src/TreeView/TreeView.tsx index 234a8115da3..212bb9bf49c 100644 --- a/packages/react/src/TreeView/TreeView.tsx +++ b/packages/react/src/TreeView/TreeView.tsx @@ -396,7 +396,7 @@ const Item = React.forwardRef( (event: React.KeyboardEvent) => { switch (event.key) { case 'Enter': - case 'Space': + case ' ': if (onSelect) { onSelect(event) } else { diff --git a/packages/react/src/TreeView/useTypeahead.ts b/packages/react/src/TreeView/useTypeahead.ts index fe430c597a3..cfd5f35f6d4 100644 --- a/packages/react/src/TreeView/useTypeahead.ts +++ b/packages/react/src/TreeView/useTypeahead.ts @@ -63,7 +63,7 @@ export function useTypeahead({containerRef, onFocusChange}: TypeaheadOptions) { function onKeyDown(event: KeyboardEvent) { // Ignore key presses that don't produce a character value - if (!event.key || event.key.length > 1) return + if (!event.key || event.key.length > 1 || event.key === ' ') return // Ignore key presses that occur with a modifier if (event.ctrlKey || event.altKey || event.metaKey) return