@shwfed/config 2.10.10 → 2.10.12

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 (79) hide show
  1. package/dist/mcp.mjs +1043 -880
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-CsPU4iZU.js → FieldGroup.vue_vue_type_script_setup_true_lang-BeqytPDr.js} +1 -1
  4. package/dist/preview/assets/{badge-B953zx7V.js → badge-DkHwLDps.js} +1 -1
  5. package/dist/preview/assets/{config-B-o7DV04.js → config-7KeAl8UU.js} +1 -1
  6. package/dist/preview/assets/{config-D5m2C0xK.js → config-CVPVYMuh.js} +1 -1
  7. package/dist/preview/assets/{config-BajA-dJ1.js → config-CZ1e9utV.js} +1 -1
  8. package/dist/preview/assets/{config-C2-lrcCq.js → config-Cedm-E2H.js} +1 -1
  9. package/dist/preview/assets/{config-CFWXRIOe.js → config-Cft-srKd.js} +1 -1
  10. package/dist/preview/assets/{config-DAJ25V43.js → config-Cy6Eix27.js} +1 -1
  11. package/dist/preview/assets/{config-DqAigk_E.js → config-DAZ2Uj6B.js} +1 -1
  12. package/dist/preview/assets/{config-DmgHMdSz.js → config-DCANpbtq.js} +1 -1
  13. package/dist/preview/assets/{config-CqMqqE_9.js → config-DJQ2LOWo.js} +1 -1
  14. package/dist/preview/assets/{config-C4Twz5UA.js → config-DQVKd54J.js} +1 -1
  15. package/dist/preview/assets/{config-BjdMNJwa.js → config-DbV3RlZz.js} +1 -1
  16. package/dist/preview/assets/{config-C3v6QvLS.js → config-Dx1SXsSf.js} +1 -1
  17. package/dist/preview/assets/{config-DpEkjTKt.js → config-OPQWANCx.js} +1 -1
  18. package/dist/preview/assets/{config-C0xCcVfy.js → config-Uw4cvZGX.js} +1 -1
  19. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-WNrh1xWy.js → definition.vue_vue_type_script_setup_true_lang-D4Gh9PzS.js} +1 -1
  20. package/dist/preview/assets/{index-BdS7dokp.js → index-B3HnlKis.js} +193 -193
  21. package/dist/preview/assets/index-BAY6NLoo.css +1 -0
  22. package/dist/preview/assets/{index-Bv_Ig-Tl.js → index-Cum0oK9u.js} +1 -1
  23. package/dist/preview/assets/index-CxUuhfsO.js +1 -0
  24. package/dist/preview/assets/{item-caTb4x-x.js → item-H4QeOpnC.js} +1 -1
  25. package/dist/preview/assets/{runtime-7ThCZ17X.js → runtime-BotFX6qJ.js} +1 -1
  26. package/dist/preview/assets/{runtime-DELhNsaH.js → runtime-C3532B0Y.js} +1 -1
  27. package/dist/preview/assets/{runtime-Bnaxoocd.js → runtime-CNMjRr9Y.js} +1 -1
  28. package/dist/preview/assets/{runtime-d4XHvjgW.js → runtime-CTnwTJlw.js} +1 -1
  29. package/dist/preview/assets/{runtime-CIWhgS6a.js → runtime-CwgX0PuH.js} +1 -1
  30. package/dist/preview/assets/{runtime-C8_u1NyC.js → runtime-D5HcLLLR.js} +1 -1
  31. package/dist/preview/assets/{runtime-B-tUuLEY.js → runtime-DvCHNIPq.js} +1 -1
  32. package/dist/preview/assets/{runtime-C9lZq_oo.js → runtime-cKOD2A6u.js} +1 -1
  33. package/dist/preview/assets/{runtime-D6EIpId9.js → runtime-ibuFFD1K.js} +1 -1
  34. package/dist/preview/assets/{runtime-CZrQz2RJ.js → runtime-sPGVp7yA.js} +1 -1
  35. package/dist/preview/assets/{schema-meta-Cf59HabB.js → schema-meta-DtZNwp3h.js} +1 -1
  36. package/dist/preview/index.html +2 -2
  37. package/dist/runtime/components/actions/components/group.d.vue.ts +2 -2
  38. package/dist/runtime/components/actions/components/group.vue.d.ts +2 -2
  39. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.actions/runtime.vue +1 -0
  40. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +22 -22
  41. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +22 -22
  42. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +22 -22
  43. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +22 -22
  44. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
  45. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
  46. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +22 -22
  47. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +22 -22
  48. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
  49. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
  50. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +22 -22
  51. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +22 -22
  52. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +22 -22
  53. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +22 -22
  54. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.vue +83 -3
  55. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue +28 -0
  56. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.d.ts +132 -0
  57. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.js +19 -2
  58. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.vue +82 -2
  59. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue +28 -0
  60. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.d.ts +132 -0
  61. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.js +19 -2
  62. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/runtime.vue +8 -0
  63. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/config.d.vue.ts +10 -0
  64. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/config.vue +717 -0
  65. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/config.vue.d.ts +10 -0
  66. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/runtime.d.vue.ts +9 -0
  67. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/runtime.vue +152 -0
  68. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/runtime.vue.d.ts +9 -0
  69. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.d.ts +87 -0
  70. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.js +122 -0
  71. package/dist/runtime/components/ui/date-picker/DatePicker.d.vue.ts +1 -0
  72. package/dist/runtime/components/ui/date-picker/DatePicker.vue +3 -0
  73. package/dist/runtime/components/ui/date-picker/DatePicker.vue.d.ts +1 -0
  74. package/dist/runtime/components/ui/date-range-picker/DateRangePicker.d.vue.ts +1 -0
  75. package/dist/runtime/components/ui/date-range-picker/DateRangePicker.vue +2 -0
  76. package/dist/runtime/components/ui/date-range-picker/DateRangePicker.vue.d.ts +1 -0
  77. package/package.json +1 -1
  78. package/dist/preview/assets/index-BkwnC_tl.js +0 -1
  79. package/dist/preview/assets/index-Cc4BT5dc.css +0 -1
