diff --git a/packages/dnb-eufemia/src/components/help-button/HelpButtonInline.tsx b/packages/dnb-eufemia/src/components/help-button/HelpButtonInline.tsx index 73f6906320d..2a616cffd3d 100644 --- a/packages/dnb-eufemia/src/components/help-button/HelpButtonInline.tsx +++ b/packages/dnb-eufemia/src/components/help-button/HelpButtonInline.tsx @@ -138,13 +138,23 @@ export function HelpButtonInlineContent( update({ isOpen: false, isUserIntent: false }) }, [update]) - const keydownHandler = useCallback( - (event) => { - switch (event.code) { - case 'Escape': - onClose() - buttonRef.current?.focus() - break + const onKeyDown = useCallback( + (event: React.KeyboardEvent) => { + if (event.currentTarget === event.target) { + // Firefox returns a whitespace (" ") on event.key when pressing space, + // therefore using .trim() can help normalize this. + // While userEvent.keyboard('{Space}') might return 'Unknown' on event.code, + // making a direct comparison less reliable across all platforms. + switch (event.key.trim() || event.code) { + case 'Enter': + case 'Space': + case 'Escape': + window.requestAnimationFrame(() => { + onClose() + buttonRef.current?.focus() + }) + break + } } }, [buttonRef, onClose] @@ -175,7 +185,7 @@ export function HelpButtonInlineContent( className="dnb-no-focus" tabIndex={-1} innerRef={innerRef} - onKeyDown={keydownHandler} + onKeyDown={onKeyDown} breakout={breakoutFromLayout} roundedCorner={!breakoutFromLayout} innerSpace={ diff --git a/packages/dnb-eufemia/src/components/help-button/__tests__/HelpButtonInline.test.tsx b/packages/dnb-eufemia/src/components/help-button/__tests__/HelpButtonInline.test.tsx index e86ba84ef16..f94dcb1bb09 100644 --- a/packages/dnb-eufemia/src/components/help-button/__tests__/HelpButtonInline.test.tsx +++ b/packages/dnb-eufemia/src/components/help-button/__tests__/HelpButtonInline.test.tsx @@ -28,13 +28,58 @@ describe('HelpButtonInline', () => { it('should toggle open state when Space key gets pressed', async () => { render() - const button = document.querySelector('button') + expect(document.body).toHaveFocus() - await userEvent.type(button, '{Space}') - expect(button).toHaveClass('dnb-help-button__inline--open') + await userEvent.tab() + expect(document.querySelector('button')).toHaveFocus() - await userEvent.type(button, '{Space}') - expect(button).not.toHaveClass('dnb-help-button__inline--open') + await userEvent.type(document.querySelector('button'), '{Space}') + await waitFor(() => { + expect(document.querySelector('section')).toHaveFocus() + }) + + await userEvent.keyboard('{Space}') + await waitFor(() => { + expect(document.querySelector('button')).toHaveFocus() + }) + }) + + it('should toggle open state when Enter key gets pressed', async () => { + render() + + expect(document.body).toHaveFocus() + + await userEvent.tab() + expect(document.querySelector('button')).toHaveFocus() + + await userEvent.keyboard('{Enter}') + await waitFor(() => { + expect(document.querySelector('section')).toHaveFocus() + }) + + await userEvent.keyboard('{Enter}') + await waitFor(() => { + expect(document.querySelector('button')).toHaveFocus() + }) + }) + + it('should set focus on the button when closing with Escape key', async () => { + render() + + expect(document.body).toHaveFocus() + + await userEvent.tab() + expect(document.querySelector('button')).toHaveFocus() + + await userEvent.keyboard('{Enter}') + await waitFor(() => { + expect(document.querySelector('section')).toHaveFocus() + }) + + await userEvent.keyboard('{Escape}') + await waitFor(() => { + expect(document.querySelector('button')).toHaveFocus() + }) }) it('should close when Escape key on the button gets pressed', async () => { @@ -161,7 +206,7 @@ describe('HelpButtonInline', () => { }) it('should set focus on the content when open', async () => { - render() + render() expect(document.body).toHaveFocus() @@ -185,27 +230,8 @@ describe('HelpButtonInline', () => { }) }) - it('should set focus on the button when closing with Escape key', async () => { - render() - - expect(document.body).toHaveFocus() - - await userEvent.tab() - expect(document.querySelector('button')).toHaveFocus() - - await userEvent.keyboard('{Enter}') - await waitFor(() => { - expect(document.querySelector('section')).toHaveFocus() - }) - - await userEvent.keyboard('{Escape}') - expect(document.querySelector('button')).toHaveFocus() - }) - it('should not set focus on the content when open is true', async () => { - render( - - ) + render() expect(document.body).toHaveFocus()