|
1 | | -import { useEffect, useMemo, useState } from "react"; |
| 1 | +import { useEffect, useMemo, useRef, useState } from "react"; |
2 | 2 |
|
3 | 3 | import { Lightning } from "@corbits/icons"; |
4 | 4 | import { EmptyState, FilterChip, Tabs } from "@corbits/react-ui"; |
@@ -133,6 +133,7 @@ function PluginCatalogPanel({ |
133 | 133 | readonly onOpenPreset: ( |
134 | 134 | preset: McpPreset, |
135 | 135 | toolCount: number | undefined, |
| 136 | + trigger: HTMLButtonElement, |
136 | 137 | ) => void; |
137 | 138 | readonly onOpenPlugin: (plugin: ResolvedPlugin) => void; |
138 | 139 | }) { |
@@ -181,8 +182,8 @@ function PluginCatalogPanel({ |
181 | 182 | preset={entry.preset} |
182 | 183 | toolCount={toolCounts.get(entry.id)} |
183 | 184 | onChanged={(toolCount) => onPresetChanged(entry.id, toolCount)} |
184 | | - onOpen={() => |
185 | | - onOpenPreset(entry.preset, toolCounts.get(entry.id)) |
| 185 | + onOpen={(trigger) => |
| 186 | + onOpenPreset(entry.preset, toolCounts.get(entry.id), trigger) |
186 | 187 | } |
187 | 188 | /> |
188 | 189 | ) : ( |
@@ -296,9 +297,22 @@ export function PluginsGallery({ |
296 | 297 | const [openPreset, setOpenPreset] = useState<{ |
297 | 298 | readonly preset: McpPreset; |
298 | 299 | readonly toolCount: number | undefined; |
| 300 | + readonly trigger: HTMLButtonElement; |
299 | 301 | } | null>(null); |
| 302 | + const presetFocusTrigger = useRef<HTMLButtonElement | null>(null); |
300 | 303 | const presetCatalog = useMcpPresetCatalog(tenantId); |
301 | 304 |
|
| 305 | + useEffect(() => { |
| 306 | + if (openPreset !== null) return; |
| 307 | + presetFocusTrigger.current?.focus(); |
| 308 | + presetFocusTrigger.current = null; |
| 309 | + }, [openPreset]); |
| 310 | + |
| 311 | + function closePreset() { |
| 312 | + presetFocusTrigger.current = openPreset?.trigger ?? null; |
| 313 | + setOpenPreset(null); |
| 314 | + } |
| 315 | + |
302 | 316 | const nativeEntries = useMemo<readonly PluginCatalogEntry[]>( |
303 | 317 | () => |
304 | 318 | plugins |
@@ -398,8 +412,8 @@ export function PluginsGallery({ |
398 | 412 | onFilterChange={setActiveFilter} |
399 | 413 | toolCounts={presetCatalog.toolCounts} |
400 | 414 | onPresetChanged={presetCatalog.handleChanged} |
401 | | - onOpenPreset={(preset, toolCount) => |
402 | | - setOpenPreset({ preset, toolCount }) |
| 415 | + onOpenPreset={(preset, toolCount, trigger) => |
| 416 | + setOpenPreset({ preset, toolCount, trigger }) |
403 | 417 | } |
404 | 418 | onOpenPlugin={onOpenPlugin} |
405 | 419 | /> |
@@ -427,11 +441,11 @@ export function PluginsGallery({ |
427 | 441 | toolCount: openPreset.toolCount, |
428 | 442 | } |
429 | 443 | } |
430 | | - onClose={() => setOpenPreset(null)} |
| 444 | + onClose={closePreset} |
431 | 445 | onChanged={(toolCount) => { |
432 | 446 | if (openPreset === null) return; |
433 | 447 | presetCatalog.handleChanged(openPreset.preset.slug, toolCount); |
434 | | - setOpenPreset(null); |
| 448 | + closePreset(); |
435 | 449 | }} |
436 | 450 | /> |
437 | 451 | </div> |
|
0 commit comments