UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

1 lines 3.18 kB
{"version":3,"file":"useKeyboardNavigation.mjs","names":[],"sources":["../../src/EditorSlashMenu/useKeyboardNavigation.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\nimport { isEditableTarget } from './utils';\n\ninterface UseKeyboardNavigationProps {\n isOpen: boolean;\n}\n\nexport const useKeyboardNavigation = ({ isOpen }: UseKeyboardNavigationProps) => {\n const listRef = useRef<HTMLDivElement | null>(null);\n\n const dispatchListKey = useCallback((key: string) => {\n const list = listRef.current;\n if (!list) return;\n const event = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, key });\n list.dispatchEvent(event);\n }, []);\n\n // Auto-highlight first item when menu opens\n useEffect(() => {\n if (!isOpen) return;\n const raf = requestAnimationFrame(() => {\n const list = listRef.current;\n if (!list) return;\n if (list.querySelector('[data-highlighted]')) return;\n if (!list.querySelector('[role=\"option\"]')) return;\n dispatchListKey('ArrowDown');\n });\n return () => cancelAnimationFrame(raf);\n }, [dispatchListKey, isOpen]);\n\n // Global keyboard navigation when menu is open\n useEffect(() => {\n if (!isOpen) return;\n const handleKeyDown = (event: KeyboardEvent) => {\n if (!event.isTrusted) return;\n const list = listRef.current;\n if (!list) return;\n if (event.metaKey || event.ctrlKey || event.altKey) return;\n const target = event.target as HTMLElement | null;\n if (!isEditableTarget(target) || list.contains(target)) return;\n if (!list.querySelector('[role=\"option\"]')) return;\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp' && event.key !== 'Enter') return;\n if (event.key === 'Enter' && !list.querySelector('[data-highlighted]')) return;\n event.preventDefault();\n dispatchListKey(event.key);\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [dispatchListKey, isOpen]);\n\n return { listRef };\n};\n"],"mappings":";;;AAQA,MAAa,yBAAyB,EAAE,aAAyC;CAC/E,MAAM,UAAU,OAA8B,IAAI;CAElD,MAAM,kBAAkB,aAAa,QAAgB;EACnD,MAAM,OAAO,QAAQ;EACrB,IAAI,CAAC,MAAM;EACX,MAAM,QAAQ,IAAI,cAAc,WAAW;GAAE,SAAS;GAAM,YAAY;GAAM;EAAI,CAAC;EACnF,KAAK,cAAc,KAAK;CAC1B,GAAG,CAAC,CAAC;CAGL,gBAAgB;EACd,IAAI,CAAC,QAAQ;EACb,MAAM,MAAM,4BAA4B;GACtC,MAAM,OAAO,QAAQ;GACrB,IAAI,CAAC,MAAM;GACX,IAAI,KAAK,cAAc,oBAAoB,GAAG;GAC9C,IAAI,CAAC,KAAK,cAAc,mBAAiB,GAAG;GAC5C,gBAAgB,WAAW;EAC7B,CAAC;EACD,aAAa,qBAAqB,GAAG;CACvC,GAAG,CAAC,iBAAiB,MAAM,CAAC;CAG5B,gBAAgB;EACd,IAAI,CAAC,QAAQ;EACb,MAAM,iBAAiB,UAAyB;GAC9C,IAAI,CAAC,MAAM,WAAW;GACtB,MAAM,OAAO,QAAQ;GACrB,IAAI,CAAC,MAAM;GACX,IAAI,MAAM,WAAW,MAAM,WAAW,MAAM,QAAQ;GACpD,MAAM,SAAS,MAAM;GACrB,IAAI,CAAC,iBAAiB,MAAM,KAAK,KAAK,SAAS,MAAM,GAAG;GACxD,IAAI,CAAC,KAAK,cAAc,mBAAiB,GAAG;GAC5C,IAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,aAAa,MAAM,QAAQ,SAAS;GACnF,IAAI,MAAM,QAAQ,WAAW,CAAC,KAAK,cAAc,oBAAoB,GAAG;GACxE,MAAM,eAAe;GACrB,gBAAgB,MAAM,GAAG;EAC3B;EACA,SAAS,iBAAiB,WAAW,aAAa;EAClD,aAAa,SAAS,oBAAoB,WAAW,aAAa;CACpE,GAAG,CAAC,iBAAiB,MAAM,CAAC;CAE5B,OAAO,EAAE,QAAQ;AACnB"}