@manohub/ui 1.0.4 → 1.0.6

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 (140) hide show
  1. package/README.md +8 -2
  2. package/dist/components/badge/index.d.ts +24 -46
  3. package/dist/components/badge/index.js +7 -11
  4. package/dist/components/button/index.d.ts +11 -31
  5. package/dist/components/capsule/index.d.ts +13 -27
  6. package/dist/components/card/index.d.ts +28 -62
  7. package/dist/components/checkbox/index.d.ts +1 -9
  8. package/dist/components/code-block/index.d.ts +28 -55
  9. package/dist/components/collapse/index.d.ts +2 -0
  10. package/dist/components/dialog/index.d.ts +9 -18
  11. package/dist/components/dialog/index.js +3 -2
  12. package/dist/components/divider/index.d.ts +1 -12
  13. package/dist/components/drawer/index.d.ts +7 -15
  14. package/dist/components/filter/index.d.ts +27 -69
  15. package/dist/components/filter/index.js +3 -8
  16. package/dist/components/form/index.d.ts +86 -218
  17. package/dist/components/form/index.js +5 -12
  18. package/dist/components/input/bordered.d.ts +4 -6
  19. package/dist/components/input/index.d.ts +36 -83
  20. package/dist/components/input/index.js +6 -11
  21. package/dist/components/input/number-input.d.ts +11 -23
  22. package/dist/components/layout/index.d.ts +21 -28
  23. package/dist/components/layout/index.js +5 -8
  24. package/dist/components/list-view/index.d.ts +10 -43
  25. package/dist/components/loading/index.d.ts +8 -19
  26. package/dist/components/nav/index.d.ts +14 -35
  27. package/dist/components/nav/index.js +1 -3
  28. package/dist/components/notice/index.d.ts +13 -33
  29. package/dist/components/notice/index.js +3 -5
  30. package/dist/components/notification/index.d.ts +0 -9
  31. package/dist/components/page/index.d.ts +29 -71
  32. package/dist/components/page/split-resize.d.ts +9 -18
  33. package/dist/components/pagination/index.d.ts +1 -5
  34. package/dist/components/panel/index.d.ts +33 -70
  35. package/dist/components/panel/index.js +1 -4
  36. package/dist/components/part-padding.d.ts +5 -13
  37. package/dist/components/query-state/index.d.ts +8 -32
  38. package/dist/components/radio/index.d.ts +13 -17
  39. package/dist/components/search/index.d.ts +12 -32
  40. package/dist/components/select/index.d.ts +30 -49
  41. package/dist/components/select/index.js +3 -3
  42. package/dist/components/select/select-panel.d.ts +23 -35
  43. package/dist/components/select/select-panel.js +5 -10
  44. package/dist/components/select/select-shared.d.ts +18 -44
  45. package/dist/components/select/select-tree.d.ts +11 -16
  46. package/dist/components/select/select-trigger.d.ts +6 -16
  47. package/dist/components/select/select-trigger.js +5 -11
  48. package/dist/components/skeleton/index.d.ts +1 -5
  49. package/dist/components/steps/index.d.ts +55 -111
  50. package/dist/components/steps/index.js +8 -16
  51. package/dist/components/switch/index.d.ts +17 -33
  52. package/dist/components/switch/index.js +2 -4
  53. package/dist/components/tabbar/index.d.ts +1 -6
  54. package/dist/components/table/index.d.ts +20 -72
  55. package/dist/components/table/index.js +4 -8
  56. package/dist/components/tabs/index.d.ts +22 -44
  57. package/dist/components/text/index.d.ts +10 -21
  58. package/dist/components/toast/index.d.ts +4 -13
  59. package/dist/components/tooltip/index.d.ts +1 -12
  60. package/dist/components/tree/index.d.ts +51 -101
  61. package/dist/components/tree/index.js +17 -33
  62. package/dist/components/upload/index.d.ts +1 -4
  63. package/dist/index.d.ts +2 -2
  64. package/dist/services/base.d.ts +32 -8
  65. package/dist/services/dialog.d.ts +13 -23
  66. package/dist/services/dialog.js +2 -0
  67. package/dist/services/index.d.ts +2 -2
  68. package/dist/services/loading.d.ts +9 -12
  69. package/dist/services/loading.js +8 -1
  70. package/dist/services/toast.d.ts +4 -14
  71. package/dist/styles/components/avatar.css +5 -7
  72. package/dist/styles/components/avatar.tokens.css +4 -9
  73. package/dist/styles/components/badge.css +3 -6
  74. package/dist/styles/components/badge.tokens.css +5 -17
  75. package/dist/styles/components/button.css +35 -57
  76. package/dist/styles/components/button.tokens.css +5 -14
  77. package/dist/styles/components/capsule.css +13 -20
  78. package/dist/styles/components/capsule.tokens.css +4 -9
  79. package/dist/styles/components/card.css +13 -24
  80. package/dist/styles/components/checkbox.css +11 -15
  81. package/dist/styles/components/checkbox.tokens.css +4 -9
  82. package/dist/styles/components/code-block.css +30 -40
  83. package/dist/styles/components/code-block.tokens.css +7 -20
  84. package/dist/styles/components/collapse.css +6 -10
  85. package/dist/styles/components/collapse.tokens.css +4 -9
  86. package/dist/styles/components/dialog.css +19 -27
  87. package/dist/styles/components/dialog.tokens.css +9 -9
  88. package/dist/styles/components/divider.css +9 -14
  89. package/dist/styles/components/divider.tokens.css +4 -9
  90. package/dist/styles/components/drawer.css +12 -16
  91. package/dist/styles/components/drawer.tokens.css +7 -9
  92. package/dist/styles/components/filter.css +13 -24
  93. package/dist/styles/components/form.css +77 -149
  94. package/dist/styles/components/form.tokens.css +9 -6
  95. package/dist/styles/components/input.css +73 -177
  96. package/dist/styles/components/input.tokens.css +5 -13
  97. package/dist/styles/components/layout.css +13 -29
  98. package/dist/styles/components/loading.css +6 -10
  99. package/dist/styles/components/loading.tokens.css +4 -9
  100. package/dist/styles/components/notice.css +3 -1
  101. package/dist/styles/components/notice.tokens.css +8 -6
  102. package/dist/styles/components/notification.css +9 -12
  103. package/dist/styles/components/notification.tokens.css +4 -12
  104. package/dist/styles/components/page.css +32 -48
  105. package/dist/styles/components/pagination.css +14 -15
  106. package/dist/styles/components/pagination.tokens.css +4 -9
  107. package/dist/styles/components/query-state.css +1 -1
  108. package/dist/styles/components/query-state.tokens.css +6 -0
  109. package/dist/styles/components/radio.css +12 -25
  110. package/dist/styles/components/radio.tokens.css +4 -9
  111. package/dist/styles/components/search.css +8 -18
  112. package/dist/styles/components/select.css +63 -109
  113. package/dist/styles/components/select.tokens.css +4 -12
  114. package/dist/styles/components/skeleton.css +4 -7
  115. package/dist/styles/components/skeleton.tokens.css +4 -9
  116. package/dist/styles/components/steps.css +9 -12
  117. package/dist/styles/components/steps.tokens.css +4 -12
  118. package/dist/styles/components/switch.css +7 -8
  119. package/dist/styles/components/switch.tokens.css +4 -9
  120. package/dist/styles/components/tabbar.css +12 -11
  121. package/dist/styles/components/tabbar.tokens.css +4 -9
  122. package/dist/styles/components/table.css +52 -93
  123. package/dist/styles/components/table.tokens.css +5 -6
  124. package/dist/styles/components/tag.css +13 -23
  125. package/dist/styles/components/tag.tokens.css +5 -11
  126. package/dist/styles/components/text.css +11 -23
  127. package/dist/styles/components/toast.css +11 -18
  128. package/dist/styles/components/toast.tokens.css +6 -9
  129. package/dist/styles/components/tooltip.css +9 -11
  130. package/dist/styles/components/tooltip.tokens.css +5 -9
  131. package/dist/styles/components/tree.css +14 -27
  132. package/dist/styles/components/tree.tokens.css +5 -6
  133. package/dist/styles/components/upload.css +10 -13
  134. package/dist/styles/components/upload.tokens.css +4 -9
  135. package/dist/styles/index.css +27 -50
  136. package/dist/styles/operations/collapse.css +12 -25
  137. package/dist/styles/operations/popup.css +41 -79
  138. package/dist/styles/operations/tabs.css +14 -32
  139. package/dist/styles/reset.css +0 -61
  140. package/package.json +2 -2
