@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,37 +1,25 @@
1
1
  /**
2
2
  * Select —— 选择器族(单选触发器 + 多选标签 + 选项面板 + 搜索行 + 日期格)。
3
3
  *
4
- * 出处:`@aihub/theme` 的 `playground/components/select.css` 与 `src/components/select.css`
5
- * (触发器同输入框、选项行高 30、内距 8;面板内距 4 + 选项 30;多选标签复用标签族形态;
6
- * 日期格 26 方形,选中主色实底、区间 Ne10)。
4
+ * **触发器的框不在本件**:触发器 = 输入框的「触发器形态」(`<Input as="button">`),框 / 内距 / 边 / 圆角 /
5
+ * 底 / 字 / 三态 / 清除位 / 右侧图标位全部归输入面与它的表壳。本件只给选择器自己的排版(`display` / `gap` /
6
+ * `width` / `overflow` 与值 / 标签),另通过挂在**表壳**上的 `.mh-select-host` 微调两处壳内节奏。
7
+ * **禁写:本件不得再画框**(画了就又开一份会与输入面漂移的规格)。
7
8
  *
8
- * **触发器的框不在本件**:触发器 = 输入框的「触发器形态」(TSX 里是 `<Input as="button">`),
9
- * 框 / 内距 / 边 / 圆角 / 底 / 字 / hover / 聚焦 / 禁用 / 校验色与**清除位**、**右侧图标位**
10
- * 全部归输入面与它的表壳(`.mh-input` + `.mh-input__wrap`)。本件只给选择器自己的排版
11
- * (`display` / `gap` / `width` / `text-align` / `overflow` 与值 / 标签),另通过挂在**表壳**上的
12
- * `.mh-select-host` 微调两处壳内节奏(间距回到 4px、箭头收敛回 12px)。
13
- * **禁写:本件不得再画框**(画了就又开一份会与输入面漂移的规格 —— 这正是本次收敛掉的东西)。
9
+ * **面板开合与定位不在本件**:面板是操作层的组合 —— 面板根并列挂
10
+ * `class="mh-popup mh-select__panel mh-popup--anchored"`(`data-side` / `data-align` 定位档、Esc、点外部
11
+ * 关闭、顶层渲染全在 `styles/operations/popup.css`);本件只给**面**。
14
12
  *
15
- * **面板开合与定位不在本件**:面板是操作层的组合 —— 消费方/组件在面板根并列挂
16
- * `class="mh-popup mh-select__panel mh-popup--anchored"`(`data-side` / `data-align` 定位档、
17
- * Esc、点外部关闭、顶层渲染全在 `styles/operations/popup.css`)。本件只给**面**
18
- * (底 / 圆角 / 内距 / 阴影 / 选项行)。
13
+ * **面板宽度跟触发器走**:触发器是**流式宽度**(与 input 同一结论),故面板用 `anchor-size(width)` 取锚点宽。
14
+ * 触发器进表壳后 `popovertarget` 的**隐式锚**只有壳内那个控件那么宽,故走**显式锚档**:表壳挂
15
+ * `.mh-popup-anchor`、面板挂 `.mh-popup--anchored`,锚点即整件;非锚定场景回落 240px。
16
+ * **面板有高度上限**(`--ui-select-panel-max-height`,默认 320px):超出即内容区滚动、搜索行常驻 —— 列表与树
17
+ * 两形态共用这一份,形态里不许各写限高。
19
18
  *
20
- * **面板宽度跟触发器走**:规范把触发器与面板都钉在 300px,本仓触发器是**流式宽度**
21
- * (与 input 同一结论),故面板用 `anchor-size(width)` 取锚点宽。触发器进表壳后,
22
- * `popovertarget` 的**隐式锚**只有壳内那个控件那么宽,故这里走**显式锚档**:
23
- * 表壳挂 `.mh-popup-anchor`(`anchor-name`)、面板挂 `.mh-popup--anchored`(`position-anchor`),
24
- * 锚点即整件;非锚定场景回落到 240px 兜底值。
25
- *
26
- * **面板有高度上限**:`--ui-select-panel-max-height`(默认 320px)钉在面板根上,超出即内容区
27
- * (`.mh-select__body`)滚动、搜索行常驻 —— 列表与树两形态共用这一份,形态里不许各写限高。
28
- *
29
- * **一处有色差异**:规范的选中行是灰底(Ne10),本仓的「选中」统一走**主色浅底**
30
- * `--ui-primary-subtle`(与列表 / 树的选中态同一语义槽位),否则悬停(Ne11)与选中(Ne10)两档灰
31
- * 在本仓有限的灰阶里挤成同色、看不出选中。
32
- *
33
- * 选项选中态**三源等价**:原生 `:has(input:checked)`(零 JS 单选路径)/ 组件下发
34
- * `[data-state='selected']` / 静态档 `.is-selected`。
19
+ * **一处有色差异**:规范的选中行是灰底(Ne10),本仓「选中」统一走**主色浅底** `--ui-primary-subtle`
20
+ * (与列表 / 树同一语义槽位),否则悬停(Ne11)与选中(Ne10)两档灰在本仓有限灰阶里挤成同色。
21
+ * 选项选中态**三源等价**:原生 `:has(input:checked)`(零 JS 路径)/ `[data-state='selected']` /
22
+ * 静态档 `.is-selected`。
35
23
  */
