@shwfed/config 2.3.24 → 2.3.25

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 (59) hide show
  1. package/dist/mcp.mjs +1059 -634
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{config-DYAEfkYR.js → config-BYTuKQZr.js} +1 -1
  4. package/dist/preview/assets/{config-D5Kfssb7.js → config-BoE06fMj.js} +1 -1
  5. package/dist/preview/assets/{config-CWZxlCMJ.js → config-CV5P2_b2.js} +1 -1
  6. package/dist/preview/assets/{config-CaZpOvHG.js → config-CVAFGzPb.js} +1 -1
  7. package/dist/preview/assets/{config-B3at5Bue.js → config-CdH0Nxqa.js} +1 -1
  8. package/dist/preview/assets/{config-B-6Htwv0.js → config-CjlRnKnY.js} +1 -1
  9. package/dist/preview/assets/{config-CBHKrOP5.js → config-CrvG15To.js} +1 -1
  10. package/dist/preview/assets/{config-Bi9uFh4Y.js → config-DZXC8YJ4.js} +1 -1
  11. package/dist/preview/assets/{config-B2KjxFl5.js → config-QaYy6DCp.js} +1 -1
  12. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-8BVrrrak.js → definition.vue_vue_type_script_setup_true_lang-CBPR0zl_.js} +1 -1
  13. package/dist/preview/assets/{index-CJMxrUKZ.css → index-BCE-G4Ha.css} +1 -1
  14. package/dist/preview/assets/index-BbnG2cVz.js +643 -0
  15. package/dist/preview/assets/index-NFKAYzMi.js +1 -0
  16. package/dist/preview/assets/{runtime-C1iENPNJ.js → runtime-1AP_-j3e.js} +1 -1
  17. package/dist/preview/assets/{runtime-CEP42oTV.js → runtime-BQiYt6n7.js} +1 -1
  18. package/dist/preview/assets/{runtime-aBsBSCeg.js → runtime-BsiLYYky.js} +1 -1
  19. package/dist/preview/assets/{runtime-CoRrnGx1.js → runtime-C-h7PIyx.js} +1 -1
  20. package/dist/preview/assets/{runtime-CRHn61GX.js → runtime-CGW3z1YJ.js} +1 -1
  21. package/dist/preview/assets/{runtime-Hvzx1ucy.js → runtime-C_R-VCbd.js} +1 -1
  22. package/dist/preview/assets/{runtime-C5CCMnHt.js → runtime-DGdEDDUA.js} +1 -1
  23. package/dist/preview/assets/{runtime-jrsJfwMb.js → runtime-DwXjew7j.js} +1 -1
  24. package/dist/preview/assets/{runtime-CqciI2ST.js → runtime-pM3u8QsQ.js} +1 -1
  25. package/dist/preview/index.html +2 -2
  26. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +4 -4
  27. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +4 -4
  28. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +4 -4
  29. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +4 -4
  30. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.d.vue.ts +26 -26
  31. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.vue +4 -14
  32. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.vue.d.ts +26 -26
  33. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/schema.d.ts +27 -1
  34. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/schema.js +14 -11
  35. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +26 -26
  36. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue +4 -12
  37. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +26 -26
  38. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.d.ts +27 -1
  39. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.js +14 -11
  40. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.d.vue.ts +163 -0
  41. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.vue +699 -0
  42. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.vue.d.ts +163 -0
  43. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.d.vue.ts +9 -0
  44. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.vue +349 -0
  45. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/runtime.vue.d.ts +9 -0
  46. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/schema.d.ts +251 -0
  47. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/schema.js +178 -0
  48. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +167 -0
  49. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue +732 -0
  50. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +167 -0
  51. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.d.vue.ts +9 -0
  52. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.vue +383 -0
  53. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/runtime.vue.d.ts +9 -0
  54. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.d.ts +253 -0
  55. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.js +230 -0
  56. package/dist/runtime/components/table/config.vue +40 -0
  57. package/package.json +1 -1
  58. package/dist/preview/assets/index-B3wadvvl.js +0 -1
  59. package/dist/preview/assets/index-DTsYYECD.js +0 -643
