@manohub/ui 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +141 -0
  2. package/dist/components/avatar/index.d.ts +283 -0
  3. package/dist/components/avatar/index.js +167 -0
  4. package/dist/components/badge/index.d.ts +132 -0
  5. package/dist/components/badge/index.js +99 -0
  6. package/dist/components/button/index.d.ts +578 -0
  7. package/dist/components/button/index.js +191 -0
  8. package/dist/components/capsule/index.d.ts +161 -0
  9. package/dist/components/capsule/index.js +101 -0
  10. package/dist/components/card/index.d.ts +456 -0
  11. package/dist/components/card/index.js +231 -0
  12. package/dist/components/checkbox/index.d.ts +331 -0
  13. package/dist/components/checkbox/index.js +165 -0
  14. package/dist/components/code/index.d.ts +134 -0
  15. package/dist/components/code/index.js +117 -0
  16. package/dist/components/code-editor/index.d.ts +163 -0
  17. package/dist/components/code-editor/index.js +98 -0
  18. package/dist/components/collapse/index.d.ts +125 -0
  19. package/dist/components/collapse/index.js +95 -0
  20. package/dist/components/control-size.d.ts +8 -0
  21. package/dist/components/dialog/index.d.ts +224 -0
  22. package/dist/components/dialog/index.js +194 -0
  23. package/dist/components/divider/index.d.ts +64 -0
  24. package/dist/components/divider/index.js +62 -0
  25. package/dist/components/drawer/index.d.ts +226 -0
  26. package/dist/components/drawer/index.js +190 -0
  27. package/dist/components/filter/index.d.ts +391 -0
  28. package/dist/components/filter/index.js +203 -0
  29. package/dist/components/form/index.d.ts +704 -0
  30. package/dist/components/form/index.js +329 -0
  31. package/dist/components/input/index.d.ts +980 -0
  32. package/dist/components/input/index.js +334 -0
  33. package/dist/components/layout/index.d.ts +162 -0
  34. package/dist/components/layout/index.js +100 -0
  35. package/dist/components/list-view/index.d.ts +563 -0
  36. package/dist/components/list-view/index.js +221 -0
  37. package/dist/components/loading/index.d.ts +77 -0
  38. package/dist/components/loading/index.js +40 -0
  39. package/dist/components/nav/index.d.ts +293 -0
  40. package/dist/components/nav/index.js +164 -0
  41. package/dist/components/notice/index.d.ts +137 -0
  42. package/dist/components/notice/index.js +101 -0
  43. package/dist/components/notification/index.d.ts +118 -0
  44. package/dist/components/notification/index.js +99 -0
  45. package/dist/components/page/index.d.ts +276 -0
  46. package/dist/components/page/index.js +351 -0
  47. package/dist/components/page/split-resize.d.ts +42 -0
  48. package/dist/components/page/split-resize.js +36 -0
  49. package/dist/components/pagination/index.d.ts +171 -0
  50. package/dist/components/pagination/index.js +226 -0
  51. package/dist/components/panel/index.d.ts +401 -0
  52. package/dist/components/panel/index.js +193 -0
  53. package/dist/components/part-padding.d.ts +27 -0
  54. package/dist/components/part-padding.js +23 -0
  55. package/dist/components/query-state/index.d.ts +207 -0
  56. package/dist/components/query-state/index.js +181 -0
  57. package/dist/components/radio/index.d.ts +473 -0
  58. package/dist/components/radio/index.js +250 -0
  59. package/dist/components/search/index.d.ts +167 -0
  60. package/dist/components/search/index.js +105 -0
  61. package/dist/components/select/index.d.ts +252 -0
  62. package/dist/components/select/index.js +281 -0
  63. package/dist/components/skeleton/index.d.ts +88 -0
  64. package/dist/components/skeleton/index.js +56 -0
  65. package/dist/components/steps/index.d.ts +199 -0
  66. package/dist/components/steps/index.js +117 -0
  67. package/dist/components/switch/index.d.ts +150 -0
  68. package/dist/components/switch/index.js +103 -0
  69. package/dist/components/table/index.d.ts +351 -0
  70. package/dist/components/table/index.js +286 -0
  71. package/dist/components/tabs/index.d.ts +179 -0
  72. package/dist/components/tabs/index.js +153 -0
  73. package/dist/components/tabset/index.d.ts +105 -0
  74. package/dist/components/tabset/index.js +68 -0
  75. package/dist/components/tag/index.d.ts +203 -0
  76. package/dist/components/tag/index.js +144 -0
  77. package/dist/components/toast/index.d.ts +271 -0
  78. package/dist/components/toast/index.js +116 -0
  79. package/dist/components/tooltip/index.d.ts +126 -0
  80. package/dist/components/tooltip/index.js +97 -0
  81. package/dist/components/tree/index.d.ts +317 -0
  82. package/dist/components/tree/index.js +251 -0
  83. package/dist/components/upload/index.d.ts +384 -0
  84. package/dist/components/upload/index.js +172 -0
  85. package/dist/index.d.ts +63 -0
  86. package/dist/index.js +102 -0
  87. package/dist/services/base.d.ts +21 -0
  88. package/dist/services/base.js +42 -0
  89. package/dist/services/dialog.d.ts +41 -0
  90. package/dist/services/dialog.js +83 -0
  91. package/dist/services/index.d.ts +12 -0
  92. package/dist/services/loading.d.ts +21 -0
  93. package/dist/services/loading.js +41 -0
  94. package/dist/services/toast.d.ts +40 -0
  95. package/dist/services/toast.js +74 -0
  96. package/dist/styles/components/avatar.css +128 -0
  97. package/dist/styles/components/avatar.tokens.css +24 -0
  98. package/dist/styles/components/badge.css +237 -0
  99. package/dist/styles/components/button.css +454 -0
  100. package/dist/styles/components/button.tokens.css +56 -0
  101. package/dist/styles/components/capsule.css +120 -0
  102. package/dist/styles/components/capsule.tokens.css +27 -0
  103. package/dist/styles/components/card.css +192 -0
  104. package/dist/styles/components/checkbox.css +145 -0
  105. package/dist/styles/components/checkbox.tokens.css +26 -0
  106. package/dist/styles/components/code-editor.css +91 -0
  107. package/dist/styles/components/code-editor.tokens.css +24 -0
  108. package/dist/styles/components/code.css +153 -0
  109. package/dist/styles/components/code.tokens.css +29 -0
  110. package/dist/styles/components/collapse.css +62 -0
  111. package/dist/styles/components/collapse.tokens.css +20 -0
  112. package/dist/styles/components/dialog.css +106 -0
  113. package/dist/styles/components/dialog.tokens.css +24 -0
  114. package/dist/styles/components/divider.css +71 -0
  115. package/dist/styles/components/divider.tokens.css +21 -0
  116. package/dist/styles/components/drawer.css +143 -0
  117. package/dist/styles/components/drawer.tokens.css +22 -0
  118. package/dist/styles/components/filter.css +41 -0
  119. package/dist/styles/components/filter.tokens.css +14 -0
  120. package/dist/styles/components/form.css +220 -0
  121. package/dist/styles/components/form.tokens.css +15 -0
  122. package/dist/styles/components/input.css +445 -0
  123. package/dist/styles/components/input.tokens.css +41 -0
  124. package/dist/styles/components/layout.css +198 -0
  125. package/dist/styles/components/list-view.css +244 -0
  126. package/dist/styles/components/loading.css +76 -0
  127. package/dist/styles/components/loading.tokens.css +23 -0
  128. package/dist/styles/components/nav.css +48 -0
  129. package/dist/styles/components/notice.css +153 -0
  130. package/dist/styles/components/notice.tokens.css +17 -0
  131. package/dist/styles/components/notification.css +159 -0
  132. package/dist/styles/components/notification.tokens.css +37 -0
  133. package/dist/styles/components/page.css +473 -0
  134. package/dist/styles/components/pagination.css +297 -0
  135. package/dist/styles/components/pagination.tokens.css +32 -0
  136. package/dist/styles/components/panel.css +77 -0
  137. package/dist/styles/components/query-state.css +88 -0
  138. package/dist/styles/components/radio.css +271 -0
  139. package/dist/styles/components/radio.tokens.css +26 -0
  140. package/dist/styles/components/search.css +30 -0
  141. package/dist/styles/components/select.css +242 -0
  142. package/dist/styles/components/select.tokens.css +33 -0
  143. package/dist/styles/components/skeleton.css +60 -0
  144. package/dist/styles/components/skeleton.tokens.css +27 -0
  145. package/dist/styles/components/steps.css +157 -0
  146. package/dist/styles/components/steps.tokens.css +42 -0
  147. package/dist/styles/components/switch.css +165 -0
  148. package/dist/styles/components/switch.tokens.css +26 -0
  149. package/dist/styles/components/table.css +439 -0
  150. package/dist/styles/components/table.tokens.css +41 -0
  151. package/dist/styles/components/tabs.css +234 -0
  152. package/dist/styles/components/tabs.tokens.css +30 -0
  153. package/dist/styles/components/tag.css +200 -0
  154. package/dist/styles/components/tag.tokens.css +30 -0
  155. package/dist/styles/components/toast.css +150 -0
  156. package/dist/styles/components/toast.tokens.css +26 -0
  157. package/dist/styles/components/tooltip.css +89 -0
  158. package/dist/styles/components/tooltip.tokens.css +25 -0
  159. package/dist/styles/components/tree.css +139 -0
  160. package/dist/styles/components/tree.tokens.css +20 -0
  161. package/dist/styles/components/upload.css +150 -0
  162. package/dist/styles/components/upload.tokens.css +27 -0
  163. package/dist/styles/index.css +149 -0
  164. package/dist/styles/operations/collapse.css +84 -0
  165. package/dist/styles/operations/popup.css +189 -0
  166. package/dist/styles/operations/tabset.css +57 -0
  167. package/dist/utils/state-illustration.d.ts +31 -0
  168. package/dist/utils/state-illustration.js +156 -0
  169. package/package.json +62 -0
