@shwfed/config 2.2.4 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +8 -8
  3. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +8 -8
  4. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +8 -8
  5. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +8 -8
  6. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +9 -15
  7. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/row.d.vue.ts +3 -4
  8. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/row.vue +1 -1
  9. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/row.vue.d.ts +3 -4
  10. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/runtime.vue +9 -2
  11. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/config.d.vue.ts +2 -2
  12. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/config.vue +32 -52
  13. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/config.vue.d.ts +2 -2
  14. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/runtime.vue +19 -8
  15. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.d.ts +2 -2
  16. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.js +4 -3
  17. package/dist/runtime/components/form/utils/state.d.ts +10 -2
  18. package/dist/runtime/components/form/utils/state.js +10 -3
  19. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/config.vue +25 -0
  20. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/runtime.vue +2 -8
  21. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/schema.d.ts +4 -0
  22. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/schema.js +5 -0
  23. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.d.vue.ts +133 -0
  24. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.vue +533 -0
  25. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.vue.d.ts +133 -0
  26. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/runtime.d.vue.ts +9 -0
  27. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/runtime.vue +237 -0
  28. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/runtime.vue.d.ts +9 -0
  29. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/schema.d.ts +124 -0
  30. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/schema.js +96 -0
  31. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.d.vue.ts +10 -0
  32. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.vue +475 -0
  33. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.vue.d.ts +10 -0
  34. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.d.vue.ts +9 -0
  35. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue +156 -0
  36. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue.d.ts +9 -0
  37. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.d.ts +56 -0
  38. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.js +81 -0
  39. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.d.vue.ts +10 -0
  40. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.vue +292 -0
  41. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.vue.d.ts +10 -0
  42. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.d.vue.ts +9 -0
  43. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue +140 -0
  44. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue.d.ts +9 -0
  45. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.d.ts +50 -0
  46. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.js +53 -0
  47. package/dist/runtime/components/table/config.d.vue.ts +2 -0
  48. package/dist/runtime/components/table/config.vue +136 -109
  49. package/dist/runtime/components/table/config.vue.d.ts +2 -0
  50. package/dist/runtime/components/table/index.d.vue.ts +2 -2
  51. package/dist/runtime/components/table/index.vue +46 -53
  52. package/dist/runtime/components/table/index.vue.d.ts +2 -2
  53. package/dist/runtime/components/table/row-provider.d.vue.ts +23 -0
  54. package/dist/runtime/components/table/row-provider.vue +55 -0
  55. package/dist/runtime/components/table/row-provider.vue.d.ts +23 -0
  56. package/dist/runtime/components/table/schema.d.ts +17 -29
  57. package/dist/runtime/components/table/schema.js +22 -18
  58. package/dist/runtime/components/table/utils/shared.d.ts +28 -0
  59. package/dist/runtime/components/table/utils/shared.js +40 -0
  60. package/dist/runtime/components/ui/field/index.js +6 -1
  61. package/dist/runtime/components/ui/input/Input.vue +1 -1
  62. package/package.json +1 -1
