@manohub/ui 0.6.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.
Files changed (169) hide show
  1. package/README.md +141 -0
  2. package/dist/components/avatar/index.d.ts +283 -0
  3. package/dist/components/avatar/index.js +167 -0
  4. package/dist/components/badge/index.d.ts +132 -0
  5. package/dist/components/badge/index.js +99 -0
  6. package/dist/components/button/index.d.ts +578 -0
  7. package/dist/components/button/index.js +191 -0
  8. package/dist/components/capsule/index.d.ts +161 -0
  9. package/dist/components/capsule/index.js +101 -0
  10. package/dist/components/card/index.d.ts +456 -0
  11. package/dist/components/card/index.js +231 -0
  12. package/dist/components/checkbox/index.d.ts +331 -0
  13. package/dist/components/checkbox/index.js +165 -0
  14. package/dist/components/code/index.d.ts +134 -0
  15. package/dist/components/code/index.js +117 -0
  16. package/dist/components/code-editor/index.d.ts +163 -0
  17. package/dist/components/code-editor/index.js +98 -0
  18. package/dist/components/collapse/index.d.ts +125 -0
  19. package/dist/components/collapse/index.js +95 -0
  20. package/dist/components/control-size.d.ts +8 -0
  21. package/dist/components/dialog/index.d.ts +224 -0
  22. package/dist/components/dialog/index.js +194 -0
  23. package/dist/components/divider/index.d.ts +64 -0
  24. package/dist/components/divider/index.js +62 -0
  25. package/dist/components/drawer/index.d.ts +226 -0
  26. package/dist/components/drawer/index.js +190 -0
  27. package/dist/components/filter/index.d.ts +391 -0
  28. package/dist/components/filter/index.js +203 -0
  29. package/dist/components/form/index.d.ts +704 -0
  30. package/dist/components/form/index.js +329 -0
  31. package/dist/components/input/index.d.ts +980 -0
  32. package/dist/components/input/index.js +334 -0
  33. package/dist/components/layout/index.d.ts +162 -0
  34. package/dist/components/layout/index.js +100 -0
  35. package/dist/components/list-view/index.d.ts +563 -0
  36. package/dist/components/list-view/index.js +221 -0
  37. package/dist/components/loading/index.d.ts +77 -0
  38. package/dist/components/loading/index.js +40 -0
  39. package/dist/components/nav/index.d.ts +293 -0
  40. package/dist/components/nav/index.js +164 -0
  41. package/dist/components/notice/index.d.ts +137 -0
  42. package/dist/components/notice/index.js +101 -0
  43. package/dist/components/notification/index.d.ts +118 -0
  44. package/dist/components/notification/index.js +99 -0
  45. package/dist/components/page/index.d.ts +276 -0
  46. package/dist/components/page/index.js +351 -0
  47. package/dist/components/page/split-resize.d.ts +42 -0
  48. package/dist/components/page/split-resize.js +36 -0
  49. package/dist/components/pagination/index.d.ts +171 -0
  50. package/dist/components/pagination/index.js +226 -0
  51. package/dist/components/panel/index.d.ts +401 -0
  52. package/dist/components/panel/index.js +193 -0
  53. package/dist/components/part-padding.d.ts +27 -0
  54. package/dist/components/part-padding.js +23 -0
  55. package/dist/components/query-state/index.d.ts +207 -0
  56. package/dist/components/query-state/index.js +181 -0
  57. package/dist/components/radio/index.d.ts +473 -0
  58. package/dist/components/radio/index.js +250 -0
  59. package/dist/components/search/index.d.ts +167 -0
  60. package/dist/components/search/index.js +105 -0
  61. package/dist/components/select/index.d.ts +252 -0
  62. package/dist/components/select/index.js +281 -0
  63. package/dist/components/skeleton/index.d.ts +88 -0
  64. package/dist/components/skeleton/index.js +56 -0
  65. package/dist/components/steps/index.d.ts +199 -0
  66. package/dist/components/steps/index.js +117 -0
  67. package/dist/components/switch/index.d.ts +150 -0
  68. package/dist/components/switch/index.js +103 -0
  69. package/dist/components/table/index.d.ts +351 -0
  70. package/dist/components/table/index.js +286 -0
  71. package/dist/components/tabs/index.d.ts +179 -0
  72. package/dist/components/tabs/index.js +153 -0
  73. package/dist/components/tabset/index.d.ts +105 -0
  74. package/dist/components/tabset/index.js +68 -0
  75. package/dist/components/tag/index.d.ts +203 -0
  76. package/dist/components/tag/index.js +144 -0
  77. package/dist/components/toast/index.d.ts +271 -0
  78. package/dist/components/toast/index.js +116 -0
  79. package/dist/components/tooltip/index.d.ts +126 -0
  80. package/dist/components/tooltip/index.js +97 -0
  81. package/dist/components/tree/index.d.ts +317 -0
  82. package/dist/components/tree/index.js +251 -0
  83. package/dist/components/upload/index.d.ts +384 -0
  84. package/dist/components/upload/index.js +172 -0
  85. package/dist/index.d.ts +63 -0
  86. package/dist/index.js +102 -0
  87. package/dist/services/base.d.ts +21 -0
  88. package/dist/services/base.js +42 -0
  89. package/dist/services/dialog.d.ts +41 -0
  90. package/dist/services/dialog.js +83 -0
  91. package/dist/services/index.d.ts +12 -0
  92. package/dist/services/loading.d.ts +21 -0
  93. package/dist/services/loading.js +41 -0
  94. package/dist/services/toast.d.ts +40 -0
  95. package/dist/services/toast.js +74 -0
  96. package/dist/styles/components/avatar.css +128 -0
  97. package/dist/styles/components/avatar.tokens.css +24 -0
  98. package/dist/styles/components/badge.css +237 -0
  99. package/dist/styles/components/button.css +454 -0
  100. package/dist/styles/components/button.tokens.css +56 -0
  101. package/dist/styles/components/capsule.css +120 -0
  102. package/dist/styles/components/capsule.tokens.css +27 -0
  103. package/dist/styles/components/card.css +192 -0
  104. package/dist/styles/components/checkbox.css +145 -0
  105. package/dist/styles/components/checkbox.tokens.css +26 -0
  106. package/dist/styles/components/code-editor.css +91 -0
  107. package/dist/styles/components/code-editor.tokens.css +24 -0
  108. package/dist/styles/components/code.css +153 -0
  109. package/dist/styles/components/code.tokens.css +29 -0
  110. package/dist/styles/components/collapse.css +62 -0
  111. package/dist/styles/components/collapse.tokens.css +20 -0
  112. package/dist/styles/components/dialog.css +106 -0
  113. package/dist/styles/components/dialog.tokens.css +24 -0
  114. package/dist/styles/components/divider.css +71 -0
  115. package/dist/styles/components/divider.tokens.css +21 -0
  116. package/dist/styles/components/drawer.css +143 -0
  117. package/dist/styles/components/drawer.tokens.css +22 -0
  118. package/dist/styles/components/filter.css +41 -0
  119. package/dist/styles/components/filter.tokens.css +14 -0
  120. package/dist/styles/components/form.css +220 -0
  121. package/dist/styles/components/form.tokens.css +15 -0
  122. package/dist/styles/components/input.css +445 -0
  123. package/dist/styles/components/input.tokens.css +41 -0
  124. package/dist/styles/components/layout.css +198 -0
  125. package/dist/styles/components/list-view.css +244 -0
  126. package/dist/styles/components/loading.css +76 -0
  127. package/dist/styles/components/loading.tokens.css +23 -0
  128. package/dist/styles/components/nav.css +48 -0
  129. package/dist/styles/components/notice.css +153 -0
  130. package/dist/styles/components/notice.tokens.css +17 -0
  131. package/dist/styles/components/notification.css +159 -0
  132. package/dist/styles/components/notification.tokens.css +37 -0
  133. package/dist/styles/components/page.css +473 -0
  134. package/dist/styles/components/pagination.css +297 -0
  135. package/dist/styles/components/pagination.tokens.css +32 -0
  136. package/dist/styles/components/panel.css +77 -0
  137. package/dist/styles/components/query-state.css +88 -0
  138. package/dist/styles/components/radio.css +271 -0
  139. package/dist/styles/components/radio.tokens.css +26 -0
  140. package/dist/styles/components/search.css +30 -0
  141. package/dist/styles/components/select.css +242 -0
  142. package/dist/styles/components/select.tokens.css +33 -0
  143. package/dist/styles/components/skeleton.css +60 -0
  144. package/dist/styles/components/skeleton.tokens.css +27 -0
  145. package/dist/styles/components/steps.css +157 -0
  146. package/dist/styles/components/steps.tokens.css +42 -0
  147. package/dist/styles/components/switch.css +165 -0
  148. package/dist/styles/components/switch.tokens.css +26 -0
  149. package/dist/styles/components/table.css +439 -0
  150. package/dist/styles/components/table.tokens.css +41 -0
  151. package/dist/styles/components/tabs.css +234 -0
  152. package/dist/styles/components/tabs.tokens.css +30 -0
  153. package/dist/styles/components/tag.css +200 -0
  154. package/dist/styles/components/tag.tokens.css +30 -0
  155. package/dist/styles/components/toast.css +150 -0
  156. package/dist/styles/components/toast.tokens.css +26 -0
  157. package/dist/styles/components/tooltip.css +89 -0
  158. package/dist/styles/components/tooltip.tokens.css +25 -0
  159. package/dist/styles/components/tree.css +139 -0
  160. package/dist/styles/components/tree.tokens.css +20 -0
  161. package/dist/styles/components/upload.css +150 -0
  162. package/dist/styles/components/upload.tokens.css +27 -0
  163. package/dist/styles/index.css +149 -0
  164. package/dist/styles/operations/collapse.css +84 -0
  165. package/dist/styles/operations/popup.css +189 -0
  166. package/dist/styles/operations/tabset.css +57 -0
  167. package/dist/utils/state-illustration.d.ts +31 -0
  168. package/dist/utils/state-illustration.js +156 -0
  169. package/package.json +62 -0
