@manohub/ui 1.0.5 → 1.0.8
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 +8 -2
- package/dist/components/badge/index.d.ts +24 -46
- package/dist/components/badge/index.js +7 -11
- package/dist/components/button/index.d.ts +11 -31
- package/dist/components/capsule/index.d.ts +13 -27
- package/dist/components/card/index.d.ts +21 -54
- package/dist/components/checkbox/index.d.ts +1 -9
- package/dist/components/code-block/index.d.ts +35 -62
- package/dist/components/collapse/index.d.ts +2 -0
- package/dist/components/dialog/index.d.ts +6 -15
- package/dist/components/divider/index.d.ts +1 -12
- package/dist/components/drawer/index.d.ts +7 -15
- package/dist/components/filter/index.d.ts +27 -69
- package/dist/components/filter/index.js +3 -8
- package/dist/components/form/index.d.ts +52 -132
- package/dist/components/form/index.js +5 -12
- package/dist/components/input/bordered.d.ts +4 -6
- package/dist/components/input/index.d.ts +47 -66
- package/dist/components/input/index.js +7 -8
- package/dist/components/input/number-input.d.ts +11 -23
- package/dist/components/layout/index.d.ts +21 -28
- package/dist/components/layout/index.js +5 -8
- package/dist/components/list-view/index.d.ts +10 -43
- package/dist/components/loading/index.d.ts +8 -19
- package/dist/components/nav/index.d.ts +14 -35
- package/dist/components/nav/index.js +1 -3
- package/dist/components/notice/index.d.ts +13 -33
- package/dist/components/notice/index.js +3 -5
- package/dist/components/notification/index.d.ts +0 -9
- package/dist/components/page/index.d.ts +8 -43
- package/dist/components/page/split-resize.d.ts +9 -18
- package/dist/components/pagination/index.d.ts +1 -5
- package/dist/components/panel/index.d.ts +27 -62
- package/dist/components/panel/index.js +1 -4
- package/dist/components/part-padding.d.ts +5 -13
- package/dist/components/query-state/index.d.ts +8 -32
- package/dist/components/radio/index.d.ts +2 -3
- package/dist/components/search/index.d.ts +12 -32
- package/dist/components/select/index.d.ts +7 -14
- package/dist/components/select/index.js +3 -3
- package/dist/components/select/select-panel.d.ts +23 -35
- package/dist/components/select/select-panel.js +5 -10
- package/dist/components/select/select-shared.d.ts +18 -44
- package/dist/components/select/select-tree.d.ts +11 -16
- package/dist/components/select/select-trigger.d.ts +6 -16
- package/dist/components/select/select-trigger.js +5 -11
- package/dist/components/skeleton/index.d.ts +1 -5
- package/dist/components/steps/index.d.ts +55 -111
- package/dist/components/steps/index.js +8 -16
- package/dist/components/switch/index.d.ts +17 -33
- package/dist/components/switch/index.js +2 -4
- package/dist/components/tabbar/index.d.ts +1 -6
- package/dist/components/table/index.d.ts +43 -105
- package/dist/components/table/index.js +166 -125
- package/dist/components/tabs/index.d.ts +22 -44
- package/dist/components/text/index.d.ts +10 -21
- package/dist/components/toast/index.d.ts +4 -13
- package/dist/components/tooltip/index.d.ts +1 -12
- package/dist/components/tree/index.d.ts +35 -77
- package/dist/components/tree/index.js +17 -33
- package/dist/components/upload/index.d.ts +1 -4
- package/dist/index.d.ts +3 -3
- package/dist/services/base.d.ts +32 -8
- package/dist/services/dialog.d.ts +10 -22
- package/dist/services/index.d.ts +2 -2
- package/dist/services/loading.d.ts +9 -12
- package/dist/services/loading.js +8 -1
- package/dist/services/toast.d.ts +4 -14
- package/dist/styles/components/button.css +2 -0
- package/dist/styles/components/capsule.css +2 -0
- package/dist/styles/components/checkbox.css +2 -0
- package/dist/styles/components/form.css +23 -28
- package/dist/styles/components/input.css +53 -71
- package/dist/styles/components/notice.css +2 -0
- package/dist/styles/components/page.css +25 -31
- package/dist/styles/components/pagination.css +4 -0
- package/dist/styles/components/radio.css +2 -0
- package/dist/styles/components/search.css +8 -10
- package/dist/styles/components/switch.css +2 -0
- package/dist/styles/components/tabbar.css +2 -0
- package/dist/styles/components/table.css +72 -58
- package/dist/styles/components/table.tokens.css +1 -1
- package/dist/styles/components/upload.css +2 -0
- package/package.json +2 -2
|
@@ -38,45 +38,25 @@ export interface SearchProps {
|
|
|
38
38
|
* | 图标按钮 | `action="icon"` | ❌(让给按钮) | 主色图标按钮 |
|
|
39
39
|
* | 文案按钮 | `searchText="搜索"` | ✅ | 主色文案按钮 |
|
|
40
40
|
*
|
|
41
|
-
* **框内放大镜与图标按钮不会同时出现** ——
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* 缺省形态的提交走**回车**(`Input` 的 `onEnter` 与 `onSearch` 是同一次语义)。
|
|
41
|
+
* **框内放大镜与图标按钮不会同时出现** —— 两者是同一个语义的两种画法,摆在一起就是「一行里两个放大镜,分不
|
|
42
|
+
* 出哪个能点」(0.6.0 的缺陷;0.7.0 起由 `action="icon"` 把「图标按钮」这一档补上,取它时框内自动不再画
|
|
43
|
+
* 装饰)。缺省形态的提交走**回车**(`Input` 的 `onEnter` 与 `onSearch` 是同一次语义)。
|
|
45
44
|
*
|
|
46
45
|
* ## 为什么不是 `Input` 的一个档,而是单独一件
|
|
47
46
|
*
|
|
48
|
-
* 搜索语义有两件 `Input`
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* (清空只改值、不发触发),每处调用都自己写 watch 兜底。
|
|
53
|
-
* 本件把这两条收进一处:`onChange` 管值、`onSearch` / `onClear` 管动作。
|
|
47
|
+
* 搜索语义有两件 `Input` 不该背的事:① **触发是显式的**(回车与点按钮都算一次「搜索」,与「值变了」不是同一
|
|
48
|
+
* 件事)—— 调用方要的是「提交时查一次」而不是「每敲一个字查一次」;② **清空是一个独立事件**(由非空变空时补
|
|
49
|
+
* 发 `onClear`)—— 上游控件长期的坑是「清空只改值、不发触发」,每处调用都自己写 watch 兜底。本件把这两条收
|
|
50
|
+
* 进一处:`onChange` 管值、`onSearch` / `onClear` 管动作。
|
|
54
51
|
*
|
|
55
52
|
* ## 复用而不是重画
|
|
56
53
|
*
|
|
57
|
-
* 输入框那一段**就是本包的 `Input
|
|
58
|
-
*
|
|
59
|
-
*
|
|
54
|
+
* 输入框那一段**就是本包的 `Input`**(框 / 内距 / 清除位 / 聚焦态 / 禁用态 / `aria-invalid` 全部沿用输入框
|
|
55
|
+
* 面),本件只加「一行里怎么摆」与(可选的)搜索按钮 —— 不另写一份输入框几何(两份几何必然在改令牌时漂开)。
|
|
56
|
+
* **受控口径与全库同款**:传 `modelValue` 即受控(`update:modelValue` 与 `onChange` 双走),不传即非受控
|
|
57
|
+
* (由 `defaultValue` 起)。
|
|
60
58
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* 传 `modelValue` 即受控(`update:modelValue` 与 `onChange` 双走),不传即非受控(由 `defaultValue` 起)。
|
|
64
|
-
*
|
|
65
|
-
* @example 最简(框内放大镜 + 回车触发)
|
|
66
|
-
* <Search modelValue={kw} onChange={setKw} onSearch={apply} />
|
|
67
|
-
*
|
|
68
|
-
* @example 带文案的搜索按钮 + 清空动作
|
|
69
|
-
* <Search
|
|
70
|
-
* modelValue={kw}
|
|
71
|
-
* placeholder="搜索技能名称"
|
|
72
|
-
* search-text="搜索"
|
|
73
|
-
* onChange={setKw}
|
|
74
|
-
* onSearch={apply}
|
|
75
|
-
* onClear={() => apply('')}
|
|
76
|
-
* />
|
|
77
|
-
*
|
|
78
|
-
* @example 纯图标按钮(框内不再画装饰放大镜;`searchText` 退化为无障碍名)
|
|
79
|
-
* <Search modelValue={kw} action="icon" search-text="搜索" onChange={setKw} onSearch={apply} />
|
|
59
|
+
* 用法见 `docs/demos/search/`(每个维度一份可运行样例;文档页 `docs/components/search.md`)。
|
|
80
60
|
*/
|
|
81
61
|
export declare const Search: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
82
62
|
modelValue: {
|
|
@@ -37,14 +37,7 @@
|
|
|
37
37
|
* 选中行 = `[data-state='selected']`(组件下发)/ 原生 `input:checked`(静态页零 JS 路径)/ `.is-selected`
|
|
38
38
|
* (规格冻结档),样式层只写一份声明(见 `select-list.tsx`)。
|
|
39
39
|
*
|
|
40
|
-
*
|
|
41
|
-
* <Select options={opts} modelValue={v} placeholder="请选择" onChange={setV} />
|
|
42
|
-
*
|
|
43
|
-
* @example 多选(超出 maxTagCount 收纳成「其他 n 项」)
|
|
44
|
-
* <Select multiple maxTagCount={2} options={opts} modelValue={list} onChange={setList} />
|
|
45
|
-
*
|
|
46
|
-
* @example 分组 + 搜索 + 可创建
|
|
47
|
-
* <Select searchable allowCreate multiple options={grouped} modelValue={list} onChange={setList} />
|
|
40
|
+
* 用法见 `docs/demos/select/`(每个维度一份可运行样例;文档页 `docs/components/select.md`)。
|
|
48
41
|
*/
|
|
49
42
|
import { type PropType, type SlotsType, type VNodeChild } from 'vue';
|
|
50
43
|
import type { ControlSize } from '../control-size';
|
|
@@ -121,9 +114,9 @@ export declare const Select: import("vue").DefineComponent<import("vue").Extract
|
|
|
121
114
|
default: undefined;
|
|
122
115
|
};
|
|
123
116
|
/**
|
|
124
|
-
* 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop
|
|
125
|
-
*
|
|
126
|
-
*
|
|
117
|
+
* 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 完全一致):`true`(缺省)
|
|
118
|
+
* 常有框 / `false` 无框(常态、悬停、聚焦都不显)/ `'focus'` 聚焦(与悬停)才显框 —— 表格单元格里想要
|
|
119
|
+
* 「常态像值、点进去才亮框」就用 `'focus'`。
|
|
127
120
|
*/
|
|
128
121
|
bordered: {
|
|
129
122
|
type: PropType<boolean | "focus">;
|
|
@@ -219,9 +212,9 @@ export declare const Select: import("vue").DefineComponent<import("vue").Extract
|
|
|
219
212
|
default: undefined;
|
|
220
213
|
};
|
|
221
214
|
/**
|
|
222
|
-
* 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop
|
|
223
|
-
*
|
|
224
|
-
*
|
|
215
|
+
* 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 完全一致):`true`(缺省)
|
|
216
|
+
* 常有框 / `false` 无框(常态、悬停、聚焦都不显)/ `'focus'` 聚焦(与悬停)才显框 —— 表格单元格里想要
|
|
217
|
+
* 「常态像值、点进去才亮框」就用 `'focus'`。
|
|
225
218
|
*/
|
|
226
219
|
bordered: {
|
|
227
220
|
type: PropType<boolean | "focus">;
|
|
@@ -75,9 +75,9 @@ const Select = /* @__PURE__ */ defineComponent({
|
|
|
75
75
|
default: void 0
|
|
76
76
|
},
|
|
77
77
|
/**
|
|
78
|
-
* 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop
|
|
79
|
-
*
|
|
80
|
-
*
|
|
78
|
+
* 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 完全一致):`true`(缺省)
|
|
79
|
+
* 常有框 / `false` 无框(常态、悬停、聚焦都不显)/ `'focus'` 聚焦(与悬停)才显框 —— 表格单元格里想要
|
|
80
|
+
* 「常态像值、点进去才亮框」就用 `'focus'`。
|
|
81
81
|
*/
|
|
82
82
|
bordered: {
|
|
83
83
|
type: [Boolean, String],
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SelectPanel —— 选择器族的**面板壳内件**(`Select` 与 `SelectTree` 共用,不对外导出)。
|
|
3
3
|
*
|
|
4
|
-
* 它只拥有四样东西:**原生 popover 元素**(开合 / Esc / 点外部关闭 / 顶层渲染 /
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* 「面板里装什么」不在本件 —— 这正是让列表与树共用同一份面板皮肤的原因。
|
|
4
|
+
* 它只拥有四样东西:**原生 popover 元素**(开合 / Esc / 点外部关闭 / 顶层渲染 / 定位全归浏览器)、**搜索行**、**内容区**
|
|
5
|
+
* (`.mh-select__body`,面板里唯一的滚动容器,也是**两形态共用的一处内容内距** —— 列表的选项与树的树都直接装在它里面,
|
|
6
|
+
* 形态里不再各包一层给内距)与**内容槽**(列表体或树体)。「面板里装什么」不在本件 —— 这正是让列表与树共用同一份面板
|
|
7
|
+
* 皮肤的原因。
|
|
9
8
|
*
|
|
10
|
-
* **限高在面层**:面板根上钉着 `--ui-select-panel-max-height`(`select.css
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* **限高在面层**:面板根上钉着 `--ui-select-panel-max-height`(`select.css`),超出即内容区滚动、搜索行常驻不滚。内容区
|
|
10
|
+
* 这一层因此是**结构性的**(不是可有可无的包裹):少了它,长列表 / 长树会把面板一路撑高(实测 60 条选项 2212px),搜索行
|
|
11
|
+
* 也会跟着滚走。本件只负责把它渲染出来。
|
|
13
12
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* 锚是挂在**表壳**上的 `.mh-popup-anchor`(触发器进壳后隐式锚会缩成壳内控件,故走显式锚档)。
|
|
13
|
+
* 组合类名与定位属性都是**操作层的组合**,不是本件新造的浮层:`class="mh-popup mh-select__panel mh-popup--anchored"`
|
|
14
|
+
* (状态根 + 本族皮肤 + 显式锚档)、`data-side` / `data-align`(`popup.css` 的定位档)、`popover="auto"`(原生轻
|
|
15
|
+
* dismiss)。面板宽度跟触发器走:`.mh-select__panel` 用 `anchor-size(width)` 取锚点宽,锚是挂在**表壳**上的
|
|
16
|
+
* `.mh-popup-anchor`(触发器进壳后隐式锚会缩成壳内控件,故走显式锚档)。
|
|
19
17
|
*
|
|
20
|
-
* `elementRef` 是**由消费方持有的 ref**(不是本件自己的):开面板(触发器
|
|
21
|
-
*
|
|
18
|
+
* `elementRef` 是**由消费方持有的 ref**(不是本件自己的):开面板(触发器 ↑↓)、收起面板(选中后)、以及列表形态按
|
|
19
|
+
* `[data-active]` 取高亮行(滚动入视)都要在父层拿到这个 DOM 元素。
|
|
22
20
|
*/
|
|
23
21
|
import { type PropType, type SlotsType, type VNodeChild } from 'vue';
|
|
24
22
|
import type { ElementRef } from './select-shared';
|
|
@@ -52,22 +50,17 @@ export declare const SelectPanel: import("vue").DefineComponent<import("vue").Ex
|
|
|
52
50
|
default: undefined;
|
|
53
51
|
};
|
|
54
52
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* —— 选项是 `div[role='option']`、不可聚焦,焦点留在触发器上(触发器那条路走
|
|
59
|
-
* `createTriggerKeydown()`,两条路共用同一份高亮模型)。树形态不给:树的行不做键盘导航
|
|
60
|
-
* (与 `Tree` 自身同口径)。
|
|
53
|
+
* 面板上的键盘契约(列表形态给,树形态不给):列表形态接 `↑` / `↓`(平移高亮)与 `Enter`(提交高亮项)。这些事件
|
|
54
|
+
* **来自面板内的搜索行** —— 选项是 `div[role='option']`、不可聚焦,焦点留在触发器上(触发器那条路走
|
|
55
|
+
* `createTriggerKeydown()`,两条路共用同一份高亮模型)。树形态不给(与 `Tree` 自身同口径)。
|
|
61
56
|
*/
|
|
62
57
|
onKeydown: {
|
|
63
58
|
type: PropType<(event: KeyboardEvent) => void>;
|
|
64
59
|
default: undefined;
|
|
65
60
|
};
|
|
66
61
|
/**
|
|
67
|
-
* 面板的原生 `toggle` 事件(开合态变化,含 Esc
|
|
68
|
-
*
|
|
69
|
-
* 声明成本件的 prop 而不是靠 `attrs`:本件的 `attrs` 是关掉的(`inheritAttrs: false`),
|
|
70
|
-
* 且这个事件要落到**面板元素**上(`toggle` 只有它派发)。消费方据此回写「面板开着吗」
|
|
62
|
+
* 面板的原生 `toggle` 事件(开合态变化,含 Esc 与点外部关闭)。声明成 prop 而不是靠 `attrs`:本件的 `attrs` 是关掉的
|
|
63
|
+
* (`inheritAttrs: false`),且这个事件要落到**面板元素**上(只有它派发 `toggle`)。消费方据此回写「面板开着吗」
|
|
71
64
|
* —— 那是 `Enter` 接管的判定依据(见 `Select` 的 `isPanelOpen`)。
|
|
72
65
|
*/
|
|
73
66
|
onToggle: {
|
|
@@ -104,22 +97,17 @@ export declare const SelectPanel: import("vue").DefineComponent<import("vue").Ex
|
|
|
104
97
|
default: undefined;
|
|
105
98
|
};
|
|
106
99
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* —— 选项是 `div[role='option']`、不可聚焦,焦点留在触发器上(触发器那条路走
|
|
111
|
-
* `createTriggerKeydown()`,两条路共用同一份高亮模型)。树形态不给:树的行不做键盘导航
|
|
112
|
-
* (与 `Tree` 自身同口径)。
|
|
100
|
+
* 面板上的键盘契约(列表形态给,树形态不给):列表形态接 `↑` / `↓`(平移高亮)与 `Enter`(提交高亮项)。这些事件
|
|
101
|
+
* **来自面板内的搜索行** —— 选项是 `div[role='option']`、不可聚焦,焦点留在触发器上(触发器那条路走
|
|
102
|
+
* `createTriggerKeydown()`,两条路共用同一份高亮模型)。树形态不给(与 `Tree` 自身同口径)。
|
|
113
103
|
*/
|
|
114
104
|
onKeydown: {
|
|
115
105
|
type: PropType<(event: KeyboardEvent) => void>;
|
|
116
106
|
default: undefined;
|
|
117
107
|
};
|
|
118
108
|
/**
|
|
119
|
-
* 面板的原生 `toggle` 事件(开合态变化,含 Esc
|
|
120
|
-
*
|
|
121
|
-
* 声明成本件的 prop 而不是靠 `attrs`:本件的 `attrs` 是关掉的(`inheritAttrs: false`),
|
|
122
|
-
* 且这个事件要落到**面板元素**上(`toggle` 只有它派发)。消费方据此回写「面板开着吗」
|
|
109
|
+
* 面板的原生 `toggle` 事件(开合态变化,含 Esc 与点外部关闭)。声明成 prop 而不是靠 `attrs`:本件的 `attrs` 是关掉的
|
|
110
|
+
* (`inheritAttrs: false`),且这个事件要落到**面板元素**上(只有它派发 `toggle`)。消费方据此回写「面板开着吗」
|
|
123
111
|
* —— 那是 `Enter` 接管的判定依据(见 `Select` 的 `isPanelOpen`)。
|
|
124
112
|
*/
|
|
125
113
|
onToggle: {
|
|
@@ -32,22 +32,17 @@ const SelectPanel = /* @__PURE__ */ defineComponent({
|
|
|
32
32
|
default: void 0
|
|
33
33
|
},
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* —— 选项是 `div[role='option']`、不可聚焦,焦点留在触发器上(触发器那条路走
|
|
39
|
-
* `createTriggerKeydown()`,两条路共用同一份高亮模型)。树形态不给:树的行不做键盘导航
|
|
40
|
-
* (与 `Tree` 自身同口径)。
|
|
35
|
+
* 面板上的键盘契约(列表形态给,树形态不给):列表形态接 `↑` / `↓`(平移高亮)与 `Enter`(提交高亮项)。这些事件
|
|
36
|
+
* **来自面板内的搜索行** —— 选项是 `div[role='option']`、不可聚焦,焦点留在触发器上(触发器那条路走
|
|
37
|
+
* `createTriggerKeydown()`,两条路共用同一份高亮模型)。树形态不给(与 `Tree` 自身同口径)。
|
|
41
38
|
*/
|
|
42
39
|
onKeydown: {
|
|
43
40
|
type: Function,
|
|
44
41
|
default: void 0
|
|
45
42
|
},
|
|
46
43
|
/**
|
|
47
|
-
* 面板的原生 `toggle` 事件(开合态变化,含 Esc
|
|
48
|
-
*
|
|
49
|
-
* 声明成本件的 prop 而不是靠 `attrs`:本件的 `attrs` 是关掉的(`inheritAttrs: false`),
|
|
50
|
-
* 且这个事件要落到**面板元素**上(`toggle` 只有它派发)。消费方据此回写「面板开着吗」
|
|
44
|
+
* 面板的原生 `toggle` 事件(开合态变化,含 Esc 与点外部关闭)。声明成 prop 而不是靠 `attrs`:本件的 `attrs` 是关掉的
|
|
45
|
+
* (`inheritAttrs: false`),且这个事件要落到**面板元素**上(只有它派发 `toggle`)。消费方据此回写「面板开着吗」
|
|
51
46
|
* —— 那是 `Enter` 接管的判定依据(见 `Select` 的 `isPanelOpen`)。
|
|
52
47
|
*/
|
|
53
48
|
onToggle: {
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 选择器族的**共用原子**(类型、面板 id、popover 开合、触发器键盘契约、键位模型的可激活项摊平)。
|
|
3
3
|
*
|
|
4
|
-
* 这是 `select/`
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* 为什么单独一份而不是各自写一遍:这些都是**跨两件以上**的东西 ——
|
|
9
|
-
* 类型(列表体与树体都要)、面板 id 生成器(两件的面板都得全页唯一)、
|
|
10
|
-
* popover 开合(两件都要收起面板)、触发器键盘契约(两件的触发器是同一个形态)、
|
|
11
|
-
* 可激活项的摊平顺序(`Select` 算下一个高亮位、`SelectList` 算行 id 与高亮态,必须同一份)。
|
|
4
|
+
* 这是 `select/` 目录的**叶子模块**(不 import 同目录任何其它文件),故四件(触发器 / 面板壳 / 列表体 / 树体)可自由
|
|
5
|
+
* 组合而不产生环;内件一律**不对外导出**(`src/index.ts` 只出 `Select` 与 `SelectTree`),故本文件的导出面是「族内
|
|
6
|
+
* 契约」、改它要同时看那四件。单独一份的理由:这些都是**跨两件以上**的东西 —— 类型、面板 id 生成器(两件的面板都得
|
|
7
|
+
* 全页唯一)、popover 开合、触发器键盘契约、可激活项的摊平顺序(两件必须同一份)。
|
|
12
8
|
*/
|
|
13
9
|
import type { Ref } from 'vue';
|
|
14
10
|
/** 选项(平铺项与分组内选项同构) */
|
|
@@ -29,35 +25,23 @@ export type SelectValue = string | number | Array<string | number>;
|
|
|
29
25
|
/** 判别:带 `options` 数组的是分组 */
|
|
30
26
|
export declare const isGroup: (item: SelectItem) => item is SelectOptionGroup;
|
|
31
27
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* 摊平这件事**只在键位模型里**需要(`Select` 算下一个高亮位、`SelectList` 算「这一行是第几格」),
|
|
35
|
-
* 两处都调本函数 ⇒ 顺序只有一个来源,不会各自摊一遍。返回的是**原对象引用**
|
|
36
|
-
* (选项对象来自消费方传入的同一批数据),故列表侧可以直接用 `indexOf` 反查格号。
|
|
28
|
+
* **键盘可激活项**:摊平成一行行(分组只影响渲染、不影响键盘顺序)并跳过禁用项。摊平**只在键位模型里**需要,两处都调
|
|
29
|
+
* 本函数 ⇒ 顺序只有一个来源。返回的是**原对象引用**,故列表侧可直接用 `indexOf` 反查格号。
|
|
37
30
|
*/
|
|
38
31
|
export declare const activatableOptions: (items: SelectItem[]) => SelectOption[];
|
|
39
|
-
/**
|
|
40
|
-
* 可激活格总数。
|
|
41
|
-
*
|
|
42
|
-
* `creatable` 时**末尾多一格**「创建 xxx」行 —— 它也是可激活的一格(回车即创建),
|
|
43
|
-
* 键位模型与 id 生成都按「选项格 + 尾格」这同一条约定走。
|
|
44
|
-
*/
|
|
32
|
+
/** 可激活格总数。`creatable` 时**末尾多一格**「创建 xxx」行 —— 它也是可激活的一格(回车即创建),键位模型与 id 生成都按这条约定走。 */
|
|
45
33
|
export declare const activatableCount: (items: SelectItem[], creatable: boolean) => number;
|
|
46
34
|
/**
|
|
47
|
-
* 选项行 / 「创建」行的元素 id
|
|
48
|
-
*
|
|
49
|
-
* 两处用途:`aria-activedescendant` 指过来(原生 popover 下的虚拟焦点,见 `Select`),
|
|
50
|
-
* 以及消费方与用例的稳定锚点。格号由 `activatableOptions` 的顺序给,与值本身无关
|
|
51
|
-
* (值可能含空格,直接拼进 id 会破坏 `aria-activedescendant` 的引用)。
|
|
35
|
+
* 选项行 / 「创建」行的元素 id:供 `aria-activedescendant` 指过来(原生 popover 下的虚拟焦点),也是消费方与用例的
|
|
36
|
+
* 稳定锚点。格号由 `activatableOptions` 顺序给、与值本身无关(值可能含空格,直接拼进 id 会破坏引用)。
|
|
52
37
|
*/
|
|
53
38
|
export declare const optionDomId: (panelId: string, index: number) => string;
|
|
54
39
|
/** 生成全页唯一的面板 id(随机段与全库其它随机 id 同法) */
|
|
55
40
|
export declare const createSelectPanelId: () => string;
|
|
56
41
|
/**
|
|
57
|
-
* 开 / 收面板 ——
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* 先探存在性再调用:jsdom 至今没实现这套 API,直接 `?.()` 会在测试里抛「不是函数」。
|
|
42
|
+
* 开 / 收面板 —— 调**原生** `showPopover()` / `hidePopover()`,不是自建浮层逻辑(开合、Esc、点外部关闭、顶层渲染全归
|
|
43
|
+
* 浏览器与 `styles/operations/popup.css`)。先探存在性再调用:jsdom 至今没实现这套 API,直接 `?.()` 会在测试里抛
|
|
44
|
+
* 「不是函数」。
|
|
61
45
|
*/
|
|
62
46
|
export declare const showPanel: (element: HTMLElement | null) => void;
|
|
63
47
|
export declare const hidePanel: (element: HTMLElement | null) => void;
|
|
@@ -68,27 +52,17 @@ export interface TriggerKeydownOptions {
|
|
|
68
52
|
disabled: boolean;
|
|
69
53
|
clear: () => void;
|
|
70
54
|
openPanel: () => void;
|
|
71
|
-
/**
|
|
72
|
-
* 面板当前是否开着(**只服务 `Enter` / `Space` 的接管判定**,可选)。
|
|
73
|
-
*
|
|
74
|
-
* 开着才把这两个键从触发器的原生行为(开 / 收面板)里抢过来交给高亮项;
|
|
75
|
-
* 关着时必须原样放过 —— 否则「关掉面板后再按回车」不会重开面板。
|
|
76
|
-
*/
|
|
55
|
+
/** 面板当前是否开着(**只服务 `Enter` / `Space` 的接管判定**):开着才把这两个键从触发器的原生行为里抢过来交给高亮项;关着时必须原样放过,否则「关掉后再按回车」不会重开面板。 */
|
|
77
56
|
isPanelOpen?: () => boolean;
|
|
78
57
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* 与 `aria-activedescendant` 表达(见 `Select`)。入参是**方向**而不是下标:
|
|
83
|
-
* 尚无高亮时落到首项(向下)或末项(向上)。
|
|
84
|
-
* 列表形态给上它;树形态不给 —— 树的行既不可聚焦也不做键盘导航(与 `Tree` 自身同口径)。
|
|
58
|
+
* 面板打开后把**键盘高亮**平移一格(**可选**)。它**不移动焦点**:选项行不是可聚焦元素(`div[role='option']`),高亮
|
|
59
|
+
* 由 `data-active` 与 `aria-activedescendant` 表达。入参是**方向**而非下标(尚无高亮时落到首项 / 末项)。列表形态给上
|
|
60
|
+
* 它,树形态不给 —— 树的行既不可聚焦也不做键盘导航。
|
|
85
61
|
*/
|
|
86
62
|
moveActive?: (direction: 1 | -1) => void;
|
|
87
63
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* 有高亮才返回 `true`(此时键被接管:`preventDefault`,不再切换面板);
|
|
91
|
-
* 没有高亮就返回 `false`,`Enter` / `Space` 回落到按钮的原生切换行为。
|
|
64
|
+
* 提交当前高亮项(**可选**),返回**是否真的提交了**:有高亮才 `true`(键被接管:`preventDefault`,不再切换面板);
|
|
65
|
+
* 没有高亮返回 `false`,`Enter` / `Space` 回落到按钮的原生切换行为。
|
|
92
66
|
*/
|
|
93
67
|
commitActive?: () => boolean;
|
|
94
68
|
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SelectTree —— **树选择**(`Select` 的树形态,与它平级导出:`import { SelectTree } from '@manohub/ui'`)。
|
|
3
3
|
*
|
|
4
|
-
* 它与 `Select` 共用**同一批内件**:触发器(像输入框 / 清除位 / 箭头 /
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* 它与 `Select` 共用**同一批内件**:触发器(像输入框 / 清除位 / 箭头 / 键盘开面板)、面板壳(皮肤 / 定位档 /
|
|
5
|
+
* 显式锚 / 搜索行)、共用原子(面板 id / popover 开合 / 键盘契约)—— 故「面板长相与开合行为」只有一份规格;
|
|
6
|
+
* 本件独有的只有**树体那一层**:
|
|
7
7
|
*
|
|
8
|
-
* 1.
|
|
9
|
-
*
|
|
10
|
-
* 2.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 3.
|
|
14
|
-
*
|
|
15
|
-
* 把树**直接**装进内容区,不再自持一层只给内距的包裹(限高与内距都不由形态自持)。
|
|
8
|
+
* 1. **仅叶子可选**:点叶子行即选中并收起面板;点父节点行只切换展开(父节点是「分组」而不是「选项」,选中它
|
|
9
|
+
* 语义上是空的 —— `Tree` 自身不做这个判断,故在此兜住)。
|
|
10
|
+
* 2. **本地过滤树**:搜索行在场时按关键词过滤,命中节点的**祖先链保留**、父节点自身命中则**整支保留**,并强制
|
|
11
|
+
* 全展到命中层(算法与切分都是纯函数,见 `select-tree-filter.ts`);命中文本按面层的 `.mh-select__hit`
|
|
12
|
+
* 高亮(靠 `Tree` 的 `renderLabel` 钩子落进标签槽)。
|
|
13
|
+
* 3. **面板内限高滚动**:限高归面板(`--ui-select-panel-max-height`),溢出与内容内距都由面板内容区
|
|
14
|
+
* (`.mh-select__body`)承担 —— 两形态共用同一份,故本件把树**直接**装进内容区,不自持一层只给内距的包裹。
|
|
16
15
|
*
|
|
17
16
|
* ## 与 `Select` 的三处有意差异(都是「树不是列表」决定的)
|
|
18
17
|
*
|
|
@@ -22,11 +21,7 @@
|
|
|
22
21
|
* | 面板内 ↑↓ 行导航 | 有(高亮位由 `data-active` 表达,焦点留在触发器上) | **无**(树的行不做键盘导航,与 `Tree` 自身同口径) |
|
|
23
22
|
* | 空 / 加载态 | 列表体的内建行 | 面板内同样出一行文字(**不复用**整件三态容器:下拉里出空态插画太重) |
|
|
24
23
|
*
|
|
25
|
-
*
|
|
26
|
-
* <SelectTree nodes={tree} rowKey="id" modelValue={v} onChange={setV} placeholder="请选择业务域" />
|
|
27
|
-
*
|
|
28
|
-
* @example 搜索 + 默认全展开
|
|
29
|
-
* <SelectTree nodes={tree} rowKey="id" labelKey="name" searchable defaultExpandAll onChange={setV} />
|
|
24
|
+
* 用法见 `docs/demos/select/`(每个维度一份可运行样例;文档页 `docs/components/select.md`)。
|
|
30
25
|
*/
|
|
31
26
|
import { type PropType, type SlotsType, type VNodeChild } from 'vue';
|
|
32
27
|
import type { ControlSize } from '../control-size';
|
|
@@ -21,10 +21,7 @@ export declare const SelectTrigger: import("vue").DefineComponent<import("vue").
|
|
|
21
21
|
type: BooleanConstructor;
|
|
22
22
|
default: boolean;
|
|
23
23
|
};
|
|
24
|
-
/**
|
|
25
|
-
* 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):
|
|
26
|
-
* `true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。
|
|
27
|
-
*/
|
|
24
|
+
/** 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):`true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。 */
|
|
28
25
|
bordered: {
|
|
29
26
|
type: PropType<boolean | "focus">;
|
|
30
27
|
default: boolean;
|
|
@@ -54,10 +51,8 @@ export declare const SelectTrigger: import("vue").DefineComponent<import("vue").
|
|
|
54
51
|
default: undefined;
|
|
55
52
|
};
|
|
56
53
|
/**
|
|
57
|
-
* 键盘高亮行的 id(`aria-activedescendant
|
|
58
|
-
*
|
|
59
|
-
* 选项是 `div[role='option']`、不可聚焦,焦点留在本按钮上 ⇒ 高亮项要靠这个属性告诉读屏。
|
|
60
|
-
* 树形态不给(树的行不做键盘导航,见 `SelectTree`)。
|
|
54
|
+
* 键盘高亮行的 id(`aria-activedescendant`,**列表形态专用**):选项是 `div[role='option']`、不可聚焦,焦点留在
|
|
55
|
+
* 本按钮上 ⇒ 高亮项要靠这个属性告诉读屏。树形态不给(树的行不做键盘导航,见 `SelectTree`)。
|
|
61
56
|
*/
|
|
62
57
|
activeDescendant: {
|
|
63
58
|
type: StringConstructor;
|
|
@@ -98,10 +93,7 @@ export declare const SelectTrigger: import("vue").DefineComponent<import("vue").
|
|
|
98
93
|
type: BooleanConstructor;
|
|
99
94
|
default: boolean;
|
|
100
95
|
};
|
|
101
|
-
/**
|
|
102
|
-
* 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):
|
|
103
|
-
* `true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。
|
|
104
|
-
*/
|
|
96
|
+
/** 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):`true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。 */
|
|
105
97
|
bordered: {
|
|
106
98
|
type: PropType<boolean | "focus">;
|
|
107
99
|
default: boolean;
|
|
@@ -131,10 +123,8 @@ export declare const SelectTrigger: import("vue").DefineComponent<import("vue").
|
|
|
131
123
|
default: undefined;
|
|
132
124
|
};
|
|
133
125
|
/**
|
|
134
|
-
* 键盘高亮行的 id(`aria-activedescendant
|
|
135
|
-
*
|
|
136
|
-
* 选项是 `div[role='option']`、不可聚焦,焦点留在本按钮上 ⇒ 高亮项要靠这个属性告诉读屏。
|
|
137
|
-
* 树形态不给(树的行不做键盘导航,见 `SelectTree`)。
|
|
126
|
+
* 键盘高亮行的 id(`aria-activedescendant`,**列表形态专用**):选项是 `div[role='option']`、不可聚焦,焦点留在
|
|
127
|
+
* 本按钮上 ⇒ 高亮项要靠这个属性告诉读屏。树形态不给(树的行不做键盘导航,见 `SelectTree`)。
|
|
138
128
|
*/
|
|
139
129
|
activeDescendant: {
|
|
140
130
|
type: StringConstructor;
|
|
@@ -24,10 +24,7 @@ const SelectTrigger = /* @__PURE__ */ defineComponent({
|
|
|
24
24
|
type: Boolean,
|
|
25
25
|
default: false
|
|
26
26
|
},
|
|
27
|
-
/**
|
|
28
|
-
* 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):
|
|
29
|
-
* `true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。
|
|
30
|
-
*/
|
|
27
|
+
/** 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):`true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。 */
|
|
31
28
|
bordered: {
|
|
32
29
|
type: [Boolean, String],
|
|
33
30
|
default: true
|
|
@@ -57,10 +54,8 @@ const SelectTrigger = /* @__PURE__ */ defineComponent({
|
|
|
57
54
|
default: void 0
|
|
58
55
|
},
|
|
59
56
|
/**
|
|
60
|
-
* 键盘高亮行的 id(`aria-activedescendant
|
|
61
|
-
*
|
|
62
|
-
* 选项是 `div[role='option']`、不可聚焦,焦点留在本按钮上 ⇒ 高亮项要靠这个属性告诉读屏。
|
|
63
|
-
* 树形态不给(树的行不做键盘导航,见 `SelectTree`)。
|
|
57
|
+
* 键盘高亮行的 id(`aria-activedescendant`,**列表形态专用**):选项是 `div[role='option']`、不可聚焦,焦点留在
|
|
58
|
+
* 本按钮上 ⇒ 高亮项要靠这个属性告诉读屏。树形态不给(树的行不做键盘导航,见 `SelectTree`)。
|
|
64
59
|
*/
|
|
65
60
|
activeDescendant: {
|
|
66
61
|
type: String,
|
|
@@ -98,9 +93,8 @@ const SelectTrigger = /* @__PURE__ */ defineComponent({
|
|
|
98
93
|
"controlAttrs": {
|
|
99
94
|
popovertarget: props.panelId,
|
|
100
95
|
"aria-haspopup": "listbox",
|
|
101
|
-
/* 开合态由原生 popover 与 popup.css
|
|
102
|
-
|
|
103
|
-
⚠️ 这与 `aria-activedescendant`(下面那条)**都是焦点留在触发器上的必然结果**:
|
|
96
|
+
/* 开合态由原生 popover 与 popup.css 的箭头转向承担,本件不维护第二份;恒定 'false' 是既有口径(输入面的触发器
|
|
97
|
+
形态不跟踪 popover 的开关状态)。⚠️ 这与 `aria-activedescendant` **都是焦点留在触发器上的必然结果**:
|
|
104
98
|
真的做完整要连 `aria-expanded` 一起跟踪开合态,那是另一次改动(见 select.md 的注意事项)。 */
|
|
105
99
|
"aria-expanded": "false",
|
|
106
100
|
/* 高亮行引用(列表形态给、树形态不给):值 `undefined` 时 Vue 会整个摘掉这个属性 */
|
|
@@ -20,11 +20,7 @@ export interface SkeletonProps {
|
|
|
20
20
|
* `@keyframes mh-skeleton-shimmer`),`QueryState` 的加载态复用它 —— 别处不要再写一份
|
|
21
21
|
* (两处各写一份必然漂,同一屏会出现两种呼吸节奏)。
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
* <Skeleton :rows="5" />
|
|
25
|
-
*
|
|
26
|
-
* @example 卡片体占位
|
|
27
|
-
* <Skeleton block height={120} />
|
|
23
|
+
* 用法见 `docs/demos/skeleton/`(每个维度一份可运行样例;文档页 `docs/components/skeleton.md`)。
|
|
28
24
|
*/
|
|
29
25
|
export declare const Skeleton: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
30
26
|
rows: {
|