@@ -0,0 +1,475 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { Icon } from "@iconify/vue";
4
+ import { ExpressionEditor } from "../../../../ui/expression-editor";
5
+ import { Switch } from "../../../../ui/switch";
6
+ import { Separator } from "../../../../ui/separator";
7
+ import { Field, FieldLabel } from "../../../../ui/field";
8
+ import { Locale } from "../../../../ui/locale";
9
+ import {
10
+ DropdownMenu,
11
+ DropdownMenuContent,
12
+ DropdownMenuItem,
13
+ DropdownMenuTrigger
14
+ } from "../../../../ui/dropdown-menu";
15
+ import {
16
+ InputGroup,
17
+ InputGroupAddon,
18
+ InputGroupButton,
19
+ InputGroupInput,
20
+ InputGroupNumberField
21
+ } from "../../../../ui/input-group";
22
+ import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
23
+ import { Markdown } from "../../../../ui/markdown";
24
+ import DerivedValueEditor from "../../../../form/DerivedValueEditor.vue";
25
+ import { schema } from "./schema";
26
+ defineOptions({ name: "ShwfedTableNumberInputRendererConfig" });
27
+ const value = defineModel({ type: Object, ...{ required: true } });
28
+ const fieldSchema = schema(() => {
29
+ });
30
+ const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
31
+ const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
32
+ const ROW_VARS = {
33
+ row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
34
+ index: { type: "number", label: "\u884C\u7D22\u5F15" }
35
+ };
36
+ const ROUNDING_MODE_OPTIONS = [
37
+ { value: "round", label: "\u56DB\u820D\u4E94\u5165" },
38
+ { value: "floor", label: "\u5411\u4E0B\u53D6\u6574" },
39
+ { value: "ceil", label: "\u5411\u4E0A\u53D6\u6574" }
40
+ ];
41
+ const bindingText = computed({
42
+ get: () => value.value.binding ?? "",
43
+ set: (v) => {
44
+ const trimmed = v.trim();
45
+ if (trimmed === "") delete value.value.binding;
46
+ else value.value.binding = trimmed;
47
+ }
48
+ });
49
+ const hiddenModel = computed({
50
+ get: () => value.value.hidden ?? "",
51
+ set: (v) => {
52
+ if (v === "") delete value.value.hidden;
53
+ else value.value.hidden = v;
54
+ }
55
+ });
56
+ const disabledModel = computed({
57
+ get: () => value.value.disabled ?? "",
58
+ set: (v) => {
59
+ if (v === "") delete value.value.disabled;
60
+ else value.value.disabled = v;
61
+ }
62
+ });
63
+ const readonlyModel = computed({
64
+ get: () => value.value.readonly ?? "",
65
+ set: (v) => {
66
+ if (v === "") delete value.value.readonly;
67
+ else value.value.readonly = v;
68
+ }
69
+ });
70
+ const derivedModel = computed({
71
+ get: () => value.value.derived,
72
+ set: (v) => {
73
+ if (v == null) delete value.value.derived;
74
+ else value.value.derived = v;
75
+ }
76
+ });
77
+ const currentRoundingModeLabel = computed(
78
+ () => ROUNDING_MODE_OPTIONS.find((o) => o.value === (value.value.roundingMode ?? "round"))?.label
79
+ );
80
+ function onPrecisionChange(v) {
81
+ if (v === void 0) {
82
+ delete value.value.precision;
83
+ delete value.value.roundingMode;
84
+ } else {
85
+ value.value.precision = v;
86
+ if (value.value.roundingMode === void 0) value.value.roundingMode = "round";
87
+ }
88
+ }
89
+ function onRoundingModeChange(mode) {
90
+ value.value.roundingMode = mode;
91
+ }
92
+ function onStepChange(v) {
93
+ if (v === void 0 || !(v > 0)) delete value.value.step;
94
+ else value.value.step = v;
95
+ }
96
+ function onValueAsStringChange(next) {
97
+ if (next) value.value.valueAsString = true;
98
+ else delete value.value.valueAsString;
99
+ }
100
+ </script>
101
+
102
+ <template>
103
+ <div class="space-y-5">
104
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
105
+ <Field orientation="vertical">
106
+ <FieldLabel class="text-xs text-zinc-500">
107
+ <template
108
+ v-if="fieldDescription('title')"
109
+ #tooltip
110
+ >
111
+ <Markdown
112
+ :source="fieldDescription('title')"
113
+ block
114
+ class="prose prose-sm prose-zinc"
115
+ />
116
+ </template>
117
+ {{ fieldTitle("title") }}
118
+ </FieldLabel>
119
+ <Locale v-model="value.title" />
120
+ </Field>
121
+ <Field orientation="vertical">
122
+ <FieldLabel class="text-xs text-zinc-500">
123
+ <template
124
+ v-if="fieldDescription('tooltip')"
125
+ #tooltip
126
+ >
127
+ <Markdown
128
+ :source="fieldDescription('tooltip')"
129
+ block
130
+ class="prose prose-sm prose-zinc"
131
+ />
132
+ </template>
133
+ {{ fieldTitle("tooltip") }}
134
+ </FieldLabel>
135
+ <Locale
136
+ v-model="value.tooltip"
137
+ markdown
138
+ />
139
+ </Field>
140
+ </div>
141
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
142
+ <Field orientation="vertical">
143
+ <FieldLabel class="text-xs text-zinc-500">
144
+ <template
145
+ v-if="fieldDescription('binding')"
146
+ #tooltip
147
+ >
148
+ <Markdown
149
+ :source="fieldDescription('binding')"
150
+ block
151
+ class="prose prose-sm prose-zinc"
152
+ />
153
+ </template>
154
+ {{ fieldTitle("binding") }}
155
+ </FieldLabel>
156
+ <InputGroup>
157
+ <InputGroupInput
158
+ v-model="bindingText"
159
+ placeholder="例:age"
160
+ class="font-mono"
161
+ />
162
+ </InputGroup>
163
+ </Field>
164
+ <Field orientation="vertical">
165
+ <FieldLabel class="text-xs text-zinc-500">
166
+ <template
167
+ v-if="fieldDescription('placeholder')"
168
+ #tooltip
169
+ >
170
+ <Markdown
171
+ :source="fieldDescription('placeholder')"
172
+ block
173
+ class="prose prose-sm prose-zinc"
174
+ />
175
+ </template>
176
+ {{ fieldTitle("placeholder") }}
177
+ </FieldLabel>
178
+ <Locale v-model="value.placeholder" />
179
+ </Field>
180
+ <Field orientation="vertical">
181
+ <FieldLabel class="text-xs text-zinc-500">
182
+ <template
183
+ v-if="fieldDescription('size')"
184
+ #tooltip
185
+ >
186
+ <Markdown
187
+ :source="fieldDescription('size')"
188
+ block
189
+ class="prose prose-sm prose-zinc"
190
+ />
191
+ </template>
192
+ {{ fieldTitle("size") }}
193
+ </FieldLabel>
194
+ <InputGroup>
195
+ <InputGroupNumberField
196
+ :model-value="value.size"
197
+ :disabled="value.grow"
198
+ :min="0"
199
+ @update:model-value="(v) => value.size = v"
200
+ />
201
+ <InputGroupAddon align="inline-end">
202
+ <InputGroupButton
203
+ :variant="value.grow ? 'primary' : 'ghost'"
204
+ size="xs"
205
+ @click="value.grow = !value.grow"
206
+ >
207
+ <Icon :icon="value.grow ? 'fluent:lock-closed-20-regular' : 'fluent:arrow-autofit-width-20-regular'" />
208
+ {{ fieldTitle("grow") }}
209
+ </InputGroupButton>
210
+ </InputGroupAddon>
211
+ </InputGroup>
212
+ </Field>
213
+ <Field orientation="vertical">
214
+ <FieldLabel class="text-xs text-zinc-500">
215
+ <template
216
+ v-if="fieldDescription('precision')"
217
+ #tooltip
218
+ >
219
+ <Markdown
220
+ :source="fieldDescription('precision')"
221
+ block
222
+ class="prose prose-sm prose-zinc"
223
+ />
224
+ </template>
225
+ {{ fieldTitle("precision") }}
226
+ </FieldLabel>
227
+ <InputGroup>
228
+ <InputGroupNumberField
229
+ :model-value="value.precision"
230
+ :min="0"
231
+ @update:model-value="onPrecisionChange"
232
+ />
233
+ <InputGroupAddon
234
+ v-if="value.precision !== void 0"
235
+ align="inline-end"
236
+ >
237
+ <DropdownMenu>
238
+ <DropdownMenuTrigger as-child>
239
+ <InputGroupButton
240
+ variant="ghost"
241
+ class="pr-1.5! text-xs"
242
+ >
243
+ {{ currentRoundingModeLabel }}
244
+ <Icon
245
+ icon="lucide:chevron-down"
246
+ class="size-3"
247
+ />
248
+ </InputGroupButton>
249
+ </DropdownMenuTrigger>
250
+ <DropdownMenuContent align="end">
251
+ <DropdownMenuItem
252
+ v-for="opt in ROUNDING_MODE_OPTIONS"
253
+ :key="opt.value"
254
+ @select="onRoundingModeChange(opt.value)"
255
+ >
256
+ {{ opt.label }}
257
+ </DropdownMenuItem>
258
+ </DropdownMenuContent>
259
+ </DropdownMenu>
260
+ </InputGroupAddon>
261
+ </InputGroup>
262
+ </Field>
263
+ <Field orientation="vertical">
264
+ <FieldLabel class="text-xs text-zinc-500">
265
+ <template
266
+ v-if="fieldDescription('step')"
267
+ #tooltip
268
+ >
269
+ <Markdown
270
+ :source="fieldDescription('step')"
271
+ block
272
+ class="prose prose-sm prose-zinc"
273
+ />
274
+ </template>
275
+ {{ fieldTitle("step") }}
276
+ </FieldLabel>
277
+ <InputGroup>
278
+ <InputGroupNumberField
279
+ :model-value="value.step"
280
+ :min="0"
281
+ @update:model-value="onStepChange"
282
+ />
283
+ </InputGroup>
284
+ </Field>
285
+ <Field orientation="vertical">
286
+ <FieldLabel class="text-xs text-zinc-500">
287
+ <template
288
+ v-if="fieldDescription('valueAsString')"
289
+ #tooltip
290
+ >
291
+ <Markdown
292
+ :source="fieldDescription('valueAsString')"
293
+ block
294
+ class="prose prose-sm prose-zinc"
295
+ />
296
+ </template>
297
+ {{ fieldTitle("valueAsString") }}
298
+ </FieldLabel>
299
+ <div>
300
+ <Switch
301
+ :model-value="value.valueAsString ?? false"
302
+ @update:model-value="onValueAsStringChange"
303
+ />
304
+ </div>
305
+ </Field>
306
+ </div>
307
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
308
+ <Field orientation="vertical">
309
+ <FieldLabel class="text-xs text-zinc-500">
310
+ <template
311
+ v-if="fieldDescription('min')"
312
+ #tooltip
313
+ >
314
+ <Markdown
315
+ :source="fieldDescription('min')"
316
+ block
317
+ class="prose prose-sm prose-zinc"
318
+ />
319
+ </template>
320
+ {{ fieldTitle("min") }}
321
+ </FieldLabel>
322
+ <ExpressionEditor
323
+ :model-value="value.min ?? ''"
324
+ placeholder="例:0"
325
+ result-type="number"
326
+ class="min-h-10"
327
+ :extra-vars="ROW_VARS"
328
+ @update:model-value="(v) => {
329
+ if (v.length > 0) value.min = v;
330
+ else delete value.min;
331
+ }"
332
+ />
333
+ </Field>
334
+ <Field orientation="vertical">
335
+ <FieldLabel class="text-xs text-zinc-500">
336
+ <template
337
+ v-if="fieldDescription('max')"
338
+ #tooltip
339
+ >
340
+ <Markdown
341
+ :source="fieldDescription('max')"
342
+ block
343
+ class="prose prose-sm prose-zinc"
344
+ />
345
+ </template>
346
+ {{ fieldTitle("max") }}
347
+ </FieldLabel>
348
+ <ExpressionEditor
349
+ :model-value="value.max ?? ''"
350
+ placeholder="例:100"
351
+ result-type="number"
352
+ class="min-h-10"
353
+ :extra-vars="ROW_VARS"
354
+ @update:model-value="(v) => {
355
+ if (v.length > 0) value.max = v;
356
+ else delete value.max;
357
+ }"
358
+ />
359
+ </Field>
360
+ </div>
361
+ <div class="grid grid-cols-2 gap-x-6 gap-y-4">
362
+ <Field orientation="vertical">
363
+ <FieldLabel class="text-xs text-zinc-500">
364
+ <template
365
+ v-if="fieldDescription('hidden')"
366
+ #tooltip
367
+ >
368
+ <Markdown
369
+ :source="fieldDescription('hidden')"
370
+ block
371
+ class="prose prose-sm prose-zinc"
372
+ />
373
+ </template>
374
+ {{ fieldTitle("hidden") }}
375
+ </FieldLabel>
376
+ <ExpressionEditor
377
+ v-model="hiddenModel"
378
+ placeholder="例:row.archived"
379
+ result-type="bool"
380
+ :extra-vars="ROW_VARS"
381
+ />
382
+ </Field>
383
+ <Field orientation="vertical">
384
+ <FieldLabel class="text-xs text-zinc-500">
385
+ <template
386
+ v-if="fieldDescription('disabled')"
387
+ #tooltip
388
+ >
389
+ <Markdown
390
+ :source="fieldDescription('disabled')"
391
+ block
392
+ class="prose prose-sm prose-zinc"
393
+ />
394
+ </template>
395
+ {{ fieldTitle("disabled") }}
396
+ </FieldLabel>
397
+ <ExpressionEditor
398
+ v-model="disabledModel"
399
+ placeholder="例:row.locked"
400
+ result-type="bool"
401
+ :extra-vars="ROW_VARS"
402
+ />
403
+ </Field>
404
+ <Field orientation="vertical">
405
+ <FieldLabel class="text-xs text-zinc-500">
406
+ <template
407
+ v-if="fieldDescription('readonly')"
408
+ #tooltip
409
+ >
410
+ <Markdown
411
+ :source="fieldDescription('readonly')"
412
+ block
413
+ class="prose prose-sm prose-zinc"
414
+ />
415
+ </template>
416
+ {{ fieldTitle("readonly") }}
417
+ </FieldLabel>
418
+ <ExpressionEditor
419
+ v-model="readonlyModel"
420
+ placeholder="例:row.id != null"
421
+ result-type="bool"
422
+ :extra-vars="ROW_VARS"
423
+ />
424
+ </Field>
425
+ <Field
426
+ orientation="vertical"
427
+ class="col-span-2"
428
+ >
429
+ <FieldLabel class="text-xs text-zinc-500">
430
+ <template
431
+ v-if="fieldDescription('derived')"
432
+ #tooltip
433
+ >
434
+ <Markdown
435
+ :source="fieldDescription('derived')"
436
+ block
437
+ class="prose prose-sm prose-zinc"
438
+ />
439
+ </template>
440
+ {{ fieldTitle("derived") }}
441
+ </FieldLabel>
442
+ <DerivedValueEditor
443
+ v-model="derivedModel"
444
+ result-type="number"
445
+ placeholder="例:row.unitPrice * row.quantity"
446
+ />
447
+ </Field>
448
+ </div>
449
+ <Separator />
450
+ <div class="flex flex-wrap gap-x-8 gap-y-3">
451
+ <Field
452
+ orientation="horizontal"
453
+ class="w-auto gap-2"
454
+ >
455
+ <Switch
456
+ :model-value="value.enableSorting ?? false"
457
+ @update:model-value="(v) => value.enableSorting = v"
458
+ />
459
+ <FieldLabel class="text-sm text-zinc-600">
460
+ <template
461
+ v-if="fieldDescription('enableSorting')"
462
+ #tooltip
463
+ >
464
+ <Markdown
465
+ :source="fieldDescription('enableSorting')"
466
+ block
467
+ class="prose prose-sm prose-zinc"
468
+ />
469
+ </template>
470
+ {{ fieldTitle("enableSorting") }}
471
+ </FieldLabel>
472
+ </Field>
473
+ </div>
474
+ </div>
475
+ </template>
@@ -0,0 +1,10 @@
1
+ type __VLS_ModelProps = {
2
+ modelValue: Record<string, any>;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
5
+ "update:modelValue": (value: Record<string, any>) => any;
6
+ }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
7
+ "onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import type { CellContext } from '@tanstack/vue-table';
2
+ import type { Value } from './schema.js';
3
+ type __VLS_Props = {
4
+ column: Value;
5
+ ctx: CellContext<unknown, unknown>;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;
@@ -0,0 +1,156 @@
1
+ <script setup>
2
+ import { Icon } from "@iconify/vue";
3
+ import { Effect } from "effect";
4
+ import { computed, nextTick } from "vue";
5
+ import { useI18n } from "vue-i18n";
6
+ import { cel as _rawCel } from "../../../../../utils/cel";
7
+ import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
8
+ import { getLocalizedText } from "../../../../../share/locale";
9
+ import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupNumberField } from "../../../../ui/input-group";
10
+ import { useFieldValue } from "../../../../form/utils/field-value";
11
+ defineOptions({ name: "ShwfedTableNumberInputRendererRuntime" });
12
+ const props = defineProps({
13
+ column: { type: null, required: true },
14
+ ctx: { type: Object, required: true }
15
+ });
16
+ const { locale } = useI18n();
17
+ const inherited = injectCELContext();
18
+ const $cel = (expression, context) => _rawCel(expression, { ...celBindings(inherited), ...context });
19
+ const placeholderText = computed(
20
+ () => props.column.placeholder ? getLocalizedText(props.column.placeholder, locale.value) : void 0
21
+ );
22
+ function evalBool(expression, label) {
23
+ if (!expression) return false;
24
+ try {
25
+ return Effect.runSync($cel(expression)) === true;
26
+ } catch (e) {
27
+ console.error(`[shwfed-table] number-input ${label} failed`, e);
28
+ return false;
29
+ }
30
+ }
31
+ function evalNumber(expression, label) {
32
+ if (!expression) return void 0;
33
+ try {
34
+ const result = Effect.runSync($cel(expression));
35
+ return typeof result === "number" && Number.isFinite(result) ? result : void 0;
36
+ } catch (e) {
37
+ console.error(`[shwfed-table] number-input ${label} failed`, e);
38
+ return void 0;
39
+ }
40
+ }
41
+ const isHidden = computed(() => evalBool(props.column.hidden, "hidden"));
42
+ const isDisabled = computed(() => evalBool(props.column.disabled, "disabled"));
43
+ const isReadonly = computed(() => evalBool(props.column.readonly, "readonly"));
44
+ const effectiveReadonly = computed(
45
+ () => isReadonly.value || props.column.derived?.mode === "formula"
46
+ );
47
+ const minValue = computed(() => evalNumber(props.column.min, "min"));
48
+ const maxValue = computed(() => evalNumber(props.column.max, "max"));
49
+ const formatOptions = computed(() => ({
50
+ useGrouping: false,
51
+ maximumFractionDigits: 20
52
+ }));
53
+ const { draft, commit } = useFieldValue({
54
+ binding: () => props.column.binding,
55
+ fromState: (raw) => {
56
+ if (typeof raw === "number" && Number.isFinite(raw)) return raw;
57
+ if (typeof raw === "string" && raw.length > 0) {
58
+ const n = Number(raw);
59
+ return Number.isFinite(n) ? n : void 0;
60
+ }
61
+ return void 0;
62
+ },
63
+ toState: (next) => {
64
+ if (typeof next !== "number" || !Number.isFinite(next)) return null;
65
+ return props.column.valueAsString ? String(next) : next;
66
+ }
67
+ });
68
+ function applyRounding(n, precision, mode) {
69
+ const factor = 10 ** precision;
70
+ switch (mode) {
71
+ case "floor":
72
+ return Math.floor(n * factor) / factor;
73
+ case "ceil":
74
+ return Math.ceil(n * factor) / factor;
75
+ default:
76
+ return Math.round(n * factor) / factor;
77
+ }
78
+ }
79
+ const showClear = computed(() => !isDisabled.value && draft.value !== void 0);
80
+ function handleClear() {
81
+ draft.value = void 0;
82
+ commit();
83
+ }
84
+ async function onBlur() {
85
+ await nextTick();
86
+ const precision = props.column.precision;
87
+ if (precision !== void 0) {
88
+ const current = draft.value;
89
+ if (current !== void 0) {
90
+ const rounded = applyRounding(current, precision, props.column.roundingMode ?? "round");
91
+ if (rounded !== current) draft.value = rounded;
92
+ }
93
+ }
94
+ commit();
95
+ }
96
+ </script>
97
+
98
+ <template>
99
+ <!--
100
+ Row budget matches the text-input cell: 2px outer inset around an `h-7`
101
+ (28px) input — 32px total. Every branch (hidden / readonly / editable)
102
+ is sized identically so rows do not jump when a CEL condition flips.
103
+ Both `text-[0.75rem]` breakpoints are explicit so `Input`'s default
104
+ `md:text-sm` cannot beat the override at md+.
105
+ -->
106
+ <div class="p-[0.125rem] w-full">
107
+ <span
108
+ v-if="isHidden"
109
+ class="block h-7 w-full"
110
+ />
111
+ <span
112
+ v-else-if="effectiveReadonly"
113
+ class="flex items-center h-7 w-full px-2 text-[0.75rem] text-zinc-700 truncate"
114
+ >
115
+ {{ draft ?? "\u2014" }}
116
+ </span>
117
+ <InputGroup
118
+ v-else
119
+ class="group/number-input h-7 rounded border-zinc-200/30 hover:border-zinc-200 focus-within:border-zinc-200 transition-colors ease-out duration-180"
120
+ :data-disabled="isDisabled ? 'true' : void 0"
121
+ >
122
+ <InputGroupNumberField
123
+ :model-value="draft"
124
+ :step="column.step"
125
+ :step-snapping="column.step !== void 0"
126
+ :min="minValue"
127
+ :max="maxValue"
128
+ :format-options="formatOptions"
129
+ :disabled="isDisabled"
130
+ :placeholder="placeholderText"
131
+ input-class="h-7 text-[0.75rem] md:text-[0.75rem] px-2 text-left"
132
+ @update:model-value="(v) => draft = v"
133
+ @blur="onBlur"
134
+ />
135
+ <InputGroupAddon
136
+ v-if="showClear"
137
+ align="inline-end"
138
+ class="[@media(hover:hover)]:opacity-0 transition-opacity group-hover/number-input:opacity-100 focus-within:opacity-100"
139
+ >
140
+ <InputGroupButton
141
+ size="icon-xs"
142
+ data-slot="number-input-clear"
143
+ class="size-4 text-zinc-500 hover:text-zinc-700"
144
+ tabindex="-1"
145
+ @mousedown.prevent
146
+ @click.stop="handleClear"
147
+ >
148
+ <Icon
149
+ icon="fluent:dismiss-20-regular"
150
+ class="size-3"
151
+ />
152
+ </InputGroupButton>
153
+ </InputGroupAddon>
154
+ </InputGroup>
155
+ </div>
156
+ </template>
@@ -0,0 +1,9 @@
1
+ import type { CellContext } from '@tanstack/vue-table';
2
+ import type { Value } from './schema.js';
3
+ type __VLS_Props = {
4
+ column: Value;
5
+ ctx: CellContext<unknown, unknown>;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;