@@ -0,0 +1,41 @@
1
+ /**
2
+ * 单件令牌。
3
+ *
4
+ * **本件有一批令牌是「跨分件消费」的**:表壳 `.mh-input__wrap` 是 `.mh-input` 的**父容器**
5
+ * (`.mh-input__wrap > .mh-input` 就是证据),`.mh-input__menu` / `.mh-input__help-tip`
6
+ * 是 popover 面板(不在控件子树里)—— 自定义属性只向下继承,声明在 `.mh-input` 上会让
7
+ * 计数位 / 前后缀 / 标签 / 菜单项取不到值(声明作废,且不报错)。
8
+ *
9
+ * 改前靠「把令牌同时声明在 4 个外层类上」的 workaround 兜;锚到容器后容器是每个分件的祖先,
10
+ * workaround 整块撤掉 —— 这正是本文件从面文件里抽出来的直接原因。
11
+ *
12
+ * ## 抽出说明
13
+ * 本文件从面文件里抽出:这些是**基础值**,锚在 `[data-manohub-ui]`(跨包唯一作用域锚,
14
+ * 由入口层无条件写在应用容器上)—— 任何落在容器里的分件都取得到值,不再依赖
15
+ * 「声明在某个组件根类上」这条脆弱假设。
16
+ * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里(拆开会让档位失效)。
17
+ */
18
+ [data-manohub-ui] {
19
+ /* 展示态是**独立 `<span>`**(不带 `.mh-input`)—— 令牌锚在容器上,它照样取得到 */
20
+ /* 单件令牌 */
21
+ --ui-input-height: var(--ui-control-height-md); /* 标准档 32 */
22
+ --ui-input-height-sm: var(--ui-control-height-sm); /* 小号 24 */
23
+ --ui-input-height-lg: var(--ui-control-height-lg); /* 大号 40 */
24
+ --ui-input-padding-x: var(--ui-space-3); /* 12:标准档左右内距 */
25
+ --ui-input-padding-x-sm: var(--ui-space-2); /* 8 */
26
+ --ui-input-padding-x-lg: 14px;
27
+ --ui-input-radius: var(--ui-radius-control); /* 6:控件档(原注释写 8,是旧稿残留) */
28
+ --ui-input-font-size: var(--ui-font-body); /* 14:控件内容走正文档 */
29
+ --ui-input-font-size-sm: var(--ui-font-caption); /* 13 */
30
+ --ui-input-font-size-lg: var(--ui-font-heading); /* 16 */
31
+ /* 描边取 base-300(= 设计 `0:3946` 搜索框的 `#e6e6e6`),与卡片 / 表格 / 按钮 / 分页同一条线。
32
+ ⚠️ 改前是 base-400,而 `filter.css` 的既有裁决早已写明「控件框边 = --ui-base-300」——
33
+ 本件与它是同一条规格,之前的 base-400 属自相矛盾。base-400 从此只服务勾选类小控件框体。 */
34
+ --ui-input-line: var(--ui-base-300);
35
+ --ui-input-line-hover: var(--ui-primary-hover); /* 滑过 / 聚焦转主色(规范 Th08) */
36
+ --ui-input-textarea-min-height: 56px; /* 多行最小高(两行正文 + 上下内距) */
37
+ --ui-input-counter-size: var(--ui-font-caption);
38
+ --ui-input-icon-size: 14px; /* 清除圆点 */
39
+ --ui-input-affix-gap: var(--ui-space-2); /* 壳内各附加位的间隔 */
40
+ --ui-input-affix-size: var(--ui-font-icon); /* 前缀 / 后缀 / 眼睛的图标槽(常规图标档) */
41
+ }
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Layout —— 布局原子件族(`Layout.Row` 排「行」/ `Layout.Column` 排「列」)。
3
+ *
4
+ * 出处:应用侧反复抄写 `display:flex; align-items:center; gap:8px` 的收敛 ——「应用侧只写布局」
5
+ * 不等于「布局可以各页各写一套」:抄十遍之后间距档与居中口径必然分叉。
6
+ * 两件只做三件事:**轴向**、**间距档**(令牌档位)、**对齐**。
7
+ *
8
+ * ## 方向口径(与 CSS 属性名相反,是刻意的)
9
+ *
10
+ * 行与行是上下关系 ⇒ `Row` 是**竖排容器**(`.mh-layout-row` = `flex-direction: column`);
11
+ * 列与列是左右关系 ⇒ `Column` 是**水平容器**(`.mh-layout-column` = `row`)。
12
+ * 判据是「读表格」:`<tr>` 一行行往下堆、一行里的格子左右并排。改这条 = 改口径。
13
+ *
14
+ * ## 栅格公式(`Row` 传了 `columns` 时)
15
+ *
16
+ * 显式 N 条轨道,track 下限取 `min(最小列宽, 均分)`、上限 `1fr`:
17
+ *
18
+ * - 容器够宽 → 每列 = 最小列宽(或更大,被 `1fr` 均分撑满);
19
+ * - 容器不够宽 → 下限退到「均分」,列**等分收窄**(不会压成窄缝、不会横向溢出)。
20
+ *
21
+ * 公式里的 `%` 解析的是**栅格容器自己的内联尺寸**(不是视口),故放进弹窗 / 分栏同样成立
22
+ * —— 这也是不用媒体查询断点的原因(页面都在弹窗与分栏里,视口宽度代表不了容器)。
23
+ *
24
+ * ⚠️ **别改回 `auto-fit`**:轨道数由「能塞下几条最小列宽」决定,恰好塞不下 N 列时会退化成
25
+ * 「1 条显式 + 1 条隐式」轨道,跨格项把隐式轨道按内容宽度压成窄缝。
26
+ * 浏览器实测(容器 526 / 最小 260 / `columns=2`):
27
+ * `auto-fit` 版 → 476px + 41px(不等宽);显式 N 版 → 259px + 259px(等宽)。
28
+ *
29
+ * ## 令牌
30
+ *
31
+ * `--mh-layout-row-*` / `--mh-layout-column-*` 都声明在各自的根类上(可被行内样式覆盖 ——
32
+ * `Layout.Row` 的 `minColumnWidth` 就是这么下发 `--mh-layout-row-min` 的);
33
+ * 间距值取主题令牌 `--ui-space-1..4`,本文件**不新造色值 / 尺寸字面量**。
34
+ */
35
+ .mh-layout-row {
36
+ --mh-layout-row-gap: var(--ui-space-2);
37
+ --mh-layout-row-min: var(--ui-grid-column-min);
38
+ --mh-layout-row-columns: 2;
39
+ display: flex;
40
+ flex-direction: column;
41
+ gap: var(--mh-layout-row-gap);
42
+ /* 交叉轴(水平)不声明 = CSS 默认的 stretch(子项齐宽);要居中写 align="center" */
43
+ /* 放开 min-width:行常被塞进窄格子(表格单元格、限宽控件列)——
44
+ 不放开的 flex 容器压不进窄格,会把外层撑破 */
45
+ min-width: 0;
46
+ }
47
+
48
+ /* 一行分 n 列:栅格轨道横向铺,这一行的子项并排(`columns-1` 就是一行一列) */
49
+ .mh-layout-row--grid {
50
+ display: grid;
51
+ /* 交叉轴默认回到 stretch(单元等高);显式 align 的规则排在本条之后,能压过它 */
52
+ align-items: stretch;
53
+ /* 列数**恒为 N**(显式轨道,不用 auto-fit:auto-fit 在「N 列刚好放不下」时会退化成
54
+ 1 条显式轨道 + 隐式轨道,跨格项把隐式轨道压成几十像素的窄缝 —— 实测过)。
55
+ track 下限取 min(最小列宽, 均分):容器够宽时它就是最小列宽,
56
+ 容器窄时退到均分 —— 于是列始终等宽,既不会被压成窄缝,也不会横向溢出。 */
57
+ grid-template-columns: repeat(
58
+ var(--mh-layout-row-columns),
59
+ minmax(
60
+ min(
61
+ var(--mh-layout-row-min),
62
+ calc(
63
+ (100% - (var(--mh-layout-row-columns) - 1) * var(--mh-layout-row-gap)) /
64
+ var(--mh-layout-row-columns)
65
+ )
66
+ ),
67
+ 1fr
68
+ )
69
+ );
70
+ }
71
+
72
+ /* 列数上限 → 变量(供上面的栅格公式取用) */
73
+ .mh-layout-row--columns-1 {
74
+ --mh-layout-row-columns: 1;
75
+ }
76
+ .mh-layout-row--columns-2 {
77
+ --mh-layout-row-columns: 2;
78
+ }
79
+ .mh-layout-row--columns-3 {
80
+ --mh-layout-row-columns: 3;
81
+ }
82
+ .mh-layout-row--columns-4 {
83
+ --mh-layout-row-columns: 4;
84
+ }
85
+
86
+ /* 间距档 → 变量(落到变量上:行那份栅格公式里要用同一个间距值算轨道下限)。
87
+ sm/md/lg/xl = --ui-space-1/2/3/4 = 4/8/12/16;none = 0 */
88
+ .mh-layout-row--gap-none {
89
+ --mh-layout-row-gap: 0;
90
+ }
91
+ .mh-layout-row--gap-sm {
92
+ --mh-layout-row-gap: var(--ui-space-1);
93
+ }
94
+ .mh-layout-row--gap-md {
95
+ --mh-layout-row-gap: var(--ui-space-2);
96
+ }
97
+ .mh-layout-row--gap-lg {
98
+ --mh-layout-row-gap: var(--ui-space-3);
99
+ }
100
+ .mh-layout-row--gap-xl {
101
+ --mh-layout-row-gap: var(--ui-space-4);
102
+ }
103
+
104
+ /* --- 列:水平容器(一行里的一格;同时是栅格单元) --- */
105
+ .mh-layout-column {
106
+ --mh-layout-column-gap: var(--ui-space-2);
107
+ display: flex;
108
+ flex-direction: row;
109
+ /* 默认**垂直居中**:列里多是「徽标 + 文本」「标签 + 值」「控件 + 按钮」这类内容要齐中线;
110
+ 要贴顶写 align="start"、要齐宽写 align="stretch" */
111
+ align-items: center;
112
+ gap: var(--mh-layout-column-gap);
113
+ min-width: 0;
114
+ }
115
+
116
+ .mh-layout-column--gap-none {
117
+ --mh-layout-column-gap: 0;
118
+ }
119
+ .mh-layout-column--gap-sm {
120
+ --mh-layout-column-gap: var(--ui-space-1);
121
+ }
122
+ .mh-layout-column--gap-md {
123
+ --mh-layout-column-gap: var(--ui-space-2);
124
+ }
125
+ .mh-layout-column--gap-lg {
126
+ --mh-layout-column-gap: var(--ui-space-3);
127
+ }
128
+ .mh-layout-column--gap-xl {
129
+ --mh-layout-column-gap: var(--ui-space-4);
130
+ }
131
+
132
+ /* 折行属于**水平容器**(列里的内容太宽要折行);竖排容器没有「折行」这回事,
133
+ 栅格形态的「折行」由自动减列承担 */
134
+ .mh-layout-column--wrap {
135
+ flex-wrap: wrap;
136
+ }
137
+
138
+ /* 栅格单元跨格(span 不要超过所在行的 columns,超了 auto-fit 会为它多开轨道) */
139
+ .mh-layout-column--span-2 {
140
+ grid-column: span 2;
141
+ }
142
+ .mh-layout-column--span-3 {
143
+ grid-column: span 3;
144
+ }
145
+ .mh-layout-column--span-4 {
146
+ grid-column: span 4;
147
+ }
148
+
149
+ /* 对齐(排在 `.mh-layout-row--grid` 的 stretch 之后:显式 align 要能压过它) */
150
+ .mh-layout-row--align-start {
151
+ align-items: flex-start;
152
+ }
153
+ .mh-layout-column--align-start {
154
+ align-items: flex-start;
155
+ }
156
+ .mh-layout-row--align-center {
157
+ align-items: center;
158
+ }
159
+ .mh-layout-column--align-center {
160
+ align-items: center;
161
+ }
162
+ .mh-layout-row--align-end {
163
+ align-items: flex-end;
164
+ }
165
+ .mh-layout-column--align-end {
166
+ align-items: flex-end;
167
+ }
168
+ .mh-layout-row--align-baseline {
169
+ align-items: baseline;
170
+ }
171
+ .mh-layout-column--align-baseline {
172
+ align-items: baseline;
173
+ }
174
+ .mh-layout-row--align-stretch {
175
+ align-items: stretch;
176
+ }
177
+ .mh-layout-column--align-stretch {
178
+ align-items: stretch;
179
+ }
180
+
181
+ .mh-layout-row--justify-center {
182
+ justify-content: center;
183
+ }
184
+ .mh-layout-column--justify-center {
185
+ justify-content: center;
186
+ }
187
+ .mh-layout-row--justify-end {
188
+ justify-content: flex-end;
189
+ }
190
+ .mh-layout-column--justify-end {
191
+ justify-content: flex-end;
192
+ }
193
+ .mh-layout-row--justify-between {
194
+ justify-content: space-between;
195
+ }
196
+ .mh-layout-column--justify-between {
197
+ justify-content: space-between;
198
+ }
@@ -0,0 +1,244 @@
1
+ /**
2
+ * ListView(卡片网格列表:容器自适应列数 + 骨架卡 + 三态)。
3
+ *
4
+ * 依据:卡片本体沿用 card.css(Card);本文件只管网格容器、骨架卡与卡片项几何。
5
+ */
6
+
7
+ /* ===== ListView(卡片网格列表:容器自适应列数 + 骨架卡 + 三态)=====
8
+ 列数由**容器宽度**决定(auto-fill),不跟视口断点:窄栏自动减列。
9
+ `min(var(--mh-list-view-min), 100%)` 是必需的一层保护 —— 只写固定下限时,
10
+ 容器比下限还窄会溢出(列宽不会缩到容器以内)。 */
11
+
12
+ .mh-list-view {
13
+ --mh-list-view-min: var(--ui-grid-column-min);
14
+ --mh-list-view-gap: var(--ui-space-5);
15
+ --mh-list-view-card-min-height: 144px;
16
+ display: grid;
17
+ grid-template-columns: repeat(auto-fill, minmax(min(var(--mh-list-view-min), 100%), 1fr));
18
+ gap: var(--mh-list-view-gap);
19
+ align-items: stretch;
20
+ }
21
+
22
+ /* 骨架卡:与卡片同尺寸(最小高 + 圆角),避免加载完成时高度跳动 */
23
+
24
+ .mh-list-view__skeleton {
25
+ min-height: var(--mh-list-view-card-min-height);
26
+ border-radius: var(--ui-radius-md);
27
+ background: var(--ui-base-200);
28
+ animation: mh-list-view-pulse 1.4s ease-in-out infinite;
29
+ }
30
+
31
+ @keyframes mh-list-view-pulse {
32
+ 0%,
33
+ 100% {
34
+ opacity: 1;
35
+ }
36
+ 50% {
37
+ opacity: 0.55;
38
+ }
39
+ }
40
+
41
+ /* 列表卡片项:最小高对齐(原型 min-h-36),同排卡片等高、尾部一行对齐 */
42
+
43
+ .mh-list-view__card {
44
+ min-height: var(--mh-list-view-card-min-height);
45
+ }
46
+
47
+ /* 头部:图标 + 标题块 + 状态胶囊(原型 flex items-start) */
48
+
49
+ .mh-list-view__card-head {
50
+ display: flex;
51
+ align-items: flex-start;
52
+ gap: var(--ui-space-3);
53
+ }
54
+
55
+ /* 图标容器 36×36(原型 h-9 w-9),圆角取控件档 6(原型 rounded-md) */
56
+
57
+ .mh-list-view__card-icon {
58
+ flex: none;
59
+ width: 36px;
60
+ height: 36px;
61
+ overflow: hidden;
62
+ border-radius: var(--ui-radius-control);
63
+ }
64
+
65
+ .mh-list-view__card-icon-img {
66
+ display: block;
67
+ width: 100%;
68
+ height: 100%;
69
+ object-fit: cover;
70
+ }
71
+
72
+ .mh-list-view__card-title-block {
73
+ display: flex;
74
+ flex: 1;
75
+ flex-direction: column;
76
+ min-width: 0;
77
+ }
78
+
79
+ /* 标题 16/600(原型 text-base font-semibold leading-6,与令牌档一致) */
80
+
81
+ .mh-list-view__card-title {
82
+ overflow: hidden;
83
+ font-size: var(--ui-font-heading);
84
+ font-weight: var(--ui-weight-semibold);
85
+ line-height: var(--ui-line-heading);
86
+ color: var(--ui-base-content);
87
+ text-overflow: ellipsis;
88
+ white-space: nowrap;
89
+ }
90
+
91
+ .mh-list-view__card-subtitle {
92
+ font-size: var(--ui-font-caption);
93
+ line-height: var(--ui-line-caption);
94
+ color: var(--ui-base-content-muted);
95
+ }
96
+
97
+ /* 状态胶囊:全圆角 + 弱底同色字(原型 rounded-full px-2.5 text-xs leading-5) */
98
+
99
+ .mh-list-view__card-status {
100
+ --mh-status-fg: var(--ui-primary);
101
+ --mh-status-bg: var(--ui-primary-weak);
102
+ display: inline-flex;
103
+ flex: none;
104
+ align-items: center;
105
+ gap: var(--ui-space-1);
106
+ margin-left: auto;
107
+ padding: 0 10px;
108
+ border-radius: var(--ui-radius-full);
109
+ font-size: var(--ui-font-caption);
110
+ line-height: var(--ui-line-caption);
111
+ white-space: nowrap;
112
+ color: var(--mh-status-fg);
113
+ background: var(--mh-status-bg);
114
+ }
115
+
116
+ .mh-list-view__card-status--primary {
117
+ --mh-status-fg: var(--ui-primary);
118
+ --mh-status-bg: var(--ui-primary-weak);
119
+ }
120
+
121
+ .mh-list-view__card-status--success {
122
+ --mh-status-fg: var(--ui-success-strong);
123
+ --mh-status-bg: var(--ui-success-weak);
124
+ }
125
+
126
+ .mh-list-view__card-status--warning {
127
+ --mh-status-fg: var(--ui-warning-strong);
128
+ --mh-status-bg: var(--ui-warning-weak);
129
+ }
130
+
131
+ .mh-list-view__card-status--error {
132
+ --mh-status-fg: var(--ui-error);
133
+ --mh-status-bg: var(--ui-error-weak);
134
+ }
135
+
136
+ .mh-list-view__card-status--neutral {
137
+ --mh-status-fg: var(--ui-base-content-muted);
138
+ --mh-status-bg: var(--ui-base-200);
139
+ }
140
+
141
+ .mh-list-view__card-status-dot {
142
+ width: 6px;
143
+ height: 6px;
144
+ flex: none;
145
+ border-radius: var(--ui-radius-full);
146
+ background: var(--mh-status-fg);
147
+ }
148
+
149
+ /* 描述:两行截断(原型 line-clamp-2 text-xs text-muted-foreground) */
150
+
151
+ .mh-list-view__card-desc {
152
+ display: -webkit-box;
153
+ margin: 0;
154
+ overflow: hidden;
155
+ -webkit-box-orient: vertical;
156
+ -webkit-line-clamp: 2;
157
+ line-clamp: 2;
158
+ font-size: var(--ui-font-caption);
159
+ line-height: var(--ui-line-caption);
160
+ color: var(--ui-base-content-muted);
161
+ }
162
+
163
+ /* 尾部:左「自定义内容 + 标签组」、右「统计 + 操作位」;贴卡片底部(原型 mt-auto) */
164
+
165
+ .mh-list-view__card-foot {
166
+ display: flex;
167
+ align-items: center;
168
+ gap: var(--ui-space-2);
169
+ margin-top: auto;
170
+ }
171
+
172
+ .mh-list-view__card-foot-main {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: var(--ui-space-2);
176
+ min-width: 0;
177
+ }
178
+
179
+ .mh-list-view__card-foot-side {
180
+ display: flex;
181
+ flex: none;
182
+ align-items: center;
183
+ gap: var(--ui-space-1);
184
+ margin-left: auto;
185
+ }
186
+
187
+ .mh-list-view__card-tags {
188
+ display: flex;
189
+ align-items: center;
190
+ gap: var(--ui-space-2);
191
+ min-width: 0;
192
+ }
193
+
194
+ /* 标签片:主色弱底 + 主色字 + 小圆角(原型 rounded bg-primary/10 px-2 leading-5 font-medium) */
195
+
196
+ .mh-list-view__card-tag {
197
+ flex: none;
198
+ padding: 0 var(--ui-space-2);
199
+ border-radius: var(--ui-radius-sm);
200
+ font-size: var(--ui-font-caption);
201
+ font-weight: var(--ui-weight-medium);
202
+ line-height: var(--ui-line-caption);
203
+ color: var(--ui-primary);
204
+ background: var(--ui-primary-weak);
205
+ }
206
+
207
+ .mh-list-view__card-extra {
208
+ display: inline-flex;
209
+ align-items: center;
210
+ gap: var(--ui-space-1);
211
+ font-size: var(--ui-font-caption);
212
+ line-height: var(--ui-line-caption);
213
+ color: var(--ui-base-content-muted);
214
+ }
215
+
216
+ /* 操作位:默认隐藏,卡片悬浮(或卡内获得焦点)时显形 —— 键盘 Tab 进来同样可见。
217
+ 触屏没有 hover 能力,故 hover 缺失时恒显形,避免操作不可达。 */
218
+
219
+ .mh-list-view__card-actions {
220
+ display: inline-flex;
221
+ align-items: center;
222
+ gap: var(--ui-space-1);
223
+ opacity: 0;
224
+ transition: opacity 0.15s ease;
225
+ }
226
+
227
+ .mh-list-view__card:hover .mh-list-view__card-actions {
228
+ opacity: 1;
229
+ }
230
+
231
+ .mh-list-view__card:focus-within .mh-list-view__card-actions {
232
+ opacity: 1;
233
+ }
234
+
235
+ @media (hover: none) {
236
+ .mh-list-view__card-actions {
237
+ opacity: 1;
238
+ }
239
+ }
240
+
241
+ /* ===== 固定列数档(`columns > 0`):不再按容器宽度自适应 ===== */
242
+ .mh-list-view--fixed {
243
+ grid-template-columns: repeat(var(--mh-list-view-columns, 1), minmax(0, 1fr));
244
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Loading —— 加载态面(转圈 + 可选文案;行内 / 区域遮罩 / 全屏遮罩三形态)。
3
+ *
4
+ * 出处:设计稿的「正在忙」态没有独立组件,各页自绘了五花八门的遮罩与转圈
5
+ * (`::after` 画环、文字符号 `...`、gif 图各有)。本件收的是**三件事**:
6
+ * 转圈字形、遮罩底色、覆盖范围 —— 三者都是「改一处要全会跟着变」的口径。
7
+ *
8
+ * 字形归 `@manohub/icon`(`loading`),本面只负责**转**与**在哪转**:
9
+ * 动画名加 `mh-` 前缀(与 toast 的 `mh-toast-spin` 同理:动画名是全局标识,防撞名)。
10
+ *
11
+ * 尺寸按**全局图标档**派生(`calc()` 加减,与 button.css 同款):
12
+ * 改全局图标档时三档一起缩放,不会出现「转圈比旁边图标大一圈」。
13
+ *
14
+ * 遮罩底色由主题底色派生(`color-mix`,**不新造色值**):换主题跟着变。
15
+ */
16
+ .mh-loading {
17
+ display: inline-flex;
18
+ align-items: center;
19
+ justify-content: center;
20
+ gap: var(--ui-loading-gap);
21
+ color: var(--ui-loading-text-color);
22
+ font-size: var(--ui-font-body);
23
+ line-height: var(--ui-line-body);
24
+ }
25
+
26
+ /* 尺寸档(按全局图标档派生,档距用 calc 表达) */
27
+ .mh-loading--sm {
28
+ --ui-loading-spinner-size: calc(var(--ui-font-icon) - 4px);
29
+ }
30
+ .mh-loading--lg {
31
+ --ui-loading-spinner-size: calc(var(--ui-font-icon) + 8px);
32
+ }
33
+
34
+ .mh-loading__spinner {
35
+ flex: none;
36
+ width: var(--ui-loading-spinner-size);
37
+ height: var(--ui-loading-spinner-size);
38
+ /* 转圈是**提示进行中**,取主色:与语义四色(成功/警告/错误)不混 |
39
+ 独立 `rotate` 属性(不碰 transform):与全库动画令牌同款约束 */
40
+ color: var(--ui-primary);
41
+ animation: mh-loading-spin 0.8s linear infinite;
42
+ }
43
+ @keyframes mh-loading-spin {
44
+ to {
45
+ rotate: 360deg;
46
+ }
47
+ }
48
+ /* 降级:减弱动效时放慢而不是全停 —— 完全静止的转圈会被读成「卡住了」 */
49
+ @media (prefers-reduced-motion: reduce) {
50
+ .mh-loading__spinner {
51
+ animation-duration: 2.4s;
52
+ }
53
+ }
54
+
55
+ .mh-loading__text {
56
+ min-width: 0;
57
+ }
58
+
59
+ /* ===== 区域遮罩:铺满**最近的定位祖先**(宿主需自带 position: relative)===== */
60
+ .mh-loading--area {
61
+ position: absolute;
62
+ inset: 0;
63
+ z-index: 10;
64
+ background: var(--ui-loading-mask);
65
+ /* 遮罩要拦住交互:光标与吞点击都是「正在忙」的表达 */
66
+ cursor: wait;
67
+ }
68
+
69
+ /* ===== 全屏遮罩:铺满视口(层级夹在 toast 堆叠 1080 与模态 top layer 之间)===== */
70
+ .mh-loading--screen {
71
+ position: fixed;
72
+ inset: 0;
73
+ z-index: 1090;
74
+ background: var(--ui-loading-mask);
75
+ cursor: wait;
76
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * loading —— 单件令牌(**基础值**)。
3
+ *
4
+ * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
+ *
6
+ * ## 抽出说明
7
+ * 本文件从面文件里抽出(原先混写在 `loading.css` 顶部):这些是**基础值**,锚在
8
+ * `[data-manohub-ui]` —— 跨包唯一作用域锚,由入口层无条件写在应用容器上,因此**任何落在
9
+ * 容器里的分件都取得到值**,不再依赖「声明在某个组件根类上」这条脆弱假设
10
+ * (历史症状:跨件消费的 `--ui-*-group-*` 取不到值,组内间距变 0)。
11
+ *
12
+ * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里 —— 它们靠「同一元素上两个
13
+ * 选择器改写同一个令牌」生效,搬到本文件会让档位失效。
14
+ * ⚠️ 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
15
+ */
16
+ [data-manohub-ui] {
17
+ /* 单件令牌 */
18
+ --ui-loading-spinner-size: var(--ui-font-icon);
19
+ --ui-loading-gap: var(--ui-space-2);
20
+ /* 无规范取值:由主题底色派生(本包唯一的面色令牌),不新造色值 */
21
+ --ui-loading-mask: color-mix(in srgb, var(--ui-base-100) 72%, transparent);
22
+ --ui-loading-text-color: var(--ui-base-content-muted);
23
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Nav(侧栏导航:list / tree 两态,行渲染复用 Tree)。
3
+ *
4
+ * 依据:@aihub/theme 的 pages/tree-page.css(导航区 12/14)+ components/tree.css(行几何)。
5
+ */
6
+
7
+ /* ===== Nav(侧栏导航:list / tree 两态,行渲染复用 Tree)=====
8
+ 根件不滚(滚动归导航体)。宽度只认 --mh-nav-width(组件按 `width` prop 下发,缺省填满所在栏),
9
+ 与 .mh-tree 的缩进同一手法:几何载荷走变量,公式留在 CSS。 */
10
+
11
+ .mh-nav {
12
+ display: flex;
13
+ flex-direction: column;
14
+ /* 缺省填满所在栏:列宽归 Page.Split / 外层布局(导航件不重复锁一个可能与栏宽不符的数) */
15
+ width: var(--mh-nav-width, 100%);
16
+ min-width: 0;
17
+ height: 100%;
18
+ overflow: hidden;
19
+ }
20
+
21
+ .mh-nav__title {
22
+ flex-shrink: 0;
23
+ padding: var(--ui-space-2);
24
+ font-size: var(--ui-font-body);
25
+ line-height: var(--ui-line-body);
26
+ font-weight: var(--ui-weight-semibold);
27
+ color: var(--ui-base-content);
28
+ }
29
+
30
+ /* 导航体:侧栏内滚动的唯一归属(同 Panel.Body 的口径) */
31
+
32
+ .mh-nav__body {
33
+ flex: 1 1 auto;
34
+ min-height: 0;
35
+ overflow-y: auto;
36
+ padding: var(--ui-space-1) 0;
37
+ }
38
+
39
+ /* list 态:扁平导航没有层级,隐藏箭头占位(那一段留给树对齐用) */
40
+
41
+ .mh-nav--list .mh-tree__caret {
42
+ display: none;
43
+ }
44
+
45
+ /* ===== 右侧分隔线(侧栏贴在页面容器里时用) ===== */
46
+ .mh-nav--bordered {
47
+ border-right: 1px solid var(--ui-base-300);
48
+ }