diff --git a/vscode/package.json b/vscode/package.json
index 6f606e9..62a0601 100644
--- a/vscode/package.json
+++ b/vscode/package.json
@@ -2,7 +2,7 @@
"publisher": "clurdra",
"name": "superpowers-vscode-clurdra",
"displayName": "Superpowers-clurdra",
- "version": "0.2.97",
+ "version": "0.2.98",
"packageManager": "pnpm@10.27.0",
"description": "Superpowers specs and plans Kanban explorer",
"author": "clurdra",
diff --git a/vscode/webview-ui/src/components/ManagedSessionsPanel.tsx b/vscode/webview-ui/src/components/ManagedSessionsPanel.tsx
index a246a7d..79ead17 100644
--- a/vscode/webview-ui/src/components/ManagedSessionsPanel.tsx
+++ b/vscode/webview-ui/src/components/ManagedSessionsPanel.tsx
@@ -145,15 +145,16 @@ export function ManagedSessionsPanel({
Profile
-
({ value: p.path, label: p.name }))}
- variant="input"
- className="min-w-0 flex-1"
- />
+
+ ({ value: p.path, label: p.name }))}
+ variant="input"
+ />
+
名字
diff --git a/vscode/webview-ui/src/components/ui/select-menu.tsx b/vscode/webview-ui/src/components/ui/select-menu.tsx
index 128e6f8..8d981f3 100644
--- a/vscode/webview-ui/src/components/ui/select-menu.tsx
+++ b/vscode/webview-ui/src/components/ui/select-menu.tsx
@@ -22,6 +22,25 @@ export interface SelectMenuProps {
}
const MAX_MENU_HEIGHT = 240
+/** 勾选图标 + gap + 水平 padding + 竖滚动条槽。少算会把最后几个字挤成省略号。 */
+const MENU_CHROME_PX = 14 + 6 + 16 + 12
+
+function measureOptionsWidth(options: SelectMenuOption[], font: string): number {
+ const probe = document.createElement('span')
+ probe.style.cssText = `position:absolute;left:-9999px;top:0;white-space:nowrap;font:${font}`
+ document.body.appendChild(probe)
+ let max = 0
+ for (const o of options) {
+ probe.textContent = o.label
+ max = Math.max(max, probe.offsetWidth)
+ if (o.hint) {
+ probe.textContent = o.hint
+ max = Math.max(max, probe.offsetWidth)
+ }
+ }
+ probe.remove()
+ return max
+}
/**
* 自定义下拉组件,替代原生 select。
@@ -57,12 +76,21 @@ export function SelectMenu({
const spaceBelow = window.innerHeight - rect.bottom
const spaceAbove = rect.top
const openUp = spaceBelow < menuHeight && spaceAbove > spaceBelow
+ // 跟触发器同宽会把长 profile 名截成省略号(ghost / 未撑满的 button 尤其明显)。
+ // 按最长项测量,下限触发器宽、上限视口,溢出时左移,不超出 webview。
+ const gutter = 8
+ const contentW = measureOptionsWidth(options, getComputedStyle(el).font) + MENU_CHROME_PX
+ const maxWidth = window.innerWidth - gutter * 2
+ const width = Math.min(maxWidth, Math.max(rect.width, contentW))
+ let left = rect.left
+ if (left + width > window.innerWidth - gutter)
+ left = Math.max(gutter, window.innerWidth - gutter - width)
setPos({
top: openUp ? Math.max(8, rect.top - menuHeight - 4) : rect.bottom + 4,
- left: rect.left,
- width: Math.max(rect.width, 120),
+ left,
+ width,
})
- }, [options.length])
+ }, [options])
const openMenu = useCallback((): void => {
computePos()
@@ -181,7 +209,7 @@ export function SelectMenu({
const triggerClasses
= variant === 'input'
- ? 'rounded border border-[var(--vscode-input-border,var(--vscode-panel-border))] bg-[var(--vscode-input-background)] px-2 py-1 text-xs text-[var(--vscode-input-foreground)] focus:ring-1 focus:ring-inset focus:ring-[var(--vscode-focusBorder)]'
+ ? 'w-full rounded border border-[var(--vscode-input-border,var(--vscode-panel-border))] bg-[var(--vscode-input-background)] px-2 py-1 text-xs text-[var(--vscode-input-foreground)] focus:ring-1 focus:ring-inset focus:ring-[var(--vscode-focusBorder)]'
: 'rounded bg-transparent px-1 py-0 text-[10px] text-[var(--vscode-descriptionForeground)] hover:bg-[var(--vscode-toolbar-hoverBackground)]'
return (
@@ -202,7 +230,7 @@ export function SelectMenu({
className,
)}
>
-
+
{selected?.label ?? placeholder}
@@ -244,8 +272,8 @@ export function SelectMenu({
- {opt.label}
- {opt.hint && {opt.hint}}
+ {opt.label}
+ {opt.hint && {opt.hint}}
))}