UNPKG

@lobehub/ui

Version:

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

1 lines 3.15 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,KAAK;CAEnD,MAAM,kBAAkB,aAAa,QAAgB;EACnD,MAAM,OAAO,QAAQ;AACrB,MAAI,CAAC,KAAM;EACX,MAAM,QAAQ,IAAI,cAAc,WAAW;GAAE,SAAS;GAAM,YAAY;GAAM;GAAK,CAAC;AACpF,OAAK,cAAc,MAAM;IACxB,EAAE,CAAC;AAGN,iBAAgB;AACd,MAAI,CAAC,OAAQ;EACb,MAAM,MAAM,4BAA4B;GACtC,MAAM,OAAO,QAAQ;AACrB,OAAI,CAAC,KAAM;AACX,OAAI,KAAK,cAAc,qBAAqB,CAAE;AAC9C,OAAI,CAAC,KAAK,cAAc,oBAAkB,CAAE;AAC5C,mBAAgB,YAAY;IAC5B;AACF,eAAa,qBAAqB,IAAI;IACrC,CAAC,iBAAiB,OAAO,CAAC;AAG7B,iBAAgB;AACd,MAAI,CAAC,OAAQ;EACb,MAAM,iBAAiB,UAAyB;AAC9C,OAAI,CAAC,MAAM,UAAW;GACtB,MAAM,OAAO,QAAQ;AACrB,OAAI,CAAC,KAAM;AACX,OAAI,MAAM,WAAW,MAAM,WAAW,MAAM,OAAQ;GACpD,MAAM,SAAS,MAAM;AACrB,OAAI,CAAC,iBAAiB,OAAO,IAAI,KAAK,SAAS,OAAO,CAAE;AACxD,OAAI,CAAC,KAAK,cAAc,oBAAkB,CAAE;AAC5C,OAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,aAAa,MAAM,QAAQ,QAAS;AACnF,OAAI,MAAM,QAAQ,WAAW,CAAC,KAAK,cAAc,qBAAqB,CAAE;AACxE,SAAM,gBAAgB;AACtB,mBAAgB,MAAM,IAAI;;AAE5B,WAAS,iBAAiB,WAAW,cAAc;AACnD,eAAa,SAAS,oBAAoB,WAAW,cAAc;IAClE,CAAC,iBAAiB,OAAO,CAAC;AAE7B,QAAO,EAAE,SAAS"}