@@ -1,39 +1,13 @@
1
1
  /**
2
- * Input / Textarea —— 输入框族(三档尺寸 + 单行 + 多行 + 展示态 + 前后缀 + 清除/眼睛 + 前置后置标签)。
2
+ * Input / Textarea —— 输入框族(三档尺寸 / 单行 / 多行 / 展示态 / 前后缀 / 清除·眼睛 / 前置后置标签)。
3
3
  *
4
- * 出处:设计稿《MH后台-0911》的搜索框(`0:3945`:高 32 / 圆角 6 / 内距 12 / 图标 16 + 距 8 /
5
- * 占位 `#999999` / 边框 `#e6e6e6`)与 `@aihub/theme` 的 `src/components/input.css`
6
- * (控件高 32 / 内距 12 / 圆角 6 / 边框 base-300;聚焦 = 主色描边 + 主色环;禁用 = base-200 底 + base-300 边 + subtle 字;
7
- * 多行最小高 44 + 右下计数;前置后置标签嵌在同一控件内,标签底 Ne11、高 24)。
8
- *
9
- * **一处有意差异**:规范把控件最大宽钉在 300px(300px),本仓的控件宽度**由表单列宽驱动**
10
- * (`Form.Item` 的控件列 `flex: 1`),故这里 `width: 100%`、不设上限 —— 与 form.css 里
11
- * 「不受 farris 字段 max-width 约束」的既有结论同口径。需要定宽的消费方在容器上收敛。
12
- * **第二处有意差异(图标档)**:设计注记的「图标 16」按**整库口径**改为**常规图标档**
13
- * `--ui-input-affix-size = var(--ui-font-icon)`(14);前后缀 / 眼睛与全库其它常规图标同径。
14
- * 清除圆点内的叉(10)不属于常规图标,仍按设计取小字形。
15
- *
16
- * **表壳是 flex 行**(`__wrap`):前置 → 控件 → 清除 → 眼睛 → 后缀 → 计数依次排列,
17
- * 间隔统一吃 `--ui-input-affix-gap`。壳内控件 `flex: 1 1 auto + min-width: 0`,
18
- * 故任何附加位出现/消失时输入区自动伸缩,**不需要为每个附加组合各写一条让位规则**
19
- * (绝对定位 + padding 让位的旧法在「前后缀 + 清除 + 眼睛」同时出现时必然要两两枚举)。
20
- *
21
- * **高度三档全部吃主题令牌**(`--ui-control-height-sm` / `-md` / `-lg`,default 24 / 32 / 40),
22
- * 换主题即换控件尺寸;档位只覆盖令牌,几何规则只有一份。
23
- *
24
- * **触发器形态(`as="button"`)**:控件元素可以是 `<button>`(`Select` 一类复合件靠它复用整件的
25
- * 框 / 内距 / 清除位 / 右侧图标位,同时保留 `<button>` 才有的原生语义,如 `popovertarget`)。
26
- * 面层只需两条 —— `.mh-input--trigger` 只归零 `<button>` 的 UA 残留,
27
- * `.mh-input__wrap > .mh-input--trigger::after` 是**整箱热区**(见该节),
28
- * 两条都**不重写框、不重写状态**:框与状态本来就挂在 `.mh-input` 与表壳上,与元素类型无关。
29
- *
30
- * **聚焦环不新造阴影令牌**:规范的聚焦阴影槽位映射为本仓的「主色弱底」令牌
31
- * `--ui-primary-weak`(同一用途:主色低透明度环)。
32
- *
33
- * 状态三源等价:原生 `:hover` / `:focus` / `:disabled` / `[aria-invalid]` ⟷ 组件下发 `data-state`
34
- * ⟷ 静态档 `.is-*`,同名面共用一份声明。
35
- *
36
- * 禁写:本件不消费 farris 类;跨件令牌一律进 `theme/`。
4
+ * 表壳是 flex 行(`__wrap`):前置 → 控件 → 清除 → 眼睛 → 后缀 → 计数依次排列,间隔统一吃 `--ui-input-affix-gap`;
5
+ * 壳内控件 `flex: 1 1 auto + min-width: 0`,故附加位出现 / 消失时输入区自动伸缩,**不需要为每种附加组合各写一条让位
6
+ * 规则**(绝对定位 + padding 让位的旧法必然要两两枚举)。
7
+ * 高度三档全部吃主题令牌(`--ui-control-height-sm|-md|-lg`),档位只覆盖令牌、几何规则只有一份。
8
+ * 状态三源等价:`:hover` / `:focus` / `:disabled` / `[aria-invalid]` ⟷ `data-state` ⟷ 静态档 `.is-*`,同一份声明。
9
+ * 有意差异(对齐设计源时定下的):控件宽度由表单列宽驱动(`width: 100%`,不设 300 上限);常规图标取 14
10
+ * (`--ui-input-affix-size = var(--ui-font-icon)`),非设计注记的 16。禁写:本件不消费 farris 类;跨件令牌一律进 `theme/`。
37
11
  */
38
12
 
