weifuwu 0.63.0 → 0.64.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.
@@ -702,6 +702,28 @@ code {
702
702
  }
703
703
  }
704
704
 
705
+ @layer layout {
706
+ /* popup — 浮层基类(usePopup.portal 自动附加;Modal/Drawer 等手动浮层可选用)
707
+ *
708
+ * 宽度视口 clamp:任何浮层默认不横向溢出(375px 屏也能完整操作)。
709
+ * usePopup 已内联 maxWidth;本类兜底组件手动引用场景(audit 规则的目标选择器)。
710
+ */
711
+ .wf-popup {
712
+ max-width: min(var(--wf-popup-max, 480px), calc(100vw - 32px));
713
+ box-sizing: border-box;
714
+ }
715
+ }
716
+
717
+ @layer layout {
718
+ /* safe-area — iOS 刘海屏/Home 条安全区工具(env() 未生效环境自动为 0) */
719
+ .wf-safe-bottom {
720
+ padding-bottom: env(safe-area-inset-bottom);
721
+ }
722
+ .wf-safe-top {
723
+ padding-top: env(safe-area-inset-top);
724
+ }
725
+ }
726
+
705
727
  @layer layout {
706
728
  /* anchor — 定位锚点容器 */
707
729
  .wf-anchor {
@@ -2049,6 +2071,14 @@ code {
2049
2071
  color: var(--wf-color-text-tertiary);
2050
2072
  }
2051
2073
 
2074
+ /* 触屏(coarse):月份切换按钮 44px 命中区 */
2075
+ @media (pointer: coarse) {
2076
+ .wf-calendar-nav-btn {
2077
+ min-height: 44px;
2078
+ min-width: 44px;
2079
+ }
2080
+ }
2081
+
2052
2082
  /* weifuwu/components — Card */
2053
2083
 
2054
2084
  .wf-card {
@@ -2187,6 +2217,25 @@ code {
2187
2217
  transform: scale(1.25);
2188
2218
  }
2189
2219
 
2220
+ /* 触屏(coarse):箭头 44px;圆点保持视觉 8px,用 ::after 扩展命中区(视觉不变) */
2221
+ @media (pointer: coarse) {
2222
+ .wf-carousel-arrow {
2223
+ width: 44px;
2224
+ height: 44px;
2225
+ min-width: 44px;
2226
+ min-height: 44px;
2227
+ }
2228
+ .wf-carousel-dot {
2229
+ position: relative;
2230
+ }
2231
+ .wf-carousel-dot::after {
2232
+ content: '';
2233
+ position: absolute;
2234
+ inset: -14px;
2235
+ border-radius: 50%;
2236
+ }
2237
+ }
2238
+
2190
2239
  /* weifuwu/components — Cascader */
2191
2240
 
2192
2241
  .wf-cascader-wrap {
@@ -3240,6 +3289,34 @@ code {
3240
3289
  padding: 0 2px;
3241
3290
  }
3242
3291
 
3292
+ /* ── 移动端适配(P0):面板宽度视口 clamp + range 窄屏纵向堆叠 ── */
3293
+
3294
+ .wf-datepicker-dropdown {
3295
+ max-width: calc(100vw - 32px);
3296
+ }
3297
+
3298
+ .wf-time-picker {
3299
+ max-width: calc(100vw - 32px);
3300
+ }
3301
+
3302
+ .wf-datepicker-range-wrap {
3303
+ max-width: calc(100vw - 32px);
3304
+ }
3305
+
3306
+ /* range 双面板(240px×2 ≈ 500px)在 375px 屏溢出 → 窄屏纵向堆叠 */
3307
+ @media (max-width: 639px) {
3308
+ .wf-datepicker-range-wrap {
3309
+ flex-direction: column;
3310
+ max-height: 80vh;
3311
+ overflow-y: auto;
3312
+ }
3313
+ }
3314
+
3315
+ /* 时间选择列(时/分/秒)窄屏横向滚动 */
3316
+ .wf-time-body {
3317
+ overflow-x: auto;
3318
+ }
3319
+
3243
3320
  /* weifuwu/components — Descriptions */
3244
3321
 
3245
3322
  .wf-descriptions {
@@ -3477,6 +3554,14 @@ code {
3477
3554
  border-top: var(--wf-border-width, 1px) solid var(--wf-color-border);
3478
3555
  }
3479
3556
 
3557
+ /* 移动端适配(P2):小屏抽屉全宽(底部安全区) */
3558
+ @media (max-width: 639px) {
3559
+ .wf-drawer-panel {
3560
+ width: 100vw;
3561
+ max-width: 100vw;
3562
+ }
3563
+ }
3564
+
3480
3565
  /* weifuwu/components — Dropdown */
3481
3566
 
3482
3567
  .wf-dropdown {
@@ -3843,6 +3928,14 @@ code {
3843
3928
  border-top: 1px solid var(--wf-color-border);
3844
3929
  }
3845
3930
 
3931
+ /* 触屏(coarse):工具栏按钮 44px 命中区 */
3932
+ @media (pointer: coarse) {
3933
+ .wf-editor-toolbar button {
3934
+ min-height: 44px;
3935
+ min-width: 44px;
3936
+ }
3937
+ }
3938
+
3846
3939
  /* weifuwu/components — EmptyState */
3847
3940
 
3848
3941
  .wf-empty {
@@ -4915,6 +5008,25 @@ code {
4915
5008
  border-top: var(--wf-border-width) solid var(--wf-color-border);
4916
5009
  }
4917
5010
 
5011
+ /* ── 移动端适配(P2):min-width 视口 clamp(修 375px 屏 400px 溢出)+ 小屏 bottom-sheet ── */
5012
+
5013
+ .wf-modal-content {
5014
+ min-width: min(var(--wf-modal-width, 400px), calc(100vw - 32px));
5015
+ }
5016
+
5017
+ @media (max-width: 639px) {
5018
+ .wf-modal {
5019
+ align-items: flex-end; /* bottom-sheet 形态 */
5020
+ }
5021
+ .wf-modal-content {
5022
+ width: 100%;
5023
+ max-width: 100vw;
5024
+ max-height: 85vh;
5025
+ border-radius: var(--wf-radius-lg) var(--wf-radius-lg) 0 0;
5026
+ padding-bottom: env(safe-area-inset-bottom);
5027
+ }
5028
+ }
5029
+
4918
5030
  /* weifuwu/components — Notification */
4919
5031
 
4920
5032
  .wf-notification-container {
@@ -5111,6 +5223,23 @@ code {
5111
5223
  color: var(--wf-color-text-tertiary);
5112
5224
  }
5113
5225
 
5226
+ /* 触屏(coarse):页码 44px 命中区(覆盖全局 button min-height) */
5227
+ @media (pointer: coarse) {
5228
+ .wf-pagination-item {
5229
+ min-height: 44px;
5230
+ min-width: 44px;
5231
+ }
5232
+ }
5233
+
5234
+ /* 移动端适配(P2):窄屏页码横向滚动兜底(44px 命中区 + 折叠后仍可能溢出) */
5235
+ .wf-pagination {
5236
+ overflow-x: auto;
5237
+ scrollbar-width: none;
5238
+ }
5239
+ .wf-pagination::-webkit-scrollbar {
5240
+ display: none;
5241
+ }
5242
+
5114
5243
  /* weifuwu/components — PasswordInput(复用 Input 基础类) */
5115
5244
 
5116
5245
  .wf-password {
@@ -5816,6 +5945,15 @@ code {
5816
5945
  border-radius: var(--wf-radius-sm);
5817
5946
  }
5818
5947
 
5948
+ /* 触屏(coarse):搜索选项行 44px 命中区(非 button 元素,需显式覆盖) */
5949
+ @media (pointer: coarse) {
5950
+ .wf-select-search-opt {
5951
+ min-height: 44px;
5952
+ display: flex;
5953
+ align-items: center;
5954
+ }
5955
+ }
5956
+
5819
5957
  /* weifuwu/components — Skeleton */
5820
5958
 
5821
5959
  .wf-skeleton {
@@ -6277,6 +6415,15 @@ code {
6277
6415
  padding-top: var(--wf-space-md);
6278
6416
  }
6279
6417
 
6418
+ /* 移动端适配(P2):窄屏标签横向滚动(隐藏滚动条) */
6419
+ .wf-tab-list {
6420
+ overflow-x: auto;
6421
+ scrollbar-width: none;
6422
+ }
6423
+ .wf-tab-list::-webkit-scrollbar {
6424
+ display: none;
6425
+ }
6426
+
6280
6427
  /* weifuwu/components — Tag */
6281
6428
 
6282
6429
  .wf-tag {
@@ -7065,6 +7212,23 @@ code {
7065
7212
  cursor: not-allowed;
7066
7213
  }
7067
7214
 
7215
+ /* 触屏(coarse):移动按钮 44px 命中区 */
7216
+ @media (pointer: coarse) {
7217
+ .wf-transfer-btn {
7218
+ width: 44px;
7219
+ height: 44px;
7220
+ min-width: 44px;
7221
+ min-height: 44px;
7222
+ }
7223
+ }
7224
+
7225
+ /* 移动端适配(P2):窄屏双栏纵向堆叠(操作钮居中) */
7226
+ @media (max-width: 767px) {
7227
+ .wf-transfer {
7228
+ flex-direction: column;
7229
+ }
7230
+ }
7231
+
7068
7232
  /* weifuwu/components — Tree */
7069
7233
 
7070
7234
  .wf-tree {
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export type { EmailOptions, EmailMessage, EmailResult, EmailAdapter, EmailInject
18
18
  export { sendSmtp } from './email/smtp.ts';
19
19
  export type { SmtpConfig } from './email/smtp.ts';
20
20
  export { userSystem } from './user/index.ts';
21
+ export { hashPassword, verifyPassword } from './user/password.ts';
21
22
  export { messager } from './messager/index.ts';
22
23
  export type { UserSystemOptions, UserInjected, AuthApi, RegisterInput } from './user/index.ts';
23
24
  export type { MessagerOptions, MessagerInjected, MessagerClient, MessagerSystem, Message, Conversation } from './messager/index.ts';
package/dist/index.js CHANGED
@@ -6035,6 +6035,7 @@ export {
6035
6035
  created,
6036
6036
  email,
6037
6037
  forbidden,
6038
+ hashPassword,
6038
6039
  messager,
6039
6040
  noContent,
6040
6041
  notFound,
@@ -6055,5 +6056,6 @@ export {
6055
6056
  uiSsr,
6056
6057
  unauthorized,
6057
6058
  unprocessable,
6058
- userSystem
6059
+ userSystem,
6060
+ verifyPassword
6059
6061
  };
@@ -702,6 +702,28 @@ code {
702
702
  }
703
703
  }
704
704
 
705
+ @layer layout {
706
+ /* popup — 浮层基类(usePopup.portal 自动附加;Modal/Drawer 等手动浮层可选用)
707
+ *
708
+ * 宽度视口 clamp:任何浮层默认不横向溢出(375px 屏也能完整操作)。
709
+ * usePopup 已内联 maxWidth;本类兜底组件手动引用场景(audit 规则的目标选择器)。
710
+ */
711
+ .wf-popup {
712
+ max-width: min(var(--wf-popup-max, 480px), calc(100vw - 32px));
713
+ box-sizing: border-box;
714
+ }
715
+ }
716
+
717
+ @layer layout {
718
+ /* safe-area — iOS 刘海屏/Home 条安全区工具(env() 未生效环境自动为 0) */
719
+ .wf-safe-bottom {
720
+ padding-bottom: env(safe-area-inset-bottom);
721
+ }
722
+ .wf-safe-top {
723
+ padding-top: env(safe-area-inset-top);
724
+ }
725
+ }
726
+
705
727
  @layer layout {
706
728
  /* anchor — 定位锚点容器 */
707
729
  .wf-anchor {
@@ -0,0 +1,314 @@
1
+ # 组件库(weifuwu/components)
2
+
3
+ > 本页为 weifuwu 官方文档拆分页 · [返回 README](../README.md)
4
+
5
+ 92 个 HTML 原语组件。每个是 `(_init, ctx) => (props) => VNode`(两阶段组件,与前端框架同一模型),引用 `--wf-*` CSS 变量做主题。另含 `confirm()` / `toast()` 命令式中间件。
6
+
7
+ > **组件速查(weifuwu 组件 ↔ antd / Element Plus / shadcn-ui 对应 + 迁移示例)**:见 [`design/components-map.md`](../design/components-map.md)——从其他组件库迁来的开发者按功能直接找对应组件。
8
+
9
+ ```ts
10
+ import { Button, Input, Table, Modal, Toast } from 'weifuwu/components'
11
+ import 'weifuwu/components/style.css' // 包含 Token + 67 布局原语 + 组件样式,一次性引入
12
+ ```
13
+
14
+ ### 使用示例
15
+
16
+ ```tsx
17
+ // ├─ 按钮
18
+ <Button variant="primary" onClick={() => alert('提交')}>提交</Button>
19
+ <Button variant="ghost" loading>加载中</Button>
20
+ <Button variant="danger" size="lg" block>删除</Button>
21
+
22
+ // ├─ 输入框
23
+ <Input placeholder="请输入邮箱" />
24
+ <Input label="用户名" name="username" required error="必填" />
25
+ <Input type="password" hint="至少6位" />
26
+ <Input name="email" type="email" disabled placeholder="name@example.com" />
27
+
28
+ // ├─ 选择器
29
+ <Select options={[{ value: 'a', label: '选项A' }]} placeholder="请选择" />
30
+ <Select searchable options={options} onChange={v => setVal(v)} />
31
+
32
+ // ├─ 复选框 / 开关 / 单选
33
+ <Checkbox checked={agree} onChange={setAgree} label="同意协议" />
34
+ <Switch checked={enabled} onChange={setEnabled} />
35
+ <RadioGroup options={[{ value: '1', label: '男' }, { value: '2', label: '女' }]} value={gender} />
36
+
37
+ // ├─ 表格
38
+ <Table columns={[{ key: 'id', label: 'ID', sortable: true }, { key: 'name', label: '名称' }]}
39
+ data={rows} sortKey="id" sortOrder="asc" onSort={(k, o) => setSort(k, o)} />
40
+
41
+ // ├─ 模态框 / 确认框 / 抽屉
42
+ <Modal open={show} title="提示" onClose={() => setShow(false)} width="500px" closable>
43
+ <p>确认删除?</p>
44
+ </Modal>
45
+ <Confirm open={confirming} message="确定删除?" variant="danger" onConfirm={doDelete} onCancel={() => setConfirming(false)} />
46
+ // 命令式:await ctx.confirm?.('确定删除?') —— 组件里直接调用
47
+ <Drawer open={open} title="详情" onClose={() => setOpen(false)} position="right">内容</Drawer>
48
+
49
+ // ├─ 消息提示
50
+ <Toast toasts={items} position="top-right" max={5} onRemove={id => remove(id)} />
51
+ <Alert variant="warning" closable>注意:磁盘空间不足</Alert>
52
+
53
+ // ├─ 标签 / 徽标 / 头像
54
+ <Badge variant="primary">消息</Badge>
55
+ <Badge variant="success" dot>通过</Badge>
56
+ <Tag variant="primary" closable onClose={() => {}}>标签</Tag>
57
+ <Avatar name="张三" size="lg" />
58
+
59
+ // ├─ 卡片 / 统计卡片
60
+ <Card variant="outlined" padding="md">卡片内容</Card>
61
+ <StatCard label="总用户" value="1,234" trend="up" trendLabel="12%" />
62
+
63
+ // ├─ 标签页 / 下拉菜单
64
+ <Tabs items={[{ key: 'a', label: '标签A' }, { key: 'b', label: '标签B' }]} active="a" onChange={setTab} />
65
+ <Dropdown items={[{ label: '编辑', onClick: () => {} }, { label: '删除', variant: 'danger' }]}>操作</Dropdown>
66
+
67
+ // ├─ 分页 / 步骤条
68
+ <Pagination total={100} page={1} pageSize={10} onChange={setPage} />
69
+ <Steps items={[{ key: 's1', label: '第一步' }, { key: 's2', label: '第二步' }]} current={1} />
70
+
71
+ // ├─ 滑块 / 进度条
72
+ <Slider min={0} max={100} value={50} onChange={setValue} />
73
+ <ProgressBar value={75} label="75%" />
74
+
75
+ // ├─ 面包屑 / 分割线
76
+ <Breadcrumb items={[{ label: '首页' }, { label: '用户管理' }]} />
77
+ <Divider />
78
+ <Divider>分割文字</Divider>
79
+
80
+ // ├─ 加载 / 空状态 / 骨架屏
81
+ <Loading text="加载中..." />
82
+ <EmptyState text="暂无数据" hint="请先创建一条记录"><Button>新建</Button></EmptyState>
83
+ <Skeleton variant="text" lines={3} />
84
+ <Skeleton variant="table" lines={5} cols={4} />
85
+ <Skeleton variant="avatar" />
86
+ <Skeleton variant="image" />
87
+
88
+ // ├─ 表单验证
89
+ <Form validation={{ email: [{ required: true, message: '请输入邮箱' }] }}
90
+ onSubmit={values => ctx.api?.post('/login', values)} // ctx.api 由中间件注入
91
+ onError={errors => setErrors(errors)}>
92
+ <Field label="邮箱" error={errors.email}>
93
+ <Input name="email" />
94
+ </Field>
95
+ <Button type="submit">登录</Button>
96
+ </Form>
97
+
98
+ // ├─ 新增批次组件(全量实现)
99
+ <Rate value={3} onChange={setRate} /> // 评分
100
+ <ToggleGroup type="single" options={toolbar} value={fmt} /> // 工具栏切换
101
+ <CheckboxGroup options={members} value={selected} onChange={setSelected} /> // 多选列表
102
+ <PinInput length={6} value={code} onChange={setCode} /> // 验证码
103
+ <CopyButton value="https://weifuwu.dev" label="复制" /> // 复制
104
+ <ColorPicker value={color} showInput onChange={setColor} /> // 颜色
105
+ <Notification /> + notification.success({ title, description }) // 队列通知
106
+ <Collapse items={docs} active={open} /> // 行内折叠
107
+ <Tree data={orgTree} checkable checkedKeys={keys} /> // 树形(父子联动)
108
+ <Cascader options={regions} value={['zj','hz']} /> // 级联选择
109
+ <Transfer data={members} targetKeys={selected} /> // 穿梭框
110
+ <Command items={commands} open={open} onOpenChange={setOpen} /> // ⌘K 命令面板
111
+ <Carousel autoplay>{slides}</Carousel> // 轮播
112
+ <Resizable defaultSize={180}>…</Resizable> // 拖拽分割
113
+ <Calendar month={5} year={2025} events={events} /> // 月历
114
+ <Watermark text="内部资料">…</Watermark> // 水印
115
+ <VirtualList height={400} itemHeight={36} items={rows} renderItem={render} /> // 虚拟列表
116
+ <QRCode value="https://weifuwu.dev" size={128} /> // 二维码(自研编码)
117
+ <Img src="photo.png" preview /> // 图片点击放大
118
+ <BackTop /> <Affix offsetTop={64}>…</Affix> // 回顶 / 固定
119
+ <HoverCard content={<UserCard />}>…</HoverCard> // 悬停富内容
120
+ <Mentions options={users} value={text} /> // @提及
121
+ <ContextMenu items={actions}>…</ContextMenu> // 右键菜单
122
+ <Menubar menus={menus} /> // 水平菜单
123
+ <InfiniteScroll hasMore onLoadMore>…</InfiniteScroll> // 无限滚动
124
+ ```
125
+
126
+ > 所有组件引用 `--wf-*` CSS 变量做主题,详见下文的「样式定制指南」。
127
+
128
+ ### 生命周期映射
129
+
130
+ 组件没有生命周期函数。每个阶段对应到代码的明确位置:
131
+
132
+ ```
133
+ mount ──────────────────────────────────────────
134
+ const Counter = (_init, ctx) => { ← mount(只一次)
135
+ let count = 0 ← 初始化状态
136
+ return (props) => { ← render 函数
137
+ // ... ← 每次 dirty/props 变化执行
138
+ }
139
+ }
140
+
141
+ ref ────────────────────────────────────────────
142
+ h('div', {
143
+ ref: (el) => {
144
+ if (el) { /* 元素已创建 */ } ← 相当于 onmounted
145
+ else { /* 元素已移除 */ } ← 相当于 onunmount
146
+ }
147
+ })
148
+
149
+ props 变化 ─────────────────────────────────────
150
+ return (props) => {
151
+ // 每次 render 都收到最新 props ← 相当于 onupdate
152
+ if (props.value !== prevValue) { ... }
153
+ }
154
+ ```
155
+
156
+ | 旧概念 | 新写法 |
157
+ |--------|--------|
158
+ | `onmount` | mount 外层函数直接写 |
159
+ | `onmounted` | `ref` 的 `if (el)` 分支 |
160
+ | `onunmount` | `ref` 的 `else` 分支 |
161
+ | `onupdate` | render 内层函数收新 props 自行比较 |
162
+ | `全局刷新` | `ctx.ui.render(['_wf_root'])` |
163
+ | `局部刷新` | `ctx.ui.render()` 或 `$.x = val` |
164
+ | `跨组件刷新` | `ctx.ui.selfId('name')` + `render(['name'])` |
165
+
166
+ ## 组件列表
167
+
168
+ ### 表单核心
169
+
170
+ | 组件 | 导入名 | 关键 Props | 说明 |
171
+ |-----|--------|-----------|------|
172
+ | Button | `Button` | `variant`, `size`, `loading`, `disabled`, `block`, `type` | 按钮 |
173
+ | Input | `Input` | `label`, `name`, `type`, `value`, `placeholder`, `required`, `disabled`, `error`, `hint`, `onInput`, `onChange` | 输入框 |
174
+ | Textarea | `Textarea` | `rows`, `maxLength`, `showCount`, `error` | 文本域 |
175
+ | Select | `Select` | `options: SelectOption[]`, `placeholder`, `searchable` | 下拉选择 |
176
+
177
+ ### 表单选择
178
+
179
+ | 组件 | 导入名 | 关键 Props | 说明 |
180
+ |-----|--------|-----------|------|
181
+ | Checkbox | `Checkbox` | `checked`, `label`, `onChange` | 复选框 |
182
+ | Switch | `Switch` | `checked`, `label`, `onChange` | 开关 |
183
+ | RadioGroup | `RadioGroup` | `options: RadioOption[]`, `value`, `name` | 单选组 |
184
+ | Slider | `Slider` | `min`, `max`, `step`, `value`, `onChange` | 滑块 |
185
+
186
+ ### 表单增强
187
+
188
+ | 组件 | 导入名 | 关键 Props | 说明 |
189
+ |-----|--------|-----------|------|
190
+ | Form | `Form` | `onSubmit`, `validation` | 表单容器 |
191
+ | Field | `Field` | `label`, `error`, `required`, `hint` | 字段包装 |
192
+ | FileUpload | `FileUpload` | `accept`, `multiple`, `maxSize`, `onChange` | 文件上传 |
193
+ | SearchInput | `SearchInput` | `value`, `placeholder`, `onInput`, `onClear` | 搜索框 |
194
+ | SegmentedControl | `SegmentedControl` | `options: SegmentedOption[]`, `value`, `onChange`, `size` | 分段选择器 |
195
+ | ProgressBar | `ProgressBar` | `value`, `max`, `label`, `showValue` | 进度条 |
196
+ | InputNumber | `InputNumber` | `value`, `min`, `max`, `step`, `precision`, `onChange` | 数字输入(增减按钮) |
197
+ | PasswordInput | `PasswordInput` | `value`, `onInput`, `autoComplete` | 密码输入(可见性切换) |
198
+ | TagsInput | `TagsInput` | `value: string[]`, `maxTags`, `allowDuplicates` | 标签输入(中文输入法感知) |
199
+
200
+ ### 数据展示
201
+
202
+ | 组件 | 导入名 | 关键 Props | 说明 |
203
+ |-----|--------|-----------|------|
204
+ | Table | `Table` | `columns: TableColumn[]`, `data`, `loading`, `sortKey`, `sortOrder`, `onSort`, `onRowClick` | 表格 |
205
+ | Card | `Card` | `variant`, `outlined`, `padding`, `clickable`, `hover`, `active`, `onClick` | 卡片 |
206
+ | Badge | `Badge` | `variant: BadgeVariant`, `dot` | 徽标 |
207
+ | Tag | `Tag` | `variant: 'default'\|'primary'\|'success'\|'danger'`, `closable`, `onClose` | 标签 |
208
+ | Avatar | `Avatar` | `src`, `name`, `size`, `color` | 头像 |
209
+ | AvatarGroup | `AvatarGroup` | `items`, `max`, `size` | 头像组(堆叠 + 溢出 +N) |
210
+ | Timeline | `Timeline` | `items: TimelineItem[]`, `mode`, `reverse` | 时间线(执行日志/历史) |
211
+ | Descriptions | `Descriptions` | `items: DescriptionItem[]`, `column`, `bordered` | 描述列表(详情页字段) |
212
+ | Markdown | `Markdown` | `content` | AI 回复渲染(安全子集 parser) |
213
+ | CodeBlock | `CodeBlock` | `code`, `lang`, `title` | 代码块(语言标签 + 复制) |
214
+ | Highlight | `Highlight` | `text`, `query: string \| string[]` | 搜索词高亮(mark) |
215
+ | List | `List` | `items`, `renderItem`, `divided`, `header/footer/empty` | 通用列表 |
216
+ | Result | `Result` | `status`, `title`, `desc`, `extra` | 结果页(成功/失败/警告/信息) |
217
+ | Icon | `Icon` | `name: IconName`, `size` | 图标(内置 25 个 stroke 图标,currentColor 随字号) |
218
+ | StatCard | `StatCard` | `label`, `value`, `trend: 'up'\|'down'`, `trendLabel`, `icon`, `animate` | 统计卡片 |
219
+ | PageHeader | `PageHeader` | `title`, `sub`, `display` | 页面标题(actions 放 children) |
220
+ | Img | `Img` | `src`, `alt`, `fallback`, `loading`, `width`, `height` | 图片(含 fallback) |
221
+ | InView | `InView` | `once`, `threshold`, `rootMargin`, `placeholder`, `onEnter` | 进入视窗后懒加载内容 |
222
+
223
+ ### 数据反馈
224
+
225
+ | 组件 | 导入名 | 关键 Props | 说明 |
226
+ |-----|--------|-----------|------|
227
+ | Modal | `Modal` | `open`, `title`, `onClose`, `width`, `footer`, `closable` | 模态框 |
228
+ | Confirm | `Confirm` | `open`, `message`, `confirmText`, `cancelText`, `variant`, `onConfirm`, `onCancel` | 确认对话框(同 `ctx.confirm()` 命令式) |
229
+ | Drawer | `Drawer` | `open`, `title`, `position: DrawerPosition`, `onClose`, `footer` | 抽屉 |
230
+ | Tooltip | `Tooltip` | `content`, `position: TooltipPosition`, `disabled` | 工具提示(hover/focus 触发) |
231
+ | Popover | `Popover` | `content`, `position: PopoverPosition`, `trigger`, `open`, `onOpenChange`, `disabled` | 弹出层 |
232
+ | Toast | `Toast` | `toasts: ToastItem[]`, `position`, `max`, `onRemove` | 消息提示 |
233
+ | Alert | `Alert` | `variant: AlertVariant`, `closable`, `onClose` | 警告提示(内容放 children) |
234
+ | Loading | `Loading` | `text` | 加载中 |
235
+ | EmptyState | `EmptyState` | `icon`, `text`, `hint` | 空状态(操作放 children) |
236
+ | Skeleton | `Skeleton` | `variant: SkeletonVariant`, `lines`, `cols`, `width`, `height` | 骨架屏 |
237
+
238
+ ### 导航组件
239
+
240
+ | 组件 | 导入名 | 关键 Props | 说明 |
241
+ |-----|--------|-----------|------|
242
+ | Breadcrumb | `Breadcrumb` | `items: BreadcrumbItem[]` | 面包屑 |
243
+ | Menu | `Menu` | `items: MenuItem[]`, `activeKey`, `onSelect` | 侧栏导航(分组 + 图标 + 方向键) |
244
+ | Tabs | `Tabs` | `items: TabItem[]`, `active`, `onChange` | 标签页 |
245
+ | Dropdown | `Dropdown` | `trigger`, `items: DropdownItem[]`, `open`, `onOpenChange` | 下拉菜单 |
246
+ | Pagination | `Pagination` | `total`, `page`, `pageSize`, `onChange` | 分页 |
247
+ | Steps | `Steps` | `items: StepItem[]`(`{ key, label }`), `current`, `active` | 步骤条 |
248
+ | Accordion | `Accordion` | `items: AccordionItem[]`, `multiple` | 手风琴 |
249
+
250
+ ### 新增批次(全量 92 组件)
251
+
252
+ | 组件 | 导入名 | 关键 Props | 说明 |
253
+ |-----|--------|-----------|------|
254
+ | Rate | `Rate` | `value`, `count`, `onChange`, `allowClear`, `readOnly`, `size` | 评分(键盘方向键/Home/End) |
255
+ | Typography | `Title` `Text` `Paragraph` | `Title: level 1-5`;`Text: type/strong/underline/strike/mark/code`;`Paragraph: ellipsis` | 语义排版(Title/Text/Paragraph 三组件) |
256
+ | Label | `Label` | `htmlFor`, `required` | 独立标签(必填星号) |
257
+ | AspectRatio | `AspectRatio` | `ratio` | 宽高比容器(内容填满) |
258
+ | Toggle | `Toggle` | `pressed`, `onPressedChange`, `variant`, `size` | 切换按钮(shadcn 对齐) |
259
+ | ToggleGroup | `ToggleGroup` | `type: 'single'\|'multiple'`, `options`, `value`, `onChange` | 切换组 |
260
+ | CheckboxGroup | `CheckboxGroup` | `options`, `value: string[]`, `onChange`, `cols` | 复选框组(栅格列数) |
261
+ | PinInput | `PinInput` | `length`, `value`, `onChange`, `type` | 验证码输入(自动聚焦/粘贴分派/回退) |
262
+ | CopyButton | `CopyButton` | `value`, `label`, `onCopy` | 复制按钮(clipboard + execCommand 降级) |
263
+ | ColorPicker | `ColorPicker` | `value`, `onChange`, `showInput`, `preset` | 颜色选择(预设色板 + hex 输入) |
264
+ | HoverCard | `HoverCard` | `content`, `position`, `openDelay`, `closeDelay` | 悬停富内容卡(shadcn) |
265
+ | Notification | `Notification` | 命令式 `notification.success/error/warning/open` | 队列式通知(antd 对齐) |
266
+ | BackTop | `BackTop` | `visibilityHeight`, `target`, `smooth` | 回到顶部(滚动超阈值显示) |
267
+ | Affix | `Affix` | `offsetTop`, `target` | 固定定位(滚动超阈值钉住) |
268
+ | ContextMenu | `ContextMenu` | `items: ContextMenuItem[]`(`{ label, onClick, variant: 'danger' }`) | 右键菜单(光标定位 + 方向键) |
269
+ | Mentions | `Mentions` | `options: { value, label }[]`, `value`, `onChange`, `prefix` | @提及(composition 抑制) |
270
+ | Collapse | `Collapse` | `items: CollapseItem[]`(`{ key, title, content, loading }`), `active`, `multiple` | 行内折叠(异步 loading) |
271
+ | Tree | `Tree` | `data: TreeNode[]`, `expandedKeys`, `checkedKeys`, `checkable`, `selectedKeys`, `onCheck/onExpand/onSelect` | 树(递归 + 勾选父子联动 + 半选传播) |
272
+ | Cascader | `Cascader` | `options: CascaderOption[]`, `value: string[]`, `onChange` | 级联选择(多列推进) |
273
+ | Transfer | `Transfer` | `data: { key, label }[]`, `targetKeys`, `onChange`, `titles` | 穿梭框(选中 + 批量移动) |
274
+ | Command | `Command` | `items: CommandItem[]`, `open`, `onOpenChange`, `shortcut` | 命令面板(⌘K 全局 + 键盘流) |
275
+ | Menubar | `Menubar` | `menus: { key, label, items }[]` | 水平菜单栏(←→ 切换 + ↓ 展开) |
276
+ | Carousel | `Carousel` | `children`, `autoplay`, `interval`, `loop`, `showArrows/Dots` | 轮播(箭头/圆点/循环/自动播放) |
277
+ | Resizable | `Resizable` | `direction`, `defaultSize`, `min/maxSize` | 拖拽分割面板(pointer + 键盘方向键) |
278
+ | Calendar | `Calendar` | `month`, `year`, `events`, `selectedDate`, `onMonthChange/onSelectDate` | 月历(事件点 + 月切换 + 选日) |
279
+ | Watermark | `Watermark` | `text`, `fontSize`, `rotate`, `zIndex` | 水印(canvas 平铺) |
280
+ | VirtualList | `VirtualList` | `items`, `height`, `itemHeight`, `renderItem`, `overscan` | 虚拟列表(spacer + 可见窗口,1000+ 条) |
281
+ | InfiniteScroll | `InfiniteScroll` | `hasMore`, `loadMore`, `children`, `loader` | 触底加载(IntersectionObserver) |
282
+ | QRCode | `QRCode` | `value`, `ecLevel`, `size`, `color`, `bgColor` | 二维码(自研 Reed-Solomon,版本 1-6) |
283
+
284
+ ### 图表
285
+
286
+ | 组件 | 导入名 | 关键 Props | 说明 |
287
+ |-----|--------|-----------|------|
288
+ | Chart | `Chart` | `type: ChartType`, `data`, `options`, `title`, `area` | SVG 图表(line/bar/pie)|
289
+ | DatePicker | `DatePicker` | `mode: DatePickerMode`, `value`, `onChange`, `placeholder`, `disabled` | 日期选择器(date/datetime/time/range)|
290
+ | Editor | `Editor` | `value`, `onChange`, `toolbar`, `placeholder`, `disabled` | 富文本编辑器,零依赖 |
291
+
292
+ ### 布局
293
+
294
+ | 组件 | 导入名 | 关键 Props | 说明 |
295
+ |-----|--------|-----------|------|
296
+ | Divider | `Divider` | `vertical` | 分割线(水平带文字放 children,`vertical` 垂直) |
297
+
298
+ ### AI 交互原语(wf: 协议配套)
299
+
300
+ | 组件 | 导入名 | 关键 Props | 说明 |
301
+ |-----|--------|-----------|------|
302
+ | AiChat | `AiChat` | `chat`, `maxHeight?`, `labels?`, `renderMessage?`, `renderToolArgs?` | 标准 AI 对话界面:气泡 + 工具卡 + 审批卡 + 自动滚动 + 错误重试(接收 `ctx.ui.useChat()` handle) |
303
+ | MessageBubble | `MessageBubble` | `content`, `role`, `status`, `actions` | 独立消息气泡(业务聊天页复用) |
304
+ | ToolCallCard | `ToolCallCard` | `call`, `progress?`, `result?`, `renderArgs?` | 工具调用卡片:running(进度条)/ ok / error 三态(协议 §4) |
305
+ | ApprovalCard | `ApprovalCard` | `request`, `status?`, `onApprove`, `onReject` | 人工审批卡片:待批(允许/拒绝+备注)/ 已批 / 已拒 / 超时(协议 §4.5) |
306
+
307
+ ### 全局工具
308
+
309
+ | 组件 | 导入名 | 关键 Props | 说明 |
310
+ |-----|--------|-----------|------|
311
+ | ThemeSwitch | `ThemeSwitch` | `mode: 'auto'\|'light'\|'dark'`, `onChange`, `storageKey` | 主题切换(auto/light/dark,localStorage 持久化);另有 `applyTheme()` / `getTheme()` 命令式工具 |
312
+
313
+ ---
314
+