diff --git a/apps/desktop/src/renderer/src/components/SidePanel.tsx b/apps/desktop/src/renderer/src/components/SidePanel.tsx index 4fe3e93..e4c33da 100644 --- a/apps/desktop/src/renderer/src/components/SidePanel.tsx +++ b/apps/desktop/src/renderer/src/components/SidePanel.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState, type ComponentType, type JSX, type ReactNode } from 'react' -import { LuChevronDown, LuX } from 'react-icons/lu' +import { LuChevronDown, LuPlus, LuX } from 'react-icons/lu' /** * 右侧通用标签面板(TabPanel,ZCode 式)。 @@ -59,6 +59,7 @@ export function SidePanel({ }: SidePanelProps): JSX.Element { const dragRef = useRef<{ startX: number; startWidth: number } | null>(null) const [listOpen, setListOpen] = useState(false) + const [plusOpen, setPlusOpen] = useState(false) const [ctxMenu, setCtxMenu] = useState<{ x: number; y: number; tabId: string } | null>(null) // 面板宽度拖拽(左边缘把手) @@ -85,21 +86,22 @@ export function SidePanel({ // 菜单打开时 Esc 关闭 useEffect(() => { - if (!listOpen && !ctxMenu) return + if (!listOpen && !plusOpen && !ctxMenu) return const onKey = (e: KeyboardEvent): void => { if (e.key === 'Escape') { setListOpen(false) + setPlusOpen(false) setCtxMenu(null) } } window.addEventListener('keydown', onKey) return () => window.removeEventListener('keydown', onKey) - }, [listOpen, ctxMenu]) + }, [listOpen, plusOpen, ctxMenu]) // 覆盖层开合上报(宿主借此暂停原生视图) useEffect(() => { - onOverlayChange?.(listOpen || ctxMenu !== null) - }, [listOpen, ctxMenu, onOverlayChange]) + onOverlayChange?.(listOpen || plusOpen || ctxMenu !== null) + }, [listOpen, plusOpen, ctxMenu, onOverlayChange]) const current = tabs.find((t) => t.id === activeId) ?? tabs[tabs.length - 1] ?? null @@ -196,6 +198,52 @@ export function SidePanel({ )} + {/* 新增标签:列出注册表中的类型,已打开的置灰 */} + {available.length > 0 && ( +