From ed89305e1ae8cf1784ec093f36da080330c89362 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Mon, 11 Nov 2024 12:21:06 +0100 Subject: [PATCH] refactor: cleanup implementation --- .../Accessibility/React/InsertMenu.tsx | 11 +- .../Examples/Accessibility/React/MenuBar.tsx | 22 ++- .../Examples/Accessibility/React/TextMenu.tsx | 9 +- .../Accessibility/React/useFocusMenubar.ts | 163 ------------------ .../Accessibility/React/useMenubarNav.ts | 128 ++++++++++++++ 5 files changed, 157 insertions(+), 176 deletions(-) delete mode 100644 demos/src/Examples/Accessibility/React/useFocusMenubar.ts create mode 100644 demos/src/Examples/Accessibility/React/useMenubarNav.ts diff --git a/demos/src/Examples/Accessibility/React/InsertMenu.tsx b/demos/src/Examples/Accessibility/React/InsertMenu.tsx index 957c9aff4..382b89c7f 100644 --- a/demos/src/Examples/Accessibility/React/InsertMenu.tsx +++ b/demos/src/Examples/Accessibility/React/InsertMenu.tsx @@ -1,7 +1,7 @@ import { Editor, FloatingMenu, useEditorState } from '@tiptap/react' import React, { useRef } from 'react' -import { useFocusMenubar } from './useFocusMenubar.js' +import { useMenubarNav } from './useMenubarNav.js' /** * A floating menu for inserting new elements like lists, horizontal rules, etc. @@ -21,10 +21,11 @@ export function InsertMenu({ editor }: { editor: Editor }) { }) // Handle arrow navigation within a menu bar container, and allow to escape to the editor - const { focusButton } = useFocusMenubar({ + const { getFocusableElements } = useMenubarNav({ editor, ref: containerRef, - onEscape: () => { + onEscape: e => { + e.preventDefault() // On escape, focus the editor editor.chain().focus().run() }, @@ -43,8 +44,8 @@ export function InsertMenu({ editor }: { editor: Editor }) { onFocus={e => { // The ref we have is to the container, not the menu itself if (containerRef.current === e.target?.parentNode) { - // Focus the first button when the menu bar is focused - focusButton(containerRef.current?.querySelector('button')) + // Focus the first enabled button-like when the menu bar is focused + getFocusableElements()?.[0]?.focus() } }} tabIndex={0} diff --git a/demos/src/Examples/Accessibility/React/MenuBar.tsx b/demos/src/Examples/Accessibility/React/MenuBar.tsx index 00495cfd0..b2473125f 100644 --- a/demos/src/Examples/Accessibility/React/MenuBar.tsx +++ b/demos/src/Examples/Accessibility/React/MenuBar.tsx @@ -2,7 +2,7 @@ import { Editor } from '@tiptap/core' import { useEditorState } from '@tiptap/react' import React, { useEffect, useRef, useState } from 'react' -import { useFocusMenubar } from './useFocusMenubar.js' +import { useMenubarNav } from './useMenubarNav.js' /** * Handles the heading dropdown @@ -48,10 +48,24 @@ function NodeTypeDropdown({ editor }: { editor: Editor }) { }, []) return ( -
+
{ + // Escape or tab should close the dropdown if it's open + if (isOpen && (e.key === 'Escape' || e.key === 'Tab')) { + setIsOpen(false) + if (e.key === 'Escape') { + // Prevent the editor from handling the escape key + e.preventDefault() + } + } + }} + >