export function isTypingTarget(target: EventTarget | null) { if (!(target instanceof HTMLElement)) { return false; } return Boolean(target.closest('input, textarea, select, [contenteditable="true"], .ant-input, .ant-select')); } export function matchesShortcut(event: KeyboardEvent, shortcut: string) { const tokens = shortcut .split('+') .map((token) => token.trim().toLowerCase()) .filter(Boolean); if (tokens.length === 0) { return false; } const expectsCtrl = tokens.includes('ctrl') || tokens.includes('control'); const expectsMeta = tokens.includes('meta') || tokens.includes('cmd') || tokens.includes('command'); const expectsShift = tokens.includes('shift'); const expectsAlt = tokens.includes('alt') || tokens.includes('option'); const expectsMod = tokens.includes('mod'); const keyToken = tokens.find((token) => !['ctrl', 'control', 'meta', 'cmd', 'command', 'shift', 'alt', 'option', 'mod'].includes(token)); if (event.ctrlKey !== expectsCtrl && !(expectsMod && event.ctrlKey && !event.metaKey)) { return false; } if (event.metaKey !== expectsMeta && !(expectsMod && event.metaKey && !event.ctrlKey)) { return false; } if (event.shiftKey !== expectsShift || event.altKey !== expectsAlt) { return false; } if (!expectsCtrl && !expectsMeta && !expectsMod && (event.ctrlKey || event.metaKey)) { return false; } if (!keyToken) { return expectsCtrl || expectsMeta || expectsMod || expectsShift || expectsAlt; } return event.key.toLowerCase() === keyToken; } export function scrollToElement(elementId: string) { window.setTimeout(() => { document.getElementById(elementId)?.scrollIntoView({ block: 'start', behavior: 'smooth', }); }, 80); } export function compactKeywords(values: Array) { return values.filter((value): value is string => Boolean(value)); }