@shwfed/config 2.3.26 → 2.3.28

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 (84) hide show
  1. package/dist/mcp.mjs +1211 -701
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{config-BkimX91E.js → config--PcXQV_r.js} +1 -1
  4. package/dist/preview/assets/{config-CO2iovZD.js → config-5KVDXgUF.js} +1 -1
  5. package/dist/preview/assets/{config-u1rl9w2L.js → config-B5avpKJE.js} +1 -1
  6. package/dist/preview/assets/{config-DgZ4NYoA.js → config-CJHPt8Gx.js} +1 -1
  7. package/dist/preview/assets/{config-ypYLVfRE.js → config-CNo3isHa.js} +1 -1
  8. package/dist/preview/assets/{config-Cm9t0CvW.js → config-CQHS6cZe.js} +1 -1
  9. package/dist/preview/assets/{config-DPFHMkHc.js → config-D0_1yZdF.js} +1 -1
  10. package/dist/preview/assets/{config-Dzqe6v-x.js → config-DDfTl9Cs.js} +1 -1
  11. package/dist/preview/assets/{config-BATy87wV.js → config-fvkC2rB8.js} +1 -1
  12. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-CliXxe84.js → definition.vue_vue_type_script_setup_true_lang-RM-qDh0R.js} +1 -1
  13. package/dist/preview/assets/index-DNd8J9Zv.js +643 -0
  14. package/dist/preview/assets/index-DrIMqXAa.js +1 -0
  15. package/dist/preview/assets/index-a2QwAots.css +1 -0
  16. package/dist/preview/assets/{runtime-Dtc1ETUF.js → runtime-BGTWf-O7.js} +1 -1
  17. package/dist/preview/assets/{runtime-B_FMZ5eD.js → runtime-BPjZQmcY.js} +1 -1
  18. package/dist/preview/assets/{runtime-BTROwcw4.js → runtime-Bq3fmxeF.js} +1 -1
  19. package/dist/preview/assets/{runtime-Dsx8Y56q.js → runtime-CCbyrqQT.js} +1 -1
  20. package/dist/preview/assets/{runtime-T_tUqLxO.js → runtime-C_XX6a0C.js} +1 -1
  21. package/dist/preview/assets/{runtime-BR6-W3u_.js → runtime-CtqwtTE_.js} +1 -1
  22. package/dist/preview/assets/{runtime-D1xLbTQ9.js → runtime-DcrzodsN.js} +1 -1
  23. package/dist/preview/assets/{runtime-CTpsTb-X.js → runtime-Dr_10emf.js} +1 -1
  24. package/dist/preview/assets/{runtime-Cj0kLSqP.js → runtime-Dy4ZmQ-n.js} +1 -1
  25. package/dist/preview/index.html +2 -2
  26. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/config.d.vue.ts +2 -0
  27. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/config.vue +57 -3
  28. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/config.vue.d.ts +2 -0
  29. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/runtime.d.vue.ts +2 -0
  30. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/runtime.vue +1 -0
  31. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/runtime.vue.d.ts +2 -0
  32. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/schema.d.ts +2 -0
  33. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.tabs/schema.js +4 -0
  34. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +4 -4
  35. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +4 -4
  36. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +127 -0
  37. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue +593 -0
  38. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +127 -0
  39. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/runtime.d.vue.ts +8 -0
  40. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/runtime.vue +465 -0
  41. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/runtime.vue.d.ts +8 -0
  42. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/schema.d.ts +95 -0
  43. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/schema.js +112 -0
  44. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +125 -0
  45. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue +525 -0
  46. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +125 -0
  47. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/runtime.d.vue.ts +8 -0
  48. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/runtime.vue +460 -0
  49. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/runtime.vue.d.ts +8 -0
  50. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/schema.d.ts +92 -0
  51. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/schema.js +104 -0
  52. package/dist/runtime/components/form/fields/2026-05-26/tree-combobox-shared.d.ts +35 -0
  53. package/dist/runtime/components/form/fields/2026-05-26/tree-combobox-shared.js +31 -0
  54. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/runtime.vue +36 -13
  55. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/runtime.vue +36 -12
  56. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/runtime.vue +0 -1
  57. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +131 -0
  58. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue +607 -0
  59. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +131 -0
  60. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/runtime.d.vue.ts +9 -0
  61. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/runtime.vue +447 -0
  62. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/runtime.vue.d.ts +9 -0
  63. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/schema.d.ts +90 -0
  64. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/schema.js +143 -0
  65. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +129 -0
  66. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue +538 -0
  67. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +129 -0
  68. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/runtime.d.vue.ts +9 -0
  69. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/runtime.vue +429 -0
  70. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/runtime.vue.d.ts +9 -0
  71. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/schema.d.ts +87 -0
  72. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/schema.js +135 -0
  73. package/dist/runtime/components/table/columns/2026-05-27/tree-combobox-shared.d.ts +35 -0
  74. package/dist/runtime/components/table/columns/2026-05-27/tree-combobox-shared.js +31 -0
  75. package/dist/runtime/components/table/config.vue +29 -0
  76. package/dist/runtime/components/ui/command/CommandItem.vue +12 -4
  77. package/dist/runtime/components/ui/tree/Tree.d.vue.ts +2 -0
  78. package/dist/runtime/components/ui/tree/Tree.vue +7 -2
  79. package/dist/runtime/components/ui/tree/Tree.vue.d.ts +2 -0
  80. package/dist/runtime/components/ui/tree/TreeNode.vue +16 -26
  81. package/package.json +1 -1
  82. package/dist/preview/assets/index-6rM4rqXR.js +0 -1
  83. package/dist/preview/assets/index-BCE-G4Ha.css +0 -1
  84. package/dist/preview/assets/index-wBVA0mNO.js +0 -643