36
24
 
37
25
  /* ===== 触发器:只留选择器自己的排版(框与状态全归输入面) ===== */
@@ -45,33 +33,29 @@
45
33
  overflow: hidden;
46
34
  }
47
35
 
48
- /* 表壳上的本件修饰(TSX 把 `mh-select-host` 挂在**表壳**上:`class` 落壳是输入面的既有契约)。 */
49
- /* ① 壳内间距:输入框的附加位节奏是 8px,选择器自己的是 4px(值 / 标签与清除位、箭头之间) */
36
+ /* 表壳上的本件修饰(TSX 把 `mh-select-host` 挂在**表壳**上:`class` 落壳是输入面的既有契约)。
37
+ ① 壳内间距:输入面的附加位节奏是 8px,选择器自己的是 4px;② 箭头尺寸:输入面把槽内图标统一成
38
+ 16px,本件箭头是 12px —— 以 0-2-0 收敛回来。不能在 select.css 里直写 `.mh-input__suffix`:
39
+ 面文件的类名必须与文件词根同根(机械护栏),故走自己的壳修饰类。 */
50
40
  .mh-select-host {
51
41
  gap: var(--ui-space-1);
52
42
  }
53
- /* ② 箭头尺寸:`.mh-input__suffix > svg`(0-1-1)会把槽内图标统一成 16px,而本件箭头是 12px
54
- —— 这里以 0-2-0 收敛回来。注意不能在 select.css 里直写 `.mh-input__suffix`:
55
- 面文件的类名必须与文件词根同根(机械护栏),故走自己的壳修饰类。 */
56
43
  .mh-select-host .mh-select__caret {
57
44
  width: var(--ui-select-icon-size);
58
45
  height: var(--ui-select-icon-size);
59
46
  }
60
47
 
61
- /* ===== 尺寸档:框的尺寸归输入面,本类只承载选择器自有部位的对档微调 ===== */
62
- /* 框高 / 字号由 `<Input size>` 下发的 `mh-input--sm` / `--lg` 承担(含表壳的换高)。
63
- 两处口径要认(都是输入面既有事实,不是本件选择):
64
- ① **左右内距不随档位变**:带壳时内距归表壳(`--ui-input-padding-x` = 12px 恒定),
65
- `--ui-input-padding-x-sm/-lg` 只对**裸控件**生效 —— 输入框自己的 sm / lg 实测也是 12px;
66
- ② `mh-select--*` 只跟「选择器自己的东西」有关 —— 当前只有标签:小号控件 24px 高,
67
- 24px 的标签会顶满整件、失去呼吸位,故收 4px。 */
48
+ /* ===== 尺寸档:框的尺寸归输入面,本类只承载选择器自有部位的对档微调 =====
49
+ 框高 / 字号由 `<Input size>` 下发的 `mh-input--sm` / `--lg` 承担。两处口径都是输入面的既有事实:
50
+ ① **左右内距不随档位变**(带壳时内距归表壳,`--ui-input-padding-x-sm/-lg` 只对裸控件生效);
51
+ ② `mh-select--*` 只跟「选择器自己的东西」有关 —— 当前只有标签(小号控件 24px 高,24px 的标签会
52
+ 顶满整件、失去呼吸位,故收 4px)。 */
68
53
  .mh-select--sm .mh-select__chip {
69
54
  height: calc(var(--ui-select-chip-height) - 4px);
70
55
  }
71
56
 
72
- /* 值区:有值时的单选那一行(占满剩余宽、超出省略)。
73
- ⚠️ **无值态不在这里** —— 占位由输入面渲染(`.mh-input__placeholder`,色与截断同档):
74
- 2026-09-29 收敛,此前本文件还有一个 `--placeholder` 修饰类专门给占位上灰字。 */
57
+ /* 值区:有值时的单选那一行(占满剩余宽、超出省略)。⚠️ **无值态不在这里** —— 占位由输入面渲染
58
+ (`.mh-input__placeholder`,色与截断同档)。 */
75
59
  .mh-select__value {
76
60
  flex: 1;
77
61
  min-width: 0;
@@ -79,18 +63,16 @@
79
63
  text-overflow: ellipsis;
80
64
  white-space: nowrap;
81
65
  }