@@ -0,0 +1,221 @@
1
+ import { defineComponent, createVNode, h } from "vue";
2
+ import { Card } from "../card/index.js";
3
+ import { QueryState } from "../query-state/index.js";
4
+ const ListViewCardItem = /* @__PURE__ */ defineComponent({
5
+ name: "ListViewCardItem",
6
+ inheritAttrs: false,
7
+ props: {
8
+ icon: {
9
+ type: [String, Function, Object],
10
+ default: void 0
11
+ },
12
+ title: {
13
+ type: String,
14
+ required: true
15
+ },
16
+ subtitle: {
17
+ type: String,
18
+ default: void 0
19
+ },
20
+ description: {
21
+ type: String,
22
+ default: void 0
23
+ },
24
+ tags: {
25
+ type: Array,
26
+ default: void 0
27
+ },
28
+ status: {
29
+ type: Object,
30
+ default: void 0
31
+ },
32
+ /** 尾部左侧自定义内容(如状态徽标);与 `footer` 插槽等价 */
33
+ footer: {
34
+ type: [Function, Object, Array, String],
35
+ default: void 0
36
+ },
37
+ /** 尾部右侧统计(如下载量);渲染在操作位之前 */
38
+ extra: {
39
+ type: [Function, Object, Array, String],
40
+ default: void 0
41
+ },
42
+ /** 操作位:**默认隐藏、卡片悬浮(或卡内获得焦点)时显形**;点击不冒泡到整卡 */
43
+ actions: {
44
+ type: [Function, Object, Array, String],
45
+ default: void 0
46
+ },
47
+ onClick: {
48
+ type: Function,
49
+ default: void 0
50
+ }
51
+ },
52
+ slots: Object,
53
+ setup(props, {
54
+ slots
55
+ }) {
56
+ const renderSlotValue = (slotFn, propValue) => {
57
+ if (slotFn) return slotFn();
58
+ if (typeof propValue === "function") return propValue();
59
+ return propValue;
60
+ };
61
+ const renderIcon = () => {
62
+ if (props.icon === void 0 || props.icon === null) return null;
63
+ if (typeof props.icon === "function") return props.icon();
64
+ return createVNode("img", {
65
+ "class": "mh-list-view__card-icon-img",
66
+ "src": String(props.icon),
67
+ "alt": ""
68
+ }, null);
69
+ };
70
+ return () => {
71
+ const footer = renderSlotValue(slots.footer, props.footer);
72
+ const extra = renderSlotValue(slots.extra, props.extra);
73
+ const actions = renderSlotValue(slots.actions, props.actions);
74
+ const tags = props.tags ?? [];
75
+ const hasFoot = !!footer || !!extra || !!actions || tags.length > 0;
76
+ const head = createVNode("div", {
77
+ "class": "mh-list-view__card-head"
78
+ }, [props.icon ? createVNode("span", {
79
+ "class": "mh-list-view__card-icon"
80
+ }, [renderIcon()]) : null, createVNode("span", {
81
+ "class": "mh-list-view__card-title-block"
82
+ }, [createVNode("span", {
83
+ "class": "mh-list-view__card-title"
84
+ }, [props.title]), props.subtitle ? createVNode("span", {
85
+ "class": "mh-list-view__card-subtitle"
86
+ }, [props.subtitle]) : null]), props.status ? createVNode("span", {
87
+ "class": ["mh-list-view__card-status", `mh-list-view__card-status--${props.status.tone ?? "primary"}`].join(" ")
88
+ }, [props.status.dot ? createVNode("span", {
89
+ "class": "mh-list-view__card-status-dot"
90
+ }, null) : null, props.status.label]) : null]);
91
+ const description = props.description ? createVNode("div", {
92
+ "class": "mh-list-view__card-desc"
93
+ }, [props.description]) : null;
94
+ const foot = hasFoot ? createVNode("div", {
95
+ "class": "mh-list-view__card-foot"
96
+ }, [createVNode("span", {
97
+ "class": "mh-list-view__card-foot-main"
98
+ }, [footer, tags.length > 0 ? createVNode("span", {
99
+ "class": "mh-list-view__card-tags"
100
+ }, [tags.map((tag) => createVNode("span", {
101
+ "class": "mh-list-view__card-tag",
102
+ "key": tag
103
+ }, [tag]))]) : null]), createVNode("span", {
104
+ "class": "mh-list-view__card-foot-side"
105
+ }, [extra ? createVNode("span", {
106
+ "class": "mh-list-view__card-extra"
107
+ }, [extra]) : null, actions ? createVNode("span", {
108
+ "class": "mh-list-view__card-actions",
109
+ "onClick": (event) => event.stopPropagation()
110
+ }, [actions]) : null])]) : null;
111
+ return h(Card, {
112
+ interactive: true,
113
+ class: "mh-list-view__card",
114
+ onClick: props.onClick
115
+ }, {
116
+ default: () => [head, description, foot].filter(Boolean)
117
+ });
118
+ };
119
+ }
120
+ });
121
+ const ListViewRoot = /* @__PURE__ */ defineComponent({
122
+ name: "ListView",
123
+ inheritAttrs: false,
124
+ props: {
125
+ minItemWidth: {
126
+ type: Number,
127
+ default: void 0
128
+ },
129
+ /** 固定列数(>0 时不再按容器宽度自适应;窄屏要锁死列数时用) */
130
+ columns: {
131
+ type: Number,
132
+ default: 0
133
+ },
134
+ loading: {
135
+ type: Boolean,
136
+ default: false
137
+ },
138
+ error: {
139
+ type: [String, Boolean, Object, Number, Array],
140
+ default: void 0
141
+ },
142
+ empty: {
143
+ type: [Boolean, String],
144
+ default: false
145
+ },
146
+ emptyDescription: {
147
+ type: String,
148
+ default: void 0
149
+ },
150
+ emptyActionText: {
151
+ type: String,
152
+ default: void 0
153
+ },
154
+ onEmptyAction: {
155
+ type: Function,
156
+ default: void 0
157
+ },
158
+ errorTitle: {
159
+ type: String,
160
+ default: void 0
161
+ },
162
+ errorDescription: {
163
+ type: String,
164
+ default: void 0
165
+ },
166
+ errorActionText: {
167
+ type: String,
168
+ default: void 0
169
+ },
170
+ onErrorAction: {
171
+ type: Function,
172
+ default: void 0
173
+ },
174
+ skeletonCount: {
175
+ type: Number,
176
+ default: 8
177
+ }
178
+ },
179
+ slots: Object,
180
+ setup(props, {
181
+ slots,
182
+ attrs
183
+ }) {
184
+ return () => {
185
+ if (props.error || props.empty) {
186
+ return createVNode(QueryState, {
187
+ "error": props.error,
188
+ "errorTitle": props.errorTitle,
189
+ "errorDescription": props.errorDescription ?? (typeof props.error === "string" ? props.error : void 0),
190
+ "errorActionText": props.errorActionText,
191
+ "onErrorAction": props.onErrorAction,
192
+ "empty": props.empty,
193
+ "emptyDescription": props.emptyDescription,
194
+ "emptyActionText": props.emptyActionText,
195
+ "onEmptyAction": props.onEmptyAction
196
+ }, null);
197
+ }
198
+ const style = [attrs.style, props.minItemWidth === void 0 ? void 0 : {
199
+ "--mh-list-view-min": `${props.minItemWidth}px`
200
+ }, props.columns > 0 ? {
201
+ "--mh-list-view-columns": String(props.columns)
202
+ } : void 0];
203
+ return createVNode("div", {
204
+ "class": ["mh-list-view", props.columns > 0 ? "mh-list-view--fixed" : "", attrs.class].filter(Boolean).join(" "),
205
+ "style": style
206
+ }, [props.loading ? Array.from({
207
+ length: props.skeletonCount
208
+ }).map((_, index) => createVNode("div", {
209
+ "class": "mh-list-view__skeleton",
210
+ "key": index
211
+ }, null)) : slots.default?.()]);
212
+ };
213
+ }
214
+ });
215
+ const ListView = Object.assign(ListViewRoot, {
216
+ CardItem: ListViewCardItem
217
+ });
218
+ export {
219
+ ListView,
220
+ ListViewCardItem
221
+ };
@@ -0,0 +1,77 @@
1
+ import { type PropType, type SlotsType, type VNodeChild } from 'vue';
2
+ import type { ControlSize } from '../control-size';
3
+ /** 覆盖档:`area` = 铺满最近定位祖先(区域级);`screen` = 铺满视口(全屏)。不传即行内居中 */
4
+ export type LoadingOverlay = 'area' | 'screen';
5
+ export interface LoadingProps {
6
+ /** 文案(缺省只有转圈;复杂内容走默认插槽) */
7
+ text?: string;
8
+ /** 尺寸档(转圈直径按全局图标档派生) */
9
+ size?: ControlSize;
10
+ /** 覆盖档;不传即行内居中(与文字并排的小转圈) */
11
+ overlay?: LoadingOverlay;
12
+ }
13
+ /**
14
+ * 加载态(转圈 + 可选文案;三种形态)。
15
+ *
16
+ * ## 三态与三个不同的东西
17
+ *
18
+ * | 形态 | 用什么 | 为什么不是本件 |
19
+ * | --- | --- | --- |
20
+ * | 区域/页面的加载中 | `QueryState` 的 `loading` | 那件带骨架屏与三态切换,是「容器」 |
21
+ * | 内容占位 | `Skeleton` | 骨架屏表达「这里将出现什么」,不是「正在忙」 |
22
+ * | **正在忙、请等待** | 本件 | 遮罩 + 转圈,**拦住交互**才是它的职责 |
23
+ *
24
+ * ## 覆盖档必须由消费方给出定位上下文
25
+ *
26
+ * `overlay="area"` 走 `position: absolute`:它铺的是**最近的定位祖先**,所以宿主元素要有
27
+ * `position: relative`(`Panel.Body` / `Card.Body` 这类件自带)。宿主没有定位上下文时它会跑到
28
+ * 更外层去 —— 这是 CSS 的规则,不是本件的缺陷;界面上看不出错位但覆盖范围不对时,先查这一条。
29
+ *
30
+ * `overlay="screen"` 走 `position: fixed`:铺整个视口,层级压在 `Toast` 堆叠(1080)之上、
31
+ * 模态层(原生 `<dialog>` 的 top layer)之下。
32
+ *
33
+ * 转圈走 `@manohub/icon` 的 `loading` 字形 + CSS 旋转(**不手绘 SVG**);尺寸按全局图标档
34
+ * `--ui-font-icon` 用 `calc()` 派生,换主题时与其它图标一起缩放。
35
+ *
36
+ * @example 行内:小转圈 + 文案
37
+ * <Loading text="加载中" />
38
+ *
39
+ * @example 区域遮罩(宿主需自带 position: relative)
40
+ * <Panel.Body><Loading overlay="area" text="保存中" /></Panel.Body>
41
+ *
42
+ * @example 全屏遮罩
43
+ * <Loading overlay="screen" text="正在导入,请勿关闭页面" />
44
+ */
45
+ export declare const Loading: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
46
+ text: {
47
+ type: StringConstructor;
48
+ default: undefined;
49
+ };
50
+ size: {
51
+ type: PropType<ControlSize>;
52
+ default: string;
53
+ };
54
+ overlay: {
55
+ type: PropType<LoadingOverlay>;
56
+ default: undefined;
57
+ };
58
+ }>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
59
+ text: {
60
+ type: StringConstructor;
61
+ default: undefined;
62
+ };
63
+ size: {
64
+ type: PropType<ControlSize>;
65
+ default: string;
66
+ };
67
+ overlay: {
68
+ type: PropType<LoadingOverlay>;
69
+ default: undefined;
70
+ };
71
+ }>> & Readonly<{}>, {
72
+ overlay: LoadingOverlay;
73
+ text: string;
74
+ size: ControlSize;
75
+ }, SlotsType<{
76
+ default?: () => VNodeChild;
77
+ }>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,40 @@
1
+ import { defineComponent, createVNode } from "vue";
2
+ import { Icon } from "@manohub/icon";
3
+ const Loading = /* @__PURE__ */ defineComponent({
4
+ name: "Loading",
5
+ inheritAttrs: false,
6
+ props: {
7
+ text: {
8
+ type: String,
9
+ default: void 0
10
+ },
11
+ size: {
12
+ type: String,
13
+ default: "md"
14
+ },
15
+ overlay: {
16
+ type: String,
17
+ default: void 0
18
+ }
19
+ },
20
+ slots: Object,
21
+ setup(props, {
22
+ slots,
23
+ attrs
24
+ }) {
25
+ return () => createVNode("div", {
26
+ "class": ["mh-loading", props.size === "md" ? "" : `mh-loading--${props.size}`, props.overlay ? `mh-loading--${props.overlay}` : "", attrs.class].filter(Boolean).join(" "),
27
+ "style": attrs.style,
28
+ "role": "status",
29
+ "aria-live": "polite"
30
+ }, [createVNode(Icon, {
31
+ "name": "loading",
32
+ "class": "mh-loading__spinner"
33
+ }, null), props.text || slots.default ? createVNode("span", {
34
+ "class": "mh-loading__text"
35
+ }, [slots.default ? slots.default() : props.text]) : null]);
36
+ }
37
+ });
38
+ export {
39
+ Loading
40
+ };
@@ -0,0 +1,293 @@
1
+ import { type PropType } from 'vue';
2
+ import { type TreeNode } from '../tree';
3
+ /** 导航形态:`tree` 层级导航(可展开)/ `list` 扁平导航 */
4
+ export type NavVariant = 'tree' | 'list';
5
+ /**
6
+ * 侧栏导航(单列、固定宽、内滚):**`tree` / `list` 两态,行渲染完全复用 `Tree`**。
7
+ *
8
+ * ## 为什么不是 `Tree` 的一个 prop
9
+ *
10
+ * `Tree` 是**展示件**(层级数据怎么显示);导航是另一种语义:选中驱动右侧内容、单列固定宽、
11
+ * 外壳自己滚动。两者对**行**的几何要求完全一致,所以本件不重写行渲染 —— 数据、展开态、选中态、
12
+ * 缩进、三态全部交给 `Tree`,改一处两处同时生效(不存在第二棵树)。
13
+ * 两态的差异只有一处:`variant="list"` 隐藏箭头占位(扁平导航没有层级,不需要那一段缩进)。
14
+ *
15
+ * ## 滚动归属
16
+ *
17
+ * 根件 `overflow: hidden`,**只有 `mh-nav__body` 滚**(与 `Panel.Body` 同一口径):
18
+ * 侧栏滚动不再由应用侧写 `overflow-y: auto` 的应用侧类来顶。
19
+ *
20
+ * ## 宽度
21
+ *
22
+ * 缺省**填满所在栏**(`width: var(--mh-nav-width, 100%)`):列宽由 `Page.Split` 的侧栏列
23
+ * 或外层布局决定,导航件不重复锁一个可能与栏宽不符的数;独立使用需要固定宽时传 `width`(px 数字)。
24
+ *
25
+ * ## 行尾操作
26
+ *
27
+ * `renderActions` 直接透传给 `Tree`:默认隐藏、行悬浮或行内获得焦点时显形、点击不冒泡(§4.16)。
28
+ * 应用侧只给节点,不要自己写显隐 CSS,也不要把它塞进 `renderNode`(那是常驻附加内容)。
29
+ *
30
+ * @example 分类导航树(选中驱动右侧 + 行尾管理操作)
31
+ * <Nav variant="tree" nodes={categoryNodes.value} rowKey="id" labelKey="name" width={220}
32
+ * selected={categoryId.value} onSelect={(node) => (categoryId.value = node.id)}
33
+ * expandedKeys={expandedKeys.value} onExpandChange={(keys) => (expandedKeys.value = keys)}
34
+ * loading={query.isPending.value} error={query.isError.value} empty="暂无分类"
35
+ * renderActions={(node) => <Button title="删除" onClick={() => removeCategory(node.id)} />} />
36
+ */
37
+ export declare const Nav: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
38
+ /** 导航形态:`tree`(默认,层级 + 箭头)/ `list`(扁平,无箭头占位) */
39
+ variant: {
40
+ type: PropType<NavVariant>;
41
+ default: string;
42
+ };
43
+ /** 导航节点(`list` 态传扁平数组);结构与 `Tree` 同 */
44
+ nodes: {
45
+ type: PropType<TreeNode[]>;
46
+ required: true;
47
+ };
48
+ /** 节点主键:字段名或取值函数 */
49
+ rowKey: {
50
+ type: PropType<string | ((node: TreeNode) => string)>;
51
+ required: true;
52
+ };
53
+ /** 标签字段名(默认 'label') */
54
+ labelKey: {
55
+ type: StringConstructor;
56
+ default: string;
57
+ };
58
+ /** 子节点字段名(默认 'children') */
59
+ childrenKey: {
60
+ type: StringConstructor;
61
+ default: string;
62
+ };
63
+ /** 受控选中(行主键值) */
64
+ selected: {
65
+ type: StringConstructor;
66
+ default: undefined;
67
+ };
68
+ /** 选中回调:给的是**节点对象**(不是主键值),口径同 `Tree` */
69
+ onSelect: {
70
+ type: PropType<(node: TreeNode) => void>;
71
+ default: undefined;
72
+ };
73
+ /** 受控展开集(传了就完全受控) */
74
+ expandedKeys: {
75
+ type: PropType<string[]>;
76
+ default: undefined;
77
+ };
78
+ /** 非受控展开初值 */
79
+ defaultExpandedKeys: {
80
+ type: PropType<string[]>;
81
+ default: () => never[];
82
+ };
83
+ onExpandChange: {
84
+ type: PropType<(keys: string[]) => void>;
85
+ default: undefined;
86
+ };
87
+ /** 行尾操作区(新增 / 重命名 / 删除…):悬浮显形 + 点击不冒泡,见 `Tree.renderActions` */
88
+ renderActions: {
89
+ type: PropType<(node: TreeNode) => unknown>;
90
+ default: undefined;
91
+ };
92
+ /** 侧栏标题(可选;不传则只有导航体) */
93
+ title: {
94
+ type: StringConstructor;
95
+ default: undefined;
96
+ };
97
+ /** 侧栏宽度(px 数字):只下发 `--mh-nav-width`;**不传则填满所在栏**(列宽归 `Page.Split` / 外层布局) */
98
+ width: {
99
+ type: NumberConstructor;
100
+ default: undefined;
101
+ };
102
+ /** 尺寸档:`md`(行高 30,默认)/ `sm`(紧凑 28) */
103
+ size: {
104
+ type: PropType<"md" | "sm">;
105
+ default: string;
106
+ };
107
+ loading: {
108
+ type: BooleanConstructor;
109
+ default: boolean;
110
+ };
111
+ /** 空态文案 */
112
+ empty: {
113
+ type: StringConstructor;
114
+ default: string;
115
+ };
116
+ /** 空态操作按钮(如「新建」);与 `onEmptyAction` 同时传才渲染 */
117
+ emptyActionText: {
118
+ type: StringConstructor;
119
+ default: undefined;
120
+ };
121
+ onEmptyAction: {
122
+ type: PropType<() => void>;
123
+ default: undefined;
124
+ };
125
+ /**
126
+ * 错误态(truthy 即触发)。
127
+ *
128
+ * **构造器顺序同 `Tree.error`:`String` 必须排在 `Boolean` 前** —— 顺序写反时,成功态传的
129
+ * 空字符串会被 Vue 的布尔转换判成 `true`,侧栏永远停在错误态。
130
+ */
131
+ error: {
132
+ type: PropType<any>;
133
+ default: undefined;
134
+ };
135
+ /** 错误态标题(默认「加载失败」) */
136
+ errorTitle: {
137
+ type: StringConstructor;
138
+ default: string;
139
+ };
140
+ /** 错误态操作按钮(如「重试」);与 `onErrorAction` 同时传才渲染 */
141
+ errorActionText: {
142
+ type: StringConstructor;
143
+ default: undefined;
144
+ };
145
+ onErrorAction: {
146
+ type: PropType<() => void>;
147
+ default: undefined;
148
+ };
149
+ /** 右侧分隔线(侧栏与内容区之间;贴在页面容器里时用) */
150
+ bordered: {
151
+ type: BooleanConstructor;
152
+ default: boolean;
153
+ };
154
+ }>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
155
+ /** 导航形态:`tree`(默认,层级 + 箭头)/ `list`(扁平,无箭头占位) */
156
+ variant: {
157
+ type: PropType<NavVariant>;
158
+ default: string;
159
+ };
160
+ /** 导航节点(`list` 态传扁平数组);结构与 `Tree` 同 */
161
+ nodes: {
162
+ type: PropType<TreeNode[]>;
163
+ required: true;
164
+ };
165
+ /** 节点主键:字段名或取值函数 */
166
+ rowKey: {
167
+ type: PropType<string | ((node: TreeNode) => string)>;
168
+ required: true;
169
+ };
170
+ /** 标签字段名(默认 'label') */
171
+ labelKey: {
172
+ type: StringConstructor;
173
+ default: string;
174
+ };
175
+ /** 子节点字段名(默认 'children') */
176
+ childrenKey: {
177
+ type: StringConstructor;
178
+ default: string;
179
+ };
180
+ /** 受控选中(行主键值) */
181
+ selected: {
182
+ type: StringConstructor;
183
+ default: undefined;
184
+ };
185
+ /** 选中回调:给的是**节点对象**(不是主键值),口径同 `Tree` */
186
+ onSelect: {
187
+ type: PropType<(node: TreeNode) => void>;
188
+ default: undefined;
189
+ };
190
+ /** 受控展开集(传了就完全受控) */
191
+ expandedKeys: {
192
+ type: PropType<string[]>;
193
+ default: undefined;
194
+ };
195
+ /** 非受控展开初值 */
196
+ defaultExpandedKeys: {
197
+ type: PropType<string[]>;
198
+ default: () => never[];
199
+ };
200
+ onExpandChange: {
201
+ type: PropType<(keys: string[]) => void>;
202
+ default: undefined;
203
+ };
204
+ /** 行尾操作区(新增 / 重命名 / 删除…):悬浮显形 + 点击不冒泡,见 `Tree.renderActions` */
205
+ renderActions: {
206
+ type: PropType<(node: TreeNode) => unknown>;
207
+ default: undefined;
208
+ };
209
+ /** 侧栏标题(可选;不传则只有导航体) */
210
+ title: {
211
+ type: StringConstructor;
212
+ default: undefined;
213
+ };
214
+ /** 侧栏宽度(px 数字):只下发 `--mh-nav-width`;**不传则填满所在栏**(列宽归 `Page.Split` / 外层布局) */
215
+ width: {
216
+ type: NumberConstructor;
217
+ default: undefined;
218
+ };
219
+ /** 尺寸档:`md`(行高 30,默认)/ `sm`(紧凑 28) */
220
+ size: {
221
+ type: PropType<"md" | "sm">;
222
+ default: string;
223
+ };
224
+ loading: {
225
+ type: BooleanConstructor;
226
+ default: boolean;
227
+ };
228
+ /** 空态文案 */
229
+ empty: {
230
+ type: StringConstructor;
231
+ default: string;
232
+ };
233
+ /** 空态操作按钮(如「新建」);与 `onEmptyAction` 同时传才渲染 */
234
+ emptyActionText: {
235
+ type: StringConstructor;
236
+ default: undefined;
237
+ };
238
+ onEmptyAction: {
239
+ type: PropType<() => void>;
240
+ default: undefined;
241
+ };
242
+ /**
243
+ * 错误态(truthy 即触发)。
244
+ *
245
+ * **构造器顺序同 `Tree.error`:`String` 必须排在 `Boolean` 前** —— 顺序写反时,成功态传的
246
+ * 空字符串会被 Vue 的布尔转换判成 `true`,侧栏永远停在错误态。
247
+ */
248
+ error: {
249
+ type: PropType<any>;
250
+ default: undefined;
251
+ };
252
+ /** 错误态标题(默认「加载失败」) */
253
+ errorTitle: {
254
+ type: StringConstructor;
255
+ default: string;
256
+ };
257
+ /** 错误态操作按钮(如「重试」);与 `onErrorAction` 同时传才渲染 */
258
+ errorActionText: {
259
+ type: StringConstructor;
260
+ default: undefined;
261
+ };
262
+ onErrorAction: {
263
+ type: PropType<() => void>;
264
+ default: undefined;
265
+ };
266
+ /** 右侧分隔线(侧栏与内容区之间;贴在页面容器里时用) */
267
+ bordered: {
268
+ type: BooleanConstructor;
269
+ default: boolean;
270
+ };
271
+ }>> & Readonly<{}>, {
272
+ size: "sm" | "md";
273
+ title: string;
274
+ onSelect: (node: TreeNode) => void;
275
+ error: any;
276
+ loading: boolean;
277
+ width: number;
278
+ variant: NavVariant;
279
+ selected: string;
280
+ empty: string;
281
+ errorTitle: string;
282
+ emptyActionText: string;
283
+ onEmptyAction: () => void;
284
+ errorActionText: string;
285
+ onErrorAction: () => void;
286
+ labelKey: string;
287
+ childrenKey: string;
288
+ renderActions: (node: TreeNode) => unknown;
289
+ expandedKeys: string[];
290
+ defaultExpandedKeys: string[];
291
+ onExpandChange: (keys: string[]) => void;
292
+ bordered: boolean;
293
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;