@@ -0,0 +1,717 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { Icon } from "@iconify/vue";
4
+ import { format as formatDate } from "date-fns";
5
+ import { ExpressionEditor } from "../../../../ui/expression-editor";
6
+ import { Separator } from "../../../../ui/separator";
7
+ import { Button } from "../../../../ui/button";
8
+ import { Field, FieldLabel } from "../../../../ui/field";
9
+ import { IconPicker } from "../../../../ui/icon-picker";
10
+ import { Locale } from "../../../../ui/locale";
11
+ import {
12
+ InputGroup,
13
+ InputGroupAddon,
14
+ InputGroupButton,
15
+ InputGroupInput,
16
+ InputGroupNumberField,
17
+ InputGroupText
18
+ } from "../../../../ui/input-group";
19
+ import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
20
+ import { Markdown } from "../../../../ui/markdown";
21
+ import DerivedValueEditor from "../../../../form/DerivedValueEditor.vue";
22
+ import { presetSchema, schema } from "./schema";
23
+ defineOptions({ name: "ShwfedTableDateRangeInputRendererConfig" });
24
+ const value = defineModel({ type: Object, ...{ required: true } });
25
+ const fieldSchema = schema(() => {
26
+ });
27
+ const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
28
+ const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
29
+ const presetFieldSchema = presetSchema(() => {
30
+ });
31
+ const presetFieldTitle = (field) => getStructFieldTitle(presetFieldSchema, field) ?? field;
32
+ const presetFieldDescription = (field) => getStructFieldDescription(presetFieldSchema, field);
33
+ const ROW_VARS = {
34
+ row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
35
+ index: { type: "number", label: "\u884C\u7D22\u5F15" }
36
+ };
37
+ const presets = computed(() => value.value.presets ?? []);
38
+ function newId() {
39
+ return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
40
+ const r = Math.random() * 16 | 0;
41
+ const v = c === "x" ? r : r & 3 | 8;
42
+ return v.toString(16);
43
+ });
44
+ }
45
+ function newPreset() {
46
+ return { id: newId(), label: [{ locale: "zh", message: "" }], start: "", end: "" };
47
+ }
48
+ function patchPreset(index, patch) {
49
+ const next = [...value.value.presets ?? []];
50
+ const cur = next[index];
51
+ if (!cur) return;
52
+ next[index] = { ...cur, ...patch };
53
+ value.value = { ...value.value, presets: next };
54
+ }
55
+ function addPreset() {
56
+ value.value = { ...value.value, presets: [...value.value.presets ?? [], newPreset()] };
57
+ }
58
+ function removePreset(index) {
59
+ const next = [...value.value.presets ?? []];
60
+ next.splice(index, 1);
61
+ value.value = { ...value.value, presets: next };
62
+ }
63
+ function setPresetLabel(index, label) {
64
+ patchPreset(index, { label });
65
+ }
66
+ function setPresetStart(index, expr) {
67
+ patchPreset(index, { start: expr });
68
+ }
69
+ function setPresetEnd(index, expr) {
70
+ patchPreset(index, { end: expr });
71
+ }
72
+ const bindingMode = computed(
73
+ () => Array.isArray(value.value.binding) ? "split" : "single"
74
+ );
75
+ const singlePathText = computed({
76
+ get: () => typeof value.value.binding === "string" ? value.value.binding : "",
77
+ set: (next) => {
78
+ const trimmed = next.trim();
79
+ if (trimmed.length === 0) {
80
+ const { binding: _drop, ...rest } = value.value;
81
+ value.value = rest;
82
+ } else {
83
+ value.value = { ...value.value, binding: trimmed };
84
+ }
85
+ }
86
+ });
87
+ const splitStartText = computed(
88
+ () => Array.isArray(value.value.binding) ? value.value.binding[0] : ""
89
+ );
90
+ const splitEndText = computed(
91
+ () => Array.isArray(value.value.binding) ? value.value.binding[1] : ""
92
+ );
93
+ function setSplitStart(next) {
94
+ const cur = Array.isArray(value.value.binding) ? value.value.binding : ["", ""];
95
+ value.value = { ...value.value, binding: [next.trim(), cur[1]] };
96
+ }
97
+ function setSplitEnd(next) {
98
+ const cur = Array.isArray(value.value.binding) ? value.value.binding : ["", ""];
99
+ value.value = { ...value.value, binding: [cur[0], next.trim()] };
100
+ }
101
+ function toggleBindingMode() {
102
+ if (bindingMode.value === "single") {
103
+ value.value = { ...value.value, binding: ["", ""] };
104
+ } else {
105
+ value.value = { ...value.value, binding: "" };
106
+ }
107
+ }
108
+ const formatText = computed({
109
+ get: () => value.value.format ?? "",
110
+ set: (v) => {
111
+ const trimmed = v.trim();
112
+ if (trimmed === "") {
113
+ const { format: _drop, ...rest } = value.value;
114
+ value.value = rest;
115
+ } else {
116
+ value.value = { ...value.value, format: trimmed };
117
+ }
118
+ }
119
+ });
120
+ const valueFormatText = computed({
121
+ get: () => value.value.valueFormat ?? "",
122
+ set: (v) => {
123
+ const trimmed = v.trim();
124
+ if (trimmed === "") {
125
+ const { valueFormat: _drop, ...rest } = value.value;
126
+ value.value = rest;
127
+ } else {
128
+ value.value = { ...value.value, valueFormat: trimmed };
129
+ }
130
+ }
131
+ });
132
+ function setSeparatorIcon(next) {
133
+ const trimmed = next.trim();
134
+ if (trimmed.length === 0) {
135
+ const { rangeSeparatorIcon: _drop, ...rest } = value.value;
136
+ value.value = rest;
137
+ } else {
138
+ value.value = { ...value.value, rangeSeparatorIcon: trimmed };
139
+ }
140
+ }
141
+ function setNumberOfMonths(next) {
142
+ if (next == null || !Number.isInteger(next) || next <= 0) {
143
+ const { numberOfMonths: _drop, ...rest } = value.value;
144
+ value.value = rest;
145
+ return;
146
+ }
147
+ value.value = { ...value.value, numberOfMonths: next };
148
+ }
149
+ function previewFormat(fmt) {
150
+ if (!fmt) return "";
151
+ try {
152
+ return formatDate(/* @__PURE__ */ new Date(), fmt);
153
+ } catch {
154
+ return "(\u65E0\u6548\u683C\u5F0F)";
155
+ }
156
+ }
157
+ const formatExample = computed(() => previewFormat(value.value.format ?? ""));
158
+ const valueFormatExample = computed(() => previewFormat(value.value.valueFormat ?? ""));
159
+ const hiddenModel = computed({
160
+ get: () => value.value.hidden ?? "",
161
+ set: (v) => {
162
+ if (v === "") {
163
+ const { hidden: _drop, ...rest } = value.value;
164
+ value.value = rest;
165
+ } else {
166
+ value.value = { ...value.value, hidden: v };
167
+ }
168
+ }
169
+ });
170
+ const disabledModel = computed({
171
+ get: () => value.value.disabled ?? "",
172
+ set: (v) => {
173
+ if (v === "") {
174
+ const { disabled: _drop, ...rest } = value.value;
175
+ value.value = rest;
176
+ } else {
177
+ value.value = { ...value.value, disabled: v };
178
+ }
179
+ }
180
+ });
181
+ const readonlyModel = computed({
182
+ get: () => value.value.readonly ?? "",
183
+ set: (v) => {
184
+ if (v === "") {
185
+ const { readonly: _drop, ...rest } = value.value;
186
+ value.value = rest;
187
+ } else {
188
+ value.value = { ...value.value, readonly: v };
189
+ }
190
+ }
191
+ });
192
+ const derivedModel = computed({
193
+ get: () => value.value.derived,
194
+ set: (v) => {
195
+ if (v == null) {
196
+ const { derived: _drop, ...rest } = value.value;
197
+ value.value = rest;
198
+ } else {
199
+ value.value = { ...value.value, derived: v };
200
+ }
201
+ }
202
+ });
203
+ </script>
204
+
205
+ <template>
206
+ <div class="space-y-5">
207
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
208
+ <Field orientation="vertical">
209
+ <FieldLabel class="text-xs text-zinc-500">
210
+ <template
211
+ v-if="fieldDescription('title')"
212
+ #tooltip
213
+ >
214
+ <Markdown
215
+ :source="fieldDescription('title')"
216
+ block
217
+ class="prose prose-sm prose-zinc"
218
+ />
219
+ </template>
220
+ {{ fieldTitle("title") }}
221
+ </FieldLabel>
222
+ <Locale
223
+ :model-value="value.title"
224
+ @update:model-value="(v) => value = { ...value, title: v }"
225
+ />
226
+ </Field>
227
+ <Field orientation="vertical">
228
+ <FieldLabel class="text-xs text-zinc-500">
229
+ <template
230
+ v-if="fieldDescription('tooltip')"
231
+ #tooltip
232
+ >
233
+ <Markdown
234
+ :source="fieldDescription('tooltip')"
235
+ block
236
+ class="prose prose-sm prose-zinc"
237
+ />
238
+ </template>
239
+ {{ fieldTitle("tooltip") }}
240
+ </FieldLabel>
241
+ <Locale
242
+ :model-value="value.tooltip"
243
+ markdown
244
+ @update:model-value="(v) => value = { ...value, tooltip: v }"
245
+ />
246
+ </Field>
247
+ </div>
248
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
249
+ <Field
250
+ orientation="vertical"
251
+ class="col-span-2"
252
+ >
253
+ <FieldLabel class="text-xs text-zinc-500">
254
+ <template #tooltip>
255
+ <Markdown
256
+ source="单元格读写的 `dot-prop` 路径。单路径模式读写 `[start, end]` 字符串数组;拆分模式分别读写起始与结束两端"
257
+ block
258
+ class="prose prose-sm prose-zinc"
259
+ />
260
+ </template>
261
+ {{ fieldTitle("binding") }}
262
+ </FieldLabel>
263
+ <template v-if="bindingMode === 'single'">
264
+ <InputGroup>
265
+ <InputGroupInput
266
+ v-model="singlePathText"
267
+ placeholder="例:event.range"
268
+ class="font-mono"
269
+ />
270
+ <InputGroupAddon align="inline-end">
271
+ <InputGroupButton
272
+ size="icon-xs"
273
+ aria-label="拆分起止绑定路径"
274
+ @click="toggleBindingMode"
275
+ >
276
+ <Icon icon="fluent:split-horizontal-20-regular" />
277
+ </InputGroupButton>
278
+ </InputGroupAddon>
279
+ </InputGroup>
280
+ </template>
281
+ <template v-else>
282
+ <div class="grid grid-cols-2 gap-2">
283
+ <InputGroup>
284
+ <InputGroupAddon align="inline-start">
285
+ <InputGroupText class="text-xs text-zinc-400">
286
+
287
+ </InputGroupText>
288
+ </InputGroupAddon>
289
+ <InputGroupInput
290
+ :model-value="splitStartText"
291
+ placeholder="例:event.start"
292
+ class="font-mono"
293
+ @update:model-value="(v) => setSplitStart(String(v ?? ''))"
294
+ />
295
+ </InputGroup>
296
+ <InputGroup>
297
+ <InputGroupAddon align="inline-start">
298
+ <InputGroupText class="text-xs text-zinc-400">
299
+
300
+ </InputGroupText>
301
+ </InputGroupAddon>
302
+ <InputGroupInput
303
+ :model-value="splitEndText"
304
+ placeholder="例:event.end"
305
+ class="font-mono"
306
+ @update:model-value="(v) => setSplitEnd(String(v ?? ''))"
307
+ />
308
+ <InputGroupAddon align="inline-end">
309
+ <InputGroupButton
310
+ size="icon-xs"
311
+ aria-label="合并起止绑定路径"
312
+ @click="toggleBindingMode"
313
+ >
314
+ <Icon icon="fluent:merge-vertical-20-regular" />
315
+ </InputGroupButton>
316
+ </InputGroupAddon>
317
+ </InputGroup>
318
+ </div>
319
+ </template>
320
+ </Field>
321
+ <Field orientation="vertical">
322
+ <FieldLabel class="text-xs text-zinc-500">
323
+ <template
324
+ v-if="fieldDescription('startPlaceholder')"
325
+ #tooltip
326
+ >
327
+ <Markdown
328
+ :source="fieldDescription('startPlaceholder')"
329
+ block
330
+ class="prose prose-sm prose-zinc"
331
+ />
332
+ </template>
333
+ {{ fieldTitle("startPlaceholder") }}
334
+ </FieldLabel>
335
+ <Locale
336
+ :model-value="value.startPlaceholder"
337
+ @update:model-value="(v) => value = { ...value, startPlaceholder: v }"
338
+ />
339
+ </Field>
340
+ <Field orientation="vertical">
341
+ <FieldLabel class="text-xs text-zinc-500">
342
+ <template
343
+ v-if="fieldDescription('endPlaceholder')"
344
+ #tooltip
345
+ >
346
+ <Markdown
347
+ :source="fieldDescription('endPlaceholder')"
348
+ block
349
+ class="prose prose-sm prose-zinc"
350
+ />
351
+ </template>
352
+ {{ fieldTitle("endPlaceholder") }}
353
+ </FieldLabel>
354
+ <Locale
355
+ :model-value="value.endPlaceholder"
356
+ @update:model-value="(v) => value = { ...value, endPlaceholder: v }"
357
+ />
358
+ </Field>
359
+ <Field orientation="vertical">
360
+ <FieldLabel class="text-xs text-zinc-500">
361
+ <template #tooltip>
362
+ <Markdown
363
+ :source="fieldDescription('format') ?? '\u8F93\u5165\u6846\u4E2D\u5C55\u793A\u65E5\u671F\u7684 `date-fns` \u683C\u5F0F\u4E32'"
364
+ block
365
+ class="prose prose-sm prose-zinc"
366
+ />
367
+ </template>
368
+ {{ fieldTitle("format") }}
369
+ </FieldLabel>
370
+ <InputGroup>
371
+ <InputGroupInput
372
+ v-model="formatText"
373
+ placeholder="例:yyyy-MM-dd"
374
+ class="font-mono"
375
+ />
376
+ <InputGroupAddon
377
+ v-if="formatExample"
378
+ align="inline-end"
379
+ >
380
+ <InputGroupText class="text-xs text-zinc-400">
381
+ {{ formatExample }}
382
+ </InputGroupText>
383
+ </InputGroupAddon>
384
+ </InputGroup>
385
+ </Field>
386
+ <Field orientation="vertical">
387
+ <FieldLabel class="text-xs text-zinc-500">
388
+ <template #tooltip>
389
+ <Markdown
390
+ :source="fieldDescription('valueFormat') ?? '\u5199\u5165\u884C\u6570\u636E\u7684 `date-fns` \u683C\u5F0F\u4E32'"
391
+ block
392
+ class="prose prose-sm prose-zinc"
393
+ />
394
+ </template>
395
+ {{ fieldTitle("valueFormat") }}
396
+ </FieldLabel>
397
+ <InputGroup>
398
+ <InputGroupInput
399
+ v-model="valueFormatText"
400
+ placeholder="例:yyyy-MM-dd"
401
+ class="font-mono"
402
+ />
403
+ <InputGroupAddon
404
+ v-if="valueFormatExample"
405
+ align="inline-end"
406
+ >
407
+ <InputGroupText class="text-xs text-zinc-400">
408
+ {{ valueFormatExample }}
409
+ </InputGroupText>
410
+ </InputGroupAddon>
411
+ </InputGroup>
412
+ </Field>
413
+ <Field orientation="vertical">
414
+ <FieldLabel class="text-xs text-zinc-500">
415
+ <template #tooltip>
416
+ <Markdown
417
+ :source="fieldDescription('rangeSeparatorIcon') ?? '\u8303\u56F4\u4E24\u7AEF\u4E4B\u95F4\u5206\u9694\u56FE\u6807\u7684 Iconify \u540D\u79F0'"
418
+ block
419
+ class="prose prose-sm prose-zinc"
420
+ />
421
+ </template>
422
+ {{ fieldTitle("rangeSeparatorIcon") }}
423
+ </FieldLabel>
424
+ <IconPicker
425
+ :model-value="value.rangeSeparatorIcon ?? ''"
426
+ placeholder="例:lucide:arrow-right"
427
+ @update:model-value="setSeparatorIcon"
428
+ />
429
+ </Field>
430
+ <Field orientation="vertical">
431
+ <FieldLabel class="text-xs text-zinc-500">
432
+ <template #tooltip>
433
+ <Markdown
434
+ :source="fieldDescription('numberOfMonths') ?? '\u65E5\u5386\u9762\u677F\u4E2D\u5E76\u6392\u663E\u793A\u7684\u6708\u4EFD\u6570'"
435
+ block
436
+ class="prose prose-sm prose-zinc"
437
+ />
438
+ </template>
439
+ {{ fieldTitle("numberOfMonths") }}
440
+ </FieldLabel>
441
+ <InputGroup>
442
+ <InputGroupNumberField
443
+ :model-value="value.numberOfMonths"
444
+ :min="1"
445
+ :step="1"
446
+ @update:model-value="setNumberOfMonths"
447
+ />
448
+ </InputGroup>
449
+ </Field>
450
+ <Field orientation="vertical">
451
+ <FieldLabel class="text-xs text-zinc-500">
452
+ <template
453
+ v-if="fieldDescription('size')"
454
+ #tooltip
455
+ >
456
+ <Markdown
457
+ :source="fieldDescription('size')"
458
+ block
459
+ class="prose prose-sm prose-zinc"
460
+ />
461
+ </template>
462
+ {{ fieldTitle("size") }}
463
+ </FieldLabel>
464
+ <InputGroup>
465
+ <InputGroupNumberField
466
+ :model-value="value.size"
467
+ :disabled="value.grow"
468
+ :min="0"
469
+ @update:model-value="(v) => value = { ...value, size: v }"
470
+ />
471
+ <InputGroupAddon align="inline-end">
472
+ <InputGroupButton
473
+ :variant="value.grow ? 'primary' : 'ghost'"
474
+ size="xs"
475
+ @click="value = { ...value, grow: !value.grow }"
476
+ >
477
+ <Icon :icon="value.grow ? 'fluent:lock-closed-20-regular' : 'fluent:arrow-autofit-width-20-regular'" />
478
+ {{ fieldTitle("grow") }}
479
+ </InputGroupButton>
480
+ </InputGroupAddon>
481
+ </InputGroup>
482
+ </Field>
483
+ <Field orientation="vertical">
484
+ <FieldLabel class="text-xs text-zinc-500">
485
+ <template
486
+ v-if="fieldDescription('hidden')"
487
+ #tooltip
488
+ >
489
+ <Markdown
490
+ :source="fieldDescription('hidden')"
491
+ block
492
+ class="prose prose-sm prose-zinc"
493
+ />
494
+ </template>
495
+ {{ fieldTitle("hidden") }}
496
+ </FieldLabel>
497
+ <ExpressionEditor
498
+ v-model="hiddenModel"
499
+ placeholder="例:row.archived"
500
+ result-type="bool"
501
+ :extra-vars="ROW_VARS"
502
+ />
503
+ </Field>
504
+ <Field orientation="vertical">
505
+ <FieldLabel class="text-xs text-zinc-500">
506
+ <template
507
+ v-if="fieldDescription('disabled')"
508
+ #tooltip
509
+ >
510
+ <Markdown
511
+ :source="fieldDescription('disabled')"
512
+ block
513
+ class="prose prose-sm prose-zinc"
514
+ />
515
+ </template>
516
+ {{ fieldTitle("disabled") }}
517
+ </FieldLabel>
518
+ <ExpressionEditor
519
+ v-model="disabledModel"
520
+ placeholder="例:row.locked"
521
+ result-type="bool"
522
+ :extra-vars="ROW_VARS"
523
+ />
524
+ </Field>
525
+ <Field orientation="vertical">
526
+ <FieldLabel class="text-xs text-zinc-500">
527
+ <template
528
+ v-if="fieldDescription('readonly')"
529
+ #tooltip
530
+ >
531
+ <Markdown
532
+ :source="fieldDescription('readonly')"
533
+ block
534
+ class="prose prose-sm prose-zinc"
535
+ />
536
+ </template>
537
+ {{ fieldTitle("readonly") }}
538
+ </FieldLabel>
539
+ <ExpressionEditor
540
+ v-model="readonlyModel"
541
+ placeholder="例:row.id != null"
542
+ result-type="bool"
543
+ :extra-vars="ROW_VARS"
544
+ />
545
+ </Field>
546
+ <Field
547
+ orientation="vertical"
548
+ class="col-span-2"
549
+ >
550
+ <FieldLabel class="text-xs text-zinc-500">
551
+ <template
552
+ v-if="fieldDescription('derived')"
553
+ #tooltip
554
+ >
555
+ <Markdown
556
+ :source="fieldDescription('derived')"
557
+ block
558
+ class="prose prose-sm prose-zinc"
559
+ />
560
+ </template>
561
+ {{ fieldTitle("derived") }}
562
+ </FieldLabel>
563
+ <DerivedValueEditor
564
+ v-model="derivedModel"
565
+ result-type="dyn"
566
+ placeholder="例:[row.startDate, row.endDate]"
567
+ />
568
+ </Field>
569
+ </div>
570
+ <Field orientation="vertical">
571
+ <FieldLabel class="text-xs text-zinc-500">
572
+ <template
573
+ v-if="fieldDescription('presets')"
574
+ #tooltip
575
+ >
576
+ <Markdown
577
+ :source="fieldDescription('presets')"
578
+ block
579
+ class="prose prose-sm prose-zinc"
580
+ />
581
+ </template>
582
+ {{ fieldTitle("presets") }}
583
+ </FieldLabel>
584
+ <div class="flex flex-col gap-3">
585
+ <div
586
+ v-for="(preset, index) in presets"
587
+ :key="preset.id"
588
+ data-slot="date-range-input-preset"
589
+ class="relative pt-8 grid grid-cols-3 gap-3 rounded border border-zinc-200 bg-zinc-50/40 p-3"
590
+ >
591
+ <InputGroupButton
592
+ variant="destructive"
593
+ size="icon-xs"
594
+ data-slot="date-range-input-preset-delete"
595
+ aria-label="删除预设"
596
+ class="absolute right-2 top-2 z-10"
597
+ @click="removePreset(index)"
598
+ >
599
+ <Icon icon="fluent:delete-20-regular" />
600
+ </InputGroupButton>
601
+ <Field orientation="vertical">
602
+ <FieldLabel class="text-xs text-zinc-500">
603
+ <template
604
+ v-if="presetFieldDescription('label')"
605
+ #tooltip
606
+ >
607
+ <Markdown
608
+ :source="presetFieldDescription('label')"
609
+ block
610
+ class="prose prose-sm prose-zinc"
611
+ />
612
+ </template>
613
+ {{ presetFieldTitle("label") }}
614
+ </FieldLabel>
615
+ <Locale
616
+ :model-value="preset.label"
617
+ @update:model-value="(v) => setPresetLabel(index, v)"
618
+ />
619
+ </Field>
620
+ <Field orientation="vertical">
621
+ <FieldLabel class="text-xs text-zinc-500">
622
+ <template
623
+ v-if="presetFieldDescription('start')"
624
+ #tooltip
625
+ >
626
+ <Markdown
627
+ :source="presetFieldDescription('start')"
628
+ block
629
+ class="prose prose-sm prose-zinc"
630
+ />
631
+ </template>
632
+ {{ presetFieldTitle("start") }}
633
+ </FieldLabel>
634
+ <ExpressionEditor
635
+ :model-value="preset.start"
636
+ placeholder="例:now.offset(-7, &quot;days&quot;)"
637
+ result-type="Date"
638
+ class="min-h-10"
639
+ :extra-vars="ROW_VARS"
640
+ @update:model-value="(v) => setPresetStart(index, v)"
641
+ />
642
+ </Field>
643
+ <Field orientation="vertical">
644
+ <FieldLabel class="text-xs text-zinc-500">
645
+ <template
646
+ v-if="presetFieldDescription('end')"
647
+ #tooltip
648
+ >
649
+ <Markdown
650
+ :source="presetFieldDescription('end')"
651
+ block
652
+ class="prose prose-sm prose-zinc"
653
+ />
654
+ </template>
655
+ {{ presetFieldTitle("end") }}
656
+ </FieldLabel>
657
+ <ExpressionEditor
658
+ :model-value="preset.end"
659
+ placeholder="例:now"
660
+ result-type="Date"
661
+ class="min-h-10"
662
+ :extra-vars="ROW_VARS"
663
+ @update:model-value="(v) => setPresetEnd(index, v)"
664
+ />
665
+ </Field>
666
+ </div>
667
+ <Button
668
+ type="button"
669
+ data-slot="date-range-input-add-preset"
670
+ class="w-full justify-center"
671
+ @click="addPreset"
672
+ >
673
+ <Icon icon="fluent:add-20-regular" />
674
+ <span>增加快捷选项</span>
675
+ </Button>
676
+ </div>
677
+ </Field>
678
+ <Separator />
679
+ <div class="flex flex-wrap gap-x-8 gap-y-3">
680
+ <Field
681
+ orientation="vertical"
682
+ class="w-full max-w-xs"
683
+ >
684
+ <FieldLabel class="text-xs text-zinc-500">
685
+ <template
686
+ v-if="fieldDescription('enableSorting')"
687
+ #tooltip
688
+ >
689
+ <Markdown
690
+ :source="fieldDescription('enableSorting')"
691
+ block
692
+ class="prose prose-sm prose-zinc"
693
+ />
694
+ </template>
695
+ {{ fieldTitle("enableSorting") }}
696
+ </FieldLabel>
697
+ <InputGroup>
698
+ <InputGroupInput
699
+ :model-value="value.sortKey"
700
+ placeholder="例:created_at"
701
+ @update:model-value="(v) => value = { ...value, sortKey: v || void 0 }"
702
+ />
703
+ <InputGroupAddon align="inline-end">
704
+ <InputGroupButton
705
+ :variant="value.enableSorting ? 'primary' : 'ghost'"
706
+ size="xs"
707
+ @click="value = { ...value, enableSorting: !value.enableSorting }"
708
+ >
709
+ <Icon :icon="value.enableSorting ? 'fluent:arrow-sort-up-16-regular' : 'fluent:arrow-sort-16-regular'" />
710
+ {{ fieldTitle("enableSorting") }}
711
+ </InputGroupButton>
712
+ </InputGroupAddon>
713
+ </InputGroup>
714
+ </Field>
715
+ </div>
716
+ </div>
717
+ </template>