@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.
- package/README.md +141 -0
- package/dist/components/avatar/index.d.ts +283 -0
- package/dist/components/avatar/index.js +167 -0
- package/dist/components/badge/index.d.ts +132 -0
- package/dist/components/badge/index.js +99 -0
- package/dist/components/button/index.d.ts +578 -0
- package/dist/components/button/index.js +191 -0
- package/dist/components/capsule/index.d.ts +161 -0
- package/dist/components/capsule/index.js +101 -0
- package/dist/components/card/index.d.ts +456 -0
- package/dist/components/card/index.js +231 -0
- package/dist/components/checkbox/index.d.ts +331 -0
- package/dist/components/checkbox/index.js +165 -0
- package/dist/components/code/index.d.ts +134 -0
- package/dist/components/code/index.js +117 -0
- package/dist/components/code-editor/index.d.ts +163 -0
- package/dist/components/code-editor/index.js +98 -0
- package/dist/components/collapse/index.d.ts +125 -0
- package/dist/components/collapse/index.js +95 -0
- package/dist/components/control-size.d.ts +8 -0
- package/dist/components/dialog/index.d.ts +224 -0
- package/dist/components/dialog/index.js +194 -0
- package/dist/components/divider/index.d.ts +64 -0
- package/dist/components/divider/index.js +62 -0
- package/dist/components/drawer/index.d.ts +226 -0
- package/dist/components/drawer/index.js +190 -0
- package/dist/components/filter/index.d.ts +391 -0
- package/dist/components/filter/index.js +203 -0
- package/dist/components/form/index.d.ts +704 -0
- package/dist/components/form/index.js +329 -0
- package/dist/components/input/index.d.ts +980 -0
- package/dist/components/input/index.js +334 -0
- package/dist/components/layout/index.d.ts +162 -0
- package/dist/components/layout/index.js +100 -0
- package/dist/components/list-view/index.d.ts +563 -0
- package/dist/components/list-view/index.js +221 -0
- package/dist/components/loading/index.d.ts +77 -0
- package/dist/components/loading/index.js +40 -0
- package/dist/components/nav/index.d.ts +293 -0
- package/dist/components/nav/index.js +164 -0
- package/dist/components/notice/index.d.ts +137 -0
- package/dist/components/notice/index.js +101 -0
- package/dist/components/notification/index.d.ts +118 -0
- package/dist/components/notification/index.js +99 -0
- package/dist/components/page/index.d.ts +276 -0
- package/dist/components/page/index.js +351 -0
- package/dist/components/page/split-resize.d.ts +42 -0
- package/dist/components/page/split-resize.js +36 -0
- package/dist/components/pagination/index.d.ts +171 -0
- package/dist/components/pagination/index.js +226 -0
- package/dist/components/panel/index.d.ts +401 -0
- package/dist/components/panel/index.js +193 -0
- package/dist/components/part-padding.d.ts +27 -0
- package/dist/components/part-padding.js +23 -0
- package/dist/components/query-state/index.d.ts +207 -0
- package/dist/components/query-state/index.js +181 -0
- package/dist/components/radio/index.d.ts +473 -0
- package/dist/components/radio/index.js +250 -0
- package/dist/components/search/index.d.ts +167 -0
- package/dist/components/search/index.js +105 -0
- package/dist/components/select/index.d.ts +252 -0
- package/dist/components/select/index.js +281 -0
- package/dist/components/skeleton/index.d.ts +88 -0
- package/dist/components/skeleton/index.js +56 -0
- package/dist/components/steps/index.d.ts +199 -0
- package/dist/components/steps/index.js +117 -0
- package/dist/components/switch/index.d.ts +150 -0
- package/dist/components/switch/index.js +103 -0
- package/dist/components/table/index.d.ts +351 -0
- package/dist/components/table/index.js +286 -0
- package/dist/components/tabs/index.d.ts +179 -0
- package/dist/components/tabs/index.js +153 -0
- package/dist/components/tabset/index.d.ts +105 -0
- package/dist/components/tabset/index.js +68 -0
- package/dist/components/tag/index.d.ts +203 -0
- package/dist/components/tag/index.js +144 -0
- package/dist/components/toast/index.d.ts +271 -0
- package/dist/components/toast/index.js +116 -0
- package/dist/components/tooltip/index.d.ts +126 -0
- package/dist/components/tooltip/index.js +97 -0
- package/dist/components/tree/index.d.ts +317 -0
- package/dist/components/tree/index.js +251 -0
- package/dist/components/upload/index.d.ts +384 -0
- package/dist/components/upload/index.js +172 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +102 -0
- package/dist/services/base.d.ts +21 -0
- package/dist/services/base.js +42 -0
- package/dist/services/dialog.d.ts +41 -0
- package/dist/services/dialog.js +83 -0
- package/dist/services/index.d.ts +12 -0
- package/dist/services/loading.d.ts +21 -0
- package/dist/services/loading.js +41 -0
- package/dist/services/toast.d.ts +40 -0
- package/dist/services/toast.js +74 -0
- package/dist/styles/components/avatar.css +128 -0
- package/dist/styles/components/avatar.tokens.css +24 -0
- package/dist/styles/components/badge.css +237 -0
- package/dist/styles/components/button.css +454 -0
- package/dist/styles/components/button.tokens.css +56 -0
- package/dist/styles/components/capsule.css +120 -0
- package/dist/styles/components/capsule.tokens.css +27 -0
- package/dist/styles/components/card.css +192 -0
- package/dist/styles/components/checkbox.css +145 -0
- package/dist/styles/components/checkbox.tokens.css +26 -0
- package/dist/styles/components/code-editor.css +91 -0
- package/dist/styles/components/code-editor.tokens.css +24 -0
- package/dist/styles/components/code.css +153 -0
- package/dist/styles/components/code.tokens.css +29 -0
- package/dist/styles/components/collapse.css +62 -0
- package/dist/styles/components/collapse.tokens.css +20 -0
- package/dist/styles/components/dialog.css +106 -0
- package/dist/styles/components/dialog.tokens.css +24 -0
- package/dist/styles/components/divider.css +71 -0
- package/dist/styles/components/divider.tokens.css +21 -0
- package/dist/styles/components/drawer.css +143 -0
- package/dist/styles/components/drawer.tokens.css +22 -0
- package/dist/styles/components/filter.css +41 -0
- package/dist/styles/components/filter.tokens.css +14 -0
- package/dist/styles/components/form.css +220 -0
- package/dist/styles/components/form.tokens.css +15 -0
- package/dist/styles/components/input.css +445 -0
- package/dist/styles/components/input.tokens.css +41 -0
- package/dist/styles/components/layout.css +198 -0
- package/dist/styles/components/list-view.css +244 -0
- package/dist/styles/components/loading.css +76 -0
- package/dist/styles/components/loading.tokens.css +23 -0
- package/dist/styles/components/nav.css +48 -0
- package/dist/styles/components/notice.css +153 -0
- package/dist/styles/components/notice.tokens.css +17 -0
- package/dist/styles/components/notification.css +159 -0
- package/dist/styles/components/notification.tokens.css +37 -0
- package/dist/styles/components/page.css +473 -0
- package/dist/styles/components/pagination.css +297 -0
- package/dist/styles/components/pagination.tokens.css +32 -0
- package/dist/styles/components/panel.css +77 -0
- package/dist/styles/components/query-state.css +88 -0
- package/dist/styles/components/radio.css +271 -0
- package/dist/styles/components/radio.tokens.css +26 -0
- package/dist/styles/components/search.css +30 -0
- package/dist/styles/components/select.css +242 -0
- package/dist/styles/components/select.tokens.css +33 -0
- package/dist/styles/components/skeleton.css +60 -0
- package/dist/styles/components/skeleton.tokens.css +27 -0
- package/dist/styles/components/steps.css +157 -0
- package/dist/styles/components/steps.tokens.css +42 -0
- package/dist/styles/components/switch.css +165 -0
- package/dist/styles/components/switch.tokens.css +26 -0
- package/dist/styles/components/table.css +439 -0
- package/dist/styles/components/table.tokens.css +41 -0
- package/dist/styles/components/tabs.css +234 -0
- package/dist/styles/components/tabs.tokens.css +30 -0
- package/dist/styles/components/tag.css +200 -0
- package/dist/styles/components/tag.tokens.css +30 -0
- package/dist/styles/components/toast.css +150 -0
- package/dist/styles/components/toast.tokens.css +26 -0
- package/dist/styles/components/tooltip.css +89 -0
- package/dist/styles/components/tooltip.tokens.css +25 -0
- package/dist/styles/components/tree.css +139 -0
- package/dist/styles/components/tree.tokens.css +20 -0
- package/dist/styles/components/upload.css +150 -0
- package/dist/styles/components/upload.tokens.css +27 -0
- package/dist/styles/index.css +149 -0
- package/dist/styles/operations/collapse.css +84 -0
- package/dist/styles/operations/popup.css +189 -0
- package/dist/styles/operations/tabset.css +57 -0
- package/dist/utils/state-illustration.d.ts +31 -0
- package/dist/utils/state-illustration.js +156 -0
- package/package.json +62 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 操作层 · 折叠(零 JS,**只给操作、不给任何面**)。
|
|
3
|
+
*
|
|
4
|
+
* 出处:`@aihub/theme` 的 `playground/components/collapse.css`(本仓第一处照搬操作层)。
|
|
5
|
+
* 映射:`--mh-*` → `--ui-*`;类名加 `.mh-` 前缀;**箭头不再是 CSS 字形**,改由 `@manohub/icon`
|
|
6
|
+
* 的 `<Icon name="chevron-down">` 渲染(本层只负责「收起时转向」,不画字形)。
|
|
7
|
+
*
|
|
8
|
+
* 面与几何一律来自皮肤族类(组合只是「根上并列两个类」):
|
|
9
|
+
* 卡片版 = `Card + Collapse`,字段分组版 = 表单分组 + `Collapse`。
|
|
10
|
+
* 因此本文件**不落任何色值/尺寸**,也没有 `--ui-collapse-*` 皮肤令牌 —— 这正是「不顶掉皮肤」的前提。
|
|
11
|
+
*
|
|
12
|
+
* 结构(原生 disclosure,零 JS 即具备键盘与读屏语义):
|
|
13
|
+
* <details class="mh-collapse [皮肤类]" open>
|
|
14
|
+
* <summary class="[皮肤头类]">标题 <Icon name="chevron-down" class="mh-collapse-caret" /></summary>
|
|
15
|
+
* <div class="[皮肤体类]">…</div>
|
|
16
|
+
* </details>
|
|
17
|
+
*
|
|
18
|
+
* 一、开关与状态根 `.mh-collapse`
|
|
19
|
+
* · 原生 `<details>` 的 `[open]` 与组件下发的 `data-state` 两条状态源等价;无状态属性即展开
|
|
20
|
+
* (收折必须显式声明)。
|
|
21
|
+
* · 触发器钩子 = 根的直接子 `<summary>`(原生形态)或 `.mh-collapse-header`(组件下发 `<button>` 形态)
|
|
22
|
+
* —— 皮肤族的部件类照旧挂在触发器上,本层不认识它们,故皮肤族零改动。
|
|
23
|
+
* · 面板体不设约定类:皮肤族自己命名。
|
|
24
|
+
*
|
|
25
|
+
* 二、收起态派生(全部由面板根状态推出)
|
|
26
|
+
* · 箭头转竖向(收起态指右);字形自身不带态。
|
|
27
|
+
* · 组件根下除触发器外直接子一律不显示;原生根由浏览器收起。
|
|
28
|
+
* · 收起态不留 gap(flex 列皮肤的隐藏内容槽仍占一个 flex 项)。
|
|
29
|
+
*
|
|
30
|
+
* 三、硬约束:**不写底 / 边 / 圆角 / 内距 / 高 / 字号 / gap** —— 写了就会顶掉皮肤族的属性面
|
|
31
|
+
* (卡片头的内距与底边线、表单分组头的行高),这正是「根上只加两个类就能组合」的前提。
|
|
32
|
+
*/
|
|
33
|
+
.mh-collapse {
|
|
34
|
+
min-width: 0; /* 仅作状态根 + 作 flex 子项时不横向溢出;面由皮肤给 */
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* 面板组:多条面板纵向成组(组间距属「组容器」的量,不进皮肤);互斥展开给同组各面板同名 name 即可,原生支持 */
|
|
38
|
+
.mh-collapse-stack {
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
gap: var(--ui-space-2);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* ===== 触发器(只做「可点 + 可键盘 + 去原生装饰」) ===== */
|
|
45
|
+
.mh-collapse > :is(summary, .mh-collapse-header) {
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
list-style: none; /* 去 <summary> 原生三角标 */
|
|
48
|
+
user-select: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Safari 的原生三角标 */
|
|
52
|
+
.mh-collapse > :is(summary, .mh-collapse-header)::-webkit-details-marker {
|
|
53
|
+
display: none;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* 可见焦点环:原生触发器(升格自 div)必须自备键盘焦点环 */
|
|
57
|
+
.mh-collapse > :is(summary, .mh-collapse-header):focus-visible {
|
|
58
|
+
outline: 2px solid var(--ui-primary);
|
|
59
|
+
outline-offset: -2px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* 组件形态的触发器是 <button>:UA 外观归零 —— 只落在 button 上,
|
|
63
|
+
免得清掉皮肤族的底边线一类属性面 */
|
|
64
|
+
.mh-collapse > button.mh-collapse-header {
|
|
65
|
+
width: 100%;
|
|
66
|
+
border: 0;
|
|
67
|
+
background: none;
|
|
68
|
+
font: inherit;
|
|
69
|
+
text-align: left;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* ===== 收起态派生 ===== */
|
|
73
|
+
details.mh-collapse:not([open]) > :is(summary, .mh-collapse-header) .mh-collapse-caret,
|
|
74
|
+
.mh-collapse[data-state='closed'] > :is(summary, .mh-collapse-header) .mh-collapse-caret {
|
|
75
|
+
transform: rotate(-90deg);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.mh-collapse[data-state='closed'] > :not(:is(summary, .mh-collapse-header)) {
|
|
79
|
+
display: none;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
details.mh-collapse:not([open]) {
|
|
83
|
+
gap: 0;
|
|
84
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 操作层 · 浮层(零 JS,**只给操作、不给任何面**)。
|
|
3
|
+
*
|
|
4
|
+
* 出处:`@aihub/theme` 的 `playground/components/popup.css`。
|
|
5
|
+
* 映射:`--mh-*` → `--ui-*`;类名加 `.mh-` 前缀;**箭头不再取 utils 的 CSS 字形**,改由 `@manohub/icon`
|
|
6
|
+
* 的 `<Icon name="chevron-down" class="mh-popup-caret">` 渲染(本层只负责「展开时转向」)。
|
|
7
|
+
*
|
|
8
|
+
* 面与几何一律来自皮肤族类,面板根上并列两个类即组合:
|
|
9
|
+
* 气泡确认 = 气泡皮肤、下拉层 = 选择面板皮肤、提示 = 提示皮肤、对话框 = 卡片 + 对话框皮肤。
|
|
10
|
+
*
|
|
11
|
+
* 结构(原生 popover,零 JS 即具备轻 dismiss / Esc / top layer 渲染):
|
|
12
|
+
* <button popovertarget="p1">触发器</button>
|
|
13
|
+
* <div id="p1" popover class="mh-popup [皮肤类]" data-side="bottom">…</div>
|
|
14
|
+
*
|
|
15
|
+
* 本层只做五件事:
|
|
16
|
+
*
|
|
17
|
+
* 一、状态根 `.mh-popup` —— 三条状态源等价(与折叠的 `[open]` / `data-state` 同构):
|
|
18
|
+
* · 原生 popover:`popovertarget` 开合,`:popover-open` 即展开(本层无需为它写状态规则);
|
|
19
|
+
* · 原生 `<dialog>`:`[open]`(`showModal()` 那条路同样接得住);
|
|
20
|
+
* · 组件下发:`data-state="open|closed"`(与本仓其它件的 `data-state` 协议同款)。
|
|
21
|
+
* 收起态本该由 UA 的 `display: none` 承担(组件路径则由组件卸载)—— 但皮肤自带 display 的会以作者源
|
|
22
|
+
* 压过 UA(提示皮肤实测踩坑),故收起态仍要按高特异性重新钉一次(见「收起态派生」)。
|
|
23
|
+
*
|
|
24
|
+
* 二、触发器钩子 —— `[popovertarget]`(原生,属性即钩子)/ `.mh-popup-trigger`(组件路径),
|
|
25
|
+
* 只做「可点 + 可键盘 + 焦点环」。**触发器不做 UA 归零**(与折叠清 `<summary>` 三角标相反):
|
|
26
|
+
* 它本身就是带皮肤的控件,那样清会顶掉按钮皮肤。
|
|
27
|
+
*
|
|
28
|
+
* 三、UA 装饰归零 + 收起态派生 —— 原生 `[popover]` 与 `<dialog>` 会发下 `border` / `padding` /
|
|
29
|
+
* `background`,不归零就在面板外面多出一圈黑框;收起态则如上条所述要重新钉住 display。
|
|
30
|
+
* 两条都只落在浮层本体,不碰任何皮肤属性面。
|
|
31
|
+
*
|
|
32
|
+
* 四、零 JS 锚定 —— CSS Anchor Positioning:`position-area` 定位档(`data-side` / `data-align`)
|
|
33
|
+
* + `position-try-fallbacks` 自动翻面;锚点走 `popovertarget` 的**隐式锚**,一个 `anchor-name`
|
|
34
|
+
* 都不用写(隐式锚够不着时才用 `.mh-popup-anchor` / `.mh-popup--anchored` 那一档)。
|
|
35
|
+
* 无 `data-side` 时不落定位档 —— 模态与无锚点浮层退回 UA 的视口居中。
|
|
36
|
+
*
|
|
37
|
+
* 五、展开态派生 —— 箭头转向:原生路径由宿主 `:has` 反推,组件路径由触发器自带的
|
|
38
|
+
* `aria-expanded` 反推。
|
|
39
|
+
*
|
|
40
|
+
* 六、hover 档 `.mh-popup--hover` —— 给「非交互提示」的纯 CSS 显形(移入 / 聚焦即出)。
|
|
41
|
+
* 必须存在的原因:popover 只能由点击或 JS 开合,CSS 开合不了;hover 触发的原生属性尚未落地。
|
|
42
|
+
* 代价见该节注释(不进 top layer:会被裁切、要自带 z-index、无 light dismiss)。
|
|
43
|
+
*
|
|
44
|
+
* **硬约束:本层规则一律走 `:where()`(特异性 0)** —— 这是「不顶掉皮肤」的机械保证:
|
|
45
|
+
* 作者源本来就高于 UA 源,故 `:where()` 压得住 UA 装饰;而对皮肤类(0-1-0 起)永远让位
|
|
46
|
+
* (反例即折叠里 `.mh-collapse > button.mh-collapse-header`:那里清的是 UA 按钮装饰,故须高特异性
|
|
47
|
+
* 且只落在组件形态的触发器上;本层结论是「能不动触发器就不动」)。
|
|
48
|
+
* 例外只有三类,都是「必须压过皮肤」的 display 与「只声明身份」的属性:
|
|
49
|
+
* ① 四条裸类规则(`.mh-popup` / `.mh-popup-anchor` / `.mh-popup-host` / `.mh-popup--anchored`)
|
|
50
|
+
* —— 声明状态根与锚点身份,皮肤族不碰这些属性面;
|
|
51
|
+
* ② 收起态规则走 `:is()`(0-3-0)—— 皮肤自带 display 会压过 UA 的收起 display:none;
|
|
52
|
+
* ③ hover 档两条(`.mh-popup.mh-popup--hover` 0-2-0 / `.mh-popup-host:hover …` 0-3-0)—— 同上。
|
|
53
|
+
* 三条 display 规则都只碰 display(hover 档另加定位与层级),不动任何皮肤属性面。
|
|
54
|
+
*
|
|
55
|
+
* 禁写清单(与折叠同款):底 / 边 / 圆角 / 内距 / 宽高 / 字号 / 阴影 / 遮罩色 / 动画
|
|
56
|
+
* —— 遮罩色归对话框皮肤(真实弹出层遮罩由其 `::backdrop` 画),进出场动画归显示层。
|
|
57
|
+
* 层级:popover 档由 top layer 接管(零 z-index),hover 档不进 top layer 故自带一层 z-index。
|
|
58
|
+
*/
|
|
59
|
+
/* ===== 一、状态根 ===== */
|
|
60
|
+
.mh-popup {
|
|
61
|
+
min-width: 0; /* 状态根标记;同时作本族独立基类 */
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* ===== 二、触发器钩子(只做「可点 + 可键盘」) ===== */
|
|
65
|
+
:where(.mh-popup-trigger, [popovertarget]) {
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
user-select: none;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* 可见焦点环:原生按钮有 UA 环,但带皮肤类的控件与普通元素都要有 —— 与折叠取同一句 */
|
|
71
|
+
:where(.mh-popup-trigger:focus-visible, [popovertarget]:focus-visible) {
|
|
72
|
+
outline: 2px solid var(--ui-primary);
|
|
73
|
+
outline-offset: -2px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ===== 三、UA 装饰归零(只落浮层本体,不碰任何皮肤属性面) ===== */
|
|
77
|
+
:where(.mh-popup[popover], dialog.mh-popup) {
|
|
78
|
+
border: 0;
|
|
79
|
+
padding: 0;
|
|
80
|
+
background: transparent;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* 收起态派生(本层唯一一条非 `:where()` 的状态规则,理由在特异性):
|
|
84
|
+
原生 popover / dialog 的收起靠 UA 的 `display: none`,而皮肤自带 display 的会以作者源压过 UA
|
|
85
|
+
—— 提示皮肤的 inline-block 就让收起的面板在流内显形(实测踩坑)。
|
|
86
|
+
故按「收起的浮层就是 display: none」重新钉一次:`:is()` 取最具体分支,特异性 0-3-0 足以压过任何
|
|
87
|
+
皮肤类,且只碰 display 一项;组件路径(data-state)由组件卸载,不经此条。 */
|
|
88
|
+
:is(.mh-popup[popover]:not(:popover-open), dialog.mh-popup:not([open])) {
|
|
89
|
+
display: none;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* ===== 四、零 JS 锚定(CSS Anchor Positioning) ===== */
|
|
93
|
+
/* 定位档:声明「面板落在锚点的哪一侧」+ 与锚点的呼吸位(4px)。
|
|
94
|
+
皮肤或消费方要改间距/换侧,用自己的 margin / position-area 覆盖即可 —— 本层恒 0 特异性。
|
|
95
|
+
锚点 = `popovertarget` 的调用者(隐式锚,`position-anchor: auto` 是初始值,无需声明)。 */
|
|
96
|
+
:where(.mh-popup[data-side='bottom']) {
|
|
97
|
+
position-area: bottom;
|
|
98
|
+
margin-block-start: var(--ui-space-1);
|
|
99
|
+
}
|
|
100
|
+
:where(.mh-popup[data-side='top']) {
|
|
101
|
+
position-area: top;
|
|
102
|
+
margin-block-end: var(--ui-space-1);
|
|
103
|
+
}
|
|
104
|
+
:where(.mh-popup[data-side='left']) {
|
|
105
|
+
position-area: left;
|
|
106
|
+
margin-inline-end: var(--ui-space-1);
|
|
107
|
+
}
|
|
108
|
+
:where(.mh-popup[data-side='right']) {
|
|
109
|
+
position-area: right;
|
|
110
|
+
margin-inline-start: var(--ui-space-1);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* 溢出自动翻面:贴视口边时按块轴 / 行内轴翻到对侧,零 JS 免裁切 */
|
|
114
|
+
:where(.mh-popup[data-side]) {
|
|
115
|
+
position-try-fallbacks: flip-block, flip-inline;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* 两侧对齐档(与 reka 同名的 data-align):top / bottom 沿行内轴、left / right 沿块轴;
|
|
119
|
+
不写 data-align(或写 center)= 面板中线对齐锚点(position-area 的默认行为,实测中线偏差 0)。
|
|
120
|
+
**钉边必须用 anchor() 而不是 justify-self / align-self**(实测踩坑):
|
|
121
|
+
单关键词的 position-area(如 `bottom`)在另一条轴上是铺满**包含块**的(此处即视口)——
|
|
122
|
+
于是 `justify-self: start` 会把面板贴到视口左边(实测偏了 409px),而不是锚点左边。 */
|
|
123
|
+
:where(.mh-popup[data-side='top'][data-align='start'],
|
|
124
|
+
.mh-popup[data-side='bottom'][data-align='start']) {
|
|
125
|
+
left: anchor(left);
|
|
126
|
+
right: auto;
|
|
127
|
+
}
|
|
128
|
+
:where(.mh-popup[data-side='top'][data-align='end'],
|
|
129
|
+
.mh-popup[data-side='bottom'][data-align='end']) {
|
|
130
|
+
left: auto;
|
|
131
|
+
right: anchor(right);
|
|
132
|
+
}
|
|
133
|
+
:where(.mh-popup[data-side='left'][data-align='start'],
|
|
134
|
+
.mh-popup[data-side='right'][data-align='start']) {
|
|
135
|
+
top: anchor(top);
|
|
136
|
+
bottom: auto;
|
|
137
|
+
}
|
|
138
|
+
:where(.mh-popup[data-side='left'][data-align='end'],
|
|
139
|
+
.mh-popup[data-side='right'][data-align='end']) {
|
|
140
|
+
top: auto;
|
|
141
|
+
bottom: anchor(bottom);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* 显式锚档(隐式锚够不着时用:浮层由 JS `showPopover()` 打开、触发器不是 `popovertarget` 元素等):
|
|
145
|
+
锚点元素挂 `.mh-popup-anchor` 声明锚点名、浮层加 `.mh-popup--anchored` 接入;
|
|
146
|
+
同页多实例用 `.mh-popup-host`(两者的共同祖先)把同名锚收敛到子树(`anchor-scope`),
|
|
147
|
+
否则固定锚点名在整页只有最后一个声明者生效。 */
|
|
148
|
+
.mh-popup-anchor {
|
|
149
|
+
anchor-name: --mh-popup-anchor;
|
|
150
|
+
}
|
|
151
|
+
.mh-popup-host {
|
|
152
|
+
anchor-scope: --mh-popup-anchor;
|
|
153
|
+
}
|
|
154
|
+
.mh-popup--anchored {
|
|
155
|
+
position-anchor: --mh-popup-anchor;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* ===== 五、展开态派生(箭头转向:字形由 @manohub/icon 给,本层只转向) =====
|
|
159
|
+
* 前三条是**后代**关系(箭头在触发器子树里);后两条是**兄弟**关系 ——
|
|
160
|
+
* 组合件把箭头挂到触发器的同级附加位槽里(本仓的「触发器形态」:`Select` 的箭头在表壳的
|
|
161
|
+
* `.mh-input__suffix` 里,与 `[popovertarget]` 那个控件是兄弟),后代组合器一条都命不中(实测),
|
|
162
|
+
* 故补 `~ *` 一档:同宿主内、触发器**之后**的任一兄弟(及其子树)里的箭头跟着转向。 */
|
|
163
|
+
:where(.mh-popup-host:has(.mh-popup:popover-open)) [popovertarget] .mh-popup-caret,
|
|
164
|
+
:where(.mh-popup-host:has(dialog.mh-popup[open])) [popovertarget] .mh-popup-caret,
|
|
165
|
+
:where(.mh-popup-trigger[aria-expanded='true']) .mh-popup-caret,
|
|
166
|
+
:where(.mh-popup-host:has(.mh-popup:popover-open)) [popovertarget] ~ * .mh-popup-caret,
|
|
167
|
+
:where(.mh-popup-host:has(dialog.mh-popup[open])) [popovertarget] ~ * .mh-popup-caret {
|
|
168
|
+
transform: rotate(180deg);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* ===== 六、hover 档(非交互提示:移入 / 聚焦即显形,移开即消失) =====
|
|
172
|
+
* 为何需要单独一档:原生 popover 的开合只有两个入口 —— JS `showPopover()` 与 `popovertarget`(点击),
|
|
173
|
+
* **CSS 开合不了 popover**;原生给 hover 留的口子(interest invoker)尚未落地。
|
|
174
|
+
* 故 hover 档退回普通定位元素,**不进 top layer**,代价三条,用前先认:
|
|
175
|
+
* ① 会被祖先 overflow 裁切(popover 档不会);② 层级要自带一层 z-index;③ 无 light dismiss / Esc
|
|
176
|
+
* (移开即消失,本就不需要)。换来的是提示语义正确:不吃点击、不抢焦点。
|
|
177
|
+
* 锚点必须显式声明(hover 没有隐式锚):触发器挂 `.mh-popup-anchor`、面板挂 `.mh-popup--anchored`、
|
|
178
|
+
* 两者共同祖先挂 `.mh-popup-host`(宿主 `:hover` / `:focus-within` 即显形)。`:hover` 按 DOM 祖先传播,
|
|
179
|
+
* 故指针从触发器移到面板上不会闪断。延迟与淡入属显示层 / 组件层,本层不管。
|
|
180
|
+
* 特异性说明:`display` 必须压过皮肤(提示皮肤自带 inline-block),故这两条不走 `:where()`。 */
|
|
181
|
+
.mh-popup.mh-popup--hover {
|
|
182
|
+
position: fixed;
|
|
183
|
+
z-index: 1;
|
|
184
|
+
display: none;
|
|
185
|
+
}
|
|
186
|
+
.mh-popup-host:hover .mh-popup--hover,
|
|
187
|
+
.mh-popup-host:focus-within .mh-popup--hover {
|
|
188
|
+
display: block;
|
|
189
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 操作层 · 面板切换(把「一组同名 radio + 对应面板」接起来;零 JS,**只给操作、不给面**)。
|
|
3
|
+
*
|
|
4
|
+
* 出处:`@aihub/theme` 的 `playground/components/tabset.css`。
|
|
5
|
+
* 映射:`--mh-*` → `--ui-*`;类名加 `.mh-` 前缀。
|
|
6
|
+
*
|
|
7
|
+
* 与折叠 / 浮层同一路数:本层只做三件事 —— ① 根(条带 → 面板的呼吸位)② 面板钩子与默认收起
|
|
8
|
+
* ③ 档位表(第 n 个开关 ↔ 第 n 个面板)。
|
|
9
|
+
* 开关的隐身与焦点环**归皮肤族**(谁家的选择控件谁自己画:胶囊见 `styles/components/capsule.css`),
|
|
10
|
+
* 本层不碰 —— 这样同一层能伺候任意选择控件(胶囊 / 分段按钮 / 单选卡片 / 向导步骤),换皮肤不必动本文件。
|
|
11
|
+
*
|
|
12
|
+
* **与皮肤零互指**(两层连接点全部走原生元素,谁都不引用对方的类):
|
|
13
|
+
* · 皮肤键在 `input:checked + <自家项>`(原生路径)与 `[data-state='active']`(组件路径)上;
|
|
14
|
+
* · 本层只认 `input` 与面板的**顺序**,不认任何皮肤类名。
|
|
15
|
+
*
|
|
16
|
+
* 结构契约(开关与项平级相邻、开关在前;面板组顺序与开关**一一对应**):
|
|
17
|
+
* <div class="mh-tabset">
|
|
18
|
+
* <div class="[皮肤:轨道/选择控件]">
|
|
19
|
+
* <input type="radio" name="t1" id="t1a" checked>
|
|
20
|
+
* <label class="[皮肤项]" for="t1a">全部</label>
|
|
21
|
+
* <input type="radio" name="t1" id="t1b">
|
|
22
|
+
* <label class="[皮肤项]" for="t1b">进行中</label>
|
|
23
|
+
* </div>
|
|
24
|
+
* <div class="mh-tabset-panels">
|
|
25
|
+
* <section class="mh-tabset-panel [皮肤类]">…</section>
|
|
26
|
+
* </div>
|
|
27
|
+
* </div>
|
|
28
|
+
*
|
|
29
|
+
* 禁写(与折叠 / 浮层同款):底 / 边 / 圆角 / 内距 / 宽高 / 字号 / 阴影 —— 写了就顶掉皮肤族属性面。
|
|
30
|
+
* 面板的面与几何由皮肤族给(卡片一类),本层只写「哪一个显形」与根上的呼吸位。
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/* ===== 操作根:选择控件在上、面板在下 ===== */
|
|
34
|
+
.mh-tabset {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
gap: var(--ui-space-4); /* 控件 → 面板的呼吸位 12px */
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* ===== 面板显隐:档位表(上限 8 档) ===== */
|
|
41
|
+
/* 第 n 个开关 ↔ 第 n 个面板。写不出通式:CSS 没有「按被勾选开关的序号去选同序面板」的选择器
|
|
42
|
+
(树的缩进档位表同一路数)。超过 8 个请扩表,或改走组件路径由 JS 下发 hidden。
|
|
43
|
+
注:`input:nth-of-type(n)` 按「同一父级里的第 n 个 input」计数 —— 故开关须集中在同一个轨道容器内。 */
|
|
44
|
+
.mh-tabset-panel {
|
|
45
|
+
display: none;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.mh-tabset:has(input:nth-of-type(1):checked) .mh-tabset-panels > :nth-child(1),
|
|
49
|
+
.mh-tabset:has(input:nth-of-type(2):checked) .mh-tabset-panels > :nth-child(2),
|
|
50
|
+
.mh-tabset:has(input:nth-of-type(3):checked) .mh-tabset-panels > :nth-child(3),
|
|
51
|
+
.mh-tabset:has(input:nth-of-type(4):checked) .mh-tabset-panels > :nth-child(4),
|
|
52
|
+
.mh-tabset:has(input:nth-of-type(5):checked) .mh-tabset-panels > :nth-child(5),
|
|
53
|
+
.mh-tabset:has(input:nth-of-type(6):checked) .mh-tabset-panels > :nth-child(6),
|
|
54
|
+
.mh-tabset:has(input:nth-of-type(7):checked) .mh-tabset-panels > :nth-child(7),
|
|
55
|
+
.mh-tabset:has(input:nth-of-type(8):checked) .mh-tabset-panels > :nth-child(8) {
|
|
56
|
+
display: block;
|
|
57
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 状态插画资产:**设计交付的四张 SVG,原样内联**(空 / 成功 / 异常 / 错误)。
|
|
3
|
+
*
|
|
4
|
+
* 四张图由设计直接导出(原交付件已随本轮迁移清理,**本文件是它们的唯一留存**),一字未改地收录:结构、坐标、渐变、
|
|
5
|
+
* **固定色值**、`id`、`<title>`、连 XML 声明都在 —— 渲染结果与设计稿逐像素一致。任何「重绘成令牌 /
|
|
6
|
+
* 精简路径 / 改 id」的做法都会走样,故这里不做。
|
|
7
|
+
*
|
|
8
|
+
* ## 取舍(已知并接受)
|
|
9
|
+
*
|
|
10
|
+
* - **不跟随主题**:颜色是设计交付的终值(`#EAEAEA` 底纹 / `#8DABFF` 折角 / 各态角标色),不进 `--ui-*`;
|
|
11
|
+
* 换主题、进深色域时插画保持原样。
|
|
12
|
+
* - **体积**:四张合计约 0.63 MB(空态那张的圆点网格被设计展开成了路径),随包进消费方产物。
|
|
13
|
+
* - **id 冲突**:`异常` 与 `错误` 出自同一设计页,16 个 `id` 同名,其中 `linearGradient-8` 在一张里是
|
|
14
|
+
* 角标橙、在另一张里是文本条灰 —— 两张挂进**同一个 document** 时会互相顶掉(其余组合无冲突)。
|
|
15
|
+
* 必须同页共存时,改这里的 `id` 前缀或改名其中一张。
|
|
16
|
+
*
|
|
17
|
+
* ## 谁在用
|
|
18
|
+
*
|
|
19
|
+
* `components/query-state/index.tsx` 直接引本文件的串(空态取「空状态」、错误态取「错误」),塞进
|
|
20
|
+
* `.mh-state-illustration` 壳(`innerHTML`,与 `@manohub/icon` 渲染字形同一套路),壳宽由 `illustrationSize` 定。
|
|
21
|
+
* 成功 / 异常两张暂无内建消费方,要「提交完成」整页那样的图形时按同一路子引即可。
|
|
22
|
+
* 换图 = 重新从设计导出并整体替换本文件,不要在这里改结构、也不要在组件里改细节。
|
|
23
|
+
*/
|
|
24
|
+
/** 空态(设计稿「空状态」):圆点底纹 + 叠加卡片 + 蓝色折角 + 绿色回形针角标 */
|
|
25
|
+
export declare const STATE_ILLUSTRATION_EMPTY_SVG: string;
|
|
26
|
+
/** 成功态(设计稿「已完成插图」):同族卡片 + 绿色对勾角标 */
|
|
27
|
+
export declare const STATE_ILLUSTRATION_SUCCESS_SVG: string;
|
|
28
|
+
/** 异常态(设计稿「异常插图」):同族卡片 + 橙色感叹号角标 */
|
|
29
|
+
export declare const STATE_ILLUSTRATION_WARNING_SVG: string;
|
|
30
|
+
/** 错误态(设计稿「错误」):同族卡片 + 红色叉角标 */
|
|
31
|
+
export declare const STATE_ILLUSTRATION_ERROR_SVG: string;
|