@manohub/ui 0.10.2 → 0.10.4
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 +1 -1
- package/dist/components/badge/index.d.ts +46 -1
- package/dist/components/badge/index.js +42 -9
- package/dist/components/card/index.d.ts +1 -1
- package/dist/components/drawer/index.d.ts +1 -1
- package/dist/components/filter/index.d.ts +74 -6
- package/dist/components/filter/index.js +38 -10
- package/dist/components/form/index.d.ts +50 -1
- package/dist/components/form/index.js +20 -2
- package/dist/components/input/index.js +1 -0
- package/dist/components/nav/index.d.ts +27 -0
- package/dist/components/nav/index.js +12 -0
- package/dist/components/notice/index.d.ts +1 -1
- package/dist/components/notification/index.d.ts +2 -2
- package/dist/components/select/index.d.ts +9 -0
- package/dist/components/select/index.js +57 -12
- package/dist/components/select/select-list.d.ts +42 -8
- package/dist/components/select/select-list.js +36 -11
- package/dist/components/select/select-panel.d.ts +36 -8
- package/dist/components/select/select-panel.js +18 -4
- package/dist/components/select/select-shared.d.ts +51 -10
- package/dist/components/select/select-shared.js +12 -2
- package/dist/components/select/select-tree.d.ts +25 -3
- package/dist/components/select/select-tree.js +17 -6
- package/dist/components/select/select-trigger.d.ts +21 -0
- package/dist/components/select/select-trigger.js +15 -1
- package/dist/components/tabs/index.d.ts +22 -0
- package/dist/components/tabs/index.js +6 -0
- package/dist/components/tag/index.d.ts +32 -153
- package/dist/components/tag/index.js +102 -101
- package/dist/components/text/index.d.ts +1 -1
- package/dist/components/tooltip/index.d.ts +1 -1
- package/dist/components/tree/index.d.ts +65 -0
- package/dist/components/tree/index.js +29 -2
- package/dist/index.d.ts +2 -2
- package/dist/styles/components/avatar.css +2 -2
- package/dist/styles/components/badge.css +21 -1
- package/dist/styles/components/badge.tokens.css +24 -0
- package/dist/styles/components/button.css +7 -6
- package/dist/styles/components/button.tokens.css +5 -2
- package/dist/styles/components/capsule.css +8 -0
- package/dist/styles/components/divider.css +8 -4
- package/dist/styles/components/divider.tokens.css +2 -1
- package/dist/styles/components/form.css +51 -0
- package/dist/styles/components/notification.css +1 -1
- package/dist/styles/components/select.css +62 -39
- package/dist/styles/components/select.tokens.css +15 -8
- package/dist/styles/components/tag.css +77 -154
- package/dist/styles/components/tag.tokens.css +13 -22
- package/dist/styles/components/tree.css +37 -3
- package/dist/styles/components/tree.tokens.css +4 -3
- package/dist/styles/components/upload.tokens.css +1 -1
- package/dist/styles/index.css +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ import { Card, Form, Tree, Checkbox } from '@manohub/ui'
|
|
|
62
62
|
| 分组 | 组件 |
|
|
63
63
|
|---|---|
|
|
64
64
|
| 容器与分区 | `Page`(页面级骨架:`.Header` / `.Body` / `.Footer` / `.Filter` / `.Toolbar` / `.Split`)、`Panel`(+ `.Header` / `.Body` / `.Footer`)、`Card`(+ 三件)、`Nav`、`Layout`(`Layout.Row` 排「行」/ `Layout.Column` 排「列」:轴向 × 间距档 × 对齐) |
|
|
65
|
-
| 数据展示 | `Tree`、`ListView`(+ `.CardItem`)、`Badge`、`Tag
|
|
65
|
+
| 数据展示 | `Tree`、`ListView`(+ `.CardItem`)、`Badge`、`Tag`(`Badge` 的可关闭 / 可新增封装) |
|
|
66
66
|
| 展示 | `Avatar`(+ `.Group`)、`Skeleton`(行 / 列表 / 块状) |
|
|
67
67
|
| 表单基础(**自绘**) | `Button`(+ `.Group` / `.Divider`;五型 / 小号 / 加载 / 菜单按钮 / 连体切换)、`Input`(+ `.Group` / `.Chip` / `.Display` / `.Textarea`;清除 / 可见性切换 / 校验)、`Search`(搜索框:值 / 搜索 / 清空三条回调)、`Select`(单选 / 多选 / 搜索 / 加载;面板用原生 popover)、`SelectTree`(树形态:仅叶子可选 + 本地过滤 + 命中高亮;与 `Select` 平级导出、共用触发器与面板)、`Switch`(表格档 / 表单档) |
|
|
68
68
|
| 表单与选择 | `Form`(+ `.Header` / `.Item`;标签体系、成员归位、`v-model` 值收集与命令式 `clear()`)、`Filter`(+ `.Item`;`Form` 的壳:条件字段写成子件、控件自放、查询/重置与快照归一)、`Checkbox`、`Radio`(+ `.Group` / `.Card`;卡片式单选)、`Capsule`(胶囊选择器;胶囊 / 方形两档外形,与 `Tabs` 组合即页签) |
|
|
@@ -19,6 +19,13 @@ export type BadgeStatus = 'success' | 'processing' | 'default' | 'warning' | 'er
|
|
|
19
19
|
* - `outline`:浅底 + 同色描边;`tone="default"` 时退化为白底 + 中性描边 + 正文色(状态胶囊)
|
|
20
20
|
* - `plain`:无底无框,靠圆点表达状态
|
|
21
21
|
*
|
|
22
|
+
* **本件是「只读标记」的唯一样式源**:`Tag`(可关闭 / 可新增)只是在本件之上加交互位,
|
|
23
|
+
* 几何与色彩一行都不重写 —— 改本件的档位,两件一起走(见 `components/tag/index.tsx`)。
|
|
24
|
+
*
|
|
25
|
+
* **属性落点**:`class` / `style` 有专口(并入档位类、随档位内联),**其余 attrs 一律透传到根元素**
|
|
26
|
+
* (`id` / `aria-*` / `data-*` / `title` / 原生事件)—— 停在组件上等于丢掉(`Tag` 的「新增」
|
|
27
|
+
* 就靠这条把 `onClick` 落到那颗按钮上),见 `forwardAttrs`。
|
|
28
|
+
*
|
|
22
29
|
* @example 内容徽标
|
|
23
30
|
* <Badge tone="success" shape="outline" size="md" dot="filled">运行中</Badge>
|
|
24
31
|
*
|
|
@@ -28,6 +35,9 @@ export type BadgeStatus = 'success' | 'processing' | 'default' | 'warning' | 'er
|
|
|
28
35
|
*
|
|
29
36
|
* @example 状态点
|
|
30
37
|
* <Badge status="processing" text="运行中" />
|
|
38
|
+
*
|
|
39
|
+
* @example 可点形态(复合件用;`Tag` 的「新增」即此形 + 本件自己的遮罩)
|
|
40
|
+
* <Badge as="button" tone="warning" onClick={() => add()}>新增</Badge>
|
|
31
41
|
*/
|
|
32
42
|
export declare const Badge: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
33
43
|
tone: {
|
|
@@ -73,6 +83,23 @@ export declare const Badge: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
73
83
|
type: StringConstructor;
|
|
74
84
|
default: undefined;
|
|
75
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* 根元素形态:`span`(缺省,纯展示)/ `button`(可点形态,给**复合件**用)。
|
|
88
|
+
*
|
|
89
|
+
* `Tag` 就是靠它拿到「可点」的:徽标是**只读标记**的唯一样式源,`Tag` 只往上加
|
|
90
|
+
* 关闭位与新增位,不再自己画一遍框(见 `components/tag/index.tsx`)。
|
|
91
|
+
* `as="button"` 会渲染真实 `<button type="button">`(`type` 不能省:缺省是 `submit`,
|
|
92
|
+
* 放进表单会提交),并保留本件全部档位类与几何 —— 按钮的外观缺三项由本件面自带
|
|
93
|
+
* (`border` / `background` / `padding`,见 `contract-reset.spec.ts` 的第三组),
|
|
94
|
+
* `font-family: inherit` 在 `badge.css` 的基块补(UA 会把按钮字形换成 Arial)。
|
|
95
|
+
*
|
|
96
|
+
* **只对「内容徽标」形态生效**:`count` / `status` 两种形态是装饰(角标、状态点 + 文字),
|
|
97
|
+
* 传了它们就忽略本 prop(那时走各自的分支,根仍是 `<span>`)。
|
|
98
|
+
*/
|
|
99
|
+
as: {
|
|
100
|
+
type: PropType<"span" | "button">;
|
|
101
|
+
default: string;
|
|
102
|
+
};
|
|
76
103
|
}>, () => import("vue/jsx-runtime").JSX.Element | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
77
104
|
tone: {
|
|
78
105
|
type: PropType<BadgeTone>;
|
|
@@ -117,16 +144,34 @@ export declare const Badge: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
117
144
|
type: StringConstructor;
|
|
118
145
|
default: undefined;
|
|
119
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* 根元素形态:`span`(缺省,纯展示)/ `button`(可点形态,给**复合件**用)。
|
|
149
|
+
*
|
|
150
|
+
* `Tag` 就是靠它拿到「可点」的:徽标是**只读标记**的唯一样式源,`Tag` 只往上加
|
|
151
|
+
* 关闭位与新增位,不再自己画一遍框(见 `components/tag/index.tsx`)。
|
|
152
|
+
* `as="button"` 会渲染真实 `<button type="button">`(`type` 不能省:缺省是 `submit`,
|
|
153
|
+
* 放进表单会提交),并保留本件全部档位类与几何 —— 按钮的外观缺三项由本件面自带
|
|
154
|
+
* (`border` / `background` / `padding`,见 `contract-reset.spec.ts` 的第三组),
|
|
155
|
+
* `font-family: inherit` 在 `badge.css` 的基块补(UA 会把按钮字形换成 Arial)。
|
|
156
|
+
*
|
|
157
|
+
* **只对「内容徽标」形态生效**:`count` / `status` 两种形态是装饰(角标、状态点 + 文字),
|
|
158
|
+
* 传了它们就忽略本 prop(那时走各自的分支,根仍是 `<span>`)。
|
|
159
|
+
*/
|
|
160
|
+
as: {
|
|
161
|
+
type: PropType<"span" | "button">;
|
|
162
|
+
default: string;
|
|
163
|
+
};
|
|
120
164
|
}>> & Readonly<{}>, {
|
|
121
165
|
text: string;
|
|
122
166
|
size: BadgeSize;
|
|
123
167
|
dot: boolean | BadgeDot;
|
|
124
168
|
shape: BadgeShape;
|
|
125
169
|
count: number;
|
|
126
|
-
status: BadgeStatus;
|
|
127
170
|
tone: BadgeTone;
|
|
128
171
|
overflowCount: number;
|
|
129
172
|
showZero: boolean;
|
|
173
|
+
status: BadgeStatus;
|
|
174
|
+
as: "button" | "span";
|
|
130
175
|
}, SlotsType<{
|
|
131
176
|
default?: () => VNodeChild;
|
|
132
177
|
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, computed, createVNode } from "vue";
|
|
1
|
+
import { defineComponent, computed, createVNode, mergeProps, Fragment } from "vue";
|
|
2
2
|
const STATUS_TONE = {
|
|
3
3
|
success: "success",
|
|
4
4
|
processing: "primary",
|
|
@@ -52,6 +52,23 @@ const Badge = /* @__PURE__ */ defineComponent({
|
|
|
52
52
|
text: {
|
|
53
53
|
type: String,
|
|
54
54
|
default: void 0
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* 根元素形态:`span`(缺省,纯展示)/ `button`(可点形态,给**复合件**用)。
|
|
58
|
+
*
|
|
59
|
+
* `Tag` 就是靠它拿到「可点」的:徽标是**只读标记**的唯一样式源,`Tag` 只往上加
|
|
60
|
+
* 关闭位与新增位,不再自己画一遍框(见 `components/tag/index.tsx`)。
|
|
61
|
+
* `as="button"` 会渲染真实 `<button type="button">`(`type` 不能省:缺省是 `submit`,
|
|
62
|
+
* 放进表单会提交),并保留本件全部档位类与几何 —— 按钮的外观缺三项由本件面自带
|
|
63
|
+
* (`border` / `background` / `padding`,见 `contract-reset.spec.ts` 的第三组),
|
|
64
|
+
* `font-family: inherit` 在 `badge.css` 的基块补(UA 会把按钮字形换成 Arial)。
|
|
65
|
+
*
|
|
66
|
+
* **只对「内容徽标」形态生效**:`count` / `status` 两种形态是装饰(角标、状态点 + 文字),
|
|
67
|
+
* 传了它们就忽略本 prop(那时走各自的分支,根仍是 `<span>`)。
|
|
68
|
+
*/
|
|
69
|
+
as: {
|
|
70
|
+
type: String,
|
|
71
|
+
default: "span"
|
|
55
72
|
}
|
|
56
73
|
},
|
|
57
74
|
slots: Object,
|
|
@@ -59,6 +76,13 @@ const Badge = /* @__PURE__ */ defineComponent({
|
|
|
59
76
|
slots,
|
|
60
77
|
attrs
|
|
61
78
|
}) {
|
|
79
|
+
const forwardAttrs = computed(() => {
|
|
80
|
+
const rest = {};
|
|
81
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
82
|
+
if (key !== "class" && key !== "style") rest[key] = value;
|
|
83
|
+
}
|
|
84
|
+
return rest;
|
|
85
|
+
});
|
|
62
86
|
const countText = computed(() => {
|
|
63
87
|
if (props.count === void 0) return null;
|
|
64
88
|
if (props.count === 0 && !props.showZero) return null;
|
|
@@ -69,28 +93,37 @@ const Badge = /* @__PURE__ */ defineComponent({
|
|
|
69
93
|
const style = attrs.style;
|
|
70
94
|
const extra = attrs.class;
|
|
71
95
|
if (props.status) {
|
|
72
|
-
return createVNode("span", {
|
|
96
|
+
return createVNode("span", mergeProps(forwardAttrs.value, {
|
|
73
97
|
"class": ["mh-badge--status", `mh-badge--${STATUS_TONE[props.status]}`, extra].filter(Boolean).join(" "),
|
|
74
98
|
"style": style
|
|
75
|
-
}, [createVNode("span", {
|
|
99
|
+
}), [createVNode("span", {
|
|
76
100
|
"class": "mh-badge__status-dot"
|
|
77
101
|
}, null), props.text ?? slots.default?.()]);
|
|
78
102
|
}
|
|
79
103
|
if (props.count !== void 0) {
|
|
80
104
|
if (countText.value === null && !slots.default) return null;
|
|
81
|
-
return createVNode("span", {
|
|
105
|
+
return createVNode("span", mergeProps(forwardAttrs.value, {
|
|
82
106
|
"class": ["mh-badge--count", extra].filter(Boolean).join(" "),
|
|
83
107
|
"style": style
|
|
84
|
-
}, [slots.default?.(), countText.value !== null ? createVNode("sup", {
|
|
108
|
+
}), [slots.default?.(), countText.value !== null ? createVNode("sup", {
|
|
85
109
|
"class": ["mh-badge__count", `mh-badge--${props.tone}`].join(" ")
|
|
86
110
|
}, [countText.value]) : null]);
|
|
87
111
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"style": style
|
|
91
|
-
}, [dotKind.value ? createVNode("span", {
|
|
112
|
+
const classes = ["mh-badge", `mh-badge--${props.tone}`, `mh-badge--${props.shape}`, `mh-badge--${props.size}`, dotKind.value ? `mh-badge--dot-${dotKind.value}` : "", extra].filter(Boolean).join(" ");
|
|
113
|
+
const content = createVNode(Fragment, null, [dotKind.value ? createVNode("span", {
|
|
92
114
|
"class": "mh-badge__dot"
|
|
93
115
|
}, null) : null, slots.default?.()]);
|
|
116
|
+
if (props.as === "button") {
|
|
117
|
+
return createVNode("button", mergeProps(forwardAttrs.value, {
|
|
118
|
+
"type": "button",
|
|
119
|
+
"class": classes,
|
|
120
|
+
"style": style
|
|
121
|
+
}), [content]);
|
|
122
|
+
}
|
|
123
|
+
return createVNode("span", mergeProps(forwardAttrs.value, {
|
|
124
|
+
"class": classes,
|
|
125
|
+
"style": style
|
|
126
|
+
}), [content]);
|
|
94
127
|
};
|
|
95
128
|
}
|
|
96
129
|
});
|
|
@@ -76,7 +76,7 @@ export type CardHeaderIcon = string | (() => VNodeChild);
|
|
|
76
76
|
* @example 技能卡(图标 + 标题/副标题 + 右端状态 + 正文 + 操作行)
|
|
77
77
|
* <Card>
|
|
78
78
|
* <Card.Header icon={skill.icon} title={skill.name} subtitle={`V${skill.version}`}>
|
|
79
|
-
* <template #extra><
|
|
79
|
+
* <template #extra><Badge shape="soft" tone="success">已发布</Badge></template>
|
|
80
80
|
* </Card.Header>
|
|
81
81
|
* <Card.Body>{skill.description}</Card.Body>
|
|
82
82
|
* <template #actions><Button size="sm">编辑</Button></template>
|
|
@@ -221,6 +221,7 @@ export declare const Drawer: import("vue").DefineComponent<import("vue").Extract
|
|
|
221
221
|
onClose: () => void;
|
|
222
222
|
width: string | number;
|
|
223
223
|
closable: boolean;
|
|
224
|
+
side: DrawerSide;
|
|
224
225
|
closeOnBackdrop: boolean;
|
|
225
226
|
maskClosable: boolean;
|
|
226
227
|
keyboard: boolean;
|
|
@@ -230,7 +231,6 @@ export declare const Drawer: import("vue").DefineComponent<import("vue").Extract
|
|
|
230
231
|
confirmLoading: boolean;
|
|
231
232
|
showFooter: boolean | undefined;
|
|
232
233
|
onOk: () => unknown;
|
|
233
|
-
side: DrawerSide;
|
|
234
234
|
}, SlotsType<{
|
|
235
235
|
default?: () => VNodeChild;
|
|
236
236
|
title?: () => VNodeChild;
|
|
@@ -13,6 +13,18 @@ export type FilterValues = Record<string, FilterValue>;
|
|
|
13
13
|
* 会显示占位文案)—— 两条路子的最终视觉一致,见 `docs/components/filter.md`。
|
|
14
14
|
*/
|
|
15
15
|
export declare const FILTER_ALL = "all";
|
|
16
|
+
/**
|
|
17
|
+
* 筛选时机:
|
|
18
|
+
*
|
|
19
|
+
* - `manual`(缺省):值变化只回写快照(`onChange`),查询由**回车 / 「筛选」按钮**显式触发
|
|
20
|
+
* (`onQuery`)—— 适合「几个字段填完再查」的条件区;
|
|
21
|
+
* - `auto`:值变化即查询(发 `onQuery`)—— 适合「改即查」的轻量条件区。
|
|
22
|
+
* 此时**同一次变化不再发 `onChange`**(一个变化只对应一个事件,消费方两处都接也不会查两遍),
|
|
23
|
+
* 且操作区默认不渲染(见 `showReset`)。
|
|
24
|
+
*
|
|
25
|
+
* 两种时机下**值变化都会发 `update:modelValue`**(`v-model` 落地不受时机影响)。
|
|
26
|
+
*/
|
|
27
|
+
export type FilterTrigger = 'manual' | 'auto';
|
|
16
28
|
/**
|
|
17
29
|
* 筛选字段的作用域插槽:控件由消费方渲染,本件交出**归一后**的当前值。
|
|
18
30
|
*
|
|
@@ -56,11 +68,19 @@ export interface FilterProps {
|
|
|
56
68
|
queryText?: string;
|
|
57
69
|
/** 「重置」按钮文案 */
|
|
58
70
|
resetText?: string;
|
|
59
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* 是否渲染「重置」按钮 —— **两档的缺省口径不同**(故本项缺省是 `undefined` 而非 `true`):
|
|
73
|
+
* `manual` 缺省渲染(`:show-reset="false"` 才隐藏);`auto` 缺省**不**渲染(显式传 `true` 才留一颗)。
|
|
74
|
+
*/
|
|
60
75
|
showReset?: boolean;
|
|
61
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* 筛选时机:`manual`(缺省)值变化只回写、查询靠「筛选」按钮 / 字段区回车;
|
|
78
|
+
* `auto` 值变化**即**查询,且操作区默认不渲染(详见组件说明「筛选时机」一节)。
|
|
79
|
+
*/
|
|
80
|
+
trigger?: FilterTrigger;
|
|
81
|
+
/** 条件值变化(快照已归一)。**`auto` 下不发** —— 同一次变化改走 `onQuery` */
|
|
62
82
|
onChange?: (values: FilterValues) => void;
|
|
63
|
-
/** 「筛选」按钮 /
|
|
83
|
+
/** 「筛选」按钮 / 字段区回车(回车只作用于输入框,且不认浮层里的输入);**`auto` 下由值变化触发** */
|
|
64
84
|
onQuery?: (values: FilterValues) => void;
|
|
65
85
|
/** 「重置」按钮:全部条件清空(**不再触发 `onChange`**,避免与重置回调双触发) */
|
|
66
86
|
onReset?: (values: FilterValues) => void;
|
|
@@ -175,9 +195,24 @@ export declare const Filter: {
|
|
|
175
195
|
type: StringConstructor;
|
|
176
196
|
default: string;
|
|
177
197
|
};
|
|
198
|
+
/**
|
|
199
|
+
* 是否渲染「重置」按钮。**缺省值随时机而变**(故本 prop 缺省是 `undefined`,不是 `true`):
|
|
200
|
+
*
|
|
201
|
+
* - `trigger="manual"`(缺省):缺省**渲染**(只有显式 `:show-reset="false"` 才隐藏);
|
|
202
|
+
* - `trigger="auto"`:缺省**不渲染** —— 自动模式下操作区整块让位给字段,
|
|
203
|
+
* 要留一颗重置按钮就得**显式**写 `show-reset`。
|
|
204
|
+
*
|
|
205
|
+
* 自动模式下一键清空的另一条路是各字段自带的清除位(控件自己的 `clearable`),
|
|
206
|
+
* 或页面级入口(`Form.Header` 的 `extra` 一侧)。
|
|
207
|
+
*/
|
|
178
208
|
showReset: {
|
|
179
209
|
type: BooleanConstructor;
|
|
180
|
-
default:
|
|
210
|
+
default: undefined;
|
|
211
|
+
};
|
|
212
|
+
/** 筛选时机:`manual`(缺省,回车 / 「筛选」按钮查询)/ `auto`(值变化即查询,操作区默认不渲染) */
|
|
213
|
+
trigger: {
|
|
214
|
+
type: PropType<FilterTrigger>;
|
|
215
|
+
default: string;
|
|
181
216
|
};
|
|
182
217
|
onChange: {
|
|
183
218
|
type: PropType<(values: FilterValues) => void>;
|
|
@@ -202,6 +237,7 @@ export declare const Filter: {
|
|
|
202
237
|
defaultValue: FilterValues;
|
|
203
238
|
modelValue: FilterValues;
|
|
204
239
|
description: string;
|
|
240
|
+
trigger: FilterTrigger;
|
|
205
241
|
labelWidth: number;
|
|
206
242
|
queryText: string;
|
|
207
243
|
resetText: string;
|
|
@@ -245,9 +281,24 @@ export declare const Filter: {
|
|
|
245
281
|
type: StringConstructor;
|
|
246
282
|
default: string;
|
|
247
283
|
};
|
|
284
|
+
/**
|
|
285
|
+
* 是否渲染「重置」按钮。**缺省值随时机而变**(故本 prop 缺省是 `undefined`,不是 `true`):
|
|
286
|
+
*
|
|
287
|
+
* - `trigger="manual"`(缺省):缺省**渲染**(只有显式 `:show-reset="false"` 才隐藏);
|
|
288
|
+
* - `trigger="auto"`:缺省**不渲染** —— 自动模式下操作区整块让位给字段,
|
|
289
|
+
* 要留一颗重置按钮就得**显式**写 `show-reset`。
|
|
290
|
+
*
|
|
291
|
+
* 自动模式下一键清空的另一条路是各字段自带的清除位(控件自己的 `clearable`),
|
|
292
|
+
* 或页面级入口(`Form.Header` 的 `extra` 一侧)。
|
|
293
|
+
*/
|
|
248
294
|
showReset: {
|
|
249
295
|
type: BooleanConstructor;
|
|
250
|
-
default:
|
|
296
|
+
default: undefined;
|
|
297
|
+
};
|
|
298
|
+
/** 筛选时机:`manual`(缺省,回车 / 「筛选」按钮查询)/ `auto`(值变化即查询,操作区默认不渲染) */
|
|
299
|
+
trigger: {
|
|
300
|
+
type: PropType<FilterTrigger>;
|
|
301
|
+
default: string;
|
|
251
302
|
};
|
|
252
303
|
onChange: {
|
|
253
304
|
type: PropType<(values: FilterValues) => void>;
|
|
@@ -270,6 +321,7 @@ export declare const Filter: {
|
|
|
270
321
|
defaultValue: FilterValues;
|
|
271
322
|
modelValue: FilterValues;
|
|
272
323
|
description: string;
|
|
324
|
+
trigger: FilterTrigger;
|
|
273
325
|
labelWidth: number;
|
|
274
326
|
queryText: string;
|
|
275
327
|
resetText: string;
|
|
@@ -308,9 +360,24 @@ export declare const Filter: {
|
|
|
308
360
|
type: StringConstructor;
|
|
309
361
|
default: string;
|
|
310
362
|
};
|
|
363
|
+
/**
|
|
364
|
+
* 是否渲染「重置」按钮。**缺省值随时机而变**(故本 prop 缺省是 `undefined`,不是 `true`):
|
|
365
|
+
*
|
|
366
|
+
* - `trigger="manual"`(缺省):缺省**渲染**(只有显式 `:show-reset="false"` 才隐藏);
|
|
367
|
+
* - `trigger="auto"`:缺省**不渲染** —— 自动模式下操作区整块让位给字段,
|
|
368
|
+
* 要留一颗重置按钮就得**显式**写 `show-reset`。
|
|
369
|
+
*
|
|
370
|
+
* 自动模式下一键清空的另一条路是各字段自带的清除位(控件自己的 `clearable`),
|
|
371
|
+
* 或页面级入口(`Form.Header` 的 `extra` 一侧)。
|
|
372
|
+
*/
|
|
311
373
|
showReset: {
|
|
312
374
|
type: BooleanConstructor;
|
|
313
|
-
default:
|
|
375
|
+
default: undefined;
|
|
376
|
+
};
|
|
377
|
+
/** 筛选时机:`manual`(缺省,回车 / 「筛选」按钮查询)/ `auto`(值变化即查询,操作区默认不渲染) */
|
|
378
|
+
trigger: {
|
|
379
|
+
type: PropType<FilterTrigger>;
|
|
380
|
+
default: string;
|
|
314
381
|
};
|
|
315
382
|
onChange: {
|
|
316
383
|
type: PropType<(values: FilterValues) => void>;
|
|
@@ -335,6 +402,7 @@ export declare const Filter: {
|
|
|
335
402
|
defaultValue: FilterValues;
|
|
336
403
|
modelValue: FilterValues;
|
|
337
404
|
description: string;
|
|
405
|
+
trigger: FilterTrigger;
|
|
338
406
|
labelWidth: number;
|
|
339
407
|
queryText: string;
|
|
340
408
|
resetText: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, createVNode, ref, h, Fragment } from "vue";
|
|
1
|
+
import { defineComponent, createVNode, ref, computed, h, Fragment } from "vue";
|
|
2
2
|
import { Button } from "../button/index.js";
|
|
3
3
|
import { FormItem, Form } from "../form/index.js";
|
|
4
4
|
const FILTER_ALL = "all";
|
|
@@ -50,9 +50,24 @@ const FilterRoot = /* @__PURE__ */ defineComponent({
|
|
|
50
50
|
type: String,
|
|
51
51
|
default: "重置"
|
|
52
52
|
},
|
|
53
|
+
/**
|
|
54
|
+
* 是否渲染「重置」按钮。**缺省值随时机而变**(故本 prop 缺省是 `undefined`,不是 `true`):
|
|
55
|
+
*
|
|
56
|
+
* - `trigger="manual"`(缺省):缺省**渲染**(只有显式 `:show-reset="false"` 才隐藏);
|
|
57
|
+
* - `trigger="auto"`:缺省**不渲染** —— 自动模式下操作区整块让位给字段,
|
|
58
|
+
* 要留一颗重置按钮就得**显式**写 `show-reset`。
|
|
59
|
+
*
|
|
60
|
+
* 自动模式下一键清空的另一条路是各字段自带的清除位(控件自己的 `clearable`),
|
|
61
|
+
* 或页面级入口(`Form.Header` 的 `extra` 一侧)。
|
|
62
|
+
*/
|
|
53
63
|
showReset: {
|
|
54
64
|
type: Boolean,
|
|
55
|
-
default:
|
|
65
|
+
default: void 0
|
|
66
|
+
},
|
|
67
|
+
/** 筛选时机:`manual`(缺省,回车 / 「筛选」按钮查询)/ `auto`(值变化即查询,操作区默认不渲染) */
|
|
68
|
+
trigger: {
|
|
69
|
+
type: String,
|
|
70
|
+
default: "manual"
|
|
56
71
|
},
|
|
57
72
|
onChange: {
|
|
58
73
|
type: Function,
|
|
@@ -82,6 +97,10 @@ const FilterRoot = /* @__PURE__ */ defineComponent({
|
|
|
82
97
|
if (clearing) return;
|
|
83
98
|
const snapshot2 = normalizeValues(values);
|
|
84
99
|
emit("update:modelValue", snapshot2);
|
|
100
|
+
if (props.trigger === "auto") {
|
|
101
|
+
props.onQuery?.(snapshot2);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
85
104
|
props.onChange?.(snapshot2);
|
|
86
105
|
};
|
|
87
106
|
const snapshot = () => normalizeValues(formRef.value?.getValues());
|
|
@@ -101,12 +120,14 @@ const FilterRoot = /* @__PURE__ */ defineComponent({
|
|
|
101
120
|
event.preventDefault();
|
|
102
121
|
query();
|
|
103
122
|
};
|
|
104
|
-
const
|
|
123
|
+
const showResetButton = computed(() => props.trigger === "auto" ? props.showReset === true : props.showReset !== false);
|
|
124
|
+
const hasActions = computed(() => props.trigger === "manual" || showResetButton.value);
|
|
125
|
+
const renderActions = () => createVNode(Fragment, null, [props.trigger === "manual" ? createVNode(Button, {
|
|
105
126
|
"variant": "primary",
|
|
106
127
|
"onClick": query
|
|
107
128
|
}, {
|
|
108
129
|
default: () => props.queryText
|
|
109
|
-
}),
|
|
130
|
+
}) : null, showResetButton.value ? createVNode(Button, {
|
|
110
131
|
"variant": "secondary",
|
|
111
132
|
"onClick": reset
|
|
112
133
|
}, {
|
|
@@ -126,12 +147,19 @@ const FilterRoot = /* @__PURE__ */ defineComponent({
|
|
|
126
147
|
default: () => {
|
|
127
148
|
const raw = slots.default?.();
|
|
128
149
|
const fields = Array.isArray(raw) ? raw : raw == null ? [] : [raw];
|
|
129
|
-
return [h(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
150
|
+
return [h(
|
|
151
|
+
Form.Header,
|
|
152
|
+
{
|
|
153
|
+
title: props.title,
|
|
154
|
+
description: props.description
|
|
155
|
+
},
|
|
156
|
+
/* 没有任何按钮时**不传** `extra`:`Form.Header` 认的是「插槽有没有传」,
|
|
157
|
+
传一个渲染成空的 slot 仍会撑出一行(右端空容器 + 一档行距),
|
|
158
|
+
且三样都没有时整块还会照常占位。 */
|
|
159
|
+
hasActions.value ? {
|
|
160
|
+
extra: renderActions
|
|
161
|
+
} : {}
|
|
162
|
+
), ...fields];
|
|
135
163
|
}
|
|
136
164
|
});
|
|
137
165
|
}
|
|
@@ -133,6 +133,21 @@ export interface FormItemProps {
|
|
|
133
133
|
error?: string;
|
|
134
134
|
/** 字段说明文案(常驻,排在错误之后) */
|
|
135
135
|
hint?: string;
|
|
136
|
+
/**
|
|
137
|
+
* **label 旁的提示**(问号图标 + 悬停气泡,仅文本)。
|
|
138
|
+
*
|
|
139
|
+
* 与 `hint` 分工不同:`hint` 是**常驻**在控件下方的说明文案,`tip` 是**按需展开**的补充解释 ——
|
|
140
|
+
* 不占版面,只在悬停(或键盘聚焦)问号图标时出现,两者可以同时给。
|
|
141
|
+
*
|
|
142
|
+
* 图标排在 label 文本与必填星号**之后**(`服务名称*ⓘ`);只给 `tip` 而不给 `label` 时同样保留
|
|
143
|
+
* label 列(与「只给 required」同一判据)—— 否则图标没有列可落、静默消失。
|
|
144
|
+
*
|
|
145
|
+
* 用的是 `Tooltip` 的 **hover 档**(零 JS):显隐与定位全在 CSS,移入 / 聚焦即显、移开即隐,
|
|
146
|
+
* 因此**不吃点击、不抢焦点**。代价一条:hover 档不进浏览器顶层浮层,会被祖先 `overflow` 裁切
|
|
147
|
+
* —— 弹窗 / 抽屉里贴着裁剪边的字段可能看不全(要顶层浮层就得换 `Tooltip trigger="click"`,
|
|
148
|
+
* 本件有意不暴露该维度,见文件头「label 提示」)。
|
|
149
|
+
*/
|
|
150
|
+
tip?: string;
|
|
136
151
|
/** 本行 label 列宽(px);覆盖 `Form` 的表单级设置 */
|
|
137
152
|
labelWidth?: number;
|
|
138
153
|
/** 本行 label 对齐;覆盖 `Form` 的表单级设置 */
|
|
@@ -205,6 +220,18 @@ export interface FormItemProps {
|
|
|
205
220
|
* `{ y, x }` 上下 / 左右分别给,缺省 0(贴容器边)。页面里的表单在 `Panel.Body` 里、内距由那块给;
|
|
206
221
|
* **弹窗 / 抽屉里没有别的容器**给内距,就用表单自带的 `padding={{ y: 16, x: 20 }}`。
|
|
207
222
|
*
|
|
223
|
+
* ## label 提示(`tip`)
|
|
224
|
+
*
|
|
225
|
+
* 字段名(与必填星号)之后挂一枚问号图标,悬停 / 键盘聚焦弹出说明气泡。它是**按需展开**的补充
|
|
226
|
+
* 解释,不占版面;常驻说明仍归 `hint`(排在控件下方)。两者分工不同,也**不互相替代**。
|
|
227
|
+
*
|
|
228
|
+
* - 图标取 `@manohub/icon` 的 `help`(带圈问号),尺寸随主题图标档(`--ui-font-icon`);
|
|
229
|
+
* - 图标**排在星号之后**(`服务名称*ⓘ`)—— 与「星号跟着字段名走」同一口径;
|
|
230
|
+
* - 只给 `tip`(无 `label`、非必填)时**同样保留 label 列**(与「只给 required」同一判据),
|
|
231
|
+
* 否则图标没有列可落、静默消失;
|
|
232
|
+
* - 气泡用 `Tooltip` 的 **hover 档**(零 JS):不吃点击、不抢焦点;代价是 hover 档不进浏览器
|
|
233
|
+
* 顶层浮层,会被祖先 `overflow` 裁切(弹窗 / 抽屉里贴着裁剪边的字段可能看不全)。
|
|
234
|
+
*
|
|
208
235
|
* ## 键盘事件(`onKeydown` 转发到根节点)
|
|
209
236
|
*
|
|
210
237
|
* `onKeydown` 是本件的**声明式入口**(缺省不绑):传进来的处理器绑在根节点上 ——
|
|
@@ -238,7 +265,7 @@ export interface FormItemProps {
|
|
|
238
265
|
* <Form.Item label="编码" required error={errors.code} hint="保存后不可修改">
|
|
239
266
|
* <Input modelValue={form.code} onChange={(v) => (form.code = v)} />
|
|
240
267
|
* </Form.Item>
|
|
241
|
-
* <Form.Item label="缓存策略" controlWidth={360}>
|
|
268
|
+
* <Form.Item label="缓存策略" controlWidth={360} tip="命中即不请求后端">
|
|
242
269
|
* <Select options={cacheOptions} modelValue={form.cache} onChange={…} />
|
|
243
270
|
* </Form.Item>
|
|
244
271
|
* <Form.Item label="过滤条件" fullWidth>
|
|
@@ -268,6 +295,11 @@ export declare const FormItem: import("vue").DefineComponent<import("vue").Extra
|
|
|
268
295
|
type: StringConstructor;
|
|
269
296
|
default: string;
|
|
270
297
|
};
|
|
298
|
+
/** label 旁的提示文案(问号图标 + 悬停气泡);口径见 `FormItemProps.tip` */
|
|
299
|
+
tip: {
|
|
300
|
+
type: StringConstructor;
|
|
301
|
+
default: string;
|
|
302
|
+
};
|
|
271
303
|
labelWidth: {
|
|
272
304
|
type: NumberConstructor;
|
|
273
305
|
default: undefined;
|
|
@@ -316,6 +348,11 @@ export declare const FormItem: import("vue").DefineComponent<import("vue").Extra
|
|
|
316
348
|
type: StringConstructor;
|
|
317
349
|
default: string;
|
|
318
350
|
};
|
|
351
|
+
/** label 旁的提示文案(问号图标 + 悬停气泡);口径见 `FormItemProps.tip` */
|
|
352
|
+
tip: {
|
|
353
|
+
type: StringConstructor;
|
|
354
|
+
default: string;
|
|
355
|
+
};
|
|
319
356
|
labelWidth: {
|
|
320
357
|
type: NumberConstructor;
|
|
321
358
|
default: undefined;
|
|
@@ -350,6 +387,7 @@ export declare const FormItem: import("vue").DefineComponent<import("vue").Extra
|
|
|
350
387
|
align: FormItemAlign;
|
|
351
388
|
readonly: boolean;
|
|
352
389
|
hint: string;
|
|
390
|
+
tip: string;
|
|
353
391
|
labelWidth: number;
|
|
354
392
|
labelAlign: FormLabelAlign;
|
|
355
393
|
controlWidth: number;
|
|
@@ -730,6 +768,11 @@ export declare const Form: {
|
|
|
730
768
|
type: StringConstructor;
|
|
731
769
|
default: string;
|
|
732
770
|
};
|
|
771
|
+
/** label 旁的提示文案(问号图标 + 悬停气泡);口径见 `FormItemProps.tip` */
|
|
772
|
+
tip: {
|
|
773
|
+
type: StringConstructor;
|
|
774
|
+
default: string;
|
|
775
|
+
};
|
|
733
776
|
labelWidth: {
|
|
734
777
|
type: NumberConstructor;
|
|
735
778
|
default: undefined;
|
|
@@ -778,6 +821,11 @@ export declare const Form: {
|
|
|
778
821
|
type: StringConstructor;
|
|
779
822
|
default: string;
|
|
780
823
|
};
|
|
824
|
+
/** label 旁的提示文案(问号图标 + 悬停气泡);口径见 `FormItemProps.tip` */
|
|
825
|
+
tip: {
|
|
826
|
+
type: StringConstructor;
|
|
827
|
+
default: string;
|
|
828
|
+
};
|
|
781
829
|
labelWidth: {
|
|
782
830
|
type: NumberConstructor;
|
|
783
831
|
default: undefined;
|
|
@@ -812,6 +860,7 @@ export declare const Form: {
|
|
|
812
860
|
align: FormItemAlign;
|
|
813
861
|
readonly: boolean;
|
|
814
862
|
hint: string;
|
|
863
|
+
tip: string;
|
|
815
864
|
labelWidth: number;
|
|
816
865
|
labelAlign: FormLabelAlign;
|
|
817
866
|
controlWidth: number;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { defineComponent, inject, watch, createVNode, createTextVNode, provide, toRef, ref, computed, isVNode } from "vue";
|
|
2
|
+
import { Icon } from "@manohub/icon";
|
|
2
3
|
import { mergePartStyle } from "../part-padding.js";
|
|
4
|
+
import { Tooltip } from "../tooltip/index.js";
|
|
3
5
|
const FORM_LABEL_WIDTH = /* @__PURE__ */ Symbol("mh-form-label-width");
|
|
4
6
|
const FORM_CONTROL_WIDTH = /* @__PURE__ */ Symbol("mh-form-control-width");
|
|
5
7
|
const FORM_LABEL_ALIGN = /* @__PURE__ */ Symbol("mh-form-label-align");
|
|
@@ -29,6 +31,11 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
29
31
|
type: String,
|
|
30
32
|
default: ""
|
|
31
33
|
},
|
|
34
|
+
/** label 旁的提示文案(问号图标 + 悬停气泡);口径见 `FormItemProps.tip` */
|
|
35
|
+
tip: {
|
|
36
|
+
type: String,
|
|
37
|
+
default: ""
|
|
38
|
+
},
|
|
32
39
|
labelWidth: {
|
|
33
40
|
type: Number,
|
|
34
41
|
default: void 0
|
|
@@ -85,7 +92,7 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
85
92
|
const styles = [attrs.style, labelWidth ? {
|
|
86
93
|
"--mh-form-label-width": `${labelWidth}px`
|
|
87
94
|
} : null].filter(Boolean);
|
|
88
|
-
const showLabel = !!props.label || props.required;
|
|
95
|
+
const showLabel = !!props.label || props.required || !!props.tip;
|
|
89
96
|
return createVNode("div", {
|
|
90
97
|
"class": [
|
|
91
98
|
"mh-form-item",
|
|
@@ -109,7 +116,18 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
109
116
|
"class": "mh-form-item__label-text"
|
|
110
117
|
}, [props.label]), props.required ? createVNode("span", {
|
|
111
118
|
"class": "mh-form-item__required"
|
|
112
|
-
}, [createTextVNode("*")]) : null
|
|
119
|
+
}, [createTextVNode("*")]) : null, props.tip ? createVNode(Tooltip, {
|
|
120
|
+
"class": "mh-form-item__tip",
|
|
121
|
+
"content": props.tip
|
|
122
|
+
}, {
|
|
123
|
+
default: () => [createVNode("button", {
|
|
124
|
+
"type": "button",
|
|
125
|
+
"class": "mh-form-item__tip-btn",
|
|
126
|
+
"aria-label": props.tip
|
|
127
|
+
}, [createVNode(Icon, {
|
|
128
|
+
"name": "help"
|
|
129
|
+
}, null)])]
|
|
130
|
+
}) : null]) : null, createVNode("div", {
|
|
113
131
|
"class": "mh-form-item__control",
|
|
114
132
|
"style": controlWidth ? {
|
|
115
133
|
maxWidth: `${controlWidth}px`
|
|
@@ -168,6 +168,7 @@ const Input = /* @__PURE__ */ defineComponent({
|
|
|
168
168
|
if (props.modelValue !== void 0 && props.modelValue !== el.value) el.value = props.modelValue;
|
|
169
169
|
};
|
|
170
170
|
const onKeydown = (event) => {
|
|
171
|
+
if (event.isComposing) return;
|
|
171
172
|
if (event.key === "Enter") props.onEnter?.(current.value ?? "");
|
|
172
173
|
if (event.key === "Delete" && props.clearable) commit("");
|
|
173
174
|
};
|
|
@@ -27,6 +27,11 @@ export type NavVariant = 'tree' | 'list';
|
|
|
27
27
|
* `renderActions` 直接透传给 `Tree`:默认隐藏、行悬浮或行内获得焦点时显形、点击不冒泡(§4.16)。
|
|
28
28
|
* 应用侧只给节点,不要自己写显隐 CSS,也不要把它塞进 `renderNode`(那是常驻附加内容)。
|
|
29
29
|
*
|
|
30
|
+
* ## 图标
|
|
31
|
+
*
|
|
32
|
+
* 导航项图标走 `renderIcon`(标签前的一位图标,口径同 `Tree.renderIcon`)—— **不要**用
|
|
33
|
+
* `renderLabel` 拼「图标 + 文字」:标签槽承担省略号与行内对齐,图标进去会被裁掉,也不成列。
|
|
34
|
+
*
|
|
30
35
|
* @example 分类导航树(选中驱动右侧 + 行尾管理操作)
|
|
31
36
|
* <Nav variant="tree" nodes={categoryNodes.value} rowKey="id" labelKey="name" width={220}
|
|
32
37
|
* selected={categoryId.value} onSelect={(node) => (categoryId.value = node.id)}
|
|
@@ -89,6 +94,16 @@ export declare const Nav: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
89
94
|
type: PropType<(node: TreeNode) => unknown>;
|
|
90
95
|
default: undefined;
|
|
91
96
|
};
|
|
97
|
+
/** 导航项图标(标签前的一位图标):见 `Tree.renderIcon`(侧栏图标走这一位,不要塞进 `renderLabel`) */
|
|
98
|
+
renderIcon: {
|
|
99
|
+
type: PropType<(node: TreeNode) => unknown>;
|
|
100
|
+
default: undefined;
|
|
101
|
+
};
|
|
102
|
+
/** 展开 / 收起箭头字形:见 `Tree.renderCaret`(`list` 态箭头位被隐藏,传了也不显形) */
|
|
103
|
+
renderCaret: {
|
|
104
|
+
type: PropType<(node: TreeNode, expanded: boolean) => unknown>;
|
|
105
|
+
default: undefined;
|
|
106
|
+
};
|
|
92
107
|
/** 侧栏标题(可选;不传则只有导航体) */
|
|
93
108
|
title: {
|
|
94
109
|
type: StringConstructor;
|
|
@@ -206,6 +221,16 @@ export declare const Nav: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
206
221
|
type: PropType<(node: TreeNode) => unknown>;
|
|
207
222
|
default: undefined;
|
|
208
223
|
};
|
|
224
|
+
/** 导航项图标(标签前的一位图标):见 `Tree.renderIcon`(侧栏图标走这一位,不要塞进 `renderLabel`) */
|
|
225
|
+
renderIcon: {
|
|
226
|
+
type: PropType<(node: TreeNode) => unknown>;
|
|
227
|
+
default: undefined;
|
|
228
|
+
};
|
|
229
|
+
/** 展开 / 收起箭头字形:见 `Tree.renderCaret`(`list` 态箭头位被隐藏,传了也不显形) */
|
|
230
|
+
renderCaret: {
|
|
231
|
+
type: PropType<(node: TreeNode, expanded: boolean) => unknown>;
|
|
232
|
+
default: undefined;
|
|
233
|
+
};
|
|
209
234
|
/** 侧栏标题(可选;不传则只有导航体) */
|
|
210
235
|
title: {
|
|
211
236
|
type: StringConstructor;
|
|
@@ -285,6 +310,8 @@ export declare const Nav: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
285
310
|
onErrorAction: () => void;
|
|
286
311
|
labelKey: string;
|
|
287
312
|
childrenKey: string;
|
|
313
|
+
renderCaret: (node: TreeNode, expanded: boolean) => unknown;
|
|
314
|
+
renderIcon: (node: TreeNode) => unknown;
|
|
288
315
|
renderActions: (node: TreeNode) => unknown;
|
|
289
316
|
expandedKeys: string[];
|
|
290
317
|
defaultExpandedKeys: string[];
|