@@ -0,0 +1,699 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { Icon } from "@iconify/vue";
4
+ import { Button } from "../../../../ui/button";
5
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../../../ui/dropdown-menu";
6
+ import { ExpressionEditor } from "../../../../ui/expression-editor";
7
+ import { Switch } from "../../../../ui/switch";
8
+ import { Separator } from "../../../../ui/separator";
9
+ import { Field, FieldLabel } from "../../../../ui/field";
10
+ import { Locale } from "../../../../ui/locale";
11
+ import {
12
+ InputGroup,
13
+ InputGroupAddon,
14
+ InputGroupButton,
15
+ InputGroupInput,
16
+ InputGroupNumberField
17
+ } from "../../../../ui/input-group";
18
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../../../ui/tabs";
19
+ import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
20
+ import { Markdown } from "../../../../ui/markdown";
21
+ import DerivedValueEditor from "../../../../form/DerivedValueEditor.vue";
22
+ import { itemSchema, remoteOptionsSchema, schema } from "./schema";
23
+ defineOptions({ name: "ShwfedTableComboboxSingleRendererConfig" });
24
+ const value = defineModel({ type: null, ...{ required: true } });
25
+ const fieldSchema = schema(() => {
26
+ });
27
+ const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
28
+ const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
29
+ const itemFieldSchema = itemSchema(() => {
30
+ });
31
+ const itemFieldTitle = (f) => getStructFieldTitle(itemFieldSchema, f) ?? f;
32
+ const itemFieldDescription = (f) => getStructFieldDescription(itemFieldSchema, f);
33
+ const remoteSchema = remoteOptionsSchema(() => {
34
+ });
35
+ const remoteFieldTitle = (f) => getStructFieldTitle(remoteSchema, f) ?? f;
36
+ const remoteFieldDescription = (f) => getStructFieldDescription(remoteSchema, f);
37
+ const ROW_VARS = {
38
+ row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
39
+ index: { type: "number", label: "\u884C\u7D22\u5F15" }
40
+ };
41
+ const ROW_JSON_VARS = {
42
+ ...ROW_VARS,
43
+ json: { type: "dyn", label: "HTTP \u54CD\u5E94\u4F53\uFF08\u5DF2\u89E3\u6790 JSON\uFF09" }
44
+ };
45
+ const ROW_OPTION_VARS = {
46
+ ...ROW_VARS,
47
+ option: { type: "dyn", label: "\u5F53\u524D\u9009\u9879" }
48
+ };
49
+ const bindingText = computed({
50
+ get: () => value.value.binding ?? "",
51
+ set: (v) => {
52
+ const trimmed = v.trim();
53
+ if (trimmed === "") {
54
+ const { binding: _omit, ...rest } = value.value;
55
+ value.value = rest;
56
+ } else {
57
+ value.value = { ...value.value, binding: trimmed };
58
+ }
59
+ }
60
+ });
61
+ function celModel(field) {
62
+ return computed({
63
+ get: () => value.value[field] ?? "",
64
+ set: (v) => {
65
+ if (v === "") {
66
+ const { [field]: _omit, ...rest } = value.value;
67
+ value.value = rest;
68
+ } else {
69
+ value.value = { ...value.value, [field]: v };
70
+ }
71
+ }
72
+ });
73
+ }
74
+ const hiddenModel = celModel("hidden");
75
+ const disabledModel = celModel("disabled");
76
+ const readonlyModel = celModel("readonly");
77
+ const derivedModel = computed({
78
+ get: () => value.value.derived,
79
+ set: (v) => {
80
+ if (v == null) {
81
+ const { derived: _omit, ...rest } = value.value;
82
+ value.value = rest;
83
+ } else {
84
+ value.value = { ...value.value, derived: v };
85
+ }
86
+ }
87
+ });
88
+ const optionsKind = computed(() => value.value.options.kind);
89
+ function emptyStatic() {
90
+ return { kind: "static", items: [] };
91
+ }
92
+ function emptyRemote() {
93
+ return {
94
+ kind: "remote",
95
+ request: "",
96
+ options: "",
97
+ optionValue: "option",
98
+ optionLabel: [{ locale: "zh", message: "" }]
99
+ };
100
+ }
101
+ function setKind(kind) {
102
+ if (value.value.options.kind === kind) return;
103
+ value.value = {
104
+ ...value.value,
105
+ options: kind === "static" ? emptyStatic() : emptyRemote()
106
+ };
107
+ }
108
+ const items = computed(() => {
109
+ return value.value.options.kind === "static" ? value.value.options.items : [];
110
+ });
111
+ function patchStatic(patch) {
112
+ if (value.value.options.kind !== "static") return;
113
+ value.value = {
114
+ ...value.value,
115
+ options: { ...value.value.options, ...patch }
116
+ };
117
+ }
118
+ function patchRemote(patch) {
119
+ if (value.value.options.kind !== "remote") return;
120
+ value.value = {
121
+ ...value.value,
122
+ options: { ...value.value.options, ...patch }
123
+ };
124
+ }
125
+ const requestModel = computed({
126
+ get: () => value.value.options.kind === "remote" ? value.value.options.request : "",
127
+ set: (v) => patchRemote({ request: v })
128
+ });
129
+ const optionsExprModel = computed({
130
+ get: () => value.value.options.kind === "remote" ? value.value.options.options : "",
131
+ set: (v) => patchRemote({ options: v })
132
+ });
133
+ const optionValueModel = computed({
134
+ get: () => value.value.options.kind === "remote" ? value.value.options.optionValue : "option",
135
+ set: (v) => patchRemote({ optionValue: v })
136
+ });
137
+ const optionLabelModel = computed({
138
+ get: () => value.value.options.kind === "remote" ? value.value.options.optionLabel : [{ locale: "zh", message: "" }],
139
+ set: (v) => patchRemote({ optionLabel: v })
140
+ });
141
+ function newId() {
142
+ return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
143
+ const r = Math.random() * 16 | 0;
144
+ const v = c === "x" ? r : r & 3 | 8;
145
+ return v.toString(16);
146
+ });
147
+ }
148
+ function newItem() {
149
+ return {
150
+ id: newId(),
151
+ label: [{ locale: "zh", message: "" }],
152
+ value: { kind: "text", value: "" }
153
+ };
154
+ }
155
+ function patchItem(index, patch) {
156
+ if (value.value.options.kind !== "static") return;
157
+ const next = [...value.value.options.items];
158
+ const cur = next[index];
159
+ if (!cur) return;
160
+ next[index] = { ...cur, ...patch };
161
+ patchStatic({ items: next });
162
+ }
163
+ function addItem() {
164
+ if (value.value.options.kind !== "static") return;
165
+ patchStatic({ items: [...value.value.options.items, newItem()] });
166
+ }
167
+ function removeItem(index) {
168
+ if (value.value.options.kind !== "static") return;
169
+ const next = [...value.value.options.items];
170
+ next.splice(index, 1);
171
+ patchStatic({ items: next });
172
+ }
173
+ function setItemKind(index, kind) {
174
+ if (value.value.options.kind !== "static") return;
175
+ const cur = value.value.options.items[index];
176
+ if (!cur || cur.value.kind === kind) return;
177
+ patchItem(index, {
178
+ value: kind === "text" ? { kind: "text", value: "" } : { kind: "number", value: 0 }
179
+ });
180
+ }
181
+ function setItemTextValue(index, text) {
182
+ patchItem(index, { value: { kind: "text", value: text } });
183
+ }
184
+ function setItemNumberValue(index, n) {
185
+ patchItem(index, {
186
+ value: {
187
+ kind: "number",
188
+ value: typeof n === "number" && Number.isFinite(n) ? n : 0
189
+ }
190
+ });
191
+ }
192
+ function setItemLabel(index, label) {
193
+ patchItem(index, { label });
194
+ }
195
+ function setItemTooltip(index, tooltip) {
196
+ const isEmpty = !tooltip || tooltip.every((l) => l.message.trim().length === 0);
197
+ if (value.value.options.kind !== "static") return;
198
+ if (isEmpty) {
199
+ const cur = value.value.options.items[index];
200
+ if (!cur) return;
201
+ const { tooltip: _omit, ...rest } = cur;
202
+ const next = [...value.value.options.items];
203
+ next[index] = rest;
204
+ patchStatic({ items: next });
205
+ } else {
206
+ patchItem(index, { tooltip });
207
+ }
208
+ }
209
+ </script>
210
+
211
+ <template>
212
+ <div class="space-y-5">
213
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
214
+ <Field orientation="vertical">
215
+ <FieldLabel class="text-xs text-zinc-500">
216
+ <template
217
+ v-if="fieldDescription('title')"
218
+ #tooltip
219
+ >
220
+ <Markdown
221
+ :source="fieldDescription('title')"
222
+ block
223
+ class="prose prose-sm prose-zinc"
224
+ />
225
+ </template>
226
+ {{ fieldTitle("title") }}
227
+ </FieldLabel>
228
+ <Locale v-model="value.title" />
229
+ </Field>
230
+ <Field orientation="vertical">
231
+ <FieldLabel class="text-xs text-zinc-500">
232
+ <template
233
+ v-if="fieldDescription('tooltip')"
234
+ #tooltip
235
+ >
236
+ <Markdown
237
+ :source="fieldDescription('tooltip')"
238
+ block
239
+ class="prose prose-sm prose-zinc"
240
+ />
241
+ </template>
242
+ {{ fieldTitle("tooltip") }}
243
+ </FieldLabel>
244
+ <Locale
245
+ v-model="value.tooltip"
246
+ markdown
247
+ />
248
+ </Field>
249
+ </div>
250
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
251
+ <Field orientation="vertical">
252
+ <FieldLabel class="text-xs text-zinc-500">
253
+ <template
254
+ v-if="fieldDescription('binding')"
255
+ #tooltip
256
+ >
257
+ <Markdown
258
+ :source="fieldDescription('binding')"
259
+ block
260
+ class="prose prose-sm prose-zinc"
261
+ />
262
+ </template>
263
+ {{ fieldTitle("binding") }}
264
+ </FieldLabel>
265
+ <InputGroup>
266
+ <InputGroupInput
267
+ v-model="bindingText"
268
+ placeholder="例:role"
269
+ class="font-mono"
270
+ />
271
+ </InputGroup>
272
+ </Field>
273
+ <Field orientation="vertical">
274
+ <FieldLabel class="text-xs text-zinc-500">
275
+ <template
276
+ v-if="fieldDescription('placeholder')"
277
+ #tooltip
278
+ >
279
+ <Markdown
280
+ :source="fieldDescription('placeholder')"
281
+ block
282
+ class="prose prose-sm prose-zinc"
283
+ />
284
+ </template>
285
+ {{ fieldTitle("placeholder") }}
286
+ </FieldLabel>
287
+ <Locale v-model="value.placeholder" />
288
+ </Field>
289
+ <Field orientation="vertical">
290
+ <FieldLabel class="text-xs text-zinc-500">
291
+ <template
292
+ v-if="fieldDescription('size')"
293
+ #tooltip
294
+ >
295
+ <Markdown
296
+ :source="fieldDescription('size')"
297
+ block
298
+ class="prose prose-sm prose-zinc"
299
+ />
300
+ </template>
301
+ {{ fieldTitle("size") }}
302
+ </FieldLabel>
303
+ <InputGroup>
304
+ <InputGroupNumberField
305
+ :model-value="value.size"
306
+ :disabled="value.grow"
307
+ :min="0"
308
+ @update:model-value="(v) => value = { ...value, size: v }"
309
+ />
310
+ <InputGroupAddon align="inline-end">
311
+ <InputGroupButton
312
+ :variant="value.grow ? 'primary' : 'ghost'"
313
+ size="xs"
314
+ @click="value = { ...value, grow: !value.grow }"
315
+ >
316
+ <Icon :icon="value.grow ? 'fluent:lock-closed-20-regular' : 'fluent:arrow-autofit-width-20-regular'" />
317
+ {{ fieldTitle("grow") }}
318
+ </InputGroupButton>
319
+ </InputGroupAddon>
320
+ </InputGroup>
321
+ </Field>
322
+ </div>
323
+
324
+ <Field orientation="vertical">
325
+ <FieldLabel class="text-xs text-zinc-500">
326
+ <template #tooltip>
327
+ <Markdown
328
+ source="选项可以是静态配置的固定列表,也可以由远程接口实时加载"
329
+ block
330
+ class="prose prose-sm prose-zinc"
331
+ />
332
+ </template>
333
+ 选项来源
334
+ </FieldLabel>
335
+
336
+ <Tabs
337
+ :model-value="optionsKind"
338
+ @update:model-value="(v) => {
339
+ if (v === 'static' || v === 'remote') setKind(v);
340
+ }"
341
+ >
342
+ <TabsList>
343
+ <TabsTrigger value="static">
344
+ 静态
345
+ </TabsTrigger>
346
+ <TabsTrigger value="remote">
347
+ 远程
348
+ </TabsTrigger>
349
+ </TabsList>
350
+ <TabsContent
351
+ value="static"
352
+ class="outline-none"
353
+ >
354
+ <div class="flex flex-col gap-3 pt-3">
355
+ <div
356
+ v-for="(item, index) in items"
357
+ :key="item.id"
358
+ data-slot="combobox-single-item"
359
+ class="relative pt-8 grid grid-cols-3 gap-3 rounded border border-zinc-200 bg-zinc-50/40 p-3"
360
+ >
361
+ <InputGroupButton
362
+ variant="destructive"
363
+ size="icon-xs"
364
+ data-slot="combobox-single-item-delete"
365
+ aria-label="删除选项"
366
+ class="absolute right-2 top-2 z-10"
367
+ @click="removeItem(index)"
368
+ >
369
+ <Icon icon="fluent:delete-20-regular" />
370
+ </InputGroupButton>
371
+
372
+ <Field orientation="vertical">
373
+ <FieldLabel class="text-xs text-zinc-500">
374
+ <template
375
+ v-if="itemFieldDescription('label')"
376
+ #tooltip
377
+ >
378
+ <Markdown
379
+ :source="itemFieldDescription('label')"
380
+ block
381
+ class="prose prose-sm prose-zinc"
382
+ />
383
+ </template>
384
+ {{ itemFieldTitle("label") }}
385
+ </FieldLabel>
386
+ <Locale
387
+ markdown
388
+ translate-hint="combobox option label"
389
+ :model-value="item.label"
390
+ @update:model-value="(v) => setItemLabel(index, v)"
391
+ />
392
+ </Field>
393
+
394
+ <Field orientation="vertical">
395
+ <FieldLabel class="text-xs text-zinc-500">
396
+ <template
397
+ v-if="itemFieldDescription('value')"
398
+ #tooltip
399
+ >
400
+ <Markdown
401
+ :source="itemFieldDescription('value')"
402
+ block
403
+ class="prose prose-sm prose-zinc"
404
+ />
405
+ </template>
406
+ {{ itemFieldTitle("value") }}
407
+ </FieldLabel>
408
+ <InputGroup>
409
+ <InputGroupAddon align="inline-start">
410
+ <DropdownMenu>
411
+ <DropdownMenuTrigger as-child>
412
+ <InputGroupButton
413
+ size="icon-sm"
414
+ as-child
415
+ >
416
+ <button
417
+ type="button"
418
+ data-slot="combobox-single-item-kind-trigger"
419
+ class="text-zinc-500 transition-colors hover:text-zinc-700 [&_svg:not([class*='size-'])]:size-3.5"
420
+ aria-label="切换值类型"
421
+ >
422
+ <Icon
423
+ :icon="item.value.kind === 'number' ? 'fluent:number-symbol-20-regular' : 'fluent:textbox-20-regular'"
424
+ />
425
+ </button>
426
+ </InputGroupButton>
427
+ </DropdownMenuTrigger>
428
+ <DropdownMenuContent align="start">
429
+ <DropdownMenuItem @select="setItemKind(index, 'text')">
430
+ <Icon icon="fluent:textbox-20-regular" />
431
+ <span>文本</span>
432
+ </DropdownMenuItem>
433
+ <DropdownMenuItem @select="setItemKind(index, 'number')">
434
+ <Icon icon="fluent:number-symbol-20-regular" />
435
+ <span>数字</span>
436
+ </DropdownMenuItem>
437
+ </DropdownMenuContent>
438
+ </DropdownMenu>
439
+ </InputGroupAddon>
440
+
441
+ <InputGroupInput
442
+ v-if="item.value.kind === 'text'"
443
+ :model-value="item.value.value"
444
+ placeholder="例:admin"
445
+ @update:model-value="(v) => setItemTextValue(index, String(v ?? ''))"
446
+ />
447
+ <InputGroupNumberField
448
+ v-else
449
+ :model-value="item.value.value"
450
+ @update:model-value="(v) => setItemNumberValue(index, v)"
451
+ />
452
+ </InputGroup>
453
+ </Field>
454
+
455
+ <Field orientation="vertical">
456
+ <FieldLabel class="text-xs text-zinc-500">
457
+ <template
458
+ v-if="itemFieldDescription('tooltip')"
459
+ #tooltip
460
+ >
461
+ <Markdown
462
+ :source="itemFieldDescription('tooltip')"
463
+ block
464
+ class="prose prose-sm prose-zinc"
465
+ />
466
+ </template>
467
+ {{ itemFieldTitle("tooltip") }}
468
+ </FieldLabel>
469
+ <Locale
470
+ markdown
471
+ translate-hint="combobox option tooltip"
472
+ :model-value="item.tooltip"
473
+ @update:model-value="(v) => setItemTooltip(index, v)"
474
+ />
475
+ </Field>
476
+ </div>
477
+
478
+ <Button
479
+ type="button"
480
+ data-slot="combobox-single-add-item"
481
+ class="w-full justify-center"
482
+ @click="addItem"
483
+ >
484
+ <Icon icon="fluent:add-20-regular" />
485
+ <span>增加选项</span>
486
+ </Button>
487
+ </div>
488
+ </TabsContent>
489
+ <TabsContent
490
+ value="remote"
491
+ class="outline-none"
492
+ >
493
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4 pt-3">
494
+ <Field orientation="vertical">
495
+ <FieldLabel class="text-xs text-zinc-500">
496
+ <template
497
+ v-if="remoteFieldDescription('request')"
498
+ #tooltip
499
+ >
500
+ <Markdown
501
+ :source="remoteFieldDescription('request')"
502
+ block
503
+ class="prose prose-sm prose-zinc"
504
+ />
505
+ </template>
506
+ {{ remoteFieldTitle("request") }}
507
+ </FieldLabel>
508
+ <ExpressionEditor
509
+ v-model="requestModel"
510
+ placeholder="如 http.get('/api/roles')"
511
+ result-type="HttpRequest"
512
+ :extra-vars="ROW_VARS"
513
+ multiline
514
+ />
515
+ </Field>
516
+ <Field orientation="vertical">
517
+ <FieldLabel class="text-xs text-zinc-500">
518
+ <template
519
+ v-if="remoteFieldDescription('options')"
520
+ #tooltip
521
+ >
522
+ <Markdown
523
+ :source="remoteFieldDescription('options')"
524
+ block
525
+ class="prose prose-sm prose-zinc"
526
+ />
527
+ </template>
528
+ {{ remoteFieldTitle("options") }}
529
+ </FieldLabel>
530
+ <ExpressionEditor
531
+ v-model="optionsExprModel"
532
+ placeholder="如 json.data"
533
+ result-type="dyn"
534
+ :extra-vars="ROW_JSON_VARS"
535
+ multiline
536
+ />
537
+ </Field>
538
+ <Field orientation="vertical">
539
+ <FieldLabel class="text-xs text-zinc-500">
540
+ <template
541
+ v-if="remoteFieldDescription('optionValue')"
542
+ #tooltip
543
+ >
544
+ <Markdown
545
+ :source="remoteFieldDescription('optionValue')"
546
+ block
547
+ class="prose prose-sm prose-zinc"
548
+ />
549
+ </template>
550
+ {{ remoteFieldTitle("optionValue") }}
551
+ </FieldLabel>
552
+ <ExpressionEditor
553
+ v-model="optionValueModel"
554
+ placeholder="如 option.id"
555
+ result-type="dyn"
556
+ :extra-vars="ROW_OPTION_VARS"
557
+ />
558
+ </Field>
559
+ <Field orientation="vertical">
560
+ <FieldLabel class="text-xs text-zinc-500">
561
+ <template
562
+ v-if="remoteFieldDescription('optionLabel')"
563
+ #tooltip
564
+ >
565
+ <Markdown
566
+ :source="remoteFieldDescription('optionLabel')"
567
+ block
568
+ class="prose prose-sm prose-zinc"
569
+ />
570
+ </template>
571
+ {{ remoteFieldTitle("optionLabel") }}
572
+ </FieldLabel>
573
+ <Locale
574
+ :model-value="optionLabelModel"
575
+ markdown
576
+ translate-hint="combobox option label"
577
+ @update:model-value="(v) => optionLabelModel = v"
578
+ />
579
+ </Field>
580
+ </div>
581
+ </TabsContent>
582
+ </Tabs>
583
+ </Field>
584
+
585
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
586
+ <Field orientation="vertical">
587
+ <FieldLabel class="text-xs text-zinc-500">
588
+ <template
589
+ v-if="fieldDescription('hidden')"
590
+ #tooltip
591
+ >
592
+ <Markdown
593
+ :source="fieldDescription('hidden')"
594
+ block
595
+ class="prose prose-sm prose-zinc"
596
+ />
597
+ </template>
598
+ {{ fieldTitle("hidden") }}
599
+ </FieldLabel>
600
+ <ExpressionEditor
601
+ v-model="hiddenModel"
602
+ placeholder="例:row.archived"
603
+ result-type="bool"
604
+ :extra-vars="ROW_VARS"
605
+ />
606
+ </Field>
607
+ <Field orientation="vertical">
608
+ <FieldLabel class="text-xs text-zinc-500">
609
+ <template
610
+ v-if="fieldDescription('disabled')"
611
+ #tooltip
612
+ >
613
+ <Markdown
614
+ :source="fieldDescription('disabled')"
615
+ block
616
+ class="prose prose-sm prose-zinc"
617
+ />
618
+ </template>
619
+ {{ fieldTitle("disabled") }}
620
+ </FieldLabel>
621
+ <ExpressionEditor
622
+ v-model="disabledModel"
623
+ placeholder="例:row.locked"
624
+ result-type="bool"
625
+ :extra-vars="ROW_VARS"
626
+ />
627
+ </Field>
628
+ <Field orientation="vertical">
629
+ <FieldLabel class="text-xs text-zinc-500">
630
+ <template
631
+ v-if="fieldDescription('readonly')"
632
+ #tooltip
633
+ >
634
+ <Markdown
635
+ :source="fieldDescription('readonly')"
636
+ block
637
+ class="prose prose-sm prose-zinc"
638
+ />
639
+ </template>
640
+ {{ fieldTitle("readonly") }}
641
+ </FieldLabel>
642
+ <ExpressionEditor
643
+ v-model="readonlyModel"
644
+ placeholder="例:row.id != null"
645
+ result-type="bool"
646
+ :extra-vars="ROW_VARS"
647
+ />
648
+ </Field>
649
+ <Field
650
+ orientation="vertical"
651
+ class="col-span-2"
652
+ >
653
+ <FieldLabel class="text-xs text-zinc-500">
654
+ <template
655
+ v-if="fieldDescription('derived')"
656
+ #tooltip
657
+ >
658
+ <Markdown
659
+ :source="fieldDescription('derived')"
660
+ block
661
+ class="prose prose-sm prose-zinc"
662
+ />
663
+ </template>
664
+ {{ fieldTitle("derived") }}
665
+ </FieldLabel>
666
+ <DerivedValueEditor
667
+ v-model="derivedModel"
668
+ result-type="dyn"
669
+ placeholder="例:form.defaults[row.kind]"
670
+ />
671
+ </Field>
672
+ </div>
673
+ <Separator />
674
+ <div class="flex flex-wrap gap-x-8 gap-y-3">
675
+ <Field
676
+ orientation="horizontal"
677
+ class="w-auto gap-2"
678
+ >
679
+ <Switch
680
+ :model-value="value.enableSorting ?? false"
681
+ @update:model-value="(v) => value = { ...value, enableSorting: v }"
682
+ />
683
+ <FieldLabel class="text-sm text-zinc-600">
684
+ <template
685
+ v-if="fieldDescription('enableSorting')"
686
+ #tooltip
687
+ >
688
+ <Markdown
689
+ :source="fieldDescription('enableSorting')"
690
+ block
691
+ class="prose prose-sm prose-zinc"
692
+ />
693
+ </template>
694
+ {{ fieldTitle("enableSorting") }}
695
+ </FieldLabel>
696
+ </Field>
697
+ </div>
698
+ </div>
699
+ </template>