82
- /* 下拉箭头:渲染在输入面的**右侧图标位**(`.mh-input__suffix`,表壳的子元素)里 ——
83
- 位置由表壳的 flex 排布给(控件 `flex: 1 1 auto` 自然把附加位挤到右端),故不再需要 `margin-left: auto`。
84
- 字形由 @manohub/icon 给;展开转向由 popup.css 的 `.mh-popup-caret` 承担(含触发器进表壳后的兄弟档);
85
- 尺寸的 12px 在下面 `mh-select-host` 一节按特异性收敛(槽内 svg 会被输入面统一成 16px)。 */
66
+ /* 下拉箭头:渲染在输入面的**右侧图标位**里,位置由表壳的 flex 排布给(控件 `flex: 1 1 auto` 自然把
67
+ 附加位挤到右端),故不需要 `margin-left: auto`。字形由 @manohub/icon 给;展开转向由 popup.css 的
68
+ `.mh-popup-caret` 承担(含触发器进表壳后的兄弟档);尺寸的 12px 在上面 `mh-select-host` 一节收敛。 */
86
69
  .mh-select__caret {
87
70
  flex: none;
88
71
  color: var(--ui-base-content-muted); /* Te07 */
89
72
  }
90
73
 
91
- /* ===== 多选:标签 + 收纳(单行不换行,超出由组件算「其他 n 项」) =====
92
- 清除位不在本件:它是输入面的内建件(`.mh-input__clear`,圆点实底 + 反白叉号),
93
- 由 `<Input clearable>` 渲染在**表壳**里 —— 与值 / 标签同一行的右端。 */
74
+ /* ===== 多选:标签 + 收纳(单行不换行,超出由组件算「其他 n 项」)
75
+ 清除位不在本件:它是输入面的内建件(`.mh-input__clear`),由 `<Input clearable>` 渲染在表壳里。 ===== */
94
76
  .mh-select--multiple {
95
77
  flex-wrap: nowrap;
96
78
  }
@@ -110,58 +92,46 @@
110
92
  color: var(--ui-base-content-muted);
111
93
  }
112
94
  /* ===== 面板皮肤(与操作层并列组合:`class="mh-popup mh-select__panel mh-popup--anchored"`) =====
113
- **面板是列容器 + 限高**:搜索行常驻(不滚),下一条的 `.mh-select__body` 承担滚动 ——
114
- 列表与树两形态因此共用同一份「长内容不撑破面板」的规格。
115
- (历史症状:限高原先只写在树体 `.mh-select__tree` 上,而列表形态的选项是面板的**直接子节点**,
116
- 面板会被一路撑高;实测 60 条选项的面板高 2212px、视口只有 925px。) */
95
+ **面板是列容器 + 限高**:搜索行常驻(不滚),下一条的 `.mh-select__body` 承担滚动 —— 列表与树两形态
96
+ 因此共用同一份「长内容不撑破面板」的规格。 */
117
97
  .mh-select__panel {
118
98
  /* 锚 = `.mh-popup-anchor`(挂在表壳上)→ 面板与**整件**同宽;非锚定场景回落 240 */
119
99
  width: anchor-size(width, 240px);
120
100
  /* 列容器:搜索行 `flex: none` + 内容区 `flex: 1 / min-height: 0`。
121
101
  ⚠️ 加 `display: flex` 会以作者源压过 UA 给**收起态**定的 `display: none`,收起态靠操作层
122
- `operations/popup.css` 里那条 `:is()` 兜底(把收起的浮层重新钉成 `display: none`,
123
- 特异性 0-3-0、高于本行)—— **那条兜底不能删**(与 `dialog.css` 同一处坑)。 */
102
+ `operations/popup.css` 里那条 `:is()` 兜底 —— **那条兜底不能删**(与 `dialog.css` 同一处坑)。 */
124
103
  display: flex;
125
104
  flex-direction: column;
126
105
  /* 限高(**含搜索行**):超出即内容区滚动。面板仍贴锚点,只是不再无限长 */
127
106
  max-height: var(--ui-select-panel-max-height);
128
- /* UA 给 `[popover]` 的是 `overflow: auto`,必须归零:内容区已是滚动容器,
129
- 留一层就会与它叠成两条滚动条(同一个面板上实测会同时出现)。 */
107
+ /* UA 给 `[popover]` 的是 `overflow: auto`,必须归零:内容区已是滚动容器,留一层就叠成两条滚动条 */
130
108
  overflow: hidden;
131
109
  padding: var(--ui-space-1) 0;
132
110
  border-radius: var(--ui-select-radius);
133
111
  background: var(--ui-base-100);
134
112
  /* 锚定浮层的投影走 `--ui-shadow-popover`(**不是** elevated):两枚令牌按「锚定浮层 vs 居中浮层」
135
- 分工,default 主题给前者填的是设计实测值(`0:4025` 的 `0 4px 20px rgba(0,14,51,.10)`),
136
- farris 主题给的是规范的 `--mh-shadow-lg:14dp 下拉/弹出层` —— 语义与两套来源都对得上。 */
113
+ 分工,default 主题给前者填的是设计实测值(`0:4025` 的 `0 4px 20px rgba(0,14,51,.10)`)。 */
137
114
  box-shadow: var(--ui-shadow-popover);
138
115
  }
