0 ? 'mt-1 border-t border-line pt-1' : ''}>
+ {/* 区域头 = 插件名;第一个区域右侧是收回药丸的 ⤡ */}
+
{pluginEntries.map((entry) => {
const clickable = Boolean(entry.item.openView)
- const body = (
- <>
-
- {entry.item.icon ? (
-
- ) : null}
-
{entry.item.text}
- >
- )
return (
- {clickable ? (
-
+ {entry.item.detail ? (
+ // 有详情:分组手风琴(默认收起,标题行 + 行尾徽标;无标题分组平铺)
+ entry.item.detail.sections.map((section, si) => {
+ if (!section.title) {
+ return
+ }
+ const key = `${pluginId}:${entry.itemId}:${si}`
+ const expanded = openSections.has(key)
+ return (
+
+
+ {expanded && (
+
+
+
+ )}
+
+ )
+ })
) : (
-
{body}
- )}
- {entry.item.detail && (
-
-
-
+ // 纯文本条目行
+ clickable ? (
+
+ ) : (
+
+
+ {entry.item.icon ? (
+
+ ) : null}
+
+ {entry.item.text}
+
+
+ )
)}
)
diff --git a/docs/plugins.md b/docs/plugins.md
index 71df7e6..65a357a 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -181,7 +181,7 @@ api.ui.onSettingsAction((key) => {}) // button 条目点击回调(key = 按钮
| 侧栏入口(B1) | manifest icon/name/order;点进插件整页视图 | ✅ |
| 插件整页 Main | 内置组件级 / 外置 renderer 组件 / 外置 iframe;聊天列 display:none 保活 | ✅ |
| 面板 tab(B6) | `panel: true`;SidePanel 零改动承载(内置组件 / 外置 renderer 组件 / iframe) | ✅ |
-| 状态胶囊(B2+B3) | `setStatusItem` 数据驱动,标题栏**悬浮胶囊**统一承载(ZCode 复刻):最小化药丸展示最新一条消息(宿主记录 updatedAt),点击展开面板——每插件一个专属区域、区域可收起/展开(记忆跨启动)、固定高度溢出滚动、行尾彩色数值与行内深链 | ✅ |
+| 状态胶囊(B2+B3) | `setStatusItem` 数据驱动,**悬浮胶囊**挂 main 区右上角(ZCode 复刻):最小化药丸展示最新一条消息(宿主记录 updatedAt),展开面板头即插件名、`detail` 分组为手风琴(默认收起显示 标题+trailing 徽标,点击展开行)、固定高度滚动、行尾彩色数值与行内深链 | ✅ |
| 深链 | `openView(view, params)`(main 侧 IPC 广播 / 页侧桥直通) | ✅ |
| 工具栏按钮(B5) | `registerToolbarButton` 数据已通,Composer 工具行渲染 | ⏳ 下版本 |
| 聊天流富组件(B4) | ```类型``` 围栏块 → 宿主元组件(data-table/stat-grid/step-list/kv-card) | ⏳ 下版本 |
diff --git a/docs/plugins/04-ui-slots.md b/docs/plugins/04-ui-slots.md
index 2d3d684..0e26c1f 100644
--- a/docs/plugins/04-ui-slots.md
+++ b/docs/plugins/04-ui-slots.md
@@ -4,10 +4,10 @@
## 1. 状态胶囊(悬浮胶囊:最小化药丸 ⇄ 展开面板)
-所有插件**共用一个悬浮胶囊**(标题栏右侧,ZCode 复刻)。插件照常 `setStatusItem`,宿主记录每次写入时间,两种形态:
+所有插件**共用一个悬浮胶囊**,悬浮于 main 区域右上角(侧面板打开时自动左移让位;ZCode 复刻)。插件照常 `setStatusItem`,宿主记录每次写入时间,两种形态:
- **最小化药丸**:展示「最新的消息」(全部插件中 `updatedAt` 最新的一条:tone 点 + 插件图标 + 文本;多于一条时带总数角标),点击展开面板;
-- **展开面板**:每个插件一个**专属区域**——区域头(插件图标 + 名称 + 条目数)可收起/展开(记忆跨启动),区域内是该插件的条目与详情行;面板高度固定,内容太多向下滚动;点击面板外部 / Esc 收回药丸。
+- **展开面板**:面板头就是插件名(第一个区域的右侧是收回药丸的 ⤡);多个插件时各占一个区域、区域头可收起/展开(记忆跨启动)。区域内 `detail` 的**分组是手风琴**——默认收起只显示「分组标题 + 行尾徽标」,点击展开 rows(ZCode 式「计划 ›」);无标题分组直接平铺。面板高度固定,内容太多向下滚动;点击面板外部 / Esc 收回药丸。
```js
// ① 纯展示(只出现在药丸/区域行)
@@ -21,7 +21,7 @@ api.ui.setStatusItem('conn', {
openView: { view: 'my-plugin' } // 点击跳到插件整页视图
})
-// ③ 携详情(声明 detail 时区域行下展开分组明细)
+// ③ 携详情(分组 = 手风琴:收起显示 标题+trailing 徽标,点击展开 rows)
api.ui.setStatusItem('tasks', {
text: '任务 2/5',
tone: 'accent',
diff --git a/packages/plugin-sdk/src/status.ts b/packages/plugin-sdk/src/status.ts
index 3523640..e090452 100644
--- a/packages/plugin-sdk/src/status.ts
+++ b/packages/plugin-sdk/src/status.ts
@@ -28,10 +28,14 @@ export interface StatusDetailRow {
openView?: OpenViewAction
}
-/** 详情弹层分组 */
+/** 详情弹层分组(悬浮面板中为手风琴:默认收起只显示标题行,点击展开 rows) */
export interface StatusDetailSection {
- /** 分组标题(如「Git 工具」「计划」);缺省无标题 */
+ /** 分组标题(如「计划」「进程」);缺省无标题(rows 直接平铺、不可收起) */
title?: string
+ /** 标题行尾徽标(如「4/4」「35分7秒」;收起态也可见——ZCode 式摘要) */
+ trailing?: string
+ /** 行尾徽标色调,缺省 default */
+ trailingTone?: StatusTone
rows: StatusDetailRow[]
}