@@ -243,187 +243,189 @@ export function SearchModal({
243243 aria-hidden = { ! open }
244244 />
245245
246- { /* Command palette - only render when open to ensure SVG gradients work */ }
247- { open && (
248- < div
249- role = 'dialog'
250- aria-modal = { true }
251- aria-label = 'Search'
252- className = '-translate-x-1/2 fixed top-[15%] left-1/2 z-50 w-[500px] overflow-hidden rounded-[12px] border border-[var(--border)] bg-[var(--surface-4)] shadow-lg'
253- >
254- < Command label = 'Search' filter = { customFilter } >
255- < Command . Input
256- ref = { inputRef }
257- autoFocus
258- onValueChange = { handleSearchChange }
259- placeholder = 'Search anything...'
260- className = 'w-full border-0 border-[var(--border)] border-b bg-transparent px-[12px] py-[10px] font-base text-[15px] text-[var(--text-primary)] placeholder:text-[var(--text-secondary)] focus:outline-none'
261- />
262- < Command . List className = 'scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent max-h-[400px] overflow-y-auto p-[8px]' >
263- < Command . Empty className = 'flex items-center justify-center px-[16px] py-[24px] text-[15px] text-[var(--text-subtle)]' >
264- No results found.
265- </ Command . Empty >
266-
267- { showBlocks && (
268- < Command . Group heading = 'Blocks' className = { groupHeadingClassName } >
269- { blocks . map ( ( block ) => (
270- < CommandItem
271- key = { block . id }
272- value = { block . name }
273- keywords = { [ block . description ] }
274- onSelect = { ( ) => handleBlockSelect ( block , 'block' ) }
275- icon = { block . icon }
276- bgColor = { block . bgColor }
277- showColoredIcon
278- >
279- { block . name }
280- </ CommandItem >
281- ) ) }
282- </ Command . Group >
283- ) }
284-
285- { showTools && (
286- < Command . Group heading = 'Tools' className = { groupHeadingClassName } >
287- { tools . map ( ( tool ) => (
288- < CommandItem
289- key = { tool . id }
290- value = { tool . name }
291- keywords = { [ tool . description ] }
292- onSelect = { ( ) => handleBlockSelect ( tool , 'tool' ) }
293- icon = { tool . icon }
294- bgColor = { tool . bgColor }
295- showColoredIcon
296- >
297- { tool . name }
298- </ CommandItem >
299- ) ) }
300- </ Command . Group >
301- ) }
302-
303- { showTriggers && (
304- < Command . Group heading = 'Triggers' className = { groupHeadingClassName } >
305- { triggers . map ( ( trigger ) => (
306- < CommandItem
307- key = { trigger . id }
308- value = { trigger . name }
309- keywords = { [ trigger . description ] }
310- onSelect = { ( ) => handleBlockSelect ( trigger , 'trigger' ) }
311- icon = { trigger . icon }
312- bgColor = { trigger . bgColor }
313- showColoredIcon
314- >
315- { trigger . name }
316- </ CommandItem >
317- ) ) }
318- </ Command . Group >
319- ) }
320-
321- { workflows . length > 0 && (
322- < Command . Group heading = 'Workflows' className = { groupHeadingClassName } >
323- { workflows . map ( ( workflow ) => (
324- < Command . Item
325- key = { workflow . id }
326- value = { workflow . name }
327- onSelect = { ( ) => handleWorkflowSelect ( workflow ) }
328- className = 'group flex h-[28px] w-full cursor-pointer items-center gap-[8px] rounded-[6px] px-[10px] text-left text-[15px] aria-selected:bg-[var(--border)] aria-selected:shadow-sm data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50'
329- >
330- < div
331- className = 'h-[14px] w-[14px] flex-shrink-0 rounded-[3px]'
332- style = { { backgroundColor : workflow . color } }
333- />
334- < span className = 'truncate font-medium text-[var(--text-tertiary)] group-aria-selected:text-[var(--text-primary)]' >
335- { workflow . name }
336- { workflow . isCurrent && ' (current)' }
337- </ span >
338- </ Command . Item >
339- ) ) }
340- </ Command . Group >
341- ) }
342-
343- { showToolOperations && (
344- < Command . Group heading = 'Tool Operations' className = { groupHeadingClassName } >
345- { toolOperations . map ( ( op ) => (
346- < CommandItem
347- key = { op . id }
348- value = { op . searchValue }
349- keywords = { op . keywords }
350- onSelect = { ( ) => handleToolOperationSelect ( op ) }
351- icon = { op . icon }
352- bgColor = { op . bgColor }
353- showColoredIcon
354- >
355- { op . name }
356- </ CommandItem >
357- ) ) }
358- </ Command . Group >
359- ) }
360-
361- { workspaces . length > 0 && (
362- < Command . Group heading = 'Workspaces' className = { groupHeadingClassName } >
363- { workspaces . map ( ( workspace ) => (
246+ { /* Command palette - always rendered for instant opening, hidden with CSS */ }
247+ < div
248+ role = 'dialog'
249+ aria-modal = { open }
250+ aria-hidden = { ! open }
251+ aria-label = 'Search'
252+ className = { cn (
253+ '-translate-x-1/2 fixed top-[15%] left-1/2 z-50 w-[500px] overflow-hidden rounded-[12px] border border-[var(--border)] bg-[var(--surface-4)] shadow-lg' ,
254+ open ? 'visible opacity-100' : 'invisible opacity-0'
255+ ) }
256+ >
257+ < Command label = 'Search' filter = { customFilter } >
258+ < Command . Input
259+ ref = { inputRef }
260+ autoFocus
261+ onValueChange = { handleSearchChange }
262+ placeholder = 'Search anything...'
263+ className = 'w-full border-0 border-[var(--border)] border-b bg-transparent px-[12px] py-[10px] font-base text-[15px] text-[var(--text-primary)] placeholder:text-[var(--text-secondary)] focus:outline-none'
264+ />
265+ < Command . List className = 'scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent max-h-[400px] overflow-y-auto p-[8px]' >
266+ < Command . Empty className = 'flex items-center justify-center px-[16px] py-[24px] text-[15px] text-[var(--text-subtle)]' >
267+ No results found.
268+ </ Command . Empty >
269+
270+ { showBlocks && (
271+ < Command . Group heading = 'Blocks' className = { groupHeadingClassName } >
272+ { blocks . map ( ( block ) => (
273+ < CommandItem
274+ key = { block . id }
275+ value = { block . name }
276+ keywords = { [ block . description ] }
277+ onSelect = { ( ) => handleBlockSelect ( block , 'block' ) }
278+ icon = { block . icon }
279+ bgColor = { block . bgColor }
280+ showColoredIcon
281+ >
282+ { block . name }
283+ </ CommandItem >
284+ ) ) }
285+ </ Command . Group >
286+ ) }
287+
288+ { showTools && (
289+ < Command . Group heading = 'Tools' className = { groupHeadingClassName } >
290+ { tools . map ( ( tool ) => (
291+ < CommandItem
292+ key = { tool . id }
293+ value = { tool . name }
294+ keywords = { [ tool . description ] }
295+ onSelect = { ( ) => handleBlockSelect ( tool , 'tool' ) }
296+ icon = { tool . icon }
297+ bgColor = { tool . bgColor }
298+ showColoredIcon
299+ >
300+ { tool . name }
301+ </ CommandItem >
302+ ) ) }
303+ </ Command . Group >
304+ ) }
305+
306+ { showTriggers && (
307+ < Command . Group heading = 'Triggers' className = { groupHeadingClassName } >
308+ { triggers . map ( ( trigger ) => (
309+ < CommandItem
310+ key = { trigger . id }
311+ value = { trigger . name }
312+ keywords = { [ trigger . description ] }
313+ onSelect = { ( ) => handleBlockSelect ( trigger , 'trigger' ) }
314+ icon = { trigger . icon }
315+ bgColor = { trigger . bgColor }
316+ showColoredIcon
317+ >
318+ { trigger . name }
319+ </ CommandItem >
320+ ) ) }
321+ </ Command . Group >
322+ ) }
323+
324+ { workflows . length > 0 && (
325+ < Command . Group heading = 'Workflows' className = { groupHeadingClassName } >
326+ { workflows . map ( ( workflow ) => (
327+ < Command . Item
328+ key = { workflow . id }
329+ value = { workflow . name }
330+ onSelect = { ( ) => handleWorkflowSelect ( workflow ) }
331+ className = 'group flex h-[28px] w-full cursor-pointer items-center gap-[8px] rounded-[6px] px-[10px] text-left text-[15px] aria-selected:bg-[var(--border)] aria-selected:shadow-sm data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50'
332+ >
333+ < div
334+ className = 'h-[14px] w-[14px] flex-shrink-0 rounded-[3px]'
335+ style = { { backgroundColor : workflow . color } }
336+ />
337+ < span className = 'truncate font-medium text-[var(--text-tertiary)] group-aria-selected:text-[var(--text-primary)]' >
338+ { workflow . name }
339+ { workflow . isCurrent && ' (current)' }
340+ </ span >
341+ </ Command . Item >
342+ ) ) }
343+ </ Command . Group >
344+ ) }
345+
346+ { showToolOperations && (
347+ < Command . Group heading = 'Tool Operations' className = { groupHeadingClassName } >
348+ { toolOperations . map ( ( op ) => (
349+ < CommandItem
350+ key = { op . id }
351+ value = { op . searchValue }
352+ keywords = { op . keywords }
353+ onSelect = { ( ) => handleToolOperationSelect ( op ) }
354+ icon = { op . icon }
355+ bgColor = { op . bgColor }
356+ showColoredIcon
357+ >
358+ { op . name }
359+ </ CommandItem >
360+ ) ) }
361+ </ Command . Group >
362+ ) }
363+
364+ { workspaces . length > 0 && (
365+ < Command . Group heading = 'Workspaces' className = { groupHeadingClassName } >
366+ { workspaces . map ( ( workspace ) => (
367+ < Command . Item
368+ key = { workspace . id }
369+ value = { workspace . name }
370+ onSelect = { ( ) => handleWorkspaceSelect ( workspace ) }
371+ className = 'group flex h-[28px] w-full cursor-pointer items-center gap-[8px] rounded-[6px] px-[10px] text-left text-[15px] aria-selected:bg-[var(--border)] aria-selected:shadow-sm data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50'
372+ >
373+ < span className = 'truncate font-medium text-[var(--text-tertiary)] group-aria-selected:text-[var(--text-primary)]' >
374+ { workspace . name }
375+ { workspace . isCurrent && ' (current)' }
376+ </ span >
377+ </ Command . Item >
378+ ) ) }
379+ </ Command . Group >
380+ ) }
381+
382+ { showDocs && (
383+ < Command . Group heading = 'Docs' className = { groupHeadingClassName } >
384+ { docs . map ( ( doc ) => (
385+ < CommandItem
386+ key = { doc . id }
387+ value = { `${ doc . name } docs documentation` }
388+ onSelect = { ( ) => handleDocSelect ( doc ) }
389+ icon = { doc . icon }
390+ bgColor = '#6B7280'
391+ showColoredIcon
392+ >
393+ { doc . name }
394+ </ CommandItem >
395+ ) ) }
396+ </ Command . Group >
397+ ) }
398+
399+ { pages . length > 0 && (
400+ < Command . Group heading = 'Pages' className = { groupHeadingClassName } >
401+ { pages . map ( ( page ) => {
402+ const Icon = page . icon
403+ return (
364404 < Command . Item
365- key = { workspace . id }
366- value = { workspace . name }
367- onSelect = { ( ) => handleWorkspaceSelect ( workspace ) }
405+ key = { page . id }
406+ value = { page . name }
407+ onSelect = { ( ) => handlePageSelect ( page ) }
368408 className = 'group flex h-[28px] w-full cursor-pointer items-center gap-[8px] rounded-[6px] px-[10px] text-left text-[15px] aria-selected:bg-[var(--border)] aria-selected:shadow-sm data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50'
369409 >
410+ < div className = 'relative flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center' >
411+ < Icon className = 'h-[14px] w-[14px] text-[var(--text-tertiary)] group-aria-selected:text-[var(--text-primary)]' />
412+ </ div >
370413 < span className = 'truncate font-medium text-[var(--text-tertiary)] group-aria-selected:text-[var(--text-primary)]' >
371- { workspace . name }
372- { workspace . isCurrent && ' (current)' }
414+ { page . name }
373415 </ span >
374- </ Command . Item >
375- ) ) }
376- </ Command . Group >
377- ) }
378-
379- { showDocs && (
380- < Command . Group heading = 'Docs' className = { groupHeadingClassName } >
381- { docs . map ( ( doc ) => (
382- < CommandItem
383- key = { doc . id }
384- value = { `${ doc . name } docs documentation` }
385- onSelect = { ( ) => handleDocSelect ( doc ) }
386- icon = { doc . icon }
387- bgColor = '#6B7280'
388- showColoredIcon
389- >
390- { doc . name }
391- </ CommandItem >
392- ) ) }
393- </ Command . Group >
394- ) }
395-
396- { pages . length > 0 && (
397- < Command . Group heading = 'Pages' className = { groupHeadingClassName } >
398- { pages . map ( ( page ) => {
399- const Icon = page . icon
400- return (
401- < Command . Item
402- key = { page . id }
403- value = { page . name }
404- onSelect = { ( ) => handlePageSelect ( page ) }
405- className = 'group flex h-[28px] w-full cursor-pointer items-center gap-[8px] rounded-[6px] px-[10px] text-left text-[15px] aria-selected:bg-[var(--border)] aria-selected:shadow-sm data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50'
406- >
407- < div className = 'relative flex h-[16px] w-[16px] flex-shrink-0 items-center justify-center' >
408- < Icon className = 'h-[14px] w-[14px] text-[var(--text-tertiary)] group-aria-selected:text-[var(--text-primary)]' />
409- </ div >
410- < span className = 'truncate font-medium text-[var(--text-tertiary)] group-aria-selected:text-[var(--text-primary)]' >
411- { page . name }
416+ { page . shortcut && (
417+ < span className = 'ml-auto flex-shrink-0 font-medium text-[13px] text-[var(--text-subtle)]' >
418+ { page . shortcut }
412419 </ span >
413- { page . shortcut && (
414- < span className = 'ml-auto flex-shrink-0 font-medium text-[13px] text-[var(--text-subtle)]' >
415- { page . shortcut }
416- </ span >
417- ) }
418- </ Command . Item >
419- )
420- } ) }
421- </ Command . Group >
422- ) }
423- </ Command . List >
424- </ Command >
425- </ div >
426- ) }
420+ ) }
421+ </ Command . Item >
422+ )
423+ } ) }
424+ </ Command . Group >
425+ ) }
426+ </ Command . List >
427+ </ Command >
428+ </ div >
427429 </ > ,
428430 document . body
429431 )
0 commit comments