@manohub/ui 0.10.4 → 1.0.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 +155 -155
- package/dist/components/form/index.js +8 -1
- package/dist/components/tabs/index.d.ts +9 -6
- package/dist/components/tabs/index.js +6 -1
- package/dist/styles/components/avatar.css +131 -131
- package/dist/styles/components/avatar.tokens.css +24 -24
- package/dist/styles/components/badge.css +266 -266
- package/dist/styles/components/badge.tokens.css +24 -24
- package/dist/styles/components/button.css +460 -460
- package/dist/styles/components/capsule.css +128 -128
- package/dist/styles/components/capsule.tokens.css +27 -27
- package/dist/styles/components/card.css +198 -198
- package/dist/styles/components/checkbox.css +145 -145
- package/dist/styles/components/checkbox.tokens.css +26 -26
- package/dist/styles/components/code-block.css +216 -216
- package/dist/styles/components/code-block.tokens.css +40 -40
- package/dist/styles/components/collapse.css +62 -62
- package/dist/styles/components/collapse.tokens.css +20 -20
- package/dist/styles/components/dialog.css +158 -158
- package/dist/styles/components/dialog.tokens.css +24 -24
- package/dist/styles/components/divider.css +75 -75
- package/dist/styles/components/divider.tokens.css +22 -22
- package/dist/styles/components/drawer.css +143 -143
- package/dist/styles/components/drawer.tokens.css +22 -22
- package/dist/styles/components/filter.css +29 -29
- package/dist/styles/components/form.css +442 -430
- package/dist/styles/components/form.tokens.css +15 -15
- package/dist/styles/components/input.css +538 -533
- package/dist/styles/components/input.tokens.css +43 -43
- package/dist/styles/components/layout.css +200 -200
- package/dist/styles/components/list-view.css +244 -244
- package/dist/styles/components/loading.css +76 -76
- package/dist/styles/components/loading.tokens.css +23 -23
- package/dist/styles/components/nav.css +48 -48
- package/dist/styles/components/notice.css +153 -153
- package/dist/styles/components/notice.tokens.css +17 -17
- package/dist/styles/components/notification.css +159 -159
- package/dist/styles/components/notification.tokens.css +37 -37
- package/dist/styles/components/page.css +473 -473
- package/dist/styles/components/pagination.css +303 -303
- package/dist/styles/components/pagination.tokens.css +32 -32
- package/dist/styles/components/panel.css +77 -77
- package/dist/styles/components/query-state.css +88 -88
- package/dist/styles/components/radio.css +271 -271
- package/dist/styles/components/radio.tokens.css +26 -26
- package/dist/styles/components/search.css +34 -34
- package/dist/styles/components/select.css +326 -326
- package/dist/styles/components/select.tokens.css +44 -44
- package/dist/styles/components/skeleton.css +60 -60
- package/dist/styles/components/skeleton.tokens.css +27 -27
- package/dist/styles/components/steps.css +205 -205
- package/dist/styles/components/steps.tokens.css +44 -44
- package/dist/styles/components/switch.css +165 -165
- package/dist/styles/components/switch.tokens.css +26 -26
- package/dist/styles/components/tabbar.css +235 -235
- package/dist/styles/components/tabbar.tokens.css +30 -30
- package/dist/styles/components/table.css +504 -504
- package/dist/styles/components/table.tokens.css +44 -44
- package/dist/styles/components/tag.css +127 -127
- package/dist/styles/components/tag.tokens.css +24 -24
- package/dist/styles/components/toast.css +185 -185
- package/dist/styles/components/toast.tokens.css +26 -26
- package/dist/styles/components/tooltip.css +89 -89
- package/dist/styles/components/tooltip.tokens.css +25 -25
- package/dist/styles/components/tree.css +173 -173
- package/dist/styles/components/upload.css +151 -151
- package/dist/styles/components/upload.tokens.css +27 -27
- package/dist/styles/index.css +153 -153
- package/dist/styles/operations/collapse.css +84 -84
- package/dist/styles/operations/popup.css +193 -193
- package/dist/styles/operations/tabs.css +82 -73
- package/package.json +62 -62
package/README.md
CHANGED
|
@@ -1,155 +1,155 @@
|
|
|
1
|
-
# @manohub/ui
|
|
2
|
-
|
|
3
|
-
AIHub **自绘组件层**:不依赖 farris 的手写 Vue TSX 组件 + 自带令牌层。
|
|
4
|
-
|
|
5
|
-
本包分三层,**可分别引用**:
|
|
6
|
-
|
|
7
|
-
| 层 | 入口 | 内容 |
|
|
8
|
-
|---|---|---|
|
|
9
|
-
| ① 主题 | `@manohub/theme/default.css`(兜底)/ `@manohub/theme/farris.css`(Farris 规范) | **全局**令牌(值)—— 随主题包独立发布,换主题只换这一行 |
|
|
10
|
-
| ② 组件面 | `@manohub/ui/styles.css` | **元素级 reset**(只有盒模型 + 容器基座两面,见下)+ 类与状态协议 + 组件令牌基础值,**无需 JS** 即可使用 |
|
|
11
|
-
| ③ Vue 层 | `@manohub/ui` | Vue 组件:渲染 ② 的类 + 行为增强 |
|
|
12
|
-
| ④ 服务层 | `@manohub/ui` | 命令式反馈:`toast()` / `confirm()` / `alert()` / `showLoading()`(宿主 + 队列 + 生命周期,共用 ③ 的组件) |
|
|
13
|
-
|
|
14
|
-
- **视觉与几何**:《Farris Web 基础视觉规范》(`@aihub/theme` 的令牌与组件实测值)
|
|
15
|
-
- **令牌命名**:daisyUI 式语义槽位(`--ui-primary` / `--ui-base-content` / `--ui-info*` / `--ui-warning*` …,`default ≠ primary`)
|
|
16
|
-
- **组件 API**:shadcn 通行词汇(变体维度 `tone` × `shape` × `size`、compound 点号子件、受控 prop + 语义事件)
|
|
17
|
-
- **实现**:零依赖手写 CSS,类名 `.mh-*`(bem-lite)
|
|
18
|
-
|
|
19
|
-
> **0.5.0(破坏性变更)**:`Section` 组件已退役 —— 它的「标题行 + 右端操作位(`extra`)」能力并入
|
|
20
|
-
> **`Form.Header`**(支持 `title` / `description` / `extra`,且成员归位到表单最前)。
|
|
21
|
-
> 旧写法 `Section` / `Form.Section` 统一改为 `Form.Header`;需要「区块分组」时用 `Panel` 或嵌套容器。
|
|
22
|
-
|
|
23
|
-
## 安装
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
pnpm add @manohub/ui @manohub/theme
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 接入
|
|
30
|
-
|
|
31
|
-
样式两行,顺序固定(先主题后组件面;若应用的样式链已级联本包,则不必单独引):
|
|
32
|
-
|
|
33
|
-
```css
|
|
34
|
-
@import "@manohub/theme/default.css"; /* ① 全局令牌(值) */
|
|
35
|
-
@import "@manohub/ui/styles.css"; /* ② 组件面(类 + 组件令牌值) */
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
只写静态页(不装 Vue)时引这两行即可 —— 类名与 `data-*` 状态协议直接可用。
|
|
39
|
-
|
|
40
|
-
**② 的第一条 import 就是元素级 reset**(随包内置,不需要第三行),它只有两面:
|
|
41
|
-
|
|
42
|
-
1. **盒模型**:`box-sizing: border-box` 覆盖容器、全部后代与伪元素(本包所有面的几何前提);
|
|
43
|
-
2. **容器基座**:`[data-manohub-ui]` 上的字族 / 字号 / 行高 / 字色 / 底色 / 整链高度(令牌的落点)。
|
|
44
|
-
|
|
45
|
-
作用域锚 `[data-manohub-ui]` 且特异性为 0 —— 应用侧写任何元素选择器都能盖过它。
|
|
46
|
-
**它有意不再归零标题字阶、列表序号、链接下划线、控件外观**:那些规则在 Tailwind 的层外
|
|
47
|
-
(未分层 > 分层),会把消费方的工具类整片压住(`border*`、`img` 上的 `h-*`、`hidden` …);
|
|
48
|
-
需要归零的元素各自归到渲染它的组件面上(`img` 在 Avatar / Upload、`a` 在 Button、
|
|
49
|
-
`textarea` 的 `resize` 在 `.mh-input--textarea`、`h1`-`h6` 在 `.mh-text`)。
|
|
50
|
-
Tailwind 消费方另有 preflight 兜底,两者不冲突。
|
|
51
|
-
|
|
52
|
-
所以**不必再自己写一份全局 reset**;也**不要**用元素级选择器去补(那正是被压住的成因)。
|
|
53
|
-
|
|
54
|
-
本包**可独立发布**:组件与类型一律从 `@manohub/ui` 直接引;下游(如 `@manohub/kit`)若转出口,是下游自己的选择。
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
import { Card, Form, Tree, Checkbox } from '@manohub/ui'
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## 组件清单
|
|
61
|
-
|
|
62
|
-
| 分组 | 组件 |
|
|
63
|
-
|---|---|
|
|
64
|
-
| 容器与分区 | `Page`(页面级骨架:`.Header` / `.Body` / `.Footer` / `.Filter` / `.Toolbar` / `.Split`)、`Panel`(+ `.Header` / `.Body` / `.Footer`)、`Card`(+ 三件)、`Nav`、`Layout`(`Layout.Row` 排「行」/ `Layout.Column` 排「列」:轴向 × 间距档 × 对齐) |
|
|
65
|
-
| 数据展示 | `Tree`、`ListView`(+ `.CardItem`)、`Badge`、`Tag`(`Badge` 的可关闭 / 可新增封装) |
|
|
66
|
-
| 展示 | `Avatar`(+ `.Group`)、`Skeleton`(行 / 列表 / 块状) |
|
|
67
|
-
| 表单基础(**自绘**) | `Button`(+ `.Group` / `.Divider`;五型 / 小号 / 加载 / 菜单按钮 / 连体切换)、`Input`(+ `.Group` / `.Chip` / `.Display` / `.Textarea`;清除 / 可见性切换 / 校验)、`Search`(搜索框:值 / 搜索 / 清空三条回调)、`Select`(单选 / 多选 / 搜索 / 加载;面板用原生 popover)、`SelectTree`(树形态:仅叶子可选 + 本地过滤 + 命中高亮;与 `Select` 平级导出、共用触发器与面板)、`Switch`(表格档 / 表单档) |
|
|
68
|
-
| 表单与选择 | `Form`(+ `.Header` / `.Item`;标签体系、成员归位、`v-model` 值收集与命令式 `clear()`)、`Filter`(+ `.Item`;`Form` 的壳:条件字段写成子件、控件自放、查询/重置与快照归一)、`Checkbox`、`Radio`(+ `.Group` / `.Card`;卡片式单选)、`Capsule`(胶囊选择器;胶囊 / 方形两档外形,与 `Tabs` 组合即页签) |
|
|
69
|
-
| 反馈与三态 | `Notice`(条状提示)、`Notification`(通知卡:标题 + 头像 / 标签 / 操作 / 关闭位)、`QueryState`(三态容器;内建空 / 错误插画取自设计交付的四张 SVG,原样内联在 `src/utils/state-illustration.ts`)、`Loading`(转圈 + 遮罩:行内 / 区域 / 全屏三形态) |
|
|
70
|
-
| 反馈与引导(**自绘**) | `Toast`(消息提示:语义四档 / loading + 可选动作 + 自动消失计时 + `.Stack` 堆叠)、`Steps`(步骤条:节点式 / 燕尾段式 / `.Progress` 进度条) |
|
|
71
|
-
| 数据展示(**自绘**) | `Table`(列 × 数据 + 选择列 + 排序事件 + 固定表头 / 固定列 + 批量栏 / 合计行;排序与列宽拖拽算法归调用方)、`Pagination`(总数 / 每页条数 / 页码窗口 / 简单档 / 外框档)、`TabBar`(下划线页签 + 「更多」收纳) |
|
|
72
|
-
| 内容与文件 | `CodeBlock`(**一族三件**:组合件 `CodeBlock` 按 `editable` 切只读 / 编辑两形态;`.View` 只读展示 —— 行内 chip / 代码块 + 语言角标 + 图标复制位;`.Editor` 可编辑 —— 等宽多行 + 按行自适应 / 限高内滚 / 只读、禁用)、`Upload`(+ `.Thumbs`;拖拽 / 点击上传区 + 已传文件列表) |
|
|
73
|
-
| 浮层(**自绘**) | `Dialog`(原生 `<dialog>` + 模态皮肤;关闭受控)、`Tooltip`(**零 JS**:显隐与定位全走操作层 hover 档) |
|
|
74
|
-
| 操作层(跨件原语) | `Collapse`(+ `.Stack`)、`Tabs`(+ `TabPanel`,面板切换骨架 —— 显隐归组件层,非零 JS 原语);浮层只提供样式层(`styles/operations/popup.css`,零 JS 可直接用),Vue 浮层仍用 farris 适配件 |
|
|
75
|
-
|
|
76
|
-
## 三态的操作按钮
|
|
77
|
-
|
|
78
|
-
`QueryState` / `Tree` / `ListView` 的空态·错误态操作按钮就是**本包的 `Button`**(`variant="primary"`),
|
|
79
|
-
与全站按钮同族 —— 应用**不需要**注入任何东西,只要把文案与回调给上:
|
|
80
|
-
|
|
81
|
-
```vue
|
|
82
|
-
<QueryState
|
|
83
|
-
:empty="list.length === 0"
|
|
84
|
-
empty-action-text="新建"
|
|
85
|
-
:on-empty-action="openCreate"
|
|
86
|
-
>
|
|
87
|
-
<MyList />
|
|
88
|
-
</QueryState>
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
- 要换外观:改主题令牌(`Button` 的外观档位是 `variant`);
|
|
92
|
-
- 要换结构(多个按钮 / 自定义动作区):用 `actions` 插槽自绘。
|
|
93
|
-
|
|
94
|
-
## 服务层(组件树之外调反馈)
|
|
95
|
-
|
|
96
|
-
组件是**受控**的(可见性归调用方);组件树之外(请求回调、路由守卫、工具函数里)要弹提示时用服务层:
|
|
97
|
-
|
|
98
|
-
```ts
|
|
99
|
-
import { toast, confirm, alert, showLoading, configureHost } from '@manohub/ui'
|
|
100
|
-
|
|
101
|
-
toast('success', '保存成功') // 3 秒自动消失
|
|
102
|
-
toast('error', '导出失败', { action: { text: '重试', onClick: retry } })
|
|
103
|
-
const pending = toast('loading', '正在导入…', { duration: 0 }) // 常驻,完成后自己收
|
|
104
|
-
pending.close()
|
|
105
|
-
|
|
106
|
-
if (await confirm({ title: '删除确认', detail: '删除后不可恢复', okDanger: true })) await remove()
|
|
107
|
-
await alert({ title: '导入完成', detail: '共 128 条' })
|
|
108
|
-
|
|
109
|
-
const done = showLoading('保存中…') // 引用计数:并发调用要各关各的
|
|
110
|
-
try { await save() } finally { done() }
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**四件必须知道的事**:
|
|
114
|
-
|
|
115
|
-
1. **服务层不新造浮层**:`toast()` 渲染的是本包的 `Toast`、`confirm()` 渲染的是本包的 `Dialog`、
|
|
116
|
-
`showLoading()` 渲染的是本包的 `Loading` —— 外观改一处两处一起变。
|
|
117
|
-
2. **宿主即渲染位置**:解析顺序是「**显式 `configureHost(el)`** → 带 `[data-manohub-ui]` 作用域锚的容器
|
|
118
|
-
→ `document.body`」。微前端下**必须落回本应用自己的容器**:本包全部令牌(全局值 + 组件值)都锚在
|
|
119
|
-
`[data-manohub-ui]` 上,落在容器外的浮层会「样式全丢」(变量解析为空 +
|
|
120
|
-
应用侧样式被 `scopecss` 前缀化后匹配不到)。骨架层只需在包裹节点上补一个
|
|
121
|
-
`data-manohub-ui` 属性,服务层不必反向依赖它。
|
|
122
|
-
注:`.app-container` 是 `@manohub/kit` 的输出类名(内部命名),**不是**跨包契约,服务层不认它。
|
|
123
|
-
3. **按需挂载、自动收尾**:首次调用才建宿主与 Vue 实例(模块顶层零 DOM 操作);
|
|
124
|
-
`toast` 队列空了、`loading` 计数归零即收掉宿主 —— 反复重挂不留悬挂实例。
|
|
125
|
-
4. **`loading` 是引用计数语义**:并发的两次「显示」只关一次时遮罩仍在(先结束的那个不会把
|
|
126
|
-
别人的遮罩一起收掉)。推荐用返回的句柄在 `finally` 里关掉自己那一次。
|
|
127
|
-
|
|
128
|
-
## 主题层
|
|
129
|
-
|
|
130
|
-
全局令牌(`--ui-primary` / `--ui-space-*` / `--ui-font-*` 这类跨件共用的值)**不在本包**,已拆成独立包
|
|
131
|
-
**`@manohub/theme`**(值层与面层分开:值随主题变、面不随主题变)。每个主题分五片:
|
|
132
|
-
`colors` / `typography` / `spacing` / `radius` / `shadows`,一律锚定 **`[data-manohub-ui]`**
|
|
133
|
-
(库品牌作用域锚;micro-app 的 scopecss 不作用域化 `:root`,定义在 `:root` 会泄漏到宿主)。
|
|
134
|
-
|
|
135
|
-
只服务单一组件的令牌分两半落在本包:
|
|
136
|
-
|
|
137
|
-
| 位置 | 内容 | 锚 |
|
|
138
|
-
|---|---|---|
|
|
139
|
-
| `styles/components/<件>.tokens.css` | **基础值**(唯一的、两套主题同值的那一条) | `[data-manohub-ui]` |
|
|
140
|
-
| `styles/components/<件>.css` | **档位改写**(`.mh-<件>--<档>` 覆盖同一令牌)+ `--mh-*` 内部状态变量 | 元件根类 / 档位类 |
|
|
141
|
-
|
|
142
|
-
后一半必须在面里:它们靠「同一元素上两个选择器改写同一个令牌」生效,搬走就断链。
|
|
143
|
-
|
|
144
|
-
随包两套:
|
|
145
|
-
|
|
146
|
-
| 主题 | 入口 | 锚点 | 取值来源 |
|
|
147
|
-
|---|---|---|---|
|
|
148
|
-
| `default` | `@manohub/theme/default.css` | `[data-manohub-ui]`(兜底套) | AIHub 品牌蓝(primary `#2660FF`)|
|
|
149
|
-
| `farris` | `@manohub/theme/farris.css` | `[data-manohub-ui][data-theme='farris']` | 《Farris Web 基础视觉规范》(primary `#2a87ff`,色板编号 Th/Au/Ne/Te 逐条标注)|
|
|
150
|
-
|
|
151
|
-
换皮只需给容器加属性(`createSubApp({ theme: 'farris' })` 会写 `data-theme`),不动类名、不动组件代码、不重打包。
|
|
152
|
-
新增主题 = `packages/theme/src/<name>/` 新目录,令牌锚 `[data-manohub-ui][data-theme='<name>']`,
|
|
153
|
-
且必须**全量覆盖** default 的令牌。
|
|
154
|
-
|
|
155
|
-
局部换主题:在更深的容器上重设变量即可,例如 `.role-tree-pane { --ui-primary: #7C3AED; }`。
|
|
1
|
+
# @manohub/ui
|
|
2
|
+
|
|
3
|
+
AIHub **自绘组件层**:不依赖 farris 的手写 Vue TSX 组件 + 自带令牌层。
|
|
4
|
+
|
|
5
|
+
本包分三层,**可分别引用**:
|
|
6
|
+
|
|
7
|
+
| 层 | 入口 | 内容 |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| ① 主题 | `@manohub/theme/default.css`(兜底)/ `@manohub/theme/farris.css`(Farris 规范) | **全局**令牌(值)—— 随主题包独立发布,换主题只换这一行 |
|
|
10
|
+
| ② 组件面 | `@manohub/ui/styles.css` | **元素级 reset**(只有盒模型 + 容器基座两面,见下)+ 类与状态协议 + 组件令牌基础值,**无需 JS** 即可使用 |
|
|
11
|
+
| ③ Vue 层 | `@manohub/ui` | Vue 组件:渲染 ② 的类 + 行为增强 |
|
|
12
|
+
| ④ 服务层 | `@manohub/ui` | 命令式反馈:`toast()` / `confirm()` / `alert()` / `showLoading()`(宿主 + 队列 + 生命周期,共用 ③ 的组件) |
|
|
13
|
+
|
|
14
|
+
- **视觉与几何**:《Farris Web 基础视觉规范》(`@aihub/theme` 的令牌与组件实测值)
|
|
15
|
+
- **令牌命名**:daisyUI 式语义槽位(`--ui-primary` / `--ui-base-content` / `--ui-info*` / `--ui-warning*` …,`default ≠ primary`)
|
|
16
|
+
- **组件 API**:shadcn 通行词汇(变体维度 `tone` × `shape` × `size`、compound 点号子件、受控 prop + 语义事件)
|
|
17
|
+
- **实现**:零依赖手写 CSS,类名 `.mh-*`(bem-lite)
|
|
18
|
+
|
|
19
|
+
> **0.5.0(破坏性变更)**:`Section` 组件已退役 —— 它的「标题行 + 右端操作位(`extra`)」能力并入
|
|
20
|
+
> **`Form.Header`**(支持 `title` / `description` / `extra`,且成员归位到表单最前)。
|
|
21
|
+
> 旧写法 `Section` / `Form.Section` 统一改为 `Form.Header`;需要「区块分组」时用 `Panel` 或嵌套容器。
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm add @manohub/ui @manohub/theme
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 接入
|
|
30
|
+
|
|
31
|
+
样式两行,顺序固定(先主题后组件面;若应用的样式链已级联本包,则不必单独引):
|
|
32
|
+
|
|
33
|
+
```css
|
|
34
|
+
@import "@manohub/theme/default.css"; /* ① 全局令牌(值) */
|
|
35
|
+
@import "@manohub/ui/styles.css"; /* ② 组件面(类 + 组件令牌值) */
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
只写静态页(不装 Vue)时引这两行即可 —— 类名与 `data-*` 状态协议直接可用。
|
|
39
|
+
|
|
40
|
+
**② 的第一条 import 就是元素级 reset**(随包内置,不需要第三行),它只有两面:
|
|
41
|
+
|
|
42
|
+
1. **盒模型**:`box-sizing: border-box` 覆盖容器、全部后代与伪元素(本包所有面的几何前提);
|
|
43
|
+
2. **容器基座**:`[data-manohub-ui]` 上的字族 / 字号 / 行高 / 字色 / 底色 / 整链高度(令牌的落点)。
|
|
44
|
+
|
|
45
|
+
作用域锚 `[data-manohub-ui]` 且特异性为 0 —— 应用侧写任何元素选择器都能盖过它。
|
|
46
|
+
**它有意不再归零标题字阶、列表序号、链接下划线、控件外观**:那些规则在 Tailwind 的层外
|
|
47
|
+
(未分层 > 分层),会把消费方的工具类整片压住(`border*`、`img` 上的 `h-*`、`hidden` …);
|
|
48
|
+
需要归零的元素各自归到渲染它的组件面上(`img` 在 Avatar / Upload、`a` 在 Button、
|
|
49
|
+
`textarea` 的 `resize` 在 `.mh-input--textarea`、`h1`-`h6` 在 `.mh-text`)。
|
|
50
|
+
Tailwind 消费方另有 preflight 兜底,两者不冲突。
|
|
51
|
+
|
|
52
|
+
所以**不必再自己写一份全局 reset**;也**不要**用元素级选择器去补(那正是被压住的成因)。
|
|
53
|
+
|
|
54
|
+
本包**可独立发布**:组件与类型一律从 `@manohub/ui` 直接引;下游(如 `@manohub/kit`)若转出口,是下游自己的选择。
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { Card, Form, Tree, Checkbox } from '@manohub/ui'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 组件清单
|
|
61
|
+
|
|
62
|
+
| 分组 | 组件 |
|
|
63
|
+
|---|---|
|
|
64
|
+
| 容器与分区 | `Page`(页面级骨架:`.Header` / `.Body` / `.Footer` / `.Filter` / `.Toolbar` / `.Split`)、`Panel`(+ `.Header` / `.Body` / `.Footer`)、`Card`(+ 三件)、`Nav`、`Layout`(`Layout.Row` 排「行」/ `Layout.Column` 排「列」:轴向 × 间距档 × 对齐) |
|
|
65
|
+
| 数据展示 | `Tree`、`ListView`(+ `.CardItem`)、`Badge`、`Tag`(`Badge` 的可关闭 / 可新增封装) |
|
|
66
|
+
| 展示 | `Avatar`(+ `.Group`)、`Skeleton`(行 / 列表 / 块状) |
|
|
67
|
+
| 表单基础(**自绘**) | `Button`(+ `.Group` / `.Divider`;五型 / 小号 / 加载 / 菜单按钮 / 连体切换)、`Input`(+ `.Group` / `.Chip` / `.Display` / `.Textarea`;清除 / 可见性切换 / 校验)、`Search`(搜索框:值 / 搜索 / 清空三条回调)、`Select`(单选 / 多选 / 搜索 / 加载;面板用原生 popover)、`SelectTree`(树形态:仅叶子可选 + 本地过滤 + 命中高亮;与 `Select` 平级导出、共用触发器与面板)、`Switch`(表格档 / 表单档) |
|
|
68
|
+
| 表单与选择 | `Form`(+ `.Header` / `.Item`;标签体系、成员归位、`v-model` 值收集与命令式 `clear()`)、`Filter`(+ `.Item`;`Form` 的壳:条件字段写成子件、控件自放、查询/重置与快照归一)、`Checkbox`、`Radio`(+ `.Group` / `.Card`;卡片式单选)、`Capsule`(胶囊选择器;胶囊 / 方形两档外形,与 `Tabs` 组合即页签) |
|
|
69
|
+
| 反馈与三态 | `Notice`(条状提示)、`Notification`(通知卡:标题 + 头像 / 标签 / 操作 / 关闭位)、`QueryState`(三态容器;内建空 / 错误插画取自设计交付的四张 SVG,原样内联在 `src/utils/state-illustration.ts`)、`Loading`(转圈 + 遮罩:行内 / 区域 / 全屏三形态) |
|
|
70
|
+
| 反馈与引导(**自绘**) | `Toast`(消息提示:语义四档 / loading + 可选动作 + 自动消失计时 + `.Stack` 堆叠)、`Steps`(步骤条:节点式 / 燕尾段式 / `.Progress` 进度条) |
|
|
71
|
+
| 数据展示(**自绘**) | `Table`(列 × 数据 + 选择列 + 排序事件 + 固定表头 / 固定列 + 批量栏 / 合计行;排序与列宽拖拽算法归调用方)、`Pagination`(总数 / 每页条数 / 页码窗口 / 简单档 / 外框档)、`TabBar`(下划线页签 + 「更多」收纳) |
|
|
72
|
+
| 内容与文件 | `CodeBlock`(**一族三件**:组合件 `CodeBlock` 按 `editable` 切只读 / 编辑两形态;`.View` 只读展示 —— 行内 chip / 代码块 + 语言角标 + 图标复制位;`.Editor` 可编辑 —— 等宽多行 + 按行自适应 / 限高内滚 / 只读、禁用)、`Upload`(+ `.Thumbs`;拖拽 / 点击上传区 + 已传文件列表) |
|
|
73
|
+
| 浮层(**自绘**) | `Dialog`(原生 `<dialog>` + 模态皮肤;关闭受控)、`Tooltip`(**零 JS**:显隐与定位全走操作层 hover 档) |
|
|
74
|
+
| 操作层(跨件原语) | `Collapse`(+ `.Stack`)、`Tabs`(+ `TabPanel`,面板切换骨架 —— 显隐归组件层,非零 JS 原语);浮层只提供样式层(`styles/operations/popup.css`,零 JS 可直接用),Vue 浮层仍用 farris 适配件 |
|
|
75
|
+
|
|
76
|
+
## 三态的操作按钮
|
|
77
|
+
|
|
78
|
+
`QueryState` / `Tree` / `ListView` 的空态·错误态操作按钮就是**本包的 `Button`**(`variant="primary"`),
|
|
79
|
+
与全站按钮同族 —— 应用**不需要**注入任何东西,只要把文案与回调给上:
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<QueryState
|
|
83
|
+
:empty="list.length === 0"
|
|
84
|
+
empty-action-text="新建"
|
|
85
|
+
:on-empty-action="openCreate"
|
|
86
|
+
>
|
|
87
|
+
<MyList />
|
|
88
|
+
</QueryState>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- 要换外观:改主题令牌(`Button` 的外观档位是 `variant`);
|
|
92
|
+
- 要换结构(多个按钮 / 自定义动作区):用 `actions` 插槽自绘。
|
|
93
|
+
|
|
94
|
+
## 服务层(组件树之外调反馈)
|
|
95
|
+
|
|
96
|
+
组件是**受控**的(可见性归调用方);组件树之外(请求回调、路由守卫、工具函数里)要弹提示时用服务层:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { toast, confirm, alert, showLoading, configureHost } from '@manohub/ui'
|
|
100
|
+
|
|
101
|
+
toast('success', '保存成功') // 3 秒自动消失
|
|
102
|
+
toast('error', '导出失败', { action: { text: '重试', onClick: retry } })
|
|
103
|
+
const pending = toast('loading', '正在导入…', { duration: 0 }) // 常驻,完成后自己收
|
|
104
|
+
pending.close()
|
|
105
|
+
|
|
106
|
+
if (await confirm({ title: '删除确认', detail: '删除后不可恢复', okDanger: true })) await remove()
|
|
107
|
+
await alert({ title: '导入完成', detail: '共 128 条' })
|
|
108
|
+
|
|
109
|
+
const done = showLoading('保存中…') // 引用计数:并发调用要各关各的
|
|
110
|
+
try { await save() } finally { done() }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**四件必须知道的事**:
|
|
114
|
+
|
|
115
|
+
1. **服务层不新造浮层**:`toast()` 渲染的是本包的 `Toast`、`confirm()` 渲染的是本包的 `Dialog`、
|
|
116
|
+
`showLoading()` 渲染的是本包的 `Loading` —— 外观改一处两处一起变。
|
|
117
|
+
2. **宿主即渲染位置**:解析顺序是「**显式 `configureHost(el)`** → 带 `[data-manohub-ui]` 作用域锚的容器
|
|
118
|
+
→ `document.body`」。微前端下**必须落回本应用自己的容器**:本包全部令牌(全局值 + 组件值)都锚在
|
|
119
|
+
`[data-manohub-ui]` 上,落在容器外的浮层会「样式全丢」(变量解析为空 +
|
|
120
|
+
应用侧样式被 `scopecss` 前缀化后匹配不到)。骨架层只需在包裹节点上补一个
|
|
121
|
+
`data-manohub-ui` 属性,服务层不必反向依赖它。
|
|
122
|
+
注:`.app-container` 是 `@manohub/kit` 的输出类名(内部命名),**不是**跨包契约,服务层不认它。
|
|
123
|
+
3. **按需挂载、自动收尾**:首次调用才建宿主与 Vue 实例(模块顶层零 DOM 操作);
|
|
124
|
+
`toast` 队列空了、`loading` 计数归零即收掉宿主 —— 反复重挂不留悬挂实例。
|
|
125
|
+
4. **`loading` 是引用计数语义**:并发的两次「显示」只关一次时遮罩仍在(先结束的那个不会把
|
|
126
|
+
别人的遮罩一起收掉)。推荐用返回的句柄在 `finally` 里关掉自己那一次。
|
|
127
|
+
|
|
128
|
+
## 主题层
|
|
129
|
+
|
|
130
|
+
全局令牌(`--ui-primary` / `--ui-space-*` / `--ui-font-*` 这类跨件共用的值)**不在本包**,已拆成独立包
|
|
131
|
+
**`@manohub/theme`**(值层与面层分开:值随主题变、面不随主题变)。每个主题分五片:
|
|
132
|
+
`colors` / `typography` / `spacing` / `radius` / `shadows`,一律锚定 **`[data-manohub-ui]`**
|
|
133
|
+
(库品牌作用域锚;micro-app 的 scopecss 不作用域化 `:root`,定义在 `:root` 会泄漏到宿主)。
|
|
134
|
+
|
|
135
|
+
只服务单一组件的令牌分两半落在本包:
|
|
136
|
+
|
|
137
|
+
| 位置 | 内容 | 锚 |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| `styles/components/<件>.tokens.css` | **基础值**(唯一的、两套主题同值的那一条) | `[data-manohub-ui]` |
|
|
140
|
+
| `styles/components/<件>.css` | **档位改写**(`.mh-<件>--<档>` 覆盖同一令牌)+ `--mh-*` 内部状态变量 | 元件根类 / 档位类 |
|
|
141
|
+
|
|
142
|
+
后一半必须在面里:它们靠「同一元素上两个选择器改写同一个令牌」生效,搬走就断链。
|
|
143
|
+
|
|
144
|
+
随包两套:
|
|
145
|
+
|
|
146
|
+
| 主题 | 入口 | 锚点 | 取值来源 |
|
|
147
|
+
|---|---|---|---|
|
|
148
|
+
| `default` | `@manohub/theme/default.css` | `[data-manohub-ui]`(兜底套) | AIHub 品牌蓝(primary `#2660FF`)|
|
|
149
|
+
| `farris` | `@manohub/theme/farris.css` | `[data-manohub-ui][data-theme='farris']` | 《Farris Web 基础视觉规范》(primary `#2a87ff`,色板编号 Th/Au/Ne/Te 逐条标注)|
|
|
150
|
+
|
|
151
|
+
换皮只需给容器加属性(`createSubApp({ theme: 'farris' })` 会写 `data-theme`),不动类名、不动组件代码、不重打包。
|
|
152
|
+
新增主题 = `packages/theme/src/<name>/` 新目录,令牌锚 `[data-manohub-ui][data-theme='<name>']`,
|
|
153
|
+
且必须**全量覆盖** default 的令牌。
|
|
154
|
+
|
|
155
|
+
局部换主题:在更深的容器上重设变量即可,例如 `.role-tree-pane { --ui-primary: #7C3AED; }`。
|
|
@@ -111,7 +111,14 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
111
111
|
"data-invalid": props.error ? "true" : "false",
|
|
112
112
|
"style": styles
|
|
113
113
|
}, [showLabel ? createVNode("label", {
|
|
114
|
-
"class": "mh-form-item__label"
|
|
114
|
+
"class": "mh-form-item__label",
|
|
115
|
+
"onClick": (
|
|
116
|
+
// 只在真有点击可转发(有 tip ⇒ label 里才有 labelable 元素)时挂;理由见下方 ③
|
|
117
|
+
props.tip ? (event) => {
|
|
118
|
+
if (event.target?.closest(".mh-form-item__tip-btn")) return;
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
} : void 0
|
|
121
|
+
)
|
|
115
122
|
}, [createVNode("span", {
|
|
116
123
|
"class": "mh-form-item__label-text"
|
|
117
124
|
}, [props.label]), props.required ? createVNode("span", {
|
|
@@ -21,11 +21,13 @@ export interface TabsProps {
|
|
|
21
21
|
/** 惰性档:只有激活的面板才渲染(切走即卸载),用于面板很重(图表 / 大表格)的场景 */
|
|
22
22
|
lazy?: boolean;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* 尺寸档(`sm` / `md` / `lg`,缺省 `md`)—— 管**两件事**:
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* 1. **骨架的呼吸位**:`控件 → 面板` 的 `gap`(`4 / 8 / 12px`)。这一条**与皮肤无关** ——
|
|
27
|
+
* 传了 `selector` 自定义控件时同样生效(间距归骨架,控件长什么样归皮肤);
|
|
28
|
+
* 2. **缺省皮肤的尺寸档**:原样透传给 `TabBar`(高度 `24 / 32 / 40` + 同级字号)。
|
|
29
|
+
* 换了皮肤则这一条不生效:控件的尺寸归你放进来的那个控件自己管
|
|
30
|
+
* (`Capsule` / 分段按钮各有自己的 `size`),本件不代它加类。
|
|
29
31
|
*/
|
|
30
32
|
size?: ControlSize;
|
|
31
33
|
}
|
|
@@ -119,8 +121,9 @@ export declare const TabPanel: import("vue").DefineComponent<import("vue").Extra
|
|
|
119
121
|
* - 传插槽则整块替换:放 `Capsule`(胶囊)、按钮族的分段形态、单选卡片都行,
|
|
120
122
|
* 作用域参数 `{ value, options, select }` 把值、项(已含从 `TabPanel` 提取的那些)与选中回调
|
|
121
123
|
* 递出来。本件不认识任何选择控件的类名 —— **控制器与骨架零互指**,换皮肤不必动本件。
|
|
122
|
-
* - 尺寸档 `size`
|
|
123
|
-
*
|
|
124
|
+
* - 尺寸档 `size` 管两件事:① 骨架的呼吸位(`.mh-tabs` 的 `gap`,4 / 8 / 12px,**与皮肤无关**);
|
|
125
|
+
* ② 缺省皮肤 `TabBar` 的高与字号(24 / 32 / 40)。换了皮肤则第 ② 条不生效 ——
|
|
126
|
+
* 控件尺寸归你的控件自己管,本件不代它加类。
|
|
124
127
|
*
|
|
125
128
|
* ## 显隐只有一条路径
|
|
126
129
|
* 本件按受控值给非选中面板下发 `hidden`,**与控件形态无关**(是不是原生 radio 都一样)。
|
|
@@ -112,7 +112,12 @@ const Tabs = /* @__PURE__ */ defineComponent({
|
|
|
112
112
|
}, [node]);
|
|
113
113
|
});
|
|
114
114
|
return createVNode("div", {
|
|
115
|
-
"class": [
|
|
115
|
+
"class": [
|
|
116
|
+
"mh-tabs",
|
|
117
|
+
/* `md` 缺省不发类(与 `TabBar` 同口径):骨架的呼吸位 `gap` 靠这个档位类改写 */
|
|
118
|
+
props.size === "md" ? "" : `mh-tabs--${props.size}`,
|
|
119
|
+
attrs.class
|
|
120
|
+
].filter(Boolean).join(" "),
|
|
116
121
|
"style": attrs.style
|
|
117
122
|
}, [slots.selector ? slots.selector({
|
|
118
123
|
value: current,
|