diff --git a/src/hooks/useSelect/__tests__/getToggleButtonProps.test.js b/src/hooks/useSelect/__tests__/getToggleButtonProps.test.js index 147e4d42..62fd2b29 100644 --- a/src/hooks/useSelect/__tests__/getToggleButtonProps.test.js +++ b/src/hooks/useSelect/__tests__/getToggleButtonProps.test.js @@ -26,6 +26,7 @@ import { } from '../../testUtils' import useSelect from '..' import * as stateChangeTypes from '../stateChangeTypes' +import { initialFocusAndOpenTestCases } from '../../useCombobox/testUtils' describe('getToggleButtonProps', () => { describe('hook props', () => { @@ -256,6 +257,31 @@ describe('getToggleButtonProps', () => { }) }) + describe('initial focus', () => { + for (const [ + initialIsOpen, + defaultIsOpen, + isOpen, + status, + ] of initialFocusAndOpenTestCases) { + /* eslint-disable */ + test(`is ${ + status ? '' : 'not ' + }grabbed when initialIsOpen: ${initialIsOpen}, defaultIsOpen: ${defaultIsOpen} and props.isOpen: ${isOpen}`, () => { + renderSelect({isOpen, defaultIsOpen, initialIsOpen}) + + if (status) { + expect(getToggleButton()).toHaveFocus() + expect(getItems()).toHaveLength(items.length) + } else { + expect(getToggleButton()).not.toHaveFocus() + expect(getItems()).toHaveLength(0) + } + }) + /* eslint-enable */ + } + }) + describe('event handlers', () => { describe('on click', () => { test('opens the closed menu', async () => { @@ -1429,11 +1455,7 @@ describe('getToggleButtonProps', () => { ) }) - // focus the toggle button in 2 tabs - await tab() - await tab() - - // now blur + // focus is already on the toggle button, tab should blur await tab() expect(getItems()).toHaveLength(0) @@ -1463,7 +1485,6 @@ describe('getToggleButtonProps', () => { }, ) - await tab() await mouseMoveItemAtIndex(defaultHighlightedIndex) await mouseLeaveItemAtIndex(defaultHighlightedIndex) await tab() @@ -1518,11 +1539,7 @@ describe('getToggleButtonProps', () => { ) }) - // focus the toggle button in 2 tabs - await tab() - await tab() - - // now blur + // focus is already on the toggle button, tab should blur await tab(true) expect(getItems()).toHaveLength(0) diff --git a/src/hooks/useSelect/index.js b/src/hooks/useSelect/index.js index 5719f627..f83727c4 100644 --- a/src/hooks/useSelect/index.js +++ b/src/hooks/useSelect/index.js @@ -11,6 +11,7 @@ import { useElementIds, useMouseAndTouchTracker, getItemAndIndex, + getInitialValue, } from '../utils' import { callAllEventHandlers, @@ -142,6 +143,15 @@ function useSelect(userProps = {}) { previousResultCountRef.current = items.length }) + // Focus the toggle button on first render if required. + useEffect(() => { + const focusOnOpen = getInitialValue(props, 'isOpen') + + if (focusOnOpen && toggleButtonRef.current) { + toggleButtonRef.current.focus() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) // Add mouse/touch events to document. const mouseAndTouchTrackersRef = useMouseAndTouchTracker( isOpen,