@shwfed/config 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.d.vue.ts +14 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.vue +22 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.vue.d.ts +14 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/runtime.vue +110 -22
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.d.ts +14 -0
- package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.js +4 -0
- package/dist/runtime/utils/interpolate.d.ts +1 -0
- package/dist/runtime/utils/interpolate.js +7 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.d.vue.ts
CHANGED
|
@@ -22,6 +22,13 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
22
22
|
readonly locale: "en" | "ja" | "ko";
|
|
23
23
|
readonly message: string;
|
|
24
24
|
}[]] | undefined;
|
|
25
|
+
readonly locale?: readonly [{
|
|
26
|
+
readonly locale: "zh";
|
|
27
|
+
readonly message: string;
|
|
28
|
+
}, ...{
|
|
29
|
+
readonly locale: "en" | "ja" | "ko";
|
|
30
|
+
readonly message: string;
|
|
31
|
+
}[]] | undefined;
|
|
25
32
|
readonly displayName?: string | undefined;
|
|
26
33
|
readonly compatibilityDate: "2026-05-13";
|
|
27
34
|
readonly min?: number | undefined;
|
|
@@ -71,6 +78,13 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
71
78
|
readonly locale: "en" | "ja" | "ko";
|
|
72
79
|
readonly message: string;
|
|
73
80
|
}[]] | undefined;
|
|
81
|
+
readonly locale?: readonly [{
|
|
82
|
+
readonly locale: "zh";
|
|
83
|
+
readonly message: string;
|
|
84
|
+
}, ...{
|
|
85
|
+
readonly locale: "en" | "ja" | "ko";
|
|
86
|
+
readonly message: string;
|
|
87
|
+
}[]] | undefined;
|
|
74
88
|
readonly displayName?: string | undefined;
|
|
75
89
|
readonly compatibilityDate: "2026-05-13";
|
|
76
90
|
readonly min?: number | undefined;
|
package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.vue
CHANGED
|
@@ -233,6 +233,28 @@ const reorderable = computed({
|
|
|
233
233
|
</Field>
|
|
234
234
|
</div>
|
|
235
235
|
|
|
236
|
+
<Field orientation="vertical">
|
|
237
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
238
|
+
<template
|
|
239
|
+
v-if="fieldDescription('locale')"
|
|
240
|
+
#tooltip
|
|
241
|
+
>
|
|
242
|
+
<Markdown
|
|
243
|
+
:source="fieldDescription('locale')"
|
|
244
|
+
block
|
|
245
|
+
class="prose prose-sm prose-zinc"
|
|
246
|
+
/>
|
|
247
|
+
</template>
|
|
248
|
+
{{ fieldTitle("locale") }}
|
|
249
|
+
</FieldLabel>
|
|
250
|
+
<LocaleField
|
|
251
|
+
markdown
|
|
252
|
+
translate-hint="列表项折叠摘要,Markdown 文本,保留表达式插值占位符不要翻译"
|
|
253
|
+
:model-value="value.locale"
|
|
254
|
+
@update:model-value="(v) => value = { ...value, locale: v }"
|
|
255
|
+
/>
|
|
256
|
+
</Field>
|
|
257
|
+
|
|
236
258
|
<div class="grid grid-cols-3 gap-3">
|
|
237
259
|
<Field orientation="vertical">
|
|
238
260
|
<FieldLabel class="text-xs text-zinc-500">
|
package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.vue.d.ts
CHANGED
|
@@ -22,6 +22,13 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
22
22
|
readonly locale: "en" | "ja" | "ko";
|
|
23
23
|
readonly message: string;
|
|
24
24
|
}[]] | undefined;
|
|
25
|
+
readonly locale?: readonly [{
|
|
26
|
+
readonly locale: "zh";
|
|
27
|
+
readonly message: string;
|
|
28
|
+
}, ...{
|
|
29
|
+
readonly locale: "en" | "ja" | "ko";
|
|
30
|
+
readonly message: string;
|
|
31
|
+
}[]] | undefined;
|
|
25
32
|
readonly displayName?: string | undefined;
|
|
26
33
|
readonly compatibilityDate: "2026-05-13";
|
|
27
34
|
readonly min?: number | undefined;
|
|
@@ -71,6 +78,13 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
71
78
|
readonly locale: "en" | "ja" | "ko";
|
|
72
79
|
readonly message: string;
|
|
73
80
|
}[]] | undefined;
|
|
81
|
+
readonly locale?: readonly [{
|
|
82
|
+
readonly locale: "zh";
|
|
83
|
+
readonly message: string;
|
|
84
|
+
}, ...{
|
|
85
|
+
readonly locale: "en" | "ja" | "ko";
|
|
86
|
+
readonly message: string;
|
|
87
|
+
}[]] | undefined;
|
|
74
88
|
readonly displayName?: string | undefined;
|
|
75
89
|
readonly compatibilityDate: "2026-05-13";
|
|
76
90
|
readonly min?: number | undefined;
|
package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/runtime.vue
CHANGED
|
@@ -5,6 +5,7 @@ import { computed, ref, watch } from "vue";
|
|
|
5
5
|
import { useI18n } from "vue-i18n";
|
|
6
6
|
import { cel as _rawCel } from "../../../../../utils/cel";
|
|
7
7
|
import { celBindings, injectCELContext } from "../../../../../utils/cel-context";
|
|
8
|
+
import { interpolate } from "../../../../../utils/interpolate";
|
|
8
9
|
import { getLocalizedText } from "../../../../../share/locale";
|
|
9
10
|
import {
|
|
10
11
|
useTreeDnd
|
|
@@ -31,6 +32,8 @@ const tooltipText = computed(
|
|
|
31
32
|
const addLabelText = computed(
|
|
32
33
|
() => getLocalizedText(props.config.addLabel, locale.value) || "\u65B0\u589E"
|
|
33
34
|
);
|
|
35
|
+
const summaryTemplate = computed(() => getLocalizedText(props.config.locale, locale.value));
|
|
36
|
+
const collapsible = computed(() => !!summaryTemplate.value);
|
|
34
37
|
function evalBool(expression, label) {
|
|
35
38
|
if (!expression) return false;
|
|
36
39
|
try {
|
|
@@ -50,6 +53,28 @@ const items = computed(() => {
|
|
|
50
53
|
if (!Array.isArray(raw)) return [];
|
|
51
54
|
return raw;
|
|
52
55
|
});
|
|
56
|
+
const rowSummaries = computed(() => {
|
|
57
|
+
const template = summaryTemplate.value;
|
|
58
|
+
if (template == null) return [];
|
|
59
|
+
return items.value.map(
|
|
60
|
+
(item, i) => interpolate(template, (expression) => {
|
|
61
|
+
try {
|
|
62
|
+
const out = Effect.runSync($cel(expression, {
|
|
63
|
+
form: state.value ?? {},
|
|
64
|
+
item: item ?? {},
|
|
65
|
+
index: i
|
|
66
|
+
}));
|
|
67
|
+
return out == null ? "" : String(out);
|
|
68
|
+
} catch (err) {
|
|
69
|
+
console.error(
|
|
70
|
+
`[shwfed-form] list field: failed to evaluate summary expression \`${expression}\` for ${props.fieldId}[${i}]:`,
|
|
71
|
+
err
|
|
72
|
+
);
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
});
|
|
53
78
|
function writeItems(next) {
|
|
54
79
|
const path = props.config.binding;
|
|
55
80
|
if (path == null) {
|
|
@@ -74,6 +99,16 @@ watch(
|
|
|
74
99
|
},
|
|
75
100
|
{ immediate: true }
|
|
76
101
|
);
|
|
102
|
+
const expandedKeys = ref(/* @__PURE__ */ new Set());
|
|
103
|
+
function isExpanded(key) {
|
|
104
|
+
return expandedKeys.value.has(key);
|
|
105
|
+
}
|
|
106
|
+
function toggleExpanded(key) {
|
|
107
|
+
const next = new Set(expandedKeys.value);
|
|
108
|
+
if (next.has(key)) next.delete(key);
|
|
109
|
+
else next.add(key);
|
|
110
|
+
expandedKeys.value = next;
|
|
111
|
+
}
|
|
77
112
|
const atMax = computed(
|
|
78
113
|
() => props.config.max != null && items.value.length >= props.config.max
|
|
79
114
|
);
|
|
@@ -86,13 +121,23 @@ const canReorder = computed(() => !isDisabled.value && reorderable.value);
|
|
|
86
121
|
function append() {
|
|
87
122
|
if (!canAdd.value) return;
|
|
88
123
|
writeItems([...items.value, {}]);
|
|
89
|
-
|
|
124
|
+
const id = makeId();
|
|
125
|
+
rowKeys.value = [...rowKeys.value, id];
|
|
126
|
+
const next = new Set(expandedKeys.value);
|
|
127
|
+
next.add(id);
|
|
128
|
+
expandedKeys.value = next;
|
|
90
129
|
}
|
|
91
130
|
function removeAt(i) {
|
|
92
131
|
if (!canRemove.value) return;
|
|
93
132
|
if (i < 0 || i >= items.value.length) return;
|
|
133
|
+
const removedKey = rowKeys.value[i];
|
|
94
134
|
writeItems(items.value.filter((_, j) => j !== i));
|
|
95
135
|
rowKeys.value = rowKeys.value.filter((_, j) => j !== i);
|
|
136
|
+
if (removedKey != null && expandedKeys.value.has(removedKey)) {
|
|
137
|
+
const next = new Set(expandedKeys.value);
|
|
138
|
+
next.delete(removedKey);
|
|
139
|
+
expandedKeys.value = next;
|
|
140
|
+
}
|
|
96
141
|
}
|
|
97
142
|
function moveRow(from, to) {
|
|
98
143
|
if (!canReorder.value) return;
|
|
@@ -169,19 +214,74 @@ function rowConfig(i) {
|
|
|
169
214
|
v-for="(item, i) in items"
|
|
170
215
|
:key="rowKeys[i]"
|
|
171
216
|
:ref="dnd.rowRef(rowId(i), rowConfig(i))"
|
|
172
|
-
class="relative
|
|
217
|
+
class="relative rounded border border-zinc-200 bg-zinc-50/40 p-3"
|
|
173
218
|
data-slot="list-row"
|
|
174
219
|
:data-instruction="dnd.instructionFor(rowId(i)) ?? void 0"
|
|
175
220
|
>
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
221
|
+
<div class="flex items-center gap-2">
|
|
222
|
+
<Icon
|
|
223
|
+
v-if="reorderable"
|
|
224
|
+
icon="fluent:re-order-dots-vertical-20-regular"
|
|
225
|
+
class="drag-handle size-4 shrink-0 text-zinc-400"
|
|
226
|
+
:class="canReorder ? 'cursor-grab' : 'cursor-not-allowed opacity-50'"
|
|
227
|
+
data-slot="list-row-drag-handle"
|
|
228
|
+
/>
|
|
229
|
+
|
|
230
|
+
<InputGroupButton
|
|
231
|
+
v-if="collapsible"
|
|
232
|
+
size="icon-xs"
|
|
233
|
+
class="shrink-0"
|
|
234
|
+
data-slot="list-row-collapse"
|
|
235
|
+
:aria-expanded="isExpanded(rowId(i))"
|
|
236
|
+
:aria-label="isExpanded(rowId(i)) ? '\u6298\u53E0' : '\u5C55\u5F00'"
|
|
237
|
+
@click="toggleExpanded(rowId(i))"
|
|
238
|
+
>
|
|
239
|
+
<Icon
|
|
240
|
+
:icon="isExpanded(rowId(i)) ? 'fluent:chevron-down-20-regular' : 'fluent:chevron-right-20-regular'"
|
|
241
|
+
/>
|
|
242
|
+
</InputGroupButton>
|
|
183
243
|
|
|
184
|
-
|
|
244
|
+
<div
|
|
245
|
+
v-if="collapsible"
|
|
246
|
+
class="min-w-0 flex-1"
|
|
247
|
+
data-slot="list-row-summary"
|
|
248
|
+
>
|
|
249
|
+
<Markdown
|
|
250
|
+
:source="rowSummaries[i] ?? ''"
|
|
251
|
+
class="prose prose-xs prose-zinc"
|
|
252
|
+
/>
|
|
253
|
+
</div>
|
|
254
|
+
<div
|
|
255
|
+
v-else
|
|
256
|
+
class="min-w-0 flex-1"
|
|
257
|
+
>
|
|
258
|
+
<Row
|
|
259
|
+
:model-value="item"
|
|
260
|
+
:unit="config.unit"
|
|
261
|
+
:index="i"
|
|
262
|
+
@update:model-value="(next) => updateRow(i, next)"
|
|
263
|
+
/>
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
<InputGroupButton
|
|
267
|
+
variant="destructive"
|
|
268
|
+
size="icon-xs"
|
|
269
|
+
class="shrink-0"
|
|
270
|
+
:disabled="!canRemove"
|
|
271
|
+
data-slot="list-row-remove"
|
|
272
|
+
aria-label="删除"
|
|
273
|
+
@click="removeAt(i)"
|
|
274
|
+
>
|
|
275
|
+
<Icon icon="fluent:delete-20-regular" />
|
|
276
|
+
</InputGroupButton>
|
|
277
|
+
</div>
|
|
278
|
+
|
|
279
|
+
<div
|
|
280
|
+
v-if="collapsible"
|
|
281
|
+
v-show="isExpanded(rowId(i))"
|
|
282
|
+
class="mt-3 min-w-0"
|
|
283
|
+
data-slot="list-row-content"
|
|
284
|
+
>
|
|
185
285
|
<Row
|
|
186
286
|
:model-value="item"
|
|
187
287
|
:unit="config.unit"
|
|
@@ -189,18 +289,6 @@ function rowConfig(i) {
|
|
|
189
289
|
@update:model-value="(next) => updateRow(i, next)"
|
|
190
290
|
/>
|
|
191
291
|
</div>
|
|
192
|
-
|
|
193
|
-
<InputGroupButton
|
|
194
|
-
variant="destructive"
|
|
195
|
-
size="icon-xs"
|
|
196
|
-
class="shrink-0"
|
|
197
|
-
:disabled="!canRemove"
|
|
198
|
-
data-slot="list-row-remove"
|
|
199
|
-
aria-label="删除"
|
|
200
|
-
@click="removeAt(i)"
|
|
201
|
-
>
|
|
202
|
-
<Icon icon="fluent:delete-20-regular" />
|
|
203
|
-
</InputGroupButton>
|
|
204
292
|
</div>
|
|
205
293
|
|
|
206
294
|
<Button
|
package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.d.ts
CHANGED
|
@@ -36,6 +36,13 @@ export declare function schema(configure: (env: Environment) => void): Schema.re
|
|
|
36
36
|
readonly locale: "en" | "ja" | "ko";
|
|
37
37
|
readonly message: string;
|
|
38
38
|
}[]] | undefined;
|
|
39
|
+
readonly locale?: readonly [{
|
|
40
|
+
readonly locale: "zh";
|
|
41
|
+
readonly message: string;
|
|
42
|
+
}, ...{
|
|
43
|
+
readonly locale: "en" | "ja" | "ko";
|
|
44
|
+
readonly message: string;
|
|
45
|
+
}[]] | undefined;
|
|
39
46
|
readonly displayName?: string | undefined;
|
|
40
47
|
readonly compatibilityDate: "2026-05-13";
|
|
41
48
|
readonly min?: number | undefined;
|
|
@@ -94,6 +101,13 @@ export declare function schema(configure: (env: Environment) => void): Schema.re
|
|
|
94
101
|
min: Schema.optional<Schema.refine<number, Schema.filter<typeof Schema.Number>>>;
|
|
95
102
|
max: Schema.optional<Schema.refine<number, Schema.filter<typeof Schema.Number>>>;
|
|
96
103
|
disabled: Schema.optional<Schema.Schema<string, string, never>>;
|
|
104
|
+
locale: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
|
|
105
|
+
locale: Schema.Literal<["zh"]>;
|
|
106
|
+
message: Schema.SchemaClass<string, string, never>;
|
|
107
|
+
}>], [Schema.Struct<{
|
|
108
|
+
locale: Schema.Literal<["ja", "en", "ko"]>;
|
|
109
|
+
message: Schema.SchemaClass<string, string, never>;
|
|
110
|
+
}>]>>;
|
|
97
111
|
unit: Schema.suspend<Readonly<{
|
|
98
112
|
fields: ReadonlyArray<import("../../../schema.js").FieldValue>;
|
|
99
113
|
layouts: ReadonlyArray<import("../../../schema.js").LayoutSetValue>;
|
|
@@ -64,6 +64,10 @@ export function schema(configure) {
|
|
|
64
64
|
title: "\u7981\u7528\u6761\u4EF6",
|
|
65
65
|
description: "\u8FD4\u56DE `true` \u65F6\u6574\u4E2A\u5217\u8868\u53EA\u8BFB\uFF0C\u4E0D\u80FD\u65B0\u589E/\u5220\u9664/\u91CD\u6392"
|
|
66
66
|
})),
|
|
67
|
+
locale: Schema.optional(Locale.annotations({
|
|
68
|
+
title: "\u5217\u8868\u9879\u6458\u8981",
|
|
69
|
+
description: "\u914D\u7F6E\u540E\u6BCF\u4E2A\u5217\u8868\u9879\u53EF\u6298\u53E0\uFF0C\u6298\u53E0\u65F6\u5C55\u793A\u6B64\u5904\u6587\u672C\u6E32\u67D3\u7684\u884C\u5185 Markdown \u4F5C\u4E3A\u6458\u8981\u3002\u652F\u6301 `{{ \u8868\u8FBE\u5F0F }}` \u63D2\u503C\uFF0C\u8868\u8FBE\u5F0F\u4E3A CEL\uFF0C\u53EF\u8BBF\u95EE `item`\uFF08\u5F53\u524D\u9879\uFF09\u3001`index`\uFF08\u5E8F\u53F7\uFF0C\u4ECE 0 \u5F00\u59CB\uFF09\u4E0E `form`"
|
|
70
|
+
})),
|
|
67
71
|
unit: Unit.annotations({
|
|
68
72
|
title: "\u5217\u8868\u9879\u914D\u7F6E",
|
|
69
73
|
description: "\u5355\u4E2A\u5217\u8868\u9879\u7684\u5B57\u6BB5\u4E0E\u5E03\u5C40\uFF1B\u6BCF\u4E2A\u5217\u8868\u9879\u90FD\u6309\u6B64\u7ED3\u6784\u6E32\u67D3\u4E00\u4EFD"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function interpolate(template: string, evaluate: (expression: string) => string): string;
|