weifuwu 0.65.1 → 0.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -12
- package/dist/client/browser.d.ts +10 -0
- package/dist/client/index.js +4 -4
- package/dist/client/types.d.ts +51 -0
- package/dist/client/ui.d.ts +8 -0
- package/dist/components/Anchor/Anchor.d.ts +27 -0
- package/dist/components/DiffView/DiffView.d.ts +24 -0
- package/dist/components/DiffView/diff-utils.d.ts +19 -0
- package/dist/components/Editor/Editor.d.ts +1 -1
- package/dist/components/Editor/tools/format.d.ts +1 -1
- package/dist/components/FileUpload/FileUpload.d.ts +4 -0
- package/dist/components/JSONViewer/JSONViewer.d.ts +21 -0
- package/dist/components/Kanban/Kanban.d.ts +28 -0
- package/dist/components/LogViewer/LogViewer.d.ts +29 -0
- package/dist/components/Menu/Menu.d.ts +11 -2
- package/dist/components/Pipeline/Pipeline.d.ts +27 -0
- package/dist/components/Pipeline/dag-utils.d.ts +36 -0
- package/dist/components/Sparkline/Sparkline.d.ts +21 -0
- package/dist/components/Sparkline/sparkline-utils.d.ts +16 -0
- package/dist/components/Tour/Tour.d.ts +34 -0
- package/dist/components/Tree/Tree.d.ts +2 -0
- package/dist/components/TreeSelect/TreeSelect.d.ts +24 -0
- package/dist/components/VirtualTable/VirtualTable.d.ts +32 -0
- package/dist/components/index.d.ts +16 -0
- package/dist/components/index.js +15 -11
- package/dist/components/style.css +1048 -101
- package/dist/index.js +28 -1
- package/dist/layout/weifuwu-layout.css +7 -0
- package/docs/components-map.md +28 -7
- package/docs/custom-components.md +29 -0
- package/docs/frontend.md +28 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4371,7 +4371,7 @@ function createSsrContext(serverCtx, dataStore) {
|
|
|
4371
4371
|
},
|
|
4372
4372
|
useDrag: () => ({ onPointerDown: () => {
|
|
4373
4373
|
} }),
|
|
4374
|
-
useDragDrop: () => ({ dropProps: {} }),
|
|
4374
|
+
useDragDrop: () => ({ dropProps: {}, dragProps: {} }),
|
|
4375
4375
|
useControlled: (options) => ({
|
|
4376
4376
|
value: options.value,
|
|
4377
4377
|
setValue: (v) => {
|
|
@@ -4426,8 +4426,35 @@ function createSsrContext(serverCtx, dataStore) {
|
|
|
4426
4426
|
}
|
|
4427
4427
|
})
|
|
4428
4428
|
};
|
|
4429
|
+
const browser = {
|
|
4430
|
+
activeElement: () => null,
|
|
4431
|
+
byId: () => null,
|
|
4432
|
+
query: () => null,
|
|
4433
|
+
createElement: () => null,
|
|
4434
|
+
bodyAppend: () => {
|
|
4435
|
+
},
|
|
4436
|
+
bodyRemove: () => {
|
|
4437
|
+
},
|
|
4438
|
+
copyText: async () => false,
|
|
4439
|
+
execCommand: () => false,
|
|
4440
|
+
selectionText: () => null,
|
|
4441
|
+
getSelection: () => null,
|
|
4442
|
+
queryCommandState: () => false,
|
|
4443
|
+
queryCommandValue: () => "",
|
|
4444
|
+
viewportHeight: () => 0,
|
|
4445
|
+
scrollTop: () => 0,
|
|
4446
|
+
hash: () => "",
|
|
4447
|
+
setHash: () => {
|
|
4448
|
+
},
|
|
4449
|
+
timeout: () => 0,
|
|
4450
|
+
rootElement: () => null,
|
|
4451
|
+
storageGet: () => null,
|
|
4452
|
+
storageSet: () => {
|
|
4453
|
+
}
|
|
4454
|
+
};
|
|
4429
4455
|
const ctx = Object.create(serverCtx ?? {});
|
|
4430
4456
|
ctx.ui = ui2;
|
|
4457
|
+
ctx.browser = browser;
|
|
4431
4458
|
ctx.data = {
|
|
4432
4459
|
async get(key, fetcher) {
|
|
4433
4460
|
if (dataStore.has(key)) return dataStore.get(key);
|
|
@@ -91,6 +91,13 @@
|
|
|
91
91
|
--wf-z-sticky: 40;
|
|
92
92
|
--wf-z-overlay: 80;
|
|
93
93
|
--wf-z-modal: 100;
|
|
94
|
+
--wf-z-tour: 2000;
|
|
95
|
+
--wf-tour-min-width: 240px;
|
|
96
|
+
--wf-kanban-col-min-width: 200px;
|
|
97
|
+
--wf-kanban-col-max-width: 300px;
|
|
98
|
+
--wf-treeselect-min-width: 200px;
|
|
99
|
+
--wf-treeselect-max-width: 320px;
|
|
100
|
+
--wf-treeselect-dropdown-max-height: 260px;
|
|
94
101
|
--wf-z-popover: 120; /* dropdown/select/datepicker 面板与 popover 同层 */
|
|
95
102
|
--wf-z-toast: 140;
|
|
96
103
|
--wf-z-tooltip: 160;
|
package/docs/components-map.md
CHANGED
|
@@ -141,13 +141,34 @@
|
|
|
141
141
|
<Badge variant="secondary">x</Badge> // → <Tag variant="secondary">x</Tag>
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
## weifuwu
|
|
144
|
+
## weifuwu 已补齐(第六批,2026-08)→ 待补清单清零 ✅
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
第六批 6 组件全部落地(TDD 红→绿 + style-audit + demo + agent-browser 实测):
|
|
147
147
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
| 组件 | 类型 | 要点 |
|
|
149
|
+
|------|------|------|
|
|
150
|
+
| **Menu 子菜单/折叠** | 增强 | `children` 子菜单 + `collapsible` 折叠侧栏 + 多级键盘流 |
|
|
151
|
+
| **FileUpload 增强** | 增强 | 图片缩略图(objectURL revoke)+ 进度条 + 受控纪律 |
|
|
152
|
+
| **VirtualTable** | 新增 | 固定表头 + 虚拟滚动(10k 行 ~17 DOM)+ 排序 |
|
|
153
|
+
| **Anchor** | 新增 | 滚动高亮跟随 + 点击平滑滚动 + useHash |
|
|
154
|
+
| **LogViewer** | 新增 | ANSI 着色 + 虚拟滚动 + follow 自动跟随 + maxLines |
|
|
155
|
+
| **JSONViewer** | 新增 | 递归折叠 + 类型色 + 路径复制 + 懒展开(ToolCallCard 已接入) |
|
|
152
156
|
|
|
153
|
-
>
|
|
157
|
+
> 三库共识覆盖度 ~100%(剩余均为已声明裁剪项,见 `design/components-roadmap.md` 第六批裁剪清单)。
|
|
158
|
+
|
|
159
|
+
## 第七批:AI 开发者工具深化(96 → 102 组件)
|
|
160
|
+
|
|
161
|
+
> 追平期结束(三库共识 ~100%),差异化期——本批全部组件三库没有的直接等价物。
|
|
162
|
+
|
|
163
|
+
| 组件 | 类型 | 要点 |
|
|
164
|
+
|------|------|------|
|
|
165
|
+
| **DiffView** | 新增 | LCS 行级 diff(自研算法):三态行 + 未变块折叠 + maxLines 防超大 |
|
|
166
|
+
| **Sparkline** | 新增 | 迷你趋势线:SVG 自绘 + 归一化 + 平滑曲线 + 面积填充 + 等值防抖 |
|
|
167
|
+
| **Tour** | 新增 | 新手引导:目标高亮(rect 精确跟随)+ 遮罩 + 步骤气泡 + 全局 Escape |
|
|
168
|
+
| **Kanban** | 新增 | 拖拽看板:原生 DnD + 跨列/重排 + 悬停高亮 + 受控纪律 |
|
|
169
|
+
| **Pipeline** | 新增 | Agent 工作流 DAG:Kahn 拓扑分层 + 贝塞尔连线 + 状态语义色 + 环检测 |
|
|
170
|
+
| **TreeSelect** | 新增 | 树形选择:单选/多选(父子联动)+ label 回显 + 受控纪律 |
|
|
171
|
+
|
|
172
|
+
> AI 开发者工具链成型:AiChat / Command / JSONViewer / LogViewer / DiffView /
|
|
173
|
+
> Pipeline——三库差异化最深的完整工具线。
|
|
174
|
+
> 裁剪声明见 `design/components-roadmap.md` 第七批。
|
|
@@ -207,6 +207,35 @@ const CollapseItem: Component<{ active?: boolean; onChange?: (v: boolean) => voi
|
|
|
207
207
|
|
|
208
208
|
**纪律**:组件内动画事件监听**唯一入口是 `useAnimationEnd`**——禁直接 `addEventListener('animationend')`(DatePicker 已收敛);退场优先 `usePresence`(声明式状态机)或 `animateOut`(命令式)。
|
|
209
209
|
|
|
210
|
+
## 8.6 浏览器环境纪律(ctx.browser)
|
|
211
|
+
|
|
212
|
+
> **自定义组件禁止直接引用 window/document**——统一经 `ctx.browser`:
|
|
213
|
+
> SSR 安全(shim 安全默认)+ 测试 mock 单点 + 环境差异隔离。
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
const MyComp: Component = (_init, ctx) => {
|
|
217
|
+
// mount 层取 browser(ctx.browser 优先,测试/无注入环境 fallback jsdom)
|
|
218
|
+
const browser = ctx.browser ?? createClientBrowser()
|
|
219
|
+
return (props) =>
|
|
220
|
+
h('button', {
|
|
221
|
+
onClick: () => {
|
|
222
|
+
// 复制/查询/存储/滚动——全部经 browser
|
|
223
|
+
void browser.copyText('hello')
|
|
224
|
+
const el = browser.byId('target')
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**规则**:
|
|
231
|
+
- 拖拽统一 `ctx.ui.useDragDrop`(drop 侧 dropProps + drag 侧 dragProps:draggable/
|
|
232
|
+
onDragStart/onDragEnd)——**dragstart 期间禁止重渲染**(渲染替换源元素中断拖拽;
|
|
233
|
+
身份/位置在渲染期闭包绑定,拖拽视觉高亮用 CSS :hover)
|
|
234
|
+
- 复制统一 `browser.copyText`(clipboard + 降级——勿自建 textarea+execCommand)
|
|
235
|
+
- 键盘导航用 `browser.activeElement()`(勿 document.activeElement)
|
|
236
|
+
- 存储用 `browser.storageGet/Set`(勿 localStorage 裸调)
|
|
237
|
+
- SSR 场景(render/mount 期)绝对不碰环境 API(shim 返回 null——需防御)
|
|
238
|
+
|
|
210
239
|
## 9. 样式纪律(style-audit 强制)
|
|
211
240
|
|
|
212
241
|
- 动效用 Token:`--wf-dur-*` / `--wf-ease-*` / `--wf-motion-*`(禁硬编码)
|
package/docs/frontend.md
CHANGED
|
@@ -143,6 +143,34 @@ ctx.ui.render(['name'])
|
|
|
143
143
|
|
|
144
144
|
---
|
|
145
145
|
|
|
146
|
+
## 浏览器环境抽象(ctx.browser)
|
|
147
|
+
|
|
148
|
+
> 组件**不直接引用 window/document**——统一经 `ctx.browser`(环境 API):
|
|
149
|
+
> SSR 安全(shim 返回安全默认)+ 测试可 mock + 环境差异单点隔离。
|
|
150
|
+
|
|
151
|
+
| 方法 | 说明 |
|
|
152
|
+
|------|------|
|
|
153
|
+
| `activeElement()` | 当前焦点元素(键盘导航) |
|
|
154
|
+
| `byId(id)` / `query(sel)` | 元素查询(getElementById / querySelector) |
|
|
155
|
+
| `createElement(tag)` / `bodyAppend(el)` / `bodyRemove(el)` | 动态创建/挂载容器 |
|
|
156
|
+
| `copyText(text)` | **复制统一入口**(clipboard API + execCommand 降级) |
|
|
157
|
+
| `execCommand(cmd, value?)` | 富文本编辑器命令 |
|
|
158
|
+
| `selectionText()` / `getSelection()` | 编辑器选区(文本 / 完整 Selection 对象) |
|
|
159
|
+
| `viewportHeight()` / `scrollTop()` | 视口高度 / 滚动量(scrollingElement 优先) |
|
|
160
|
+
| `hash()` / `setHash(h)` | 锚点 hash |
|
|
161
|
+
| `timeout(fn, ms)` | 定时器(SSR no-op) |
|
|
162
|
+
| `rootElement()` | document.documentElement(主题应用) |
|
|
163
|
+
| `storageGet(key)` / `storageSet(key, val)` | localStorage(SSR/隐私模式安全) |
|
|
164
|
+
|
|
165
|
+
**三态实现**:客户端 `createClientBrowser`(惰性 typeof 防御)· SSR shim(null/0/no-op)· 测试 mock 或 jsdom fallback。
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
// 组件内(mount 层)
|
|
169
|
+
const browser = ctx.browser ?? createClientBrowser()
|
|
170
|
+
// 事件回调
|
|
171
|
+
await browser.copyText(text)
|
|
172
|
+
```
|
|
173
|
+
|
|
146
174
|
## 状态管理
|
|
147
175
|
|
|
148
176
|
### ctx.ui 方法速查
|