Skip to content

Commit af74c87

Browse files
authored
Merge pull request #313 from sparksuite/chang-focus-behavior-on-click
Change focus behavior on click
2 parents dc08298 + ddf6861 commit af74c87

File tree

5 files changed

+17
-15
lines changed

5 files changed

+17
-15
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-accessible-dropdown-menu-hook",
3-
"version": "3.2.0",
3+
"version": "4.0.0",
44
"description": "A simple Hook for creating fully accessible dropdown menus in React",
55
"main": "dist/use-dropdown-menu.js",
66
"types": "dist/use-dropdown-menu.d.ts",

src/use-dropdown-menu.test.tsx

+8-6
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,16 @@ it('Moves the focus to the first menu item after pressing space while focused on
9595
expect(screen.getByText('1 Item')).toHaveFocus();
9696
});
9797

98-
it('Moves the focus to the first menu item after clicking the menu to open it', async () => {
99-
const { user } = setup(<TestComponent />);
98+
it('Moves the focus to the first menu item after clicking the menu to open it, if `focusFirstItemOnClick` is specified', async () => {
99+
const { user } = setup(<TestComponent options={{ focusFirstItemOnClick: true }} />);
100100

101101
await user.click(screen.getByText('Primary'));
102102

103103
expect(screen.getByText('1 Item')).toHaveFocus();
104104
});
105105

106-
it('Moves the focus to the first menu item after clicking the menu to open it, then pressing tab while focused on the menu button, if `disableFocusFirstItemOnClick` is specified', async () => {
107-
const { user } = setup(<TestComponent options={{ disableFocusFirstItemOnClick: true }} />);
106+
it('Moves the focus to the first menu item after clicking the menu to open it, then pressing tab while focused on the menu button', async () => {
107+
const { user } = setup(<TestComponent />);
108108

109109
await user.click(screen.getByText('Primary'));
110110

@@ -115,8 +115,8 @@ it('Moves the focus to the first menu item after clicking the menu to open it, t
115115
expect(screen.getByText('1 Item')).toHaveFocus();
116116
});
117117

118-
it('Moves the focus to the first menu item after clicking the menu to open it, then pressing arrow down while focused on the menu button, if `disableFocusFirstItemOnClick` is specified', async () => {
119-
const { user } = setup(<TestComponent options={{ disableFocusFirstItemOnClick: true }} />);
118+
it('Moves the focus to the first menu item after clicking the menu to open it, then pressing arrow down while focused on the menu button', async () => {
119+
const { user } = setup(<TestComponent />);
120120

121121
await user.click(screen.getByText('Primary'));
122122

@@ -308,6 +308,8 @@ it('Can navigate to a dynamically-added item', async () => {
308308

309309
await user.click(screen.getByText('Primary'));
310310

311+
await user.keyboard('{ArrowDown}');
312+
311313
for (let i = 0; i < 4; i += 1) {
312314
await user.keyboard('{ArrowDown}');
313315
}

src/use-dropdown-menu.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ interface ButtonProps<ButtonElement extends HTMLElement>
1212

1313
// A custom Hook that abstracts away the listeners/controls for dropdown menus
1414
export interface DropdownMenuOptions {
15-
disableFocusFirstItemOnClick?: boolean;
15+
focusFirstItemOnClick?: boolean;
1616
}
1717

1818
interface DropdownMenuResponse<ButtonElement extends HTMLElement> {
@@ -64,7 +64,7 @@ export default function useDropdownMenu<ButtonElement extends HTMLElement = HTML
6464
}
6565

6666
// If the menu is currently open focus on the first item in the menu
67-
if (isOpen && !options?.disableFocusFirstItemOnClick) {
67+
if (isOpen && (!clickedOpen.current || options?.focusFirstItemOnClick)) {
6868
moveFocus(0);
6969
} else if (!isOpen) {
7070
clickedOpen.current = false;
@@ -159,7 +159,7 @@ export default function useDropdownMenu<ButtonElement extends HTMLElement = HTML
159159
setIsOpen(false);
160160
}
161161
} else {
162-
if (options?.disableFocusFirstItemOnClick) {
162+
if (!options?.focusFirstItemOnClick) {
163163
clickedOpen.current = !isOpen;
164164
}
165165

test-projects/browser/src/app.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ it('Has the correct page title', async () => {
3535
await expect(page.title()).resolves.toMatch('Browser');
3636
});
3737

38-
it('Focuses the first menu item when menu button is clicked', async () => {
38+
it('Maintains focus when menu button is clicked', async () => {
3939
await page.click('#menu-button');
4040
await menuOpen();
4141

42-
expect(await currentFocusID()).toBe('menu-item-1');
42+
expect(await currentFocusID()).toBe('menu-button');
4343
});
4444

4545
it('Focuses on the menu button after pressing escape', async () => {

website/docs/design/options.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ You can customize the behavior with options, passed as the second argument.
66

77
Option | Default | Possible values
88
:--- | :--- | :---
9-
`disableFocusFirstItemOnClick` | `false` | `boolean`
9+
`focusFirstItemOnClick` | `false` | `boolean`
1010

1111
Option | Explanation
1212
:--- | :---
13-
`disableFocusFirstItemOnClick` | If specified as `true` the default behavior of focusing the first menu item on click will be disabled. The menu button will instead retain focus.
13+
`focusFirstItemOnClick` | If specified as `true`, the first menu item will be focused when the menu is opened via a click (in addition to via a keyboard interaction).
1414

1515
```js
1616
useDropdownMenu(numberOfItems, {
17-
disableFocusFirstItemOnClick: true,
17+
focusFirstItemOnClick: true,
1818
});
1919
```

0 commit comments

Comments
 (0)