diff --git a/components/label/LabelNossr.tsx b/components/label/LabelNossr.tsx index f902128..3db5960 100644 --- a/components/label/LabelNossr.tsx +++ b/components/label/LabelNossr.tsx @@ -55,7 +55,7 @@ import { useTimerStore, } from "./useTimerStore" import { useTopToolsStore } from "./useTopToolsStore" -import { findGroupKey } from "./util" +import { findGroupKey, isEditableKeyboardTarget } from "./util" import { safeClone } from "./utils/clone" import { labelTypeMap } from "./utils/constants" import { toggleObjectHideByShortcut } from "./utils/objectVisibility" @@ -2164,7 +2164,7 @@ const LabelPage = ({ useEffect(() => { const down = (e: KeyboardEvent) => { // console.log(e, e.key); - if (focusInput) return + if (focusInput || isEditableKeyboardTarget(e.target)) return console.log(e.key) const mode = usePaperStore.getState().mode diff --git a/components/label/util.ts b/components/label/util.ts index 8cd3855..3e0bce3 100644 --- a/components/label/util.ts +++ b/components/label/util.ts @@ -1,5 +1,71 @@ import { Project } from "./api/project/typing" +const nonEditableInputTypes = new Set([ + "button", + "checkbox", + "color", + "file", + "hidden", + "image", + "radio", + "range", + "reset", + "submit", +]) + +const editableRoles = new Set([ + "textbox", + "searchbox", + "combobox", + "spinbutton", +]) + +const resolveTargetElement = (target: EventTarget | null) => { + if (target instanceof Element) return target + if (target instanceof Node) return target.parentElement + return null +} + +export const isEditableKeyboardTarget = (target: EventTarget | null) => { + const element = resolveTargetElement(target) + if (!element) return false + + const editableElement = element.closest( + [ + "input", + "textarea", + "select", + "[contenteditable='']", + "[contenteditable='true']", + "[role='textbox']", + "[role='searchbox']", + "[role='combobox']", + "[role='spinbutton']", + ].join(",") + ) + + if (!editableElement) return false + + if (editableElement instanceof HTMLInputElement) { + return !nonEditableInputTypes.has(editableElement.type.toLowerCase()) + } + + if ( + editableElement instanceof HTMLTextAreaElement || + editableElement instanceof HTMLSelectElement + ) { + return true + } + + if (editableElement instanceof HTMLElement) { + if (editableElement.isContentEditable) return true + const role = editableElement.getAttribute("role") + return role ? editableRoles.has(role) : false + } + + return false +} + // 是否存在不符合要求的子属性 export const getSubAttrStatus = ( operationSchema: Project.LabelSchemaList | null,