@@ -0,0 +1,593 @@
1
+ <script setup>
2
+ import { computed, ref, watch } from "vue";
3
+ import { ExpressionEditor } from "../../../../ui/expression-editor";
4
+ import DerivedValueEditor from "../../../DerivedValueEditor.vue";
5
+ import { Field, FieldLabel } from "../../../../ui/field";
6
+ import { InputGroup, InputGroupInput } from "../../../../ui/input-group";
7
+ import { Locale as LocaleField } from "../../../../ui/locale";
8
+ import { Markdown } from "../../../../ui/markdown";
9
+ import {
10
+ Select,
11
+ SelectContent,
12
+ SelectItem,
13
+ SelectTrigger,
14
+ SelectValue
15
+ } from "../../../../ui/select";
16
+ import { Switch } from "../../../../ui/switch";
17
+ import { getStructFieldDescription, getStructFieldTitle } from "../../../schema";
18
+ import { DEFAULT_FIELD_ORIENTATION, FIELD_ORIENTATION_OPTIONS } from "../../../utils/common";
19
+ import { DataSource } from "../../../../table/schema";
20
+ import { schema } from "./schema";
21
+ defineOptions({ name: "ShwfedTreeComboboxMultiFieldConfig" });
22
+ const value = defineModel({ type: null, ...{ required: true } });
23
+ const fieldSchema = schema(() => {
24
+ });
25
+ const fieldTitle = (f) => getStructFieldTitle(fieldSchema, f) ?? f;
26
+ const fieldDescription = (f) => getStructFieldDescription(fieldSchema, f);
27
+ const dataSourceSchema = DataSource(() => {
28
+ });
29
+ const dataSourceFieldTitle = (f) => getStructFieldTitle(dataSourceSchema, f) ?? f;
30
+ const dataSourceFieldDescription = (f) => getStructFieldDescription(dataSourceSchema, f);
31
+ const nodeExtraVars = {
32
+ node: {
33
+ type: "dyn",
34
+ label: "\u5F53\u524D\u8282\u70B9",
35
+ description: "\u7531 `\u6570\u636E` \u8868\u8FBE\u5F0F\u8FD4\u56DE\u7684\u6BCF\u4E00\u9879\uFF1B\u7C7B\u578B\u5728\u914D\u7F6E\u65F6\u672A\u77E5\uFF08`dyn`\uFF09"
36
+ }
37
+ };
38
+ const nodeJsonExtraVars = {
39
+ json: {
40
+ type: "optional<dyn>",
41
+ label: "HTTP \u54CD\u5E94\u4F53",
42
+ description: "\u5DF2\u89E3\u6790\u7684 JSON \u54CD\u5E94\uFF1B\u672A\u914D\u7F6E `request` \u65F6\u4E3A `none`"
43
+ }
44
+ };
45
+ const bindingText = computed({
46
+ get: () => value.value.binding ?? "",
47
+ set: (next) => {
48
+ const trimmed = next.trim();
49
+ if (trimmed.length === 0) {
50
+ const { binding: _omit, ...rest } = value.value;
51
+ value.value = rest;
52
+ } else {
53
+ value.value = { ...value.value, binding: trimmed };
54
+ }
55
+ }
56
+ });
57
+ const CASCADE_OPTIONS = [
58
+ {
59
+ value: "independent",
60
+ label: "\u72EC\u7ACB",
61
+ description: "\u52FE\u9009 / \u53D6\u6D88\u53EA\u4F5C\u7528\u4E8E\u5F53\u524D\u8282\u70B9\uFF1B\u7236\u5B50\u4E92\u4E0D\u5F71\u54CD"
62
+ },
63
+ {
64
+ value: "cascade-down",
65
+ label: "\u5411\u4E0B\u7EA7\u8054",
66
+ description: "\u52FE\u9009\u7236\u8282\u70B9\u81EA\u52A8\u52FE\u9009\u5176\u5168\u90E8\u53EF\u9009\u540E\u4EE3\uFF1B\u53D6\u6D88\u65F6\u540C\u7406\u3002\u7236\u8282\u70B9\u7684\u52FE\u9009\u72B6\u6001\u72EC\u7ACB\u8FFD\u8E2A"
67
+ },
68
+ {
69
+ value: "cascade-both",
70
+ label: "\u53CC\u5411\u7EA7\u8054",
71
+ description: "\u5728\u5411\u4E0B\u7EA7\u8054\u57FA\u7840\u4E0A\uFF0C\u7236\u8282\u70B9\u53CD\u6620\u540E\u4EE3\u52FE\u9009\u72B6\u6001\uFF08\u5168\u9009\u2192\u9009\u4E2D\u3001\u90E8\u5206\u2192\u534A\u9009\u3001\u5168\u4E0D\u9009\u2192\u672A\u9009\uFF09"
72
+ }
73
+ ];
74
+ const cascadeOpen = ref(false);
75
+ const hoveredCascade = ref(null);
76
+ watch(cascadeOpen, (isOpen) => {
77
+ hoveredCascade.value = isOpen ? value.value.cascade ?? "independent" : null;
78
+ });
79
+ const hoveredCascadeDescription = computed(
80
+ () => CASCADE_OPTIONS.find((o) => o.value === hoveredCascade.value)?.description
81
+ );
82
+ function setDataSourceData(next) {
83
+ value.value = {
84
+ ...value.value,
85
+ dataSource: { ...value.value.dataSource, data: next }
86
+ };
87
+ }
88
+ function setDataSourceRequest(next) {
89
+ const trimmed = next.trim();
90
+ if (trimmed.length === 0) {
91
+ const { request: _omit, ...rest } = value.value.dataSource;
92
+ value.value = { ...value.value, dataSource: rest };
93
+ } else {
94
+ value.value = {
95
+ ...value.value,
96
+ dataSource: { ...value.value.dataSource, request: next }
97
+ };
98
+ }
99
+ }
100
+ function setOptionalExpression(key, next) {
101
+ if (next.length === 0) {
102
+ const { [key]: _omit, ...rest } = value.value;
103
+ value.value = rest;
104
+ } else {
105
+ value.value = { ...value.value, [key]: next };
106
+ }
107
+ }
108
+ </script>
109
+
110
+ <template>
111
+ <div class="flex flex-col gap-3">
112
+ <!-- Row 1: 内部名称 + 绑定路径 -->
113
+ <div class="grid grid-cols-2 gap-3">
114
+ <Field orientation="vertical">
115
+ <FieldLabel class="text-xs text-zinc-500">
116
+ <template
117
+ v-if="fieldDescription('displayName')"
118
+ #tooltip
119
+ >
120
+ <Markdown
121
+ :source="fieldDescription('displayName')"
122
+ block
123
+ class="prose prose-sm prose-zinc"
124
+ />
125
+ </template>
126
+ {{ fieldTitle("displayName") }}
127
+ </FieldLabel>
128
+ <InputGroup>
129
+ <InputGroupInput
130
+ :model-value="value.displayName ?? ''"
131
+ placeholder="例:所属部门"
132
+ @update:model-value="(v) => {
133
+ const s = String(v ?? '');
134
+ value = { ...value, displayName: s.length > 0 ? s : void 0 };
135
+ }"
136
+ />
137
+ </InputGroup>
138
+ </Field>
139
+
140
+ <Field orientation="vertical">
141
+ <FieldLabel class="text-xs text-zinc-500">
142
+ <template
143
+ v-if="fieldDescription('binding')"
144
+ #tooltip
145
+ >
146
+ <Markdown
147
+ :source="fieldDescription('binding')"
148
+ block
149
+ class="prose prose-sm prose-zinc"
150
+ />
151
+ </template>
152
+ {{ fieldTitle("binding") }}
153
+ </FieldLabel>
154
+ <InputGroup>
155
+ <InputGroupInput
156
+ v-model="bindingText"
157
+ placeholder="例:user.departmentIds"
158
+ class="font-mono"
159
+ />
160
+ </InputGroup>
161
+ </Field>
162
+ </div>
163
+
164
+ <!-- Row 2: 标签 + 占位符 + 提示 -->
165
+ <div class="grid grid-cols-3 gap-3">
166
+ <Field orientation="vertical">
167
+ <FieldLabel class="text-xs text-zinc-500">
168
+ <template
169
+ v-if="fieldDescription('label')"
170
+ #tooltip
171
+ >
172
+ <Markdown
173
+ :source="fieldDescription('label')"
174
+ block
175
+ class="prose prose-sm prose-zinc"
176
+ />
177
+ </template>
178
+ {{ fieldTitle("label") }}
179
+ </FieldLabel>
180
+ <LocaleField
181
+ translate-hint="form field label"
182
+ :model-value="value.label"
183
+ @update:model-value="(v) => value = { ...value, label: v }"
184
+ />
185
+ </Field>
186
+
187
+ <Field orientation="vertical">
188
+ <FieldLabel class="text-xs text-zinc-500">
189
+ <template
190
+ v-if="fieldDescription('placeholder')"
191
+ #tooltip
192
+ >
193
+ <Markdown
194
+ :source="fieldDescription('placeholder')"
195
+ block
196
+ class="prose prose-sm prose-zinc"
197
+ />
198
+ </template>
199
+ {{ fieldTitle("placeholder") }}
200
+ </FieldLabel>
201
+ <LocaleField
202
+ :model-value="value.placeholder"
203
+ @update:model-value="(v) => value = { ...value, placeholder: v }"
204
+ />
205
+ </Field>
206
+
207
+ <Field orientation="vertical">
208
+ <FieldLabel class="text-xs text-zinc-500">
209
+ <template
210
+ v-if="fieldDescription('tooltip')"
211
+ #tooltip
212
+ >
213
+ <Markdown
214
+ :source="fieldDescription('tooltip')"
215
+ block
216
+ class="prose prose-sm prose-zinc"
217
+ />
218
+ </template>
219
+ {{ fieldTitle("tooltip") }}
220
+ </FieldLabel>
221
+ <LocaleField
222
+ markdown
223
+ translate-hint="form field tooltip"
224
+ :model-value="value.tooltip"
225
+ @update:model-value="(v) => value = { ...value, tooltip: v }"
226
+ />
227
+ </Field>
228
+ </div>
229
+
230
+ <!-- Row 3: orientation -->
231
+ <div class="grid grid-cols-3 gap-3">
232
+ <Field orientation="vertical">
233
+ <FieldLabel class="text-xs text-zinc-500">
234
+ <template
235
+ v-if="fieldDescription('orientation')"
236
+ #tooltip
237
+ >
238
+ <Markdown
239
+ :source="fieldDescription('orientation')"
240
+ block
241
+ class="prose prose-sm prose-zinc"
242
+ />
243
+ </template>
244
+ {{ fieldTitle("orientation") }}
245
+ </FieldLabel>
246
+ <Select
247
+ :model-value="value.orientation ?? DEFAULT_FIELD_ORIENTATION"
248
+ @update:model-value="(v) => value = { ...value, orientation: v }"
249
+ >
250
+ <SelectTrigger class="w-full">
251
+ <SelectValue />
252
+ </SelectTrigger>
253
+ <SelectContent>
254
+ <SelectItem
255
+ v-for="opt in FIELD_ORIENTATION_OPTIONS"
256
+ :key="opt.value"
257
+ :value="opt.value"
258
+ >
259
+ {{ opt.label }}
260
+ </SelectItem>
261
+ </SelectContent>
262
+ </Select>
263
+ </Field>
264
+ </div>
265
+
266
+ <!-- 数据源 -->
267
+ <h3 class="text-xs font-medium text-zinc-500">
268
+ {{ fieldTitle("dataSource") }}
269
+ </h3>
270
+
271
+ <Field orientation="vertical">
272
+ <FieldLabel class="text-xs text-zinc-500">
273
+ <template
274
+ v-if="dataSourceFieldDescription('request')"
275
+ #tooltip
276
+ >
277
+ <Markdown
278
+ :source="dataSourceFieldDescription('request')"
279
+ block
280
+ class="prose prose-sm prose-zinc"
281
+ />
282
+ </template>
283
+ {{ dataSourceFieldTitle("request") }}
284
+ </FieldLabel>
285
+ <ExpressionEditor
286
+ :model-value="value.dataSource.request ?? ''"
287
+ placeholder="如 http.get('/api/departments/tree')"
288
+ result-type="HttpRequest"
289
+ multiline
290
+ class="min-h-20"
291
+ @update:model-value="setDataSourceRequest"
292
+ />
293
+ </Field>
294
+
295
+ <Field orientation="vertical">
296
+ <FieldLabel class="text-xs text-zinc-500">
297
+ <template
298
+ v-if="dataSourceFieldDescription('data')"
299
+ #tooltip
300
+ >
301
+ <Markdown
302
+ :source="dataSourceFieldDescription('data')"
303
+ block
304
+ class="prose prose-sm prose-zinc"
305
+ />
306
+ </template>
307
+ {{ dataSourceFieldTitle("data") }}
308
+ </FieldLabel>
309
+ <ExpressionEditor
310
+ :model-value="value.dataSource.data"
311
+ placeholder="如 json.?value.roots.orValue([])"
312
+ result-type="list"
313
+ :extra-vars="nodeJsonExtraVars"
314
+ @update:model-value="setDataSourceData"
315
+ />
316
+ </Field>
317
+
318
+ <!-- 节点 -->
319
+ <h3 class="text-xs font-medium text-zinc-500">
320
+ 节点
321
+ </h3>
322
+
323
+ <div class="grid grid-cols-2 gap-3">
324
+ <Field orientation="vertical">
325
+ <FieldLabel class="text-xs text-zinc-500">
326
+ <template
327
+ v-if="fieldDescription('nodeKey')"
328
+ #tooltip
329
+ >
330
+ <Markdown
331
+ :source="fieldDescription('nodeKey')"
332
+ block
333
+ class="prose prose-sm prose-zinc"
334
+ />
335
+ </template>
336
+ {{ fieldTitle("nodeKey") }}
337
+ </FieldLabel>
338
+ <ExpressionEditor
339
+ :model-value="value.nodeKey"
340
+ placeholder="例:string(node.id)"
341
+ :result-type="['string', 'number', 'dyn']"
342
+ :extra-vars="nodeExtraVars"
343
+ class="min-h-10"
344
+ @update:model-value="(v) => value = { ...value, nodeKey: v }"
345
+ />
346
+ </Field>
347
+
348
+ <Field orientation="vertical">
349
+ <FieldLabel class="text-xs text-zinc-500">
350
+ <template
351
+ v-if="fieldDescription('nodeChildren')"
352
+ #tooltip
353
+ >
354
+ <Markdown
355
+ :source="fieldDescription('nodeChildren')"
356
+ block
357
+ class="prose prose-sm prose-zinc"
358
+ />
359
+ </template>
360
+ {{ fieldTitle("nodeChildren") }}
361
+ </FieldLabel>
362
+ <ExpressionEditor
363
+ :model-value="value.nodeChildren"
364
+ placeholder="例:has(node.children) ? node.children : null"
365
+ result-type="list"
366
+ :extra-vars="nodeExtraVars"
367
+ class="min-h-10"
368
+ @update:model-value="(v) => value = { ...value, nodeChildren: v }"
369
+ />
370
+ </Field>
371
+ </div>
372
+
373
+ <div class="grid grid-cols-2 gap-3">
374
+ <Field orientation="vertical">
375
+ <FieldLabel class="text-xs text-zinc-500">
376
+ <template
377
+ v-if="fieldDescription('nodeLabel')"
378
+ #tooltip
379
+ >
380
+ <Markdown
381
+ :source="fieldDescription('nodeLabel')"
382
+ block
383
+ class="prose prose-sm prose-zinc"
384
+ />
385
+ </template>
386
+ {{ fieldTitle("nodeLabel") }}
387
+ </FieldLabel>
388
+ <LocaleField
389
+ markdown
390
+ translate-hint="tree node label"
391
+ :model-value="value.nodeLabel"
392
+ @update:model-value="(v) => value = { ...value, nodeLabel: v }"
393
+ />
394
+ </Field>
395
+
396
+ <Field orientation="vertical">
397
+ <FieldLabel class="text-xs text-zinc-500">
398
+ <template
399
+ v-if="fieldDescription('nodeTooltip')"
400
+ #tooltip
401
+ >
402
+ <Markdown
403
+ :source="fieldDescription('nodeTooltip')"
404
+ block
405
+ class="prose prose-sm prose-zinc"
406
+ />
407
+ </template>
408
+ {{ fieldTitle("nodeTooltip") }}
409
+ </FieldLabel>
410
+ <LocaleField
411
+ markdown
412
+ translate-hint="tree node tooltip"
413
+ :model-value="value.nodeTooltip"
414
+ @update:model-value="(v) => value = { ...value, nodeTooltip: v }"
415
+ />
416
+ </Field>
417
+ </div>
418
+
419
+ <!-- 行为: 节点可选条件 + 级联模式 + 默认全部展开 -->
420
+ <div class="grid grid-cols-3 gap-3">
421
+ <Field orientation="vertical">
422
+ <FieldLabel class="text-xs text-zinc-500">
423
+ <template
424
+ v-if="fieldDescription('nodeSelectable')"
425
+ #tooltip
426
+ >
427
+ <Markdown
428
+ :source="fieldDescription('nodeSelectable')"
429
+ block
430
+ class="prose prose-sm prose-zinc"
431
+ />
432
+ </template>
433
+ {{ fieldTitle("nodeSelectable") }}
434
+ </FieldLabel>
435
+ <ExpressionEditor
436
+ :model-value="value.nodeSelectable ?? ''"
437
+ placeholder="例:!has(node.disabled) || !node.disabled"
438
+ result-type="bool"
439
+ :extra-vars="nodeExtraVars"
440
+ class="min-h-10"
441
+ @update:model-value="(v) => setOptionalExpression('nodeSelectable', v)"
442
+ />
443
+ </Field>
444
+
445
+ <Field orientation="vertical">
446
+ <FieldLabel class="text-xs text-zinc-500">
447
+ <template
448
+ v-if="fieldDescription('cascade')"
449
+ #tooltip
450
+ >
451
+ <Markdown
452
+ :source="fieldDescription('cascade')"
453
+ block
454
+ class="prose prose-sm prose-zinc"
455
+ />
456
+ </template>
457
+ {{ fieldTitle("cascade") }}
458
+ </FieldLabel>
459
+ <Select
460
+ v-model:open="cascadeOpen"
461
+ :model-value="value.cascade ?? 'independent'"
462
+ @update:model-value="(v) => value = { ...value, cascade: v }"
463
+ >
464
+ <SelectTrigger class="w-full">
465
+ <SelectValue />
466
+ </SelectTrigger>
467
+ <SelectContent>
468
+ <SelectItem
469
+ v-for="opt in CASCADE_OPTIONS"
470
+ :key="opt.value"
471
+ :value="opt.value"
472
+ @mouseenter="hoveredCascade = opt.value"
473
+ @focus="hoveredCascade = opt.value"
474
+ >
475
+ {{ opt.label }}
476
+ </SelectItem>
477
+ <div
478
+ v-if="hoveredCascadeDescription"
479
+ data-slot="cascade-description"
480
+ class="mt-1 border-t border-zinc-200 px-2 py-1.5 text-xs text-zinc-500"
481
+ >
482
+ {{ hoveredCascadeDescription }}
483
+ </div>
484
+ </SelectContent>
485
+ </Select>
486
+ </Field>
487
+
488
+ <Field orientation="vertical">
489
+ <FieldLabel class="text-xs text-zinc-500">
490
+ <template
491
+ v-if="fieldDescription('expandAll')"
492
+ #tooltip
493
+ >
494
+ <Markdown
495
+ :source="fieldDescription('expandAll')"
496
+ block
497
+ class="prose prose-sm prose-zinc"
498
+ />
499
+ </template>
500
+ {{ fieldTitle("expandAll") }}
501
+ </FieldLabel>
502
+ <div>
503
+ <Switch
504
+ :model-value="value.expandAll ?? false"
505
+ @update:model-value="(v) => value = { ...value, expandAll: v }"
506
+ />
507
+ </div>
508
+ </Field>
509
+ </div>
510
+
511
+ <!-- 通用: 隐藏 / 禁用 / 只读 + 派生值 -->
512
+ <div class="grid grid-cols-3 gap-3">
513
+ <Field orientation="vertical">
514
+ <FieldLabel class="text-xs text-zinc-500">
515
+ <template #tooltip>
516
+ <Markdown
517
+ :source="fieldDescription('hidden') ?? '\u8FD4\u56DE `true` \u65F6\u5B57\u6BB5\u5728\u6240\u6709\u5E03\u5C40\u4E2D\u90FD\u4E0D\u6E32\u67D3'"
518
+ block
519
+ class="prose prose-sm prose-zinc"
520
+ />
521
+ </template>
522
+ {{ fieldTitle("hidden") }}
523
+ </FieldLabel>
524
+ <ExpressionEditor
525
+ :model-value="value.hidden ?? ''"
526
+ placeholder="例:form.role == 'guest'"
527
+ result-type="bool"
528
+ class="min-h-10"
529
+ @update:model-value="(v) => setOptionalExpression('hidden', v)"
530
+ />
531
+ </Field>
532
+
533
+ <Field orientation="vertical">
534
+ <FieldLabel class="text-xs text-zinc-500">
535
+ <template #tooltip>
536
+ <Markdown
537
+ :source="fieldDescription('disabled') ?? '\u8FD4\u56DE `true` \u65F6\u4ECD\u6E32\u67D3\u4F46\u4E0D\u53EF\u52FE\u9009'"
538
+ block
539
+ class="prose prose-sm prose-zinc"
540
+ />
541
+ </template>
542
+ {{ fieldTitle("disabled") }}
543
+ </FieldLabel>
544
+ <ExpressionEditor
545
+ :model-value="value.disabled ?? ''"
546
+ placeholder="例:form.status == 'locked'"
547
+ result-type="bool"
548
+ class="min-h-10"
549
+ @update:model-value="(v) => setOptionalExpression('disabled', v)"
550
+ />
551
+ </Field>
552
+
553
+ <Field orientation="vertical">
554
+ <FieldLabel class="text-xs text-zinc-500">
555
+ <template #tooltip>
556
+ <Markdown
557
+ :source="fieldDescription('readonly') ?? '\u8FD4\u56DE `true` \u65F6\u4EC5\u4EE5\u7EAF\u6587\u672C\u5C55\u793A\u5F53\u524D\u5DF2\u52FE\u9009\u8282\u70B9\u7684\u6807\u7B7E'"
558
+ block
559
+ class="prose prose-sm prose-zinc"
560
+ />
561
+ </template>
562
+ {{ fieldTitle("readonly") }}
563
+ </FieldLabel>
564
+ <ExpressionEditor
565
+ :model-value="value.readonly ?? ''"
566
+ placeholder="例:form.id != null"
567
+ result-type="bool"
568
+ class="min-h-10"
569
+ @update:model-value="(v) => setOptionalExpression('readonly', v)"
570
+ />
571
+ </Field>
572
+ </div>
573
+
574
+ <Field orientation="vertical">
575
+ <FieldLabel class="text-xs text-zinc-500">
576
+ <template #tooltip>
577
+ <Markdown
578
+ :source="fieldDescription('derived')"
579
+ block
580
+ class="prose prose-sm prose-zinc"
581
+ />
582
+ </template>
583
+ {{ fieldTitle("derived") }}
584
+ </FieldLabel>
585
+ <DerivedValueEditor
586
+ :model-value="value.derived"
587
+ result-type="list"
588
+ placeholder="例:form.defaultDepartmentIds"
589
+ @update:model-value="(v) => value = { ...value, derived: v }"
590
+ />
591
+ </Field>
592
+ </div>
593
+ </template>