39
13
  /* 控件本体:**裸用(不带壳)时由控件自己画框** —— Select 的搜索行、静态页写法都靠这一条。
@@ -103,27 +77,14 @@
103
77
  }
104
78
 
105
79
  /* ===== 触发器形态(`as="button"`:控件是 `<button>`,框与状态仍归表壳) =====
106
- *
107
- * 复用面(框 / 内距 / 附加位 / 三态)**不需要为按钮重写一行**:那些规则要么挂在 `.mh-input` 上
108
- * (本身与元素类型无关),要么挂在表壳上(`:has(> .mh-input…)` 对 button 同样命中)。
109
- * 这里只补**作者源没覆盖、会被 `<button>` 的原生 UA 样式漏进来的四项**(实测 Chrome 的 html.css:
110
- * `button { align-items: flex-start; text-align: center; appearance: auto; font: 400 13.3333px Arial }`):
111
- *
112
- * - `align-items: center` —— 消费方把控件开成 flex 行时(如 `Select` 的 `.mh-select`)拦住 UA 的
113
- * `flex-start`(它会把值 / 标签顶到上沿)。本件缺省**不给 `display`**,控件是 inline-block,此时
114
- * 垂直居中来自浏览器对 `<button>` 内容的默认居中 —— 这条声明在那个形态下用不到,留着是与复合件同一份规格;
115
- * - `text-align: inherit` —— UA 的 `center` 会**继承**给值文本;
116
- * - `font-weight` / `line-height: inherit` —— UA 的 `font` 简写会把这两项从继承链上摘下来,
117
- * 而作者源只写了 `font-family` 与 `font-size`(对比:`<input>` 的 UA 不设这两项,故输入框形态天然一致);
118
- * - `appearance: none` —— 防仍画原生按钮皮肤的引擎(Safari 一类)。
119
- *
120
- * 外加一条**单行契约**(`white-space: nowrap` + `overflow: hidden` + `text-overflow: ellipsis`):
121
- * 触发器与输入框同为**单行**控件,值再长也不换行。少了它,长值会在定高框里折成两行 ——
122
- * 第二行溢出到框的下沿之外、右端图标也被挤走(实测:消费方把值当**裸文本**子节点渲染时必现,
123
- * 如 `<Input as="button">{{ 部门名 }}</Input>` 放进窄表格单元格)。截断口径与
124
- * `.mh-input__placeholder` / `.mh-select__value` 同源,这里补的是**控件本身**那一层
125
- * —— 那两处只管各自的子节点,落在控件上的裸文本没有它们兜。
126
- *
80
+ * 复用面(框 / 内距 / 附加位 / 三态)不需要为按钮重写一行(那些规则挂在 `.mh-input` 或表壳上,与元素类型无关),这里
81
+ * 只补 **UA 样式会漏进来的四项**(实测 Chrome 的 html.css 给 `<button>` 铺了 `align-items: flex-start; text-align:
82
+ * center; appearance: auto; font: 400 13.3333px Arial`):`align-items: center`(拦住 UA 的 flex-start)、
83
+ * `text-align: inherit`(UA 的 center 会继承给值文本)、`font-weight` / `line-height: inherit`(UA 的 `font` 简写会
84
+ * 把这两项从继承链上摘下来)、`appearance: none`。
85
+ * 外加一条**单行契约**(nowrap + overflow hidden + ellipsis):触发器与输入框同为单行控件,少了它,消费方把值当
86
+ * **裸文本**子节点渲染时长值会在定高框里折成两行(第二行溢出到框外、右端图标被挤走);截断口径与
87
+ * `.mh-input__placeholder` / `.mh-select__value` 同源。
127
88
  * 禁写:本块不碰框 / 色 / 尺寸 / 内距 —— 那些归 `.mh-input` 与表壳,重复声明就是又开一份会漂的规格。 */
128
89
  .mh-input--trigger {
129
90
  appearance: none;
@@ -140,19 +101,10 @@
140
101
  }
141
102
 
142
103
  /* ===== 触发器形态 · 占位文案 =====
143
- *
144
- * `<button>` **没有 `::placeholder` 伪元素**,故触发器形态的占位由组件渲染一个 span 承载
145
- * (判据见 `components/input/index.tsx` 的 `showPlaceholder`)。这里只给它的排版与色。
146
- *
147
- * `display: block` 是**必要的**(实测四种父级 × 长/短文案):span 默认是 inline,而 `overflow`
148
- * 对行内盒不生效 ⇒ 长占位会直接撑破控件;`block` 之后它撑满控件的内容宽、超长走省略号,
149
- * 且在**父级是 flex**(如 `Select` 的触发器)时会被 blockify,行为与 inline 一致
150
- * —— 两种父级下都对,故不要求消费方给控件开 flex。`min-width: 0` 供 flex 父级下允许收缩。
151
- * `flex: 1` 是给**父级是 flex** 的复合件用的(`Select` 的值区`.mh-select__value` 就是这个配方):
152
- * 实测同样的「占位 + 右侧箭头」在 flex 父级下,不给 `flex: 1` 时占位只有**内容宽**(48px)、
153
- * 给了才撑满到箭头前(207 / 可用 220)—— 少了它会让选择器的占位区窄成一截。
154
- * 父级不是 flex 时 `flex` 属性被忽略,故对单件用法无副作用。
155
- * 色与原生 `.mh-input::placeholder` 同档(弱文本),选择器值区的 `--placeholder` 也是这一档。 */
104
+ * `<button>` **没有 `::placeholder` 伪元素**,故触发器形态的占位由组件渲染一个 span 承载(判据见组件里的
105
+ * `showPlaceholder`)。`display: block` 是必要的:span 默认 inline 而 `overflow` 对行内盒不生效(长占位会撑破
106
+ * 控件);`flex: 1` 是给**父级是 flex** 的复合件用的 —— 实测「占位 + 右侧箭头」不给它时占位只有内容宽(48px),
107
+ * 给了才撑满到箭头前(207 / 可用 220)。 */
156
108
  .mh-input__placeholder {
157
109
  display: block;
158
110
  flex: 1;
@@ -164,24 +116,13 @@
164
116
  }
165
117
 
166
118
  /* ===== 触发器形态 · 整箱热区(命中测试重定向,纯 CSS) =====
167
- *
168
- * 目的:让**整件**(值 / 标签 + 右侧图标 + 左右内距)都等同于点那个原生触发按钮。
169
- * 触发器形态的附加位(如右侧箭头)是控件的**兄弟**而不是子孙,点它们本来永远到不了按钮
170
- * (实测:只有按钮本体那一格能开面板)。
171
- *
172
- * 做法:给控件挂一张**透明的绝对定位覆盖层**。伪元素**不产生独立事件目标** —— 命中它即命中
173
- * 它的宿主元素,而 `inset: 0` 的包含块是最近的定位祖先,也就是**表壳**(`.mh-input__wrap`
174
- * 自带 `position: relative`,见「壳」一节)。于是整个箱子的像素点都归控件:
175
- * `popovertarget` 的原生激活、`:active`、mousedown 聚焦一律照旧,**不需要任何 JS 代理**
176
- * (JS 代理会丢掉 `:active` 与按下聚焦的原生时序)。
177
- *
178
- * 层叠:覆盖层是定位元素 → 盖住静态的兄弟(`.mh-input__suffix` 里的箭头等)→ 正是所需;
179
- * **清除位必须自己升到覆盖层之上**(它是唯一不该被热区截走的兄弟),故 `.mh-input__clear` 带
180
- * `position: relative`,并在 spec 里有断言锁住 —— 漏了点清除会变成开面板。
181
- * 消费方若在 `prefix` / `suffix` 里放**可点元素**,同样要自行 `position: relative`。
182
- *
183
- * 必须写成「表壳 > 控件」:裸写 `.mh-input--trigger::after` 时,无壳场景的包含块会落到页面级
184
- * 定位祖先上 —— 那块透明层会铺满一大片并吞掉别人的点击。 */
119
+ * 目的:整件(值 / 标签 + 右侧图标 + 左右内距)都等同于点那个原生触发按钮 —— 触发器形态的附加位是控件的**兄弟**而非
120
+ * 子孙,点它们本来永远到不了按钮。
121
+ * 做法:给控件挂一张透明绝对定位覆盖层;伪元素**不产生独立事件目标**(命中它即命中宿主),`inset: 0` 的包含块是最近
122
+ * 的定位祖先 = **表壳** ⇒ 整个箱子的像素点都归控件,且不需要 JS 代理(代理会丢掉 `:active` 与按下聚焦的原生时序)。
123
+ * 层叠:覆盖层是定位元素、盖住静态兄弟(正是所需);**清除位必须自己升到它之上**(`.mh-input__clear` 带
124
+ * `position: relative`,spec 有断言锁住 —— 漏了点清除会变成开面板)。必须写成「表壳 > 控件」:裸写时无壳场景的包含块
125
+ * 会落到页面级定位祖先上,那块透明层会铺满一大片。 */
185
126
  .mh-input__wrap > .mh-input--trigger::after {
186
127
  content: '';
187
128
  position: absolute;
@@ -189,15 +130,10 @@
189
130
  }
