import React, { useEffect, useRef } from 'react'; import * as cn from "./SearchButton.styles"; interface SearchButtonProps { onClick?: () => void; placeholder?: string; shortcutKeys?: string[]; fullWidth?: boolean; } export function SearchButton({ shortcutKeys = ['⌘', 'K'], ...props }: SearchButtonProps) { useShortcuts(shortcutKeys, () => props.onClick?.()); useEffect(() => { // @ts-ignore - !!! FIX IN THE FUTURE !!! its a fix for loading virtual-component:Search twice? original and from plugin - check if exists on prod window.__UNSAFE_xyd_search_button_inited = true return () => { // @ts-ignore window.__UNSAFE_xyd_search_button_inited = false } }, []) return ( {props.placeholder || "Search"} { shortcutKeys.length > 0 && ( {shortcutKeys.map((key, index) => ( {key} ))} ) } ) } function useShortcuts(shortcutKeys: string[], onTrigger: () => void): void { // Keep latest handler reference to avoid stale closures const savedHandler = useRef(onTrigger); useEffect(() => { savedHandler.current = onTrigger; }, [onTrigger]); useEffect(() => { // @ts-ignore if (window.__UNSAFE_xyd_search_button_inited) { return } const listener = (event: KeyboardEvent) => { // For single key shortcuts if (shortcutKeys.length === 1) { if (event.key.toLowerCase() === shortcutKeys[0].toLowerCase()) { event.preventDefault(); savedHandler.current(); } return; } // For modifier combinations if (shortcutKeys.length === 2) { const [modifier, key] = shortcutKeys; const pressedKey = event.key.toLowerCase(); const isModifierMatch = (modifier === '⌘' && event.metaKey) || (modifier === 'Ctrl' && event.ctrlKey); if (isModifierMatch && pressedKey === key.toLowerCase()) { event.preventDefault(); savedHandler.current(); } } }; // Use capture phase and listen to both keydown and keyup window.addEventListener('keydown', listener, { capture: true }); window.addEventListener('keyup', listener, { capture: true }); return () => { window.removeEventListener('keydown', listener, { capture: true }); window.removeEventListener('keyup', listener, { capture: true }); }; }, []); }