@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,116 @@
1
+ import { defineComponent, onMounted, onBeforeUnmount, createVNode } from "vue";
2
+ import { Icon } from "@manohub/icon";
3
+ const TONE_ICON = {
4
+ info: "info",
5
+ success: "check",
6
+ warning: "alert",
7
+ error: "close",
8
+ loading: "loading"
9
+ };
10
+ const Toast = /* @__PURE__ */ defineComponent({
11
+ name: "Toast",
12
+ inheritAttrs: false,
13
+ props: {
14
+ tone: {
15
+ type: String,
16
+ default: "info"
17
+ },
18
+ /** 正文(复杂内容走默认插槽) */
19
+ text: {
20
+ type: String,
21
+ default: void 0
22
+ },
23
+ /** 动作文案(走 `action` 插槽可给自定义元素) */
24
+ action: {
25
+ type: String,
26
+ default: void 0
27
+ },
28
+ /** 自动消失毫秒数;`0` = 不自动消失(缺省不给计时) */
29
+ duration: {
30
+ type: Number,
31
+ default: 0
32
+ },
33
+ /** 前置图标:缺省按 `tone` 映射;`false` 不出图标;也可直接给图标名 */
34
+ icon: {
35
+ type: [Boolean, String],
36
+ default: true
37
+ },
38
+ /** 手动关闭位(`duration` 为 0 的常驻提示必须给用户一个关掉的入口) */
39
+ closable: {
40
+ type: Boolean,
41
+ default: false
42
+ },
43
+ onAction: {
44
+ type: Function,
45
+ default: void 0
46
+ }
47
+ },
48
+ emits: {
49
+ /** 自动消失到点(**只回调不移除**:存在性归调用方,避免"组件没了、队列里还留着"两套口径) */
50
+ close: () => true
51
+ },
52
+ slots: Object,
53
+ setup(props, {
54
+ emit,
55
+ slots,
56
+ attrs
57
+ }) {
58
+ let timer;
59
+ onMounted(() => {
60
+ if (props.duration > 0) {
61
+ timer = setTimeout(() => emit("close"), props.duration);
62
+ }
63
+ });
64
+ onBeforeUnmount(() => {
65
+ if (timer) clearTimeout(timer);
66
+ });
67
+ return () => {
68
+ const hasAction = Boolean(props.action || slots.action);
69
+ return createVNode("div", {
70
+ "class": ["mh-toast", props.tone === "loading" ? "mh-toast--loading" : "", hasAction ? "mh-toast--action" : "", attrs.class].filter(Boolean).join(" "),
71
+ "style": attrs.style,
72
+ "role": "status"
73
+ }, [props.icon === false ? null : createVNode("span", {
74
+ "class": ["mh-toast__icon", `mh-toast__icon--${props.tone}`].join(" ")
75
+ }, [createVNode(Icon, {
76
+ "name": typeof props.icon === "string" ? props.icon : TONE_ICON[props.tone],
77
+ "size": props.tone === "loading" ? 16 : 12
78
+ }, null)]), createVNode("div", {
79
+ "class": "mh-toast__text"
80
+ }, [slots.default ? slots.default() : props.text]), slots.action ? slots.action() : props.action ? createVNode("button", {
81
+ "type": "button",
82
+ "class": "mh-toast__action",
83
+ "onClick": props.onAction
84
+ }, [props.action]) : null, props.closable ? createVNode("button", {
85
+ "type": "button",
86
+ "class": "mh-toast__close",
87
+ "aria-label": "关闭",
88
+ "onClick": () => emit("close")
89
+ }, [createVNode(Icon, {
90
+ "name": "close",
91
+ "size": 12,
92
+ "class": "mh-toast__close-icon"
93
+ }, null)]) : null]);
94
+ };
95
+ }
96
+ });
97
+ const ToastStack = /* @__PURE__ */ defineComponent({
98
+ name: "ToastStack",
99
+ inheritAttrs: false,
100
+ setup(_props, {
101
+ slots,
102
+ attrs
103
+ }) {
104
+ return () => createVNode("div", {
105
+ "class": ["mh-toast-stack", attrs.class].filter(Boolean).join(" "),
106
+ "style": attrs.style
107
+ }, [slots.default?.()]);
108
+ }
109
+ });
110
+ const ToastCompound = Object.assign(Toast, {
111
+ Stack: ToastStack
112
+ });
113
+ export {
114
+ Toast,
115
+ ToastCompound
116
+ };
@@ -0,0 +1,126 @@
1
+ import { type PropType, type SlotsType, type VNodeChild } from 'vue';
2
+ export type TooltipSide = 'top' | 'bottom' | 'left' | 'right';
3
+ export type TooltipAlign = 'start' | 'center' | 'end';
4
+ /** 触发方式:`hover` 鼠标悬停(零 JS)/ `click` 点击(原生 popover,同样零 JS) */
5
+ export type TooltipTrigger = 'hover' | 'click';
6
+ /**
7
+ * 提示气泡(**自绘**;两种触发都**零 JS**)。
8
+ *
9
+ * ## 两条路径(由 `trigger` 选,都是浏览器原生能力)
10
+ *
11
+ * - **`hover`(缺省)**:显隐与定位全交操作层 `styles/operations/popup.css` 的 hover 档 ——
12
+ * 宿主 `:hover` / `:focus-within` 切 display,鼠标移入即出、移开即消失,**不吃点击、不抢焦点**
13
+ * (这正是「非交互提示」该有的语义)。代价:hover 档**不进 top layer**,会被祖先 `overflow` 裁切。
14
+ * - **`click`**:触发器渲染成原生 `<button popovertarget>` + 气泡 `popover` ——
15
+ * 开合 / Esc / 点外部关闭 / **top layer 渲染**(不被裁切)全归浏览器。
16
+ * 代价:触发器被按钮化(内部不要放可交互元素)。
17
+ *
18
+ * 定位两者同一套:`data-side` 给方位、`data-align` 给两侧对齐(缺省中线),溢出自动翻面。
19
+ *
20
+ * @example 悬停
21
+ * <Tooltip content="导出为 CSV" side="bottom" align="end">
22
+ * <Button variant="secondary">导出</Button>
23
+ * </Tooltip>
24
+ *
25
+ * @example 点击(内容可交互 / 怕被裁切时)
26
+ * <Tooltip trigger="click" content="最近 24 小时无异常">
27
+ * <Icon name="info" />
28
+ * </Tooltip>
29
+ *
30
+ * @example 带标题与动作(引导档外观)
31
+ * <Tooltip guide title="新功能" content="支持批量导入" action="去看看" @action="go" />
32
+ */
33
+ export declare const Tooltip: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
34
+ /** 正文(复杂内容走 `content` 插槽) */
35
+ content: {
36
+ type: StringConstructor;
37
+ default: undefined;
38
+ };
39
+ /** 标题位(medium 字重) */
40
+ title: {
41
+ type: StringConstructor;
42
+ default: undefined;
43
+ };
44
+ /** 动作文案(走 `action` 插槽可给自定义元素) */
45
+ action: {
46
+ type: StringConstructor;
47
+ default: undefined;
48
+ };
49
+ /** 落在触发器的哪一侧 */
50
+ side: {
51
+ type: PropType<TooltipSide>;
52
+ default: string;
53
+ };
54
+ /** 两侧对齐档(缺省中线) */
55
+ align: {
56
+ type: PropType<TooltipAlign>;
57
+ default: string;
58
+ };
59
+ /** 触发方式:悬停(零 JS 操作层档)/ 点击(原生 popover) */
60
+ trigger: {
61
+ type: PropType<TooltipTrigger>;
62
+ default: string;
63
+ };
64
+ /** 引导档外观(蓝渐变底 + 更大内距/投影) */
65
+ guide: {
66
+ type: BooleanConstructor;
67
+ default: boolean;
68
+ };
69
+ onAction: {
70
+ type: PropType<() => void>;
71
+ default: undefined;
72
+ };
73
+ }>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
74
+ /** 正文(复杂内容走 `content` 插槽) */
75
+ content: {
76
+ type: StringConstructor;
77
+ default: undefined;
78
+ };
79
+ /** 标题位(medium 字重) */
80
+ title: {
81
+ type: StringConstructor;
82
+ default: undefined;
83
+ };
84
+ /** 动作文案(走 `action` 插槽可给自定义元素) */
85
+ action: {
86
+ type: StringConstructor;
87
+ default: undefined;
88
+ };
89
+ /** 落在触发器的哪一侧 */
90
+ side: {
91
+ type: PropType<TooltipSide>;
92
+ default: string;
93
+ };
94
+ /** 两侧对齐档(缺省中线) */
95
+ align: {
96
+ type: PropType<TooltipAlign>;
97
+ default: string;
98
+ };
99
+ /** 触发方式:悬停(零 JS 操作层档)/ 点击(原生 popover) */
100
+ trigger: {
101
+ type: PropType<TooltipTrigger>;
102
+ default: string;
103
+ };
104
+ /** 引导档外观(蓝渐变底 + 更大内距/投影) */
105
+ guide: {
106
+ type: BooleanConstructor;
107
+ default: boolean;
108
+ };
109
+ onAction: {
110
+ type: PropType<() => void>;
111
+ default: undefined;
112
+ };
113
+ }>> & Readonly<{}>, {
114
+ content: string;
115
+ title: string;
116
+ align: TooltipAlign;
117
+ action: string;
118
+ onAction: () => void;
119
+ side: TooltipSide;
120
+ trigger: TooltipTrigger;
121
+ guide: boolean;
122
+ }, SlotsType<{
123
+ default?: () => VNodeChild;
124
+ content?: () => VNodeChild;
125
+ action?: () => VNodeChild;
126
+ }>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,97 @@
1
+ import { defineComponent, createVNode, Fragment, mergeProps } from "vue";
2
+ const Tooltip = /* @__PURE__ */ defineComponent({
3
+ name: "Tooltip",
4
+ inheritAttrs: false,
5
+ props: {
6
+ /** 正文(复杂内容走 `content` 插槽) */
7
+ content: {
8
+ type: String,
9
+ default: void 0
10
+ },
11
+ /** 标题位(medium 字重) */
12
+ title: {
13
+ type: String,
14
+ default: void 0
15
+ },
16
+ /** 动作文案(走 `action` 插槽可给自定义元素) */
17
+ action: {
18
+ type: String,
19
+ default: void 0
20
+ },
21
+ /** 落在触发器的哪一侧 */
22
+ side: {
23
+ type: String,
24
+ default: "top"
25
+ },
26
+ /** 两侧对齐档(缺省中线) */
27
+ align: {
28
+ type: String,
29
+ default: "center"
30
+ },
31
+ /** 触发方式:悬停(零 JS 操作层档)/ 点击(原生 popover) */
32
+ trigger: {
33
+ type: String,
34
+ default: "hover"
35
+ },
36
+ /** 引导档外观(蓝渐变底 + 更大内距/投影) */
37
+ guide: {
38
+ type: Boolean,
39
+ default: false
40
+ },
41
+ onAction: {
42
+ type: Function,
43
+ default: void 0
44
+ }
45
+ },
46
+ slots: Object,
47
+ setup(props, {
48
+ slots,
49
+ attrs
50
+ }) {
51
+ const panelId = `mh-tooltip-${Math.random().toString(36).slice(2, 10)}`;
52
+ return () => {
53
+ const hasBody = Boolean(props.content || slots.content);
54
+ const hasAction = Boolean(props.action || slots.action);
55
+ const body = createVNode(Fragment, null, [props.title ? createVNode("span", {
56
+ "class": "mh-tooltip__title"
57
+ }, [props.title]) : null, props.title && hasBody ? " " : null, slots.content ? slots.content() : props.content, hasAction ? " " : null, slots.action ? slots.action() : props.action ? createVNode("button", {
58
+ "type": "button",
59
+ "class": "mh-tooltip__action",
60
+ "onClick": props.onAction
61
+ }, [props.action]) : null]);
62
+ if (props.trigger === "click") {
63
+ return createVNode("span", {
64
+ "class": ["mh-popup-host", attrs.class].filter(Boolean).join(" "),
65
+ "style": attrs.style
66
+ }, [createVNode("button", mergeProps({
67
+ "type": "button",
68
+ "class": "mh-tooltip__trigger"
69
+ }, {
70
+ popovertarget: panelId
71
+ }), [slots.default?.()]), createVNode("div", mergeProps({
72
+ "id": panelId
73
+ }, {
74
+ popover: "auto"
75
+ }, {
76
+ "class": ["mh-popup", "mh-tooltip", "mh-tooltip--click", props.guide ? "mh-tooltip--guide" : ""].filter(Boolean).join(" "),
77
+ "data-side": props.side,
78
+ "data-align": props.align === "center" ? void 0 : props.align,
79
+ "role": "tooltip"
80
+ }), [body])]);
81
+ }
82
+ return createVNode("span", {
83
+ "class": ["mh-popup-host", attrs.class].filter(Boolean).join(" "),
84
+ "style": attrs.style
85
+ }, [createVNode("span", {
86
+ "class": "mh-popup-anchor"
87
+ }, [slots.default?.()]), createVNode("span", {
88
+ "class": ["mh-popup", "mh-popup--hover", "mh-popup--anchored", "mh-tooltip", props.guide ? "mh-tooltip--guide" : ""].filter(Boolean).join(" "),
89
+ "data-side": props.side,
90
+ "data-align": props.align === "center" ? void 0 : props.align
91
+ }, [body])]);
92
+ };
93
+ }
94
+ });
95
+ export {
96
+ Tooltip
97
+ };
@@ -0,0 +1,317 @@
1
+ import { type PropType, type SlotsType, type VNodeChild } from 'vue';
2
+ /** 树节点:至少要有主键与标签,子节点字段名可用 `childrenKey` 指定 */
3
+ export interface TreeNode {
4
+ [key: string]: unknown;
5
+ }
6
+ /**
7
+ * 树(**自建**,不封装 farris)。
8
+ *
9
+ * ## 视觉与几何规范来源
10
+ *
11
+ * 对齐 `@aihub/theme` 的 Tree(`src/components/tree.css` 令牌 + `playground/components/tree.html` 标记):
12
+ * 节点行高 30(紧凑档 28)、圆角 6(`--ui-radius-control`)、字号 13、滑过 Ne11、点击瞬态 #F4F5F9、
13
+ * 选中 Au02 底 + Th03 字、箭头 8px(收起态转 −90°)、缩进 = 基础内距 8 + level × 步进 10(**无上限**)。
14
+ *
15
+ * 两处与主题包的**有意差异**(不改视觉,只改承载方式):
16
+ * 1. **缩进步进由 CSS 变量承载**:主题包用 typed `attr(data-level type(<number>))` 一步算出;
17
+ * 为兼容尚无该能力的引擎,本组件同时下发 `data-level`(数据、供 CSS/测试钩子)与
18
+ * `--mh-tree-level`(公式仍在 CSS 内,见 components.css)。不用行内 paddingLeft —— 那样
19
+ * 步进值就散落在 JS 里,改了令牌对不上。
20
+ * 2. **交互分工**:主题包的约定是「点行即展开/收拢,选中由行内选择件驱动」;本组件没有内嵌选择件,
21
+ * 故沿用「点箭头展开/收拢、点行选中」(`onSelect`)—— 消费方靠 `onSelect` 拿选中,展开态受控。
22
+ *
23
+ * ## 为什么自建(对照计划登记的退路)
24
+ *
25
+ * farris `FTreeView` 实测结论:① 是列模板式网格(节点内容可用 `columnTemplate` 承载);
26
+ * ② **只在挂载时填充一次可见行,data 变化不刷新**(仓内唯一的适配器
27
+ * `apps/skill/src/features/skill/farris-file-tree.tsx` 正是用 `key` 强制重挂绕行);
28
+ * ③ 层级缩进不可控、节点图标走 farris 图标字体类。
29
+ *
30
+ * 而本组件的硬需求是「数据更新时**不丢**用户已展开的节点 / 滚动位置 / 焦点」——
31
+ * 与 ② 直接冲突(重挂必然丢展开态);缩进又要按设计稿精确控制(③)。因此按计划
32
+ * 登记的退路改为自建:契约完整(含受控展开态)、零 farris 耦合、可在无浏览器环境测试。
33
+ *
34
+ * ## 与数据变化的关系
35
+ *
36
+ * 自建后**不需要**「nodes 变就重建」这种逃生舱:渲染直接跟随 `nodes`,
37
+ * 展开态由 `expandedKeys`(受控)或内部状态(非受控)持有,数据刷新不会改变展开态。
38
+ * `treeKey` 仅作为极端场景的强制重挂出口保留。
39
+ *
40
+ * ## 行尾操作区(`renderActions`)
41
+ *
42
+ * 行尾操作是**行的一部分**,不是导航语义 —— 与 `ListView.CardItem` 的 `actions` 同一口径:
43
+ * 几何与显隐归组件(默认隐藏、行悬浮或行内获得焦点时显形,触屏无 hover 能力时恒显形),
44
+ * 应用侧只给节点;操作容器自己做 `stopPropagation`,所以点「删除」不会顺带把这一行选中。
45
+ * 导航件(`Nav`)因此不必重写一份行渲染,把数据与 `renderActions` 透传进来即可。
46
+ *
47
+ * @example 受控展开 + 计数徽标 + 行尾操作
48
+ * <Tree nodes={treeNodes.value} rowKey="id" labelKey="name"
49
+ * selected={selectedId.value} onSelect={(n) => select(n.id)}
50
+ * expandedKeys={expandedKeys.value} onExpandChange={(k) => (expandedKeys.value = k)}
51
+ * renderNode={(n) => <Badge>{countOfDomain(n.id)}</Badge>}
52
+ * renderActions={(n) => <Button title="删除" onClick={() => removeDomain(n.id)} />} />
53
+ */
54
+ export declare const Tree: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
55
+ nodes: {
56
+ type: PropType<TreeNode[]>;
57
+ required: true;
58
+ };
59
+ /** 节点主键:字段名或取值函数 */
60
+ rowKey: {
61
+ type: PropType<string | ((node: TreeNode) => string)>;
62
+ required: true;
63
+ };
64
+ /** 标签字段名(默认 'label') */
65
+ labelKey: {
66
+ type: StringConstructor;
67
+ default: string;
68
+ };
69
+ /** 子节点字段名(默认 'children') */
70
+ childrenKey: {
71
+ type: StringConstructor;
72
+ default: string;
73
+ };
74
+ /** 受控选中(行主键值) */
75
+ selected: {
76
+ type: StringConstructor;
77
+ default: undefined;
78
+ };
79
+ onSelect: {
80
+ type: PropType<(node: TreeNode) => void>;
81
+ default: undefined;
82
+ };
83
+ /** 节点附加内容(计数徽标等),渲染在标签之后 */
84
+ renderNode: {
85
+ type: PropType<(node: TreeNode) => unknown>;
86
+ default: undefined;
87
+ };
88
+ /**
89
+ * 行尾操作区(新增 / 重命名 / 删除等)。
90
+ *
91
+ * **默认隐藏、行悬浮或行内获得焦点时显形**(触屏无 hover 能力时恒显形),点击**不冒泡**到 `onSelect`
92
+ * —— 与 `ListView.CardItem` 的 `actions` 同一口径(几何与显隐归组件,应用侧只给节点)。
93
+ *
94
+ * 与 `renderNode` 的分工:**常驻**的附加内容(计数徽标)走 `renderNode`;**可点**的行尾操作走这里。
95
+ */
96
+ renderActions: {
97
+ type: PropType<(node: TreeNode) => unknown>;
98
+ default: undefined;
99
+ };
100
+ /** 尺寸档:md 舒适(行高 30)/ sm 紧凑(行高 28),与主题包 Tree 的 M/S 档一致 */
101
+ size: {
102
+ type: PropType<"md" | "sm">;
103
+ default: string;
104
+ };
105
+ /** 受控展开集(传了就完全受控,内部不再自持) */
106
+ expandedKeys: {
107
+ type: PropType<string[]>;
108
+ default: undefined;
109
+ };
110
+ /** 非受控展开初值 */
111
+ defaultExpandedKeys: {
112
+ type: PropType<string[]>;
113
+ default: () => never[];
114
+ };
115
+ /** 初始展开全部(首次进入就要看全层级时用;与 `defaultExpandedKeys` 互斥,它优先) */
116
+ defaultExpandAll: {
117
+ type: BooleanConstructor;
118
+ default: boolean;
119
+ };
120
+ onExpandChange: {
121
+ type: PropType<(keys: string[]) => void>;
122
+ default: undefined;
123
+ };
124
+ loading: {
125
+ type: BooleanConstructor;
126
+ default: boolean;
127
+ };
128
+ /** 空态文案 */
129
+ empty: {
130
+ type: StringConstructor;
131
+ default: string;
132
+ };
133
+ /** 空态操作按钮(如「新建」);与 `onEmptyAction` 同时传才渲染 */
134
+ emptyActionText: {
135
+ type: StringConstructor;
136
+ default: undefined;
137
+ };
138
+ onEmptyAction: {
139
+ type: PropType<() => void>;
140
+ default: undefined;
141
+ };
142
+ /**
143
+ * 错误态(truthy 即触发)。
144
+ *
145
+ * **构造器顺序同 `表格.error`:`String` 必须排在 `Boolean` 前** —— 顺序写反时,成功态传的
146
+ * 空字符串会被 Vue 的布尔转换判成 `true`,树永远停在错误态。
147
+ *
148
+ * 有它之前,消费方只能把错误文案塞进 `empty`:错误被渲染成空态语义(无错误插画、无重试入口),
149
+ * 用户看不出「是没数据还是加载挂了」。
150
+ */
151
+ error: {
152
+ type: PropType<any>;
153
+ default: undefined;
154
+ };
155
+ /** 错误态标题(默认「加载失败」);字符串错误原文会自动作为副文案显示 */
156
+ errorTitle: {
157
+ type: StringConstructor;
158
+ default: string;
159
+ };
160
+ /** 错误态操作按钮(如「重试」);与 `onErrorAction` 同时传才渲染 */
161
+ errorActionText: {
162
+ type: StringConstructor;
163
+ default: undefined;
164
+ };
165
+ onErrorAction: {
166
+ type: PropType<() => void>;
167
+ default: undefined;
168
+ };
169
+ /** 强制重挂逃生舱(正常数据刷新不需要它) */
170
+ treeKey: {
171
+ type: PropType<string | number>;
172
+ default: undefined;
173
+ };
174
+ }>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
175
+ nodes: {
176
+ type: PropType<TreeNode[]>;
177
+ required: true;
178
+ };
179
+ /** 节点主键:字段名或取值函数 */
180
+ rowKey: {
181
+ type: PropType<string | ((node: TreeNode) => string)>;
182
+ required: true;
183
+ };
184
+ /** 标签字段名(默认 'label') */
185
+ labelKey: {
186
+ type: StringConstructor;
187
+ default: string;
188
+ };
189
+ /** 子节点字段名(默认 'children') */
190
+ childrenKey: {
191
+ type: StringConstructor;
192
+ default: string;
193
+ };
194
+ /** 受控选中(行主键值) */
195
+ selected: {
196
+ type: StringConstructor;
197
+ default: undefined;
198
+ };
199
+ onSelect: {
200
+ type: PropType<(node: TreeNode) => void>;
201
+ default: undefined;
202
+ };
203
+ /** 节点附加内容(计数徽标等),渲染在标签之后 */
204
+ renderNode: {
205
+ type: PropType<(node: TreeNode) => unknown>;
206
+ default: undefined;
207
+ };
208
+ /**
209
+ * 行尾操作区(新增 / 重命名 / 删除等)。
210
+ *
211
+ * **默认隐藏、行悬浮或行内获得焦点时显形**(触屏无 hover 能力时恒显形),点击**不冒泡**到 `onSelect`
212
+ * —— 与 `ListView.CardItem` 的 `actions` 同一口径(几何与显隐归组件,应用侧只给节点)。
213
+ *
214
+ * 与 `renderNode` 的分工:**常驻**的附加内容(计数徽标)走 `renderNode`;**可点**的行尾操作走这里。
215
+ */
216
+ renderActions: {
217
+ type: PropType<(node: TreeNode) => unknown>;
218
+ default: undefined;
219
+ };
220
+ /** 尺寸档:md 舒适(行高 30)/ sm 紧凑(行高 28),与主题包 Tree 的 M/S 档一致 */
221
+ size: {
222
+ type: PropType<"md" | "sm">;
223
+ default: string;
224
+ };
225
+ /** 受控展开集(传了就完全受控,内部不再自持) */
226
+ expandedKeys: {
227
+ type: PropType<string[]>;
228
+ default: undefined;
229
+ };
230
+ /** 非受控展开初值 */
231
+ defaultExpandedKeys: {
232
+ type: PropType<string[]>;
233
+ default: () => never[];
234
+ };
235
+ /** 初始展开全部(首次进入就要看全层级时用;与 `defaultExpandedKeys` 互斥,它优先) */
236
+ defaultExpandAll: {
237
+ type: BooleanConstructor;
238
+ default: boolean;
239
+ };
240
+ onExpandChange: {
241
+ type: PropType<(keys: string[]) => void>;
242
+ default: undefined;
243
+ };
244
+ loading: {
245
+ type: BooleanConstructor;
246
+ default: boolean;
247
+ };
248
+ /** 空态文案 */
249
+ empty: {
250
+ type: StringConstructor;
251
+ default: string;
252
+ };
253
+ /** 空态操作按钮(如「新建」);与 `onEmptyAction` 同时传才渲染 */
254
+ emptyActionText: {
255
+ type: StringConstructor;
256
+ default: undefined;
257
+ };
258
+ onEmptyAction: {
259
+ type: PropType<() => void>;
260
+ default: undefined;
261
+ };
262
+ /**
263
+ * 错误态(truthy 即触发)。
264
+ *
265
+ * **构造器顺序同 `表格.error`:`String` 必须排在 `Boolean` 前** —— 顺序写反时,成功态传的
266
+ * 空字符串会被 Vue 的布尔转换判成 `true`,树永远停在错误态。
267
+ *
268
+ * 有它之前,消费方只能把错误文案塞进 `empty`:错误被渲染成空态语义(无错误插画、无重试入口),
269
+ * 用户看不出「是没数据还是加载挂了」。
270
+ */
271
+ error: {
272
+ type: PropType<any>;
273
+ default: undefined;
274
+ };
275
+ /** 错误态标题(默认「加载失败」);字符串错误原文会自动作为副文案显示 */
276
+ errorTitle: {
277
+ type: StringConstructor;
278
+ default: string;
279
+ };
280
+ /** 错误态操作按钮(如「重试」);与 `onErrorAction` 同时传才渲染 */
281
+ errorActionText: {
282
+ type: StringConstructor;
283
+ default: undefined;
284
+ };
285
+ onErrorAction: {
286
+ type: PropType<() => void>;
287
+ default: undefined;
288
+ };
289
+ /** 强制重挂逃生舱(正常数据刷新不需要它) */
290
+ treeKey: {
291
+ type: PropType<string | number>;
292
+ default: undefined;
293
+ };
294
+ }>> & Readonly<{}>, {
295
+ size: "sm" | "md";
296
+ onSelect: (node: TreeNode) => void;
297
+ error: any;
298
+ loading: boolean;
299
+ selected: string;
300
+ empty: string;
301
+ errorTitle: string;
302
+ emptyActionText: string;
303
+ onEmptyAction: () => void;
304
+ errorActionText: string;
305
+ onErrorAction: () => void;
306
+ labelKey: string;
307
+ childrenKey: string;
308
+ renderNode: (node: TreeNode) => unknown;
309
+ renderActions: (node: TreeNode) => unknown;
310
+ expandedKeys: string[];
311
+ defaultExpandedKeys: string[];
312
+ defaultExpandAll: boolean;
313
+ onExpandChange: (keys: string[]) => void;
314
+ treeKey: string | number;
315
+ }, SlotsType<{
316
+ default?: () => VNodeChild;
317
+ }>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;