190
131
 
191
132
  /* ===== 无边框档(`bordered={false}`:框与底全退,**任何状态都不再出现**) =====
192
- * 本档的效果**只有一种**:无框。悬停不亮底、聚焦不显框也不留环 —— 「常态无框、聚焦才显框」
193
- * 是**另一档** `bordered="focus"`(见下一节),不要把两种效果叠在同一档上。
194
- *
195
- * **只读值档**(`readonly` + `bordered={false}`):几何与可编辑输入框**完全一致**(同高 / 同内距 /
196
- * 值文字同左缘),仍可聚焦、可选中复制(只读 ≠ 禁用:要的就是能选、能复制),
197
- * 但「可编辑」的线索本来就一条都没有 —— 它是摘要 / 详情里值回显的推荐写法,
198
- * 也是 `Form.Item` 的 `readonly` 行配的那一档。
199
- *
200
- * 中和句与通用状态规则**同为 0-2-0**(`.mh-input:hover` / `.mh-input:focus`),靠写在它们之后取胜。 */
133
+ * 本档的效果**只有一种**:无框(悬停不亮底、聚焦不显框也不留环)——「常态无框、聚焦才显框」是**另一档**
134
+ * `bordered="focus"`,别把两种效果叠在同一档。配 `readonly` 即**只读值档**:几何与可编辑输入框完全一致、仍可聚焦
135
+ * 可选中复制(只读 ≠ 禁用),但「可编辑」的线索一条都没有 —— 摘要 / 详情里值回显的推荐写法;中和句与通用状态
136
+ * 规则同为 0-2-0,靠写在它们之后取胜。 */
201
137
  .mh-input--borderless {
202
138
  border-color: transparent;
203
139
  background: transparent;
@@ -213,11 +149,8 @@
213
149
  }
214
150
 
215
151
  /* ===== 聚焦显框档(`bordered="focus"`:行内编辑那档)=====
216
- * 常态无框无底;**悬停与聚焦复用有框档那两条**(`.mh-input:hover` / `.mh-input:focus`:框转 hover
217
- * 线色、聚焦再加主色弱底环)—— 本档**不另写任何状态描写**,于是「聚焦 = 有框档的样子」这句话
218
- * 在面上只有一份。
219
- * 那两条是 0-2-0、本档常态是 0-1-0 ⇒ 悬停 / 聚焦必定压过常态,**与顺序无关**(裸控件这一层)。
220
- * 配 `readonly`:把复用的线索中和掉(只读值不许看起来能编辑;推荐写法是 `readonly` + `false`)。 */
152
+ * 常态无框无底;**悬停与聚焦复用有框档那两条**(框转 hover 线色、聚焦再加主色弱底环)—— 本档不另写任何状态描写,
153
+ * 「聚焦 = 有框档的样子」这句话在面上只有一份。那两条是 0-2-0、本档常态 0-1-0 ⇒ 悬停 / 聚焦必定压过常态,与顺序无关。 */
221
154
  .mh-input--border-on-focus {
222
155
  border-color: transparent;
223
156
  background: transparent;
@@ -266,17 +199,10 @@
266
199
  }
267
200
 
268
201
  /* ===== 壳(附加位的排布容器,**整件的框主**) =====
269
- *
270
- * 框画在壳上、不画在控件上:壳是一个 flex 行,前缀 / 清除 / 眼睛 / 后缀都在**控件之外**,
271
- * 框挂在控件上时附加位就落在框外 —— 带眼睛的密码框实测:壳 220px、带框的控件只到 196px,
272
- * 眼睛图标飘在框外。壳定高 + 控件 `height: 100%`,整件仍是可点区域。
273
- * **裸 `.mh-input`(不带壳)仍由控件自己画框**(Select 的搜索行就靠它),见上一节。
274
- *
275
- * **宽度口径归壳**(`--ui-control-width` / `--ui-control-min-width`,两枚都在主题层):
276
- * 壳就是消费方看见的那个控件箱 —— Input / Textarea / NumberInput 一律渲染壳,故定宽与收缩下限
277
- * 都设在这里;控件本体仍是 `width: 100%`(它要么在壳的内容盒里按 flex 收缩,要么在 Select 的
278
- * 搜索行里撑满面板)—— 把令牌也设到控件本体会让它在壳的内距之外多出 24px。
279
- */
202
+ * 框画在壳上、不画在控件上:壳是 flex 行、附加位都在控件之外,框挂在控件上时附加位会落到框外(实测带眼睛的
203
+ * 密码框:壳 220px,带框的控件只到 196px,眼睛飘在框外)。**裸 `.mh-input`(不带壳)仍由控件自己画框**
204
+ * (`Select` 的搜索行靠它)。**宽度口径归壳**(两枚 `--ui-control-*` 都在主题层):壳就是消费方看见的那个控件箱
205
+ * (定宽与收缩下限都设在这里),控件本体仍 `width: 100%`(把令牌也设到本体会让它在壳的内距之外多出 24px)。 */
280
206
  .mh-input__wrap {
281
207
  /* 左右内距走**内部变量**再吃令牌:壳是框与内距的主,而档位类挂在控件上(壳是它的父),
282
208
  档位规则要能改到壳的内距 —— 见下面两条 `:has()`。写成 `--mh-*` 是刻意的(内部中转),
@@ -286,8 +212,7 @@
286
212
  display: inline-flex;
287
213
  align-items: center;
288
214
  gap: var(--ui-input-affix-gap);
289
- /* 定宽 + 收缩下限:缺省撑满所在列,容器宽度由内容决定(flex 的 shrink-to-fit 槽)或行被挤时
290
- 不再塌成内容宽 —— 消费方在任意容器上重设这两枚令牌即整片生效(见 theme 的 spacing.css)。
215
+ /* 定宽 + 收缩下限(缺口见 theme 的 spacing.css)。
291
216
  ⚠️ 行内输入(`Search` 的表壳)按导入顺序被 search.css 的 `.mh-search__input` 收回
292
217
  `width: 100%; min-width: 0` —— 它的宽度归那一行,不归本件 */
293
218
  width: var(--ui-control-width);
@@ -301,9 +226,8 @@
301
226
  transition-duration: 0.15s;
302
227
  transition-timing-function: ease;
303
228
  }