139
116
 
140
- /* 内容区:**面板里唯一的滚动容器**(列表体的选项行 / 树体的树都装在它里面),
141
- 同时是**两形态共用的一处内距** —— 内容贴面板左右边各留一个最小呼吸位
142
- (行仍是满宽,只有内容缩进;选项行的内距与树行的缩进各由自己承担)。
143
- 内距为什么在这儿而不是各形态自己一层:见下方「树体壳已退场」一节的实测症状。
144
- `min-height: 0` 是这一档生效的前提:列容器里弹性项的可收缩下限默认取内容高,
145
- 不给它,内容就永远压不下去、上面的限高形同虚设(与 `panel.css` 的 `.mh-panel__body` 同款)。 */
117
+ /* 内容区:**面板里唯一的滚动容器**(列表的选项行 / 树体的树都装在它里面),同时是**两形态共用的
118
+ 一处内距**(内容贴面板左右边各留一个最小呼吸位;行仍是满宽,选项行的内距与树行的缩进各由自己承担)。
119
+ `min-height: 0` 是这一档生效的前提:列容器里弹性项的可收缩下限默认取内容高,不给它,内容就永远
120
+ 压不下去、上面的限高形同虚设(与 `panel.css` 的 `.mh-panel__body` 同款)。 */
146
121
  .mh-select__body {
147
122
  flex: 1;
148
123
  min-height: 0;
149
124
  overflow-y: auto;
150
- /* 左右与下各一个最小呼吸位(上不写:面板根已有 4px 上内距)。
151
- 底部这一档落在**滚动容器**上:现代引擎已把滚动器的 padding-bottom 计入可滚动区
152
- (实测 60 条选项 scrollHeight = 2160 + 4),故滚到底时最后一行不会贴着面板下边。 */
125
+ /* 左右与下各一个最小呼吸位(上不写:面板根已有 4px 上内距)。底部这一档落在**滚动容器**上:
126
+ 现代引擎已把滚动器的 padding-bottom 计入可滚动区(实测 60 条选项 scrollHeight = 2160 + 4)。 */
153
127
  padding: 0 var(--ui-space-1) var(--ui-space-1);
154
128
  }
155
129
 
156
- /* 选项行:滑过 / 键盘高亮 / 选中 / 禁用 / 提示 / 空态
157
- **行的几何与行态与树行同源**(`mh-tree__row`,2026-09-30 由使用方拍板对齐):行高 / 圆角 /
158
- 基础内距 / 字号 / 滑过与选中底色逐项同值 —— 同一个面板里,列表与树两形态不再各是一套行。
159
- 行元素是 `div[role='option']`、**不是 button**(见 `select-list.tsx`):listbox 的选项不是交互控件,
160
- 键盘改由「触发器持焦 + `aria-activedescendant` 指向高亮行」表达。
161
- 随之退场的两条补丁(都是为 `<button>` 而写的):
162
- ① 按钮 UA 四件套重置(`border` / `background` / `font-family` / `text-align`)—— div 本就没有 UA 外观;
163
- ② `width: 100%` —— 那是按钮的 `width: auto` 解析成「包裹内容宽」才要补的,div 是块级、本就满宽
164
- (hint / empty 两个 span 靠下面的 display 拿满宽)。 */
130
+ /* 选项行:滑过 / 键盘高亮 / 选中 / 禁用 / 提示 / 空态。
131
+ **行的几何与行态与树行同源**(`mh-tree__row`):行高 / 圆角 / 基础内距 / 字号 / 滑过与选中底色
132
+ 逐项同值 —— 同一个面板里列表与树两形态不再各是一套行。
133
+ 行元素是 `div[role='option']`、**不是 button**:listbox 的选项不是交互控件,键盘改由「触发器持焦 +
134
+ `aria-activedescendant` 指向高亮行」表达(故不需要按钮 UA 重置与 `width: 100%` 那两条补丁)。 */
165
135
  .mh-select__option {
166
136
  position: relative;
167
137
  display: flex;
@@ -187,10 +157,8 @@
187
157
  appearance: none;
188
158
  pointer-events: none;
189
159
  }