304
- /* ⚠️ 档位**必须连内距一起换**,不能只换高度:壳内控件的内距被归零(见 `.mh-input__wrap > .mh-input`),
305
- 壳的 12px 若原样留着,sm(24 高)就成了「矮框里塞着标准档的内距」—— 左右各 12 对 13 号字太挤,
306
- 看起来像内距坏了。2026-10-08 修:三档的高度与左右内距成对下发。 */
229
+ /* ⚠️ 档位**必须连内距一起换**,不能只换高度:壳内控件的内距被归零,壳的 12px 若原样留着,
230
+ sm(24 高)就成了「矮框里塞着标准档的内距」,看起来像内距坏了 ⇒ 三档的高度与左右内距成对下发。 */
307
231
  .mh-input__wrap:has(> .mh-input--sm) {
308
232
  --mh-input-padding-x: var(--ui-input-padding-x-sm);
309
233
  height: var(--ui-input-height-sm);
@@ -339,11 +263,9 @@
339
263
  .mh-input__wrap > .mh-input.is-focus {
340
264
  box-shadow: none;
341
265
  }
342
- /* **聚焦显框档(`bordered="focus"`)的常态**:框与底全退。
343
- * ⚠️ 这个位置是**语义要求**,不是排版偏好:本句与下面「悬停 / 聚焦」两条**同为 0-2-0**
344
- * (`:has()` 按参数里最具体的那个算,这里是一个类),同特异性时 CSS 取**后写者** ——
345
- * 本句若写在那两条之后,聚焦时框永远显不出来。本档的悬停 / 聚焦表现**完全复用**下面那两条
346
- * (框转 hover 线色 + 主色弱底环),故本档在这里只有「常态」这一句,不另写状态描写。 */
266
+ /* **聚焦显框档的常态**:框与底全退。
267
+ * ⚠️ 这个位置是语义要求:本句与下面「悬停 / 聚焦」两条同为 0-2-0(`:has()` 按参数里最具体的那个算),
268
+ * 同特异性时取**后写者** —— 本句若写在它们之后,聚焦时框永远显不出来。 */
347
269
  .mh-input__wrap:has(> .mh-input--border-on-focus) {
348
270
  border-color: transparent;
349
271
  background: transparent;
@@ -383,11 +305,9 @@
383
305
  background: var(--ui-base-200);
384
306
  border-color: var(--ui-base-300);
385
307
  }
386
- /* 无边框档(带壳时框主是壳,`bordered={false}`):框与底全退,**任何状态都不再出现**
387
- * —— 口径与裸控件那节完全一致(本档的效果只有一种)。
388
- * 中和句 0-3-0 压过通用悬停 / 聚焦(0-2-0),故写在本节(它们之后)也成立;
389
- * 配 `readonly` 即**只读值档**,几何照旧、线索全无(说明见裸控件那节)。
390
- * 带壳的 `bordered="focus"` 档只有「常态」那一句,在文件上半部分(与通用悬停 / 聚焦同段,位置有讲究)。 */
308
+ /* 无边框档(带壳时框主是壳):口径与裸控件那节完全一致(本档的效果只有一种)。
309
+ * 中和句 0-3-0 压过通用悬停 / 聚焦(0-2-0);带壳的 `bordered="focus"` 档只有「常态」那一句,
310
+ * 在文件上半部分(与通用悬停 / 聚焦同段,位置有讲究)。 */
391
311
  .mh-input__wrap:has(> .mh-input--borderless) {
392
312
  border-color: transparent;
393
313
  border-radius: 0;
@@ -422,19 +342,12 @@
422
342
  }
423
343
 
424
344
  /* ===== 清除(有内容才由组件渲染;圆形 + close 字形)=====
425
- *
426
- * **默认隐形,滑过表壳或聚焦时才显形**:常显会在每一个有内容的输入框右端永远挂一颗深色实心圆点 ——
427
- * 密集场景(表格内编辑、筛选条、多选触发器、带前后缀的搜索行)里那一列圆点比字段本身还抢眼,
428
- * 也与「清除是低频动作」的层级不符。
429
- *
430
- * 为什么用 `opacity` 而不是 `display` / `visibility`:
431
- * ① 它仍在流中**占位** —— 显隐时输入区宽度不变;换 `display` 会让文字在鼠标移入的一瞬间横跳;
432
- * ② 它仍是可命中的**定位元素** —— 触发器形态的整箱热区靠 `position: relative` + DOM 顺序压在
433
- * 覆盖层之上(见上一节),换 `visibility: hidden` 会连命中一起关掉,那一块反被热区接管。
434
- *
435
- * `:focus-within` 是**触屏与键盘**的兜底:没有 hover 的设备上,点进输入框同样要能点到清除
436
- * (键盘另有一条 `Delete` 路径,见组件)。禁用档不显形:那时本来就不该清,圆点落在灰底上还会
437
- * 被误读成可用。 */
345
+ * **默认隐形,滑过表壳或聚焦时才显形**:常显会在每个有内容的输入框右端永远挂一颗深色圆点,密集场景(表格内编辑、
346
+ * 筛选条、多选触发器)里那一列圆点比字段本身还抢眼,也与「清除是低频动作」的层级不符。为什么用 `opacity` 而不是
347
+ * `display` / `visibility`:① 它仍在流中**占位**(显隐时输入区宽度不变,换 `display` 会让文字在鼠标移入的一瞬间
348
+ * 横跳);② 它仍是可命中的**定位元素** —— 触发器形态的整箱热区靠 `position: relative` + DOM 顺序压在覆盖层之上,
349
+ * 换 `visibility: hidden` 会连命中一起关掉。`:focus-within` 是触屏与键盘的兜底(键盘另有 `Delete` 路径);禁用档
350
+ * 不显形。 */
438
351
  .mh-input__clear {
439
352
  flex: none;
440
353
  display: inline-flex;
@@ -502,8 +415,7 @@
502
415
  }
503
416
 
504
417
  /* ===== 字数计数 =====
505
- * 单行:壳内的普通成员(跟在后缀之后,不遮输入区);
506
- * 多行:脱流钉在右下角(`textarea` 与它同容器,见上方的底部留白规则)。 */
418
+ * 单行:壳内的普通成员(跟在后缀之后,不遮输入区);多行:脱流钉在右下角。 */
507
419
  .mh-input__counter {
508
420
  flex: none;
509
421
  font-size: var(--ui-input-counter-size);
@@ -512,39 +424,27 @@
512
424
  }
513
425
  .mh-input__wrap:has(> .mh-input--textarea) > .mh-input__counter {
514
426
  position: absolute;
515
- /* 右让位一个「拖拽角」:多行是 `resize: vertical`(`.mh-input--textarea`),浏览器于是在框的
516
- 右下角画一枚原生拖拽柄(Chromium 约 16px 见方),与计数器**同角重叠**——实测截图里
517
- `0/1024` 与手柄叠在一起。故计数器在同一行内右移整一档令牌(`--ui-space-4` = 16px):
518
- `bottom` 不动,底部留白口径(见上方 padding-bottom 规则)不受影响。
519
- 不同平台的手柄宽略有差异(Firefox 略窄),此处取整档、不按浏览器分支。 */
427
+ /* 右让位一个「拖拽角」:多行是 `resize: vertical`,浏览器于是在右下角画一枚原生拖拽柄
428
+ (Chromium 约 16px 见方),与计数器**同角重叠**(实测截图里 `0/1024` 与手柄叠在一起)。
429
+ 故计数器右移整一档令牌;`bottom` 不动,底部留白口径不受影响。 */
520
430
  right: calc(var(--ui-input-padding-x) + var(--ui-space-4));
521
431
  bottom: var(--ui-space-1);
522
432
  }
523
433
 
524
434
  /* ===== 数字输入(NumberInput;与 Input 同族同面) =====
525
- *
526
- * 表壳 / 内距 / 状态协议全部复用上面几节 —— 本件只多两样:控件上的 `.mh-input--number`
527
- * 与右端的一对步进按钮。故**没有**独立的面文件,也不进 `styles/index.css` 的登记清单
528
- * (那是「一组件一面」的清单,本件与 `Input` 共用 `input.css`)。
529
- *
530
- * 类名**与面文件同根**(`mh-input*`),口径与 `Textarea` 的 `.mh-input--textarea` 一致:
531
- * 同族两件共用一份面时,族根就是 `mh-input`,另开 `mh-number-*` 会被
532
- * `__tests__/contract-class-surface.spec.ts` 的「与面文件名同根」那条判据拦下 —— 那条判据
533
- * 正是为了让「共用一份面」这件事在命名上看得见。
534
- *
535
- * `.mh-input--number` 只声明 `font-variant-numeric`:数值等宽,编辑时数字不会因字形宽度
536
- * 变化而左右跳(比例数字下 `1111` 比 `0000` 窄一截,逐位输入时值区会抖)。它**不承载几何** ——
537
- * 框与内距归 `.mh-input__wrap` / `.mh-input`,重复声明就是又开一份会漂的规格。 */
435
+ * 表壳 / 内距 / 状态协议全部复用上面几节 —— 本件只多两样:控件上的 `.mh-input--number` 与右端一对步进按钮,故
436
+ * **没有**独立的面文件、也不进 `styles/index.css` 的登记清单。类名**与面文件同根**(`mh-input*`,与 `Textarea` 的
437
+ * `.mh-input--textarea` 一致)—— 另开 `mh-number-*` 会被「与面文件名同根」的用例拦下。`.mh-input--number` 只声明
438
+ * `font-variant-numeric`(数值等宽,编辑时数字不因字形宽度变化而左右跳:比例数字下 `1111` 比 `0000` 窄一截);
439
+ * 它**不承载几何** —— 框与内距归壳与控件。 */
538
440
  .mh-input--number {
539
441
  font-variant-numeric: tabular-nums;
540
442
  }
541
443
 
542
- /* 步进位:右端的一对上下箭头(列排、整条居中)。
543
- * 取值(两条约束一起解出来的):md 16 / 压 4(32 − 4 = 28 ≤ 30)、lg 16 / 压 0(32 ≤ 38)、
544
- * sm 13 / 压 4(26 − 4 = 22 ≤ 22;13 是「放得下 **且** 压不过字形」的最大值 —— 14 的两条约束互相打架)。
545
- * 尺寸声明落在**步进位自己**上(基准),两档改写靠表壳的 `:has()` 选到它 —— 档位类挂在控件上
546
- * (`.mh-input--sm`),而箭头是控件的**兄弟**:自定义属性只向下继承,把变量声明在控件上,
547
- * 箭头取不到值(与 `input.tokens.css` 头注释记的同一个坑)。 */
444
+ /* 步进位:右端的一对上下箭头(列排、整条居中)。取值(两条约束一起解出来的):md 16 / 压 4(32 − 4 = 28 ≤ 30)、
445
+ * lg 16 / 压 0(32 ≤ 38)、sm 13 / 压 4(26 − 4 = 22 ≤ 22;13 是「放得下且压不过字形」的最大值 —— 14 的两条约束
446
+ * 互相打架)。尺寸声明落在**步进位自己**上(基准),两档改写靠表壳的 `:has()` 选到它 —— 档位类挂在控件上、而箭头是
447
+ * 控件的**兄弟**:自定义属性只向下继承,声明在控件上箭头取不到值(同 `input.tokens.css` 的坑)。 */
548
448
  .mh-input__step {
549
449
  /* md 基准:箭头盒取**常规图标档 16**(一对 32 比内容高 30 多 2,故两枚之间压 4 → 一对 28 落进 30) */
550
450
  --mh-input-step-icon: 16px;
@@ -554,11 +454,9 @@
554
454
  flex-direction: column;
555
455
  align-self: stretch;
556
456
  justify-content: center;
557
- /* **默认隐形且不可点**:步进位是「聚焦后调值」的辅助位,常显会让页面上每个数字框的右端
558
- 都挂着一对箭头(密集表单里那一列箭头比数字本身还抢眼)。
559
- 为什么用 `opacity` 而不是 `display`:① 它仍在流中**占位** —— 显隐时值区宽度不变,
560
- 否则聚焦的一瞬间数字会横向跳一格;② `pointer-events: none` 让隐形时的热区一并失效,
561
- 避免「点了看不见的箭头、值莫名其妙变了」。读屏仍能读到这两个按钮(不丢可达性)。 */
457
+ /* **默认隐形且不可点**:步进位是「聚焦后调值」的辅助位,常显会让每个数字框右端都挂着一对箭头。用 `opacity` 而非
458
+ `display`:① 仍在流中**占位**(否则聚焦的一瞬间数字横向跳一格);② `pointer-events: none` 让隐形时的热区一并
459
+ 失效,避免「点了看不见的箭头、值莫名其妙变了」。读屏仍能读到这两个按钮。 */
562
460
  opacity: 0;
563
461
  pointer-events: none;
564
462
  transition-property: opacity;
@@ -570,8 +468,7 @@
570
468
  opacity: 1;
571
469
  pointer-events: auto;
572
470
  }
573
- /* sm:控件只 24 高(内容高 22),16 的一对(32)放不下、14 也放不下(压到安全上限 4.67 时还有 23.3 > 22)。
574
- 13 是**两条约束的唯一交集**:一对 26 − 4 = 22(正好落进),压缩 4 ≤ 13/3(不侵可点区)。 */
471
+ /* sm:控件只 24 高(内容高 22),16 的一对(32)放不下、14 也放不下 ⇒ 13 是两条约束的唯一交集 */
575
472
  .mh-input__wrap:has(> .mh-input--sm) > .mh-input__step {
576
473
  --mh-input-step-icon: 13px;
577
474
  --mh-input-step-overlap: 4px;
@@ -583,7 +480,7 @@
583
480
  }
584
481
 
585
482
  /* 步进按钮:**裸按钮必须自带 border / background / padding**(基线 reset 不再代消费方归零,
586
- 见 `styles/reset.css` 与 `__tests__/contract-reset.spec.ts` 的第三组)。
483
+ 见 `styles/reset.css` 与 `contract-reset.spec.ts` 第三组)。
587
484
  盒宽取附加位档(16)—— 热区比字形大一档;常态同附加位色档,滑过转主色;到界即 `:disabled`(不回绕)。 */
588
485
  .mh-input__step-btn {
589
486
  flex: none;
@@ -605,10 +502,9 @@
605
502
  color: var(--ui-base-content-muted);
606
503
  cursor: not-allowed;
607
504
  }
608
- /* 第二枚往上**压一档**:一对箭头(两个常规图标档的盒)比控件内容高还高,靠负 margin 挤进去
609
- (`gap` 不接受负值,故用 `margin-top` 的负值;量由 `--mh-input-step-overlap` 给,改档只动一个数)。
610
- ⚠️ 压缩量有上限(**盒 / 3**):chevron 的笔画含描边占盒高 1/3,压过它,上箭头字形的下半截
611
- 就落进下箭头的可点区 —— 用户点「增」会被判成「减」。 */
505
+ /* 第二枚往上**压一档**:一对箭头比控件内容高还高,靠负 margin 挤进去(`gap` 不接受负值)。
506
+ ⚠️ 压缩量有上限(**盒 / 3**):chevron 的笔画含描边占盒高 1/3,压过它,上箭头字形的下半截就落进
507
+ 下箭头的可点区 —— 用户点「增」会被判成「减」。 */
612
508
  .mh-input__step-btn + .mh-input__step-btn {
613
509
  margin-top: calc(-1 * var(--mh-input-step-overlap));
614
510
  }
@@ -1,18 +1,10 @@
1
1
  /**
2
- * 单件令牌。
2
+ * 单件令牌(**基础值**,锚 `[data-manohub-ui]`)。
3
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
- * 「声明在某个组件根类上」这条脆弱假设。
4
+ * **本件有一批令牌是「跨分件消费」的**:表壳 `.mh-input__wrap` 是 `.mh-input` 的**父容器**,
5
+ * `.mh-input__menu` / `__help-tip` 是 popover 面板(不在控件子树里)—— 自定义属性只向下继承,声明在
6
+ * `.mh-input` 上会让计数位 / 前后缀 / 标签 / 菜单项取不到值(作废且不报错)。锚到容器后撤掉了「同时声明在
7
+ * 4 个外层类上」那类 workaround —— 这正是本文件抽出来的原因。
16
8
  * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里(拆开会让档位失效)。
17
9
  */
18
10
  [data-manohub-ui] {
@@ -1,36 +1,20 @@
1
1
  /**
2
- * Layout —— 布局原子件族(`Layout.Row` 排「行」/ `Layout.Column` 排「列」)。
2
+ * Layout —— 布局原子件族(`Layout.Row` 排「行」/ `Layout.Column` 排「列」)。收敛「应用侧各页各写一套
3
+ * flex + gap」,只做三件事:**轴向**、**间距档**、**对齐**。
3
4
  *
4
- * 出处:应用侧反复抄写 `display:flex; align-items:center; gap:8px` 的收敛 ——「应用侧只写布局」
5
- * 不等于「布局可以各页各写一套」:抄十遍之后间距档与居中口径必然分叉。
6
- * 两件只做三件事:**轴向**、**间距档**(令牌档位)、**对齐**。
5
+ * 方向口径(与 CSS 属性名相反,是刻意的):行与行是上下关系 ⇒ `Row` 是**竖排容器**
6
+ * (`.mh-layout-row` = `column`);列与列是左右关系 ⇒ `Column` 是**水平容器**(`row`)。
7
+ * 判据是「读表格」:`<tr>` 一行行往下堆、一行里的格子左右并排。改这条 = 改口径。
7
8
  *
8
- * ## 方向口径(与 CSS 属性名相反,是刻意的)
9
+ * 栅格公式(`Row` 传了 `columns` 时):显式 N 条轨道,track 下限取 `min(最小列宽, 均分)`、上限 `1fr`
10
+ * —— 容器够宽时是最小列宽(再宽由 `1fr` 撑满),不够宽时**等分收窄**、不溢出。公式里的 `%` 解析的是
11
+ * **栅格容器自己的内联尺寸**(不是视口),故放进弹窗 / 分栏同样成立(也是不用媒体查询断点的原因)。
12
+ * ⚠️ **别改回 `auto-fit`**:恰好塞不下 N 列时会退化成「1 条显式 + 1 条隐式」轨道,跨格项把隐式轨道
13
+ * 按内容宽度压成窄缝(实测 容器 526 / 最小 260 / `columns=2`:`auto-fit` → 476 + 41 不等宽;
14
+ * 显式 N → 259 + 259 等宽)。
9
15
  *
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`,本文件**不新造色值 / 尺寸字面量**。
16
+ * 令牌:`--mh-layout-row-*` / `--mh-layout-column-*` 声明在各自根类上(可被行内样式覆盖,
17
+ * `minColumnWidth` 就是这么下发 `--mh-layout-row-min` 的);间距取主题令牌、本文件不新造字面量。
34
18
  */
35
19
  .mh-layout-row {
36
20
  --mh-layout-row-gap: var(--ui-space-2);
@@ -1,17 +1,13 @@
1
1
  /**
2
2
  * Loading —— 加载态面(转圈 + 可选文案;行内 / 区域遮罩 / 全屏遮罩三形态)。
3
3
  *
4
- * 出处:设计稿的「正在忙」态没有独立组件,各页自绘了五花八门的遮罩与转圈
5
- * (`::after` 画环、文字符号 `...`、gif 图各有)。本件收的是**三件事**:
6
- * 转圈字形、遮罩底色、覆盖范围 —— 三者都是「改一处要全会跟着变」的口径。
4
+ * 出处:设计稿的「正在忙」态没有独立组件,各页自绘了五花八门的遮罩与转圈(`::after` 画环、文字符号
5
+ * `...`、gif 图各有)。本件收的是**三件事**:转圈字形 / 遮罩底色 / 覆盖范围 —— 都是「改一处要全会跟着
6
+ * 变」的口径。
7
7
  *
8
- * 字形归 `@manohub/icon`(`loading`),本面只负责**转**与**在哪转**:
9
- * 动画名加 `mh-` 前缀(与 toast 的 `mh-toast-spin` 同理:动画名是全局标识,防撞名)。
10
- *
11
- * 尺寸按**全局图标档**派生(`calc()` 加减,与 button.css 同款):
12
- * 改全局图标档时三档一起缩放,不会出现「转圈比旁边图标大一圈」。
13
- *
14
- * 遮罩底色由主题底色派生(`color-mix`,**不新造色值**):换主题跟着变。
8
+ * 字形归 `@manohub/icon`(`loading`),本面只负责**转**与**在哪转**;动画名加 `mh-` 前缀(动画名是全局
9
+ * 标识,防撞名)。尺寸按**全局图标档**用 `calc()` 加减派生(改档时三档一起缩放,不会出现「转圈比旁边
10
+ * 图标大一圈」);遮罩底色由主题底色 `color-mix` 派生(不新造色值,换主题跟着变)。
15
11
  */
16
12
  .mh-loading {
17
13
  display: inline-flex;
@@ -3,16 +3,11 @@
3
3
  *
4
4
  * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
5
  *
6
- * ## 抽出说明
7
- * 本文件从面文件里抽出(原先混写在 `loading.css` 顶部):这些是**基础值**,锚在
8
- * `[data-manohub-ui]` —— 跨包唯一作用域锚,由入口层无条件写在应用容器上,因此**任何落在
9
- * 容器里的分件都取得到值**,不再依赖「声明在某个组件根类上」这条脆弱假设
10
- * (历史症状:跨件消费的 `--ui-*-group-*` 取不到值,组内间距变 0)。
11
6
  *
12
- * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里 —— 它们靠「同一元素上两个
13
- * 选择器改写同一个令牌」生效,搬到本文件会让档位失效。
14
- * ⚠️ 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
15
- */
7
+ * 令牌锚 `[data-manohub-ui]`(容器是每个分件的祖先 ⇒ 落在容器里的分件都取得到值)。
8
+ * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里(搬走会让档位失效);
9
+ * 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
10
+ */
16
11
  [data-manohub-ui] {
17
12
  /* 单件令牌 */
18
13
  --ui-loading-spinner-size: var(--ui-font-icon);
@@ -20,11 +20,13 @@
20
20
  gap: var(--ui-space-2);
21
21
  width: 100%;
22
22
  min-height: var(--ui-notice-height);
23
- padding: var(--ui-space-3) var(--ui-space-4);
23
+ padding: var(--ui-notice-padding-y) var(--ui-notice-padding-x);
24
24
  border-radius: var(--ui-radius-control);
25
25
  box-shadow: var(--ui-notice-shadow);
26
26
  font-size: var(--ui-notice-font);
27
27
  line-height: var(--ui-line-body);
28
+ /* 定位上下文:隐身说明文本的包含块必须落在控件内,否则逃出滚动容器裁剪、撑大文档滚动高度 */
29
+ position: relative;
28
30
  }
29
31
 
30
32
  .mh-notice__body {
@@ -2,13 +2,15 @@
2
2
  * 组件几何令牌:取自 @aihub/theme 的 components/alert.css 实测(通栏高 42 / 文案 15px /
3
3
  * 警示与错误底取 Alert 专页样张,与语义 03 档两说时以专页为准)
4
4
  *
5
- * ## 抽出说明
6
- * 本文件从面文件里抽出:这些是**基础值**,锚在 `[data-manohub-ui]`(跨包唯一作用域锚,
7
- * 由入口层无条件写在应用容器上)—— 任何落在容器里的分件都取得到值,不再依赖
8
- * 「声明在某个组件根类上」这条脆弱假设。
9
- * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里(拆开会让档位失效)。
10
- */
5
+ *
6
+ * 令牌锚 `[data-manohub-ui]`(容器是每个分件的祖先 ⇒ 落在容器里的分件都取得到值)。
7
+ * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里(搬走会让档位失效);
8
+ * 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
9
+ */
11
10
  [data-manohub-ui] {
11
+ /* 条状内距(上下 / 左右) */
12
+ --ui-notice-padding-y: var(--ui-space-3);
13
+ --ui-notice-padding-x: var(--ui-space-4);
12
14
  --ui-notice-height: 42px;
13
15
  --ui-notice-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
14
16
  --ui-notice-font: 15px;
@@ -1,22 +1,19 @@
1
1
  /**
2
2
  * Notification —— 通知卡(带标题 / 正文 / 头像 / 标签 / 操作 / 关闭的结构)。
3
3
  *
4
- * 出处:`@aihub/theme` 的 `playground/components/notification.html` 与 `src/components/toast.css`
5
- * 里的 `--mh-notice-*` 令牌(面板 430 宽 / 最小高 100 / 正文最大高 180 / 圆角 10 / 左边线 6px;
6
- * 语义淡底五档;标题 16px Te01、正文 14px Te04、关闭槽 10x10 Te07;内距 上下右 16、左 24)。
7
- * ⚠️ 关闭字形按**组件内联 12** 渲染(规范注记的 10x10 登记为偏差;关闭位是贴小控件的字形,
8
- * 不并入常规图标档 —— 改前静态样例页按规范画 10、与组件不一致,已同步为 12)。
4
+ * 出处:规范(面板 430 宽 / 最小高 100 / 正文最大高 180 / 圆角 10 / 左边线 6px;语义淡底五档;
5
+ * 标题 16px、正文 14px、关闭槽 10×10;内距 上下右 16、左 24)。
6
+ * ⚠️ 关闭字形按**组件内联 12** 渲染(规范注记的 10×10 登记为偏差;关闭位是贴小控件的字形,不并入常规
7
+ * 图标档 —— 静态样例页按规范画 10、与组件不一致,已同步为 12)。
9
8
  *
10
- * **与 `Notice` 的判据**(两者都在本仓,别互相顶替):
11
- * - `Notice`(`.mh-notice*`)= **条状提示**(对齐规范 alert 族):一行话 + 可选操作,不带头像 / 标签 / 关闭;
12
- * - 本件(`.mh-notification*`)= **通知卡**:有标题行(含关闭位)、可带头像与标签、多行正文。
13
- * 类名刻意不同前缀 —— 规范里两族的类名都叫 `.notice*`,本仓若照抄就会出现两套 `.mh-notice*` 互撞。
9
+ * **与 `Notice` 的判据**(两者都在本仓,别互相顶替):`Notice` 是**条状提示**(一行话 + 可选操作,不带
10
+ * 头像 / 标签 / 关闭);本件是**通知卡**(有标题行含关闭位、可带头像与标签、多行正文)。类名刻意不同前缀
11
+ * —— 规范里两族都叫 `.notice*`,照抄就会出现两套 `.mh-notice*` 互撞。
14
12
  *
15
13
  * **左边线用绝对定位伪元素画,不用 `border-left` + `border-image`**:后者会吃掉圆角(规范踩过这个坑)。
16
14
  * 语义八档的线色是规范 04 档**渐变**,色板编号写在令牌注释里;底色复用本仓语义弱底令牌(一处定义)。
17
- *
18
- * **标签位与操作位不重复实现**:标签用标记族(只读走 `.mh-badge`,要可关闭走 `.mh-tag`),
19
- * 操作用按钮族(`.mh-button--sm`)—— 本件只给它们的容器与间距。
15
+ * **标签位与操作位不重复实现**:标签用标记族(只读 `.mh-badge`、可关闭 `.mh-tag`)、操作用按钮族
16
+ * (`.mh-button--sm`)—— 本件只给它们的容器与间距。
20
17
  */
21
18
  .mh-notification {
22
19
  position: relative;
@@ -1,17 +1,9 @@
1
1
  /**
2
- * notification —— 单件令牌(**基础值**)。
2
+ * notification —— 单件令牌(**基础值**;只服务本件,故不随主题进 `@manohub/theme`)。
3
3
  *
4
- * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
- *
6
- * ## 抽出说明
7
- * 本文件从面文件里抽出(原先混写在 `notification.css` 顶部):这些是**基础值**,锚在
8
- * `[data-manohub-ui]` —— 跨包唯一作用域锚,由入口层无条件写在应用容器上,因此**任何落在
9
- * 容器里的分件都取得到值**,不再依赖「声明在某个组件根类上」这条脆弱假设
10
- * (历史症状:跨件消费的 `--ui-*-group-*` 取不到值,组内间距变 0)。
11
- *
12
- * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里 —— 它们靠「同一元素上两个
13
- * 选择器改写同一个令牌」生效,搬到本文件会让档位失效。
14
- * ⚠️ 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
4
+ * 令牌锚 `[data-manohub-ui]`(容器是每个分件的祖先 ⇒ 落在容器里的分件都取得到值)。
5
+ * ⚠️ `.mh-<件>--<档>` 这类**档位改写**留在面文件的修饰符块里(搬走会让档位失效);
6
+ * 新增组件要登记两处:本文件 + `src/styles/index.css`(见其文件头「五处齐备」)。
15
7
  */
16
8
  [data-manohub-ui] {
17
9
  /* 单件令牌(几何与线色) */