190
- /* 行态三档与树行逐条对应(滑过 / 按下 / 选中):
191
- ① 滑过 = 键盘高亮(`data-active`,见 `select-list.tsx` 的高亮模型)= 主色浅底;
192
- ② 按下 = 选中底(与树行的 `:active` 同款);
193
- ③ 选中 = 选中底 + 主色字。 */
160
+ /* 行态三档与树行逐条对应:① 滑过 = 键盘高亮(`data-active`)= 主色浅底;② 按下 = 选中底;③ 选中 =
161
+ 选中底 + 主色字。 */
194
162
  .mh-select__option:hover,
195
163
  .mh-select__option.is-hover,
196
164
  .mh-select__option[data-active='true'] {
@@ -212,15 +180,13 @@
212
180
  background: var(--ui-select-option-selected);
213
181
  color: var(--ui-primary);
214
182
  }
215
- /* 相连的选中行:缝上的圆角**融合抵消**(多选连续勾选时最扎眼 —— 两个 6px 圆角各自让出的
216
- 凹口拼成一个「蝴蝶结」,看着像渲染坏了)。
217
- 做法:给自己选中、**下一行也选中**的那一行补一条同色补片,向上下各延伸一个圆角位 ——
218
- 它同时盖住上行让出的下半凹口与下行让出的上半凹口,两块底因此连成一片。
219
- 只认「下一行」这一个方向(CSS 只有向后的兄弟组合子):**单向就够**,补片本来横跨两行。
220
- 补片不吃事件(`pointer-events: none`)—— 它压在下一行顶上 6px,若可点会把点击算到上一行头上。
221
- ⚠️ 零 JS 那一路的下家条件写成 `+ .mh-select__option input:checked`(兄弟组合子后再接后代),
222
- **不是** `+ .mh-select__option:has(input:checked)`:`:has()` **不许嵌套**,写了整条规则会被
223
- 解析器丢掉(浏览器里静默失效 —— 实测踩过,`contract-class-surface` 有机械护栏)。 */
183
+ /* 相连的选中行:缝上的圆角**融合抵消**(多选连续勾选时两个 6px 圆角各自让出的凹口拼成「蝴蝶结」)。做法:
184
+ 给自己选中、**下一行也选中**的那一行补一条同色补片,向上下各延伸一个圆角位 —— 它同时盖住上行让出的下半
185
+ 凹口与下行让出的上半凹口,两块底因此连成一片。只认「下一行」这一个方向(CSS 只有向后的兄弟组合子),单向
186
+ 就够(补片本来横跨两行)。补片不吃事件:它压在下一行顶上 6px,若可点会把点击算到上一行头上。
187
+ ⚠️ 零 JS 那一路的下家条件写成 `+ .mh-select__option input:checked`,**不是** `…:has(input:checked)`:
188
+ `:has()` **不许嵌套**,写了整条规则会被解析器丢掉(浏览器里静默失效 —— 实测踩过,
189
+ `contract-class-surface` 有机械护栏)。 */
224
190
  .mh-select__option.is-selected:has(+ .mh-select__option.is-selected)::after,
225
191
  .mh-select__option[data-state='selected']:has(+ .mh-select__option[data-state='selected'])::after,
226
192
  .mh-select__option:has(input:checked):has(+ .mh-select__option input:checked)::after {
@@ -246,9 +212,8 @@
246
212
  .mh-select__option--empty {
247
213
  color: var(--ui-base-content-muted);
248
214
  }
249
- /* 「创建 xxx」行:搜索词无命中时出现 —— 它是 `.mh-select__option` 上的**修饰类**
250
- (两件同写:`class="mh-select__option mh-select__add"`),行的几何与三态全沿用基类,
251
- 这里只改字色为「可创建」的主色。 */
215
+ /* 「创建 xxx」行:搜索词无命中时出现 —— 它是 `.mh-select__option` 上的**修饰类**(行几何与三态全沿用
216
+ 基类),这里只把字色改成「可创建」的主色。 */
252
217
  .mh-select__add {
253
218
  color: var(--ui-primary);
254
219
  }
@@ -266,26 +231,15 @@
266
231
  cursor: default;
267
232
  }
268
233
 
269
- /* 搜索行(**消费方显式 `searchable` 时才由组件渲染**,件不按选项条数自动决断)。
270
- `flex: none`:它是面板的**常驻**行 —— 面板限高时收缩与滚动都归内容区,
271
- 少了它,搜索行会被一起压扁(列容器里它默认是可收缩的)。 */
234
+ /* 搜索行(**消费方显式 `searchable` 时才渲染**,件不按选项条数自动决断)。
235
+ `flex: none`:它是面板的**常驻**行 —— 面板限高时收缩与滚动都归内容区,少了它搜索行会被一起压扁。 */
272
236
  .mh-select__search {
273
237
  flex: none;
274
238
  padding: var(--ui-space-2) var(--ui-space-2) var(--ui-space-1);
275
239
  }
276
240
 
277
- /* ===== 树体壳已退场(2026-09-30)=====
278
- 原先这里有一个 `.mh-select__tree`:面板里的树包在它里面拿内距(左右 4 / 下 4),
279
- 而列表形态的选项是面板的**直接子节点**、一路贴到面板边缘 —— 同一个面板里两形态的内距不一样
280
- (浏览器实测:面板 240 时树行 232、选项行 240)。
281
- 内距现归**共用的内容区**(上一节 `.mh-select__body`):一处规格、两形态同数;
282
- 树体壳的唯一职责既然已经上移,壳本身一并退场 —— 留一层不承载任何规则的包裹只是噪音。
283
- 边界不变:**面板皮肤归本文件**,**树的行态归 tree 面**(`.mh-tree__*` 那一族,本文件一行都不碰
284
- —— 跨族类名须先登记跨面豁免,这里不走那条路),行高 / 缩进 / 滑过与选中底色全沿用 tree 面。 */
285
-
286
- /* 命中高亮(搜索命中的那段文字,由组件的 `renderLabel` 落进 `.mh-tree__label` 槽)。
287
- 底色取主色浅底档(与选中 / 滑过同一套语义槽位);字色 `inherit` —— 高亮只负责「标出位置」,
288
- 不引入第二套强调色,否则同一行里会同时出现三种主色深浅。 */
241
+ /* 命中高亮(搜索命中的那段文字,由组件的 `renderLabel` 落进 `.mh-tree__label` 槽):底色取主色浅底档
242
+ (与选中 / 滑过同一套语义槽位);字色 `inherit` —— 高亮只负责「标出位置」,不引入第二套强调色。 */
289
243
  .mh-select__hit {
290
244
  border-radius: var(--ui-radius-xs);
291
245
  background: var(--ui-primary-weak);
@@ -1,17 +1,9 @@
1
1
  /**
2
- * select —— 单件令牌(**基础值**)。
2
+ * select —— 单件令牌(**基础值**;只服务本件,故不随主题进 `@manohub/theme`)。
3
3
  *
4
- * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
- *
6
- * ## 抽出说明
7
- * 本文件从面文件里抽出(原先混写在 `select.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
  /* 本件有三处「跨分件消费」的令牌,改前靠把它们同时声明在下面几个类上兜 —— 现在都靠容器锚取到值:
@@ -1,15 +1,12 @@
1
1
  /**
2
2
  * Skeleton —— 骨架屏(骨架行 / 列表骨架 / 块状骨架)。
3
3
  *
4
- * 出处:`@aihub/theme` 的 `playground/components/skeleton.css` 与 `src/components/skeleton.css`
5
- * (行高 30 与表格行高一致、圆角 6、行间距 10、shimmer 微光 1.6s ease-in-out)。
4
+ * 出处:规范(行高 30 与表格行高一致、圆角 6、行间距 10、shimmer 微光 1.6s ease-in-out)。
6
5
  *
7
6
  * **微光动画与色值在本包只有这一处定义**(`--ui-skeleton-*` + `@keyframes mh-skeleton-shimmer`):
8
- * `query-state.css` 的加载态骨架复用这里的令牌与动画名,不再自带一份 —— 两处各写一份必然漂
9
- * (时长/色值改一处漏一处,同一屏出现两种呼吸节奏)。
10
- *
11
- * 动画降级:`prefers-reduced-motion` 下应压平(本件只声明动画,压平由消费方或后续统一的降级策略负责,
12
- * 与 theme 包 `base/motion.css` 的分工一致)。
7
+ * `query-state.css` 的加载态骨架复用这里的令牌与动画名 —— 两处各写一份必然漂(时长 / 色值改一处漏一处,
8
+ * 同一屏出现两种呼吸节奏)。
9
+ * `prefers-reduced-motion` 下应压平:本件只声明动画,压平由消费方或后续统一的降级策略负责。
13
10
  */
14
11
  .mh-skeleton {
15
12
  height: var(--ui-skeleton-height);
@@ -3,16 +3,11 @@
3
3
  *
4
4
  * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
5
  *
6
- * ## 抽出说明
7
- * 本文件从面文件里抽出(原先混写在 `skeleton.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-skeleton-bg: var(--ui-base-200); /* Ne10 底 */
@@ -1,20 +1,17 @@
1
1
  /**
2
2
  * Steps —— 步骤条(横向节点式 + 条形燕尾段式 + 进度条)。
3
3
  *
4
- * 出处:`@aihub/theme` 的 `playground/components/steps.css` 与 `src/components/steps.css`
5
- * (节点 30 圆、字号 14、节点与标题**同行**、标题间距 12;连线是 2px **点线** + 末端 6px 方盒转 45°
6
- * 的 `>` 折角箭头、最小长 58.383、弹性撑开;段 140×30、相邻**重叠 10**、整条 inline-flex 收宽;
7
- * 进度条高 9)。
4
+ * 出处:规范(节点 30 圆、字号 14、节点与标题**同行**、标题间距 12;连线是 2px **点线** + 末端 6px 方盒
5
+ * 转 45° 的 `>` 折角箭头、最小长 58.383、弹性撑开;段 140×30、相邻**重叠 10**、整条 inline-flex 收宽;
6
+ * 进度条高 9)。
7
+ * ⚠️ **当前步之后那一段才转蓝**(已完成步之后仍是灰线)—— 规范实测的取向,别做成"已完成段全蓝"。
8
8
  *
9
- * **当前步之后那一段才转蓝**(已完成步之后仍是灰线)—— 这是规范实测的取向,别做成"已完成段全蓝"。
9
+ * 状态来源是**单一来源**(组件下发的 `--done` / `--current` / `--active`):步骤序号不是原生元素能表达的
10
+ * 状态,故这里没有「三源等价」可言 —— 与勾选 / 开关那类不同,别照抄那份写法。
10
11
  *
11
- * 状态来源是**单一来源**(组件下发的 `--done` / `--current` / `--active`):步骤序号不是原生元素能表达的状态,
12
- * 故这里没有「三源等价」可言 —— 与勾选/开关那类不同,别照抄那份写法。
13
- *
14
- * 连线用**独立空元素**(`.mh-steps__connector`)而不是 `.mh-steps__step + ::after`:折角箭头要撑开弹性余量,
15
- * 且 N 个节点配 N-1 条线,独立元素才能让两端节点各自保持自己的标题宽度。
16
- *
17
- * 可点档(`clickable`)下步元素是**原生 `<button>`** —— 归零、焦点环、禁用态见文件中间那节。
12
+ * 连线用**独立空元素**(`.mh-steps__connector`)而不是 `+ ::after`:折角箭头要撑开弹性余量,且 N 个节点
13
+ * 配 N-1 条线,独立元素才能让两端节点各自保持自己的标题宽度。
14
+ * 可点档(`clickable`)下步元素是**原生 `<button>`** —— 归零 / 焦点环 / 禁用态见文件中间那节。
18
15
  */
19
16
 
20
17
  /* 几何只挂在 node 档根件上:令牌在同名 `.tokens.css`(锚 `[data-manohub-ui]`),几何若跟着挂会给 bar / 进度条多套一层 flex */
@@ -1,17 +1,9 @@
1
1
  /**
2
- * steps —— 单件令牌(**基础值**)。
2
+ * steps —— 单件令牌(**基础值**;只服务本件,故不随主题进 `@manohub/theme`)。
3
3
  *
4
- * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
- *
6
- * ## 抽出说明
7
- * 本文件从面文件里抽出(原先混写在 `steps.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
  /* bar 档与独立进度条都是**自己的根节点**(无 `.mh-steps` 祖先)—— 靠容器锚取到值 */
@@ -1,15 +1,12 @@
1
1
  /**
2
2
  * Switch —— 开关(两档尺寸:表格档 36×18 / 表单档 50×24)。
3
3
  *
4
- * 出处:`@aihub/theme` 的 `playground/components/switch.css` 与 `src/components/switch.css`
5
- * (轨道 36×18、滑块 14、内距 2;表单档 50×24、滑块 18、内距 3;未选中底 Ne04、选中主色;
6
- * 文字与轨道间距 10;禁用整体降透明 0.5)。
7
- *
8
- * **结构固定**:`input` →(可选)`__label` → `__track > __knob` —— 轨道用**通用兄弟** `~` 命中,
9
- * 因为文字可以夹在开关与轨道之间(规范的结构如此),用相邻兄弟 `+` 会漏。
10
- *
11
- * 状态三源等价:原生 `input:checked`(零 JS)/ 组件下发 `[data-state='checked']` / 静态档 `.is-checked`。
4
+ * 出处:规范(轨道 36×18、滑块 14、内距 2;表单档 50×24、滑块 18、内距 3;未选中底 Ne04、选中主色;
5
+ * 文字与轨道间距 10;禁用整体降透明 0.5)。
12
6
  *
7
+ * **结构固定**:`input` →(可选)`__label` → `__track > __knob` —— 轨道用**通用兄弟** `~` 命中
8
+ * (文字可以夹在开关与轨道之间,用相邻兄弟 `+` 会漏)。
9
+ * 状态三源等价:原生 `input:checked`(零 JS)/ `[data-state='checked']` / 静态档 `.is-checked`。
13
10
  * **焦点环画在可见轨道上**(隐身开关没有可见焦点),外扩 2px —— 轨道自身无边框,内缩会吃掉滑块。
14
11
  */
15
12
  .mh-switch {
@@ -17,6 +14,8 @@
17
14
  align-items: center;
18
15
  gap: var(--ui-switch-label-gap);
19
16
  cursor: pointer;
17
+ /* 定位上下文:隐身 input 的包含块必须落在开关内,否则逃出滚动容器裁剪、撑大文档滚动高度 */
18
+ position: relative;
20
19
  }
21
20
  /* 隐身开关(1px 盒 + clip-path + appearance:none,与 checkbox / radio 同配方):
22
21
  不用 display:none / visibility:hidden —— 那会把键盘与读屏一起关掉。 */
@@ -3,16 +3,11 @@
3
3
  *
4
4
  * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
5
  *
6
- * ## 抽出说明
7
- * 本文件从面文件里抽出(原先混写在 `switch.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-switch-track-w: 36px; /* 规范表格档 */
@@ -1,21 +1,20 @@
1
1
  /**
2
2
  * TabBar —— 页签条(下划线指示条 + 禁用 + 「更多」页签)。
3
3
  *
4
- * 出处:`@aihub/theme` 的 `playground/components/tabbar.css` 与 `src/components/tabbar.css`
5
- * (区高 26 / 项间距 30 / 字号 14 / 指示条高 3、距文字 3、两端与文字同宽 / 未选字 `#446a9f` /
6
- * 滑过 `#529dff` / 选中 `#4e94ff` / 禁用 Te07)。
4
+ * 出处:规范(区高 26 / 项间距 30 / 字号 14 / 指示条高 3、距文字 3、两端与文字同宽 / 未选字 `#446a9f` /
5
+ * 滑过 `#529dff` / 选中 `#4e94ff` / 禁用 Te07)。
7
6
  *
8
7
  * 三条必须照做的几何(做错一眼就歪):
9
- *
10
- * 1. **不画轨线**:规范明确警告 —— 页签区没有底边框,选中只由指示条表达;加轨线会扣走区高 1px。
11
- * 「像不像页签」全靠那道 3px 指示条,不靠一条横线。
12
- * 2. **指示条是每个项自己的伪元素**(`::after`),不是一条共享滑块:所有项的指示条常驻,未选 `opacity:0; scale:.75`,
13
- * 选中转 `opacity:1; scale:1` —— "滑过去"的观感来自这两个属性的过渡(`display` 直切补间不了)。
8
+ * 1. **不画轨线**:页签区没有底边框,选中只由指示条表达(加轨线还会扣走区高 1px)—— 「像不像页签」
9
+ * 全靠那道 3px 指示条,不靠一条横线。
10
+ * 2. **指示条是每项自己的伪元素**(`::after`),不是共享滑块:所有项的指示条常驻,未选
11
+ * `opacity:0; scale:.75`、选中转 `opacity:1; scale:1` —— "滑过去"的观感来自这两个属性的过渡
12
+ * (`display` 直切补间不了)。
14
13
  * 3. **文字贴底**:项高 26 = 文字框 20 + 留白 3 + 指示条 3,故 `align-items:flex-end` +
15
- * `padding-bottom = indicator-gap + indicator-height`。少了这段内距,指示条会压在字上。
14
+ * `padding-bottom = indicator-gap + indicator-height`(少了这段内距,指示条会压在字上)。
16
15
  *
17
- * **三源等价**(本仓通例):原生 `:checked +` / 组件下发 `[data-state='active']` / 静态档 `.is-selected`
18
- * 指向同一份声明 —— 原生态给零 JS 用法(原生 radio 互斥 + ← → 换页签),组件态给受控值。
16
+ * **三源等价**(本仓通例):原生 `:checked +` / `[data-state='active']` / 静态档 `.is-selected` ——
17
+ * 原生态给零 JS 用法,组件态给受控值。
19
18
  */
20
19
  .mh-tabbar {
21
20
  display: flex;
@@ -23,6 +22,8 @@
23
22
  gap: var(--ui-tabbar-gap);
24
23
  height: var(--ui-tabbar-height);
25
24
  flex-shrink: 0;
25
+ /* 定位上下文:隐身 input 的包含块必须落在控件内,否则逃出滚动容器裁剪、撑大文档滚动高度 */
26
+ position: relative;
26
27
  }
27
28
 
28
29
  .mh-tabbar__tab {
@@ -3,16 +3,11 @@
3
3
  *
4
4
  * 本件自己的几何 / 尺寸 / 色彩槽位;只服务本件,故不随主题进 `@manohub/theme`。
5
5
  *
6
- * ## 抽出说明
7
- * 本文件从面文件里抽出(原先混写在 `tabbar.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-tabbar-height: var(--ui-control-height-md); /* 标准控件高 32 */