@shwfed/nuxt 0.11.49 → 0.11.51

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 (30) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/button.d.vue.ts +8 -0
  3. package/dist/runtime/components/button.vue.d.ts +8 -0
  4. package/dist/runtime/components/fields.d.vue.ts +850 -6
  5. package/dist/runtime/components/fields.vue +0 -2
  6. package/dist/runtime/components/fields.vue.d.ts +850 -6
  7. package/dist/runtime/components/ui/button-configurator/ButtonConfiguratorDialog.d.vue.ts +8 -0
  8. package/dist/runtime/components/ui/button-configurator/ButtonConfiguratorDialog.vue +137 -0
  9. package/dist/runtime/components/ui/button-configurator/ButtonConfiguratorDialog.vue.d.ts +8 -0
  10. package/dist/runtime/components/ui/button-configurator/menu.d.ts +2 -0
  11. package/dist/runtime/components/ui/button-configurator/menu.js +14 -0
  12. package/dist/runtime/components/ui/buttons/Buttons.d.vue.ts +8 -0
  13. package/dist/runtime/components/ui/buttons/Buttons.vue +42 -14
  14. package/dist/runtime/components/ui/buttons/Buttons.vue.d.ts +8 -0
  15. package/dist/runtime/components/ui/buttons/schema.d.ts +30 -0
  16. package/dist/runtime/components/ui/buttons/schema.js +5 -0
  17. package/dist/runtime/components/ui/fields/Fields.d.vue.ts +1698 -10
  18. package/dist/runtime/components/ui/fields/Fields.vue +627 -162
  19. package/dist/runtime/components/ui/fields/Fields.vue.d.ts +1698 -10
  20. package/dist/runtime/components/ui/fields/schema.d.ts +5625 -153
  21. package/dist/runtime/components/ui/fields/schema.js +83 -80
  22. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.d.vue.ts +849 -5
  23. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue +224 -618
  24. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue.d.ts +849 -5
  25. package/package.json +1 -1
  26. package/dist/runtime/components/ui/fields/FieldsBody.d.vue.ts +0 -17
  27. package/dist/runtime/components/ui/fields/FieldsBody.vue +0 -720
  28. package/dist/runtime/components/ui/fields/FieldsBody.vue.d.ts +0 -17
  29. package/dist/runtime/components/ui/fields/render-context.d.ts +0 -120
  30. package/dist/runtime/components/ui/fields/render-context.js +0 -0
@@ -7,7 +7,6 @@ import { computed, nextTick, ref, toRaw, watch } from "vue";
7
7
  import { useI18n } from "vue-i18n";
8
8
  import {
9
9
  CalendarFieldC,
10
- ContainerFieldC,
11
10
  EmptyFieldC,
12
11
  FieldGroupC,
13
12
  FieldGroupStyleC,
@@ -47,8 +46,6 @@ import { NativeSelect, NativeSelectOption } from "../native-select";
47
46
  import { Switch } from "../switch";
48
47
  import { Textarea } from "../textarea";
49
48
  const ROOT_FIELD_GROUP_VALUE = "__root__";
50
- const GROUP_OWNER_PREFIX = "group:";
51
- const CONTAINER_OWNER_PREFIX = "container:";
52
49
  const props = defineProps({
53
50
  config: { type: null, required: true }
54
51
  });
@@ -81,7 +78,6 @@ const fieldTypeOptions = computed(() => [
81
78
  { type: "radio", label: t("field-type-radio") },
82
79
  { type: "calendar", label: t("field-type-calendar") },
83
80
  { type: "upload", label: t("field-type-upload") },
84
- { type: "container", label: t("field-type-container") },
85
81
  { type: "empty", label: t("field-type-empty") },
86
82
  { type: "slot", label: t("field-type-slot") }
87
83
  ]);
@@ -90,83 +86,28 @@ const generalItem = computed(() => ({
90
86
  label: t("general")
91
87
  }));
92
88
  const normalizedSearch = computed(() => search.value.trim().toLocaleLowerCase());
93
- function cloneValue(value) {
94
- return JSON.parse(JSON.stringify(toRaw(value)));
95
- }
96
- function createContainerDraftField(field) {
97
- const { fields, ...rest } = cloneValue(field);
98
- return {
99
- draftId: createDraftId(),
100
- field: {
101
- ...rest,
102
- fields: []
103
- },
104
- children: cloneFields(fields)
105
- };
106
- }
107
- function findDraftField(fields, draftId) {
108
- for (const field of fields) {
109
- if (field.draftId === draftId) {
110
- return field;
111
- }
112
- const child = findDraftField(field.children, draftId);
113
- if (child) {
114
- return child;
115
- }
116
- }
117
- return void 0;
118
- }
119
- function findFieldOwnerInFields(fields, draftId, owner) {
120
- for (const field of fields) {
121
- if (field.draftId === draftId) {
122
- return owner;
123
- }
124
- if (field.field.type !== "container") {
125
- continue;
126
- }
127
- const childOwner = findFieldOwnerInFields(field.children, draftId, {
128
- kind: "container",
129
- draftId: field.draftId
130
- });
131
- if (childOwner) {
132
- return childOwner;
133
- }
134
- }
135
- return void 0;
136
- }
137
- function findFieldOwnerByDraftId(draftId) {
138
- const rootOwner = findFieldOwnerInFields(draftFields.value, draftId, {
139
- kind: "root"
140
- });
141
- if (rootOwner) {
142
- return rootOwner;
143
- }
144
- for (const group of draftGroups.value) {
145
- const groupOwner = findFieldOwnerInFields(group.fields, draftId, {
146
- kind: "group",
147
- draftId: group.draftId
148
- });
149
- if (groupOwner) {
150
- return groupOwner;
151
- }
152
- }
153
- return void 0;
154
- }
155
89
  const selectedGroup = computed(() => draftGroups.value.find((group) => group.draftId === selectedItemId.value));
156
90
  const selectedField = computed(() => {
157
- const rootField = findDraftField(draftFields.value, selectedItemId.value);
91
+ const rootField = draftFields.value.find((item) => item.draftId === selectedItemId.value);
158
92
  if (rootField) {
159
93
  return rootField;
160
94
  }
161
95
  for (const group of draftGroups.value) {
162
- const field = findDraftField(group.fields, selectedItemId.value);
96
+ const field = group.fields.find((item) => item.draftId === selectedItemId.value);
163
97
  if (field) {
164
98
  return field;
165
99
  }
166
100
  }
167
101
  return void 0;
168
102
  });
169
- const selectedFieldOwner = computed(() => findFieldOwnerByDraftId(selectedItemId.value));
103
+ const selectedFieldGroup = computed(() => {
104
+ for (const group of draftGroups.value) {
105
+ if (group.fields.some((item) => item.draftId === selectedItemId.value)) {
106
+ return group;
107
+ }
108
+ }
109
+ return void 0;
110
+ });
170
111
  const usesContentsOrientation = computed(() => draftOrientation.value === "contents");
171
112
  const selectedFieldValidationRules = computed(() => {
172
113
  const field = selectedField.value?.field;
@@ -188,13 +129,9 @@ function createDefaultLocaleValue() {
188
129
  return [{ locale: "zh", message: "" }];
189
130
  }
190
131
  function createDraftField(field) {
191
- if (field.type === "container") {
192
- return createContainerDraftField(field);
193
- }
194
132
  return {
195
133
  draftId: createDraftId(),
196
- field: cloneValue(field),
197
- children: []
134
+ field: JSON.parse(JSON.stringify(toRaw(field)))
198
135
  };
199
136
  }
200
137
  function cloneFields(fields) {
@@ -203,11 +140,11 @@ function cloneFields(fields) {
203
140
  function createDraftGroup(group) {
204
141
  return {
205
142
  draftId: createDraftId(),
206
- group: cloneValue({
143
+ group: JSON.parse(JSON.stringify(toRaw({
207
144
  id: group.id,
208
145
  style: group.style,
209
146
  fields: []
210
- }),
147
+ }))),
211
148
  fields: cloneFields(group.fields)
212
149
  };
213
150
  }
@@ -227,7 +164,7 @@ function getFieldTypeLabel(type) {
227
164
  return t(`field-type-${type}`);
228
165
  }
229
166
  function isPassiveField(field) {
230
- return field.type === "empty";
167
+ return field.type === "slot" || field.type === "empty";
231
168
  }
232
169
  function isMarkdownField(field) {
233
170
  return field.type === "markdown";
@@ -239,42 +176,33 @@ function isMarkdownContentField(field) {
239
176
  return isMarkdownField(field) || isMarkdownBodyField(field);
240
177
  }
241
178
  function hasFieldLabel(field) {
242
- return field.type !== "empty" && !isMarkdownBodyField(field);
179
+ return !isPassiveField(field) && !isMarkdownBodyField(field);
243
180
  }
244
181
  function supportsFieldCellStyles(field) {
245
- return field.type !== "empty" && !isMarkdownBodyField(field);
182
+ return !isPassiveField(field) && !isMarkdownBodyField(field);
246
183
  }
247
184
  function isPathlessField(field) {
248
- return field.type === "slot" || field.type === "empty" || isMarkdownContentField(field) || field.type === "container";
185
+ return isPassiveField(field) || isMarkdownContentField(field);
249
186
  }
250
187
  function isInteractiveField(field) {
251
188
  return !isPathlessField(field);
252
189
  }
253
- function getSlotFieldLabel(field) {
254
- return getFieldChineseTitle(field) ?? getFieldTypeLabel("slot");
190
+ function getSlotFieldLabel(_) {
191
+ return getFieldTypeLabel("slot");
255
192
  }
256
193
  function getEmptyFieldLabel(_) {
257
194
  return getFieldTypeLabel("empty");
258
195
  }
259
- function getContainerFieldLabel(field) {
260
- return getFieldChineseTitle(field) ?? getUnnamedFieldLabel(field);
261
- }
262
196
  function getUnnamedFieldLabel(field) {
263
197
  return t("unnamed-field", {
264
198
  type: getFieldTypeLabel(field.type)
265
199
  });
266
200
  }
267
- function getFieldTitleValue(field) {
268
- if (!hasFieldLabel(field)) {
269
- return createDefaultLocaleValue();
270
- }
271
- return field.title ?? createDefaultLocaleValue();
272
- }
273
201
  function getFieldChineseTitle(field) {
274
202
  if (!hasFieldLabel(field)) {
275
203
  return void 0;
276
204
  }
277
- const zhTitle = field.title?.find((item) => item.locale === "zh");
205
+ const zhTitle = field.title.find((item) => item.locale === "zh");
278
206
  if (!zhTitle) {
279
207
  return void 0;
280
208
  }
@@ -285,9 +213,6 @@ function getFieldListLabel(field) {
285
213
  if (field.type === "slot") {
286
214
  return getSlotFieldLabel(field);
287
215
  }
288
- if (field.type === "container") {
289
- return getContainerFieldLabel(field);
290
- }
291
216
  if (field.type === "empty") {
292
217
  return getEmptyFieldLabel(field);
293
218
  }
@@ -298,49 +223,32 @@ function getGroupListLabel(index) {
298
223
  index: index + 1
299
224
  });
300
225
  }
301
- function buildFieldSearchMeta(field) {
302
- return isPathlessField(field) ? [field.id, getFieldChineseTitle(field)].filter(Boolean).join(" ") : [field.path, field.id, getFieldChineseTitle(field)].filter(Boolean).join(" ");
303
- }
304
- function flattenFieldItems(fields, depth, groupItemId) {
305
- return fields.flatMap((item) => {
306
- const currentItem = {
307
- itemId: item.draftId,
308
- groupItemId,
309
- fieldId: item.field.id,
310
- label: getFieldListLabel(item.field),
311
- path: isPathlessField(item.field) ? void 0 : item.field.path,
312
- searchMeta: buildFieldSearchMeta(item.field),
313
- type: item.field.type,
314
- depth
315
- };
316
- if (item.field.type !== "container") {
317
- return [currentItem];
318
- }
319
- return [
320
- currentItem,
321
- ...flattenFieldItems(item.children, depth + 1, groupItemId)
322
- ];
323
- });
324
- }
325
- const rootFieldItems = computed(() => flattenFieldItems(draftFields.value, 0));
226
+ const rootFieldItems = computed(() => draftFields.value.map((item) => ({
227
+ itemId: item.draftId,
228
+ fieldId: item.field.id,
229
+ label: getFieldListLabel(item.field),
230
+ path: isPathlessField(item.field) ? void 0 : item.field.path,
231
+ searchMeta: isPathlessField(item.field) ? item.field.id : [item.field.path, item.field.id].filter(Boolean).join(" "),
232
+ type: item.field.type
233
+ })));
326
234
  const groupItems = computed(() => draftGroups.value.map((group, index) => {
235
+ const fields = group.fields.map((item) => ({
236
+ itemId: item.draftId,
237
+ groupItemId: group.draftId,
238
+ fieldId: item.field.id,
239
+ label: getFieldListLabel(item.field),
240
+ path: isPathlessField(item.field) ? void 0 : item.field.path,
241
+ searchMeta: isPathlessField(item.field) ? item.field.id : [item.field.path, item.field.id].filter(Boolean).join(" "),
242
+ type: item.field.type
243
+ }));
327
244
  return {
328
245
  itemId: group.draftId,
329
246
  groupId: group.group.id,
330
247
  label: getGroupListLabel(index),
331
248
  searchMeta: group.group.id,
332
- fields: flattenFieldItems(group.fields, 0, group.draftId)
249
+ fields
333
250
  };
334
251
  }));
335
- function getFieldOwnerValue(owner) {
336
- if (owner.kind === "root") {
337
- return ROOT_FIELD_GROUP_VALUE;
338
- }
339
- if (owner.kind === "group") {
340
- return `${GROUP_OWNER_PREFIX}${owner.draftId}`;
341
- }
342
- return `${CONTAINER_OWNER_PREFIX}${owner.draftId}`;
343
- }
344
252
  const filteredGroupItems = computed(() => {
345
253
  if (!normalizedSearch.value) {
346
254
  return groupItems.value;
@@ -371,52 +279,6 @@ const filteredRootFieldItems = computed(() => {
371
279
  });
372
280
  });
373
281
  const selectedItemLabel = computed(() => selectedField.value ? getFieldListLabel(selectedField.value.field) : selectedGroup.value ? getGroupListLabel(Math.max(draftGroups.value.findIndex((group) => group.draftId === selectedGroup.value?.draftId), 0)) : generalItem.value.label);
374
- function collectDraftFieldIds(fields) {
375
- return fields.flatMap((field) => [field.draftId, ...collectDraftFieldIds(field.children)]);
376
- }
377
- function buildFieldOwnerOptions(fields, depth, options, excludedDraftIds) {
378
- for (const field of fields) {
379
- if (field.field.type !== "container") {
380
- continue;
381
- }
382
- if (!excludedDraftIds.has(field.draftId)) {
383
- options.push({
384
- value: getFieldOwnerValue({
385
- kind: "container",
386
- draftId: field.draftId
387
- }),
388
- label: `${" ".repeat(depth)}${getFieldListLabel(field.field)}`
389
- });
390
- }
391
- buildFieldOwnerOptions(field.children, depth + 1, options, excludedDraftIds);
392
- }
393
- }
394
- const selectedFieldOwnerOptions = computed(() => {
395
- const options = [{
396
- value: ROOT_FIELD_GROUP_VALUE,
397
- label: t("field-group-none")
398
- }];
399
- const excludedDraftIds = new Set(
400
- selectedField.value ? collectDraftFieldIds([selectedField.value]) : []
401
- );
402
- for (const group of groupItems.value) {
403
- options.push({
404
- value: `${GROUP_OWNER_PREFIX}${group.itemId}`,
405
- label: group.label
406
- });
407
- }
408
- buildFieldOwnerOptions(draftFields.value, 1, options, excludedDraftIds);
409
- for (const group of draftGroups.value) {
410
- buildFieldOwnerOptions(group.fields, 1, options, excludedDraftIds);
411
- }
412
- return options;
413
- });
414
- const selectedContainerChildItems = computed(() => {
415
- if (selectedField.value?.field.type !== "container") {
416
- return [];
417
- }
418
- return flattenFieldItems(selectedField.value.children, 1);
419
- });
420
282
  function getFieldErrorKey(draftId, fieldKey) {
421
283
  return `${draftId}:${fieldKey}`;
422
284
  }
@@ -585,27 +447,8 @@ function normalizeField(field) {
585
447
  case "slot":
586
448
  return {
587
449
  ...field,
588
- title: field.title,
589
- hideLabel: field.hideLabel ? true : void 0,
590
- required: field.required ? true : void 0,
591
- hidden: normalizeOptionalString(field.hidden ?? ""),
592
- labelStyle: normalizeOptionalString(field.labelStyle ?? ""),
593
- contentStyle: normalizeOptionalString(field.contentStyle ?? ""),
594
450
  style: normalizeOptionalString(field.style ?? "")
595
451
  };
596
- case "container":
597
- return {
598
- ...field,
599
- hideLabel: field.hideLabel ? true : void 0,
600
- required: field.required ? true : void 0,
601
- hidden: normalizeOptionalString(field.hidden ?? ""),
602
- labelStyle: normalizeOptionalString(field.labelStyle ?? ""),
603
- contentStyle: normalizeOptionalString(field.contentStyle ?? ""),
604
- bodyOrientation: field.bodyOrientation ? normalizeOrientation(field.bodyOrientation) : void 0,
605
- bodyBordered: field.bodyBordered ? true : void 0,
606
- bodyStyle: normalizeOptionalString(field.bodyStyle ?? ""),
607
- fields: []
608
- };
609
452
  case "empty":
610
453
  return {
611
454
  ...field,
@@ -679,14 +522,6 @@ function createField(type) {
679
522
  path: "",
680
523
  title
681
524
  };
682
- case "container":
683
- return {
684
- id,
685
- type,
686
- hideLabel: void 0,
687
- title,
688
- fields: []
689
- };
690
525
  case "empty":
691
526
  return {
692
527
  id,
@@ -734,120 +569,6 @@ function moveField(fields, oldIndex, newIndex) {
734
569
  nextFields.splice(newIndex, 0, movedField);
735
570
  return nextFields;
736
571
  }
737
- function mapDraftFields(fields, updater) {
738
- return fields.map((item) => {
739
- const nextItem = updater(item);
740
- if (nextItem.field.type !== "container") {
741
- return nextItem;
742
- }
743
- return {
744
- ...nextItem,
745
- children: mapDraftFields(nextItem.children, updater)
746
- };
747
- });
748
- }
749
- function updateContainerFields(fields, containerDraftId, updater) {
750
- return fields.map((item) => {
751
- if (item.field.type !== "container") {
752
- return item;
753
- }
754
- if (item.draftId === containerDraftId) {
755
- return {
756
- ...item,
757
- children: updater(item.children)
758
- };
759
- }
760
- return {
761
- ...item,
762
- children: updateContainerFields(item.children, containerDraftId, updater)
763
- };
764
- });
765
- }
766
- function findContainerChildren(fields, containerDraftId) {
767
- for (const item of fields) {
768
- if (item.field.type !== "container") {
769
- continue;
770
- }
771
- if (item.draftId === containerDraftId) {
772
- return item.children;
773
- }
774
- const children = findContainerChildren(item.children, containerDraftId);
775
- if (children) {
776
- return children;
777
- }
778
- }
779
- return void 0;
780
- }
781
- function updateOwnerFields(owner, updater) {
782
- if (owner.kind === "root") {
783
- draftFields.value = updater(draftFields.value);
784
- return;
785
- }
786
- if (owner.kind === "group") {
787
- draftGroups.value = draftGroups.value.map((group) => group.draftId === owner.draftId ? {
788
- ...group,
789
- fields: updater(group.fields)
790
- } : group);
791
- return;
792
- }
793
- draftFields.value = updateContainerFields(draftFields.value, owner.draftId, updater);
794
- draftGroups.value = draftGroups.value.map((group) => ({
795
- ...group,
796
- fields: updateContainerFields(group.fields, owner.draftId, updater)
797
- }));
798
- }
799
- function getOwnerFields(owner) {
800
- if (owner.kind === "root") {
801
- return draftFields.value;
802
- }
803
- if (owner.kind === "group") {
804
- return draftGroups.value.find((group) => group.draftId === owner.draftId)?.fields ?? [];
805
- }
806
- return findContainerChildren(draftFields.value, owner.draftId) ?? draftGroups.value.flatMap((group) => findContainerChildren(group.fields, owner.draftId) ?? []);
807
- }
808
- function removeFieldFromOwner(owner, fieldDraftId) {
809
- let movedField;
810
- updateOwnerFields(owner, (fields) => fields.filter((field) => {
811
- if (field.draftId !== fieldDraftId) {
812
- return true;
813
- }
814
- movedField = field;
815
- return false;
816
- }));
817
- return movedField;
818
- }
819
- function insertFieldIntoOwner(owner, field, newIndex) {
820
- updateOwnerFields(owner, (fields) => {
821
- const nextFields = fields.slice();
822
- const insertIndex = Math.min(Math.max(newIndex, 0), nextFields.length);
823
- nextFields.splice(insertIndex, 0, field);
824
- return nextFields;
825
- });
826
- }
827
- function getOwnerItemCount(owner) {
828
- return getOwnerFields(owner).length;
829
- }
830
- function getFieldOwnerFromValue(value) {
831
- const ownerValue = String(value);
832
- if (ownerValue === ROOT_FIELD_GROUP_VALUE) {
833
- return {
834
- kind: "root"
835
- };
836
- }
837
- if (ownerValue.startsWith(GROUP_OWNER_PREFIX)) {
838
- return {
839
- kind: "group",
840
- draftId: ownerValue.slice(GROUP_OWNER_PREFIX.length)
841
- };
842
- }
843
- if (ownerValue.startsWith(CONTAINER_OWNER_PREFIX)) {
844
- return {
845
- kind: "container",
846
- draftId: ownerValue.slice(CONTAINER_OWNER_PREFIX.length)
847
- };
848
- }
849
- return void 0;
850
- }
851
572
  function setSortableGroupListRef(groupDraftId, element) {
852
573
  sortableGroupListRefs.value[groupDraftId] = element instanceof HTMLElement ? element : null;
853
574
  }
@@ -883,41 +604,84 @@ function reorderRootFields(oldIndex, newIndex) {
883
604
  draftFields.value = moveField(draftFields.value, oldIndex, newIndex);
884
605
  }
885
606
  function moveFieldBetweenGroups(sourceGroupDraftId, targetGroupDraftId, fieldDraftId, newIndex) {
886
- const movedField = removeFieldFromOwner({
887
- kind: "group",
888
- draftId: sourceGroupDraftId
889
- }, fieldDraftId);
607
+ let movedField;
608
+ draftGroups.value = draftGroups.value.map((group) => {
609
+ if (group.draftId === sourceGroupDraftId) {
610
+ const nextFields = group.fields.filter((field) => {
611
+ if (field.draftId !== fieldDraftId) {
612
+ return true;
613
+ }
614
+ movedField = field;
615
+ return false;
616
+ });
617
+ return {
618
+ ...group,
619
+ fields: nextFields
620
+ };
621
+ }
622
+ return group;
623
+ });
890
624
  if (!movedField) {
891
625
  return;
892
626
  }
893
- insertFieldIntoOwner({
894
- kind: "group",
895
- draftId: targetGroupDraftId
896
- }, movedField, newIndex);
627
+ const nextMovedField = movedField;
628
+ draftGroups.value = draftGroups.value.map((group) => {
629
+ if (group.draftId !== targetGroupDraftId) {
630
+ return group;
631
+ }
632
+ const nextFields = group.fields.slice();
633
+ const insertIndex = Math.min(Math.max(newIndex, 0), nextFields.length);
634
+ nextFields.splice(insertIndex, 0, nextMovedField);
635
+ return {
636
+ ...group,
637
+ fields: nextFields
638
+ };
639
+ });
897
640
  }
898
641
  function moveFieldToRoot(sourceGroupDraftId, fieldDraftId, newIndex) {
899
- const movedField = removeFieldFromOwner({
900
- kind: "group",
901
- draftId: sourceGroupDraftId
902
- }, fieldDraftId);
642
+ let movedField;
643
+ draftGroups.value = draftGroups.value.map((group) => {
644
+ if (group.draftId !== sourceGroupDraftId) {
645
+ return group;
646
+ }
647
+ const nextFields2 = group.fields.filter((field) => {
648
+ if (field.draftId !== fieldDraftId) {
649
+ return true;
650
+ }
651
+ movedField = field;
652
+ return false;
653
+ });
654
+ return {
655
+ ...group,
656
+ fields: nextFields2
657
+ };
658
+ });
903
659
  if (!movedField) {
904
660
  return;
905
661
  }
906
- insertFieldIntoOwner({
907
- kind: "root"
908
- }, movedField, newIndex);
662
+ const nextFields = draftFields.value.slice();
663
+ const insertIndex = Math.min(Math.max(newIndex, 0), nextFields.length);
664
+ nextFields.splice(insertIndex, 0, movedField);
665
+ draftFields.value = nextFields;
909
666
  }
910
667
  function moveRootFieldToGroup(targetGroupDraftId, fieldDraftId, newIndex) {
911
- const movedField = removeFieldFromOwner({
912
- kind: "root"
913
- }, fieldDraftId);
668
+ const movedField = draftFields.value.find((field) => field.draftId === fieldDraftId);
914
669
  if (!movedField) {
915
670
  return;
916
671
  }
917
- insertFieldIntoOwner({
918
- kind: "group",
919
- draftId: targetGroupDraftId
920
- }, movedField, newIndex);
672
+ draftFields.value = draftFields.value.filter((field) => field.draftId !== fieldDraftId);
673
+ draftGroups.value = draftGroups.value.map((group) => {
674
+ if (group.draftId !== targetGroupDraftId) {
675
+ return group;
676
+ }
677
+ const nextFields = group.fields.slice();
678
+ const insertIndex = Math.min(Math.max(newIndex, 0), nextFields.length);
679
+ nextFields.splice(insertIndex, 0, movedField);
680
+ return {
681
+ ...group,
682
+ fields: nextFields
683
+ };
684
+ });
921
685
  }
922
686
  async function refreshSortable() {
923
687
  for (const sortable of sortables.value) {
@@ -1069,14 +833,14 @@ function updateDraftStyle(value) {
1069
833
  draftStyle.value = normalizeOptionalString(String(value));
1070
834
  }
1071
835
  function updateDraftField(draftId, updater) {
1072
- draftFields.value = mapDraftFields(draftFields.value, (item) => item.draftId === draftId ? {
1073
- ...item,
836
+ draftFields.value = draftFields.value.map((item) => item.draftId === draftId ? {
837
+ draftId: item.draftId,
1074
838
  field: updater(item.field)
1075
839
  } : item);
1076
840
  draftGroups.value = draftGroups.value.map((group) => ({
1077
841
  ...group,
1078
- fields: mapDraftFields(group.fields, (item) => item.draftId === draftId ? {
1079
- ...item,
842
+ fields: group.fields.map((item) => item.draftId === draftId ? {
843
+ draftId: item.draftId,
1080
844
  field: updater(item.field)
1081
845
  } : item)
1082
846
  }));
@@ -1097,39 +861,38 @@ function updateSelectedGroupStyle(value) {
1097
861
  }
1098
862
  function updateSelectedFieldGroup(value) {
1099
863
  const selected = selectedField.value;
1100
- const sourceOwner = selectedFieldOwner.value;
1101
- const targetOwner = getFieldOwnerFromValue(value);
1102
- if (!selected || !sourceOwner || !targetOwner) {
864
+ const sourceGroup = selectedFieldGroup.value;
865
+ if (!selected) {
1103
866
  return;
1104
867
  }
1105
- if (getFieldOwnerValue(sourceOwner) === getFieldOwnerValue(targetOwner)) {
868
+ const targetGroupDraftId = String(value);
869
+ if (!targetGroupDraftId) {
1106
870
  return;
1107
871
  }
1108
- const movedField = removeFieldFromOwner(sourceOwner, selected.draftId);
1109
- if (!movedField) {
872
+ if (targetGroupDraftId === ROOT_FIELD_GROUP_VALUE) {
873
+ if (!sourceGroup) {
874
+ return;
875
+ }
876
+ moveFieldToRoot(sourceGroup.draftId, selected.draftId, draftFields.value.length);
1110
877
  return;
1111
878
  }
1112
- insertFieldIntoOwner(targetOwner, movedField, getOwnerItemCount(targetOwner));
1113
- }
1114
- function getInsertionOwner() {
1115
- if (selectedField.value?.field.type === "container") {
1116
- return {
1117
- kind: "container",
1118
- draftId: selectedField.value.draftId
1119
- };
879
+ if (sourceGroup && targetGroupDraftId === sourceGroup.draftId) {
880
+ return;
1120
881
  }
882
+ if (!sourceGroup) {
883
+ moveRootFieldToGroup(targetGroupDraftId, selected.draftId, Number.MAX_SAFE_INTEGER);
884
+ return;
885
+ }
886
+ moveFieldBetweenGroups(sourceGroup.draftId, targetGroupDraftId, selected.draftId, Number.MAX_SAFE_INTEGER);
887
+ }
888
+ function getInsertionGroupDraftId() {
1121
889
  if (selectedGroup.value) {
1122
- return {
1123
- kind: "group",
1124
- draftId: selectedGroup.value.draftId
1125
- };
890
+ return selectedGroup.value.draftId;
1126
891
  }
1127
- if (selectedFieldOwner.value) {
1128
- return selectedFieldOwner.value;
892
+ if (selectedFieldGroup.value) {
893
+ return selectedFieldGroup.value.draftId;
1129
894
  }
1130
- return {
1131
- kind: "root"
1132
- };
895
+ return void 0;
1133
896
  }
1134
897
  function addGroup() {
1135
898
  const draftGroup = createDraftGroup(createGroup());
@@ -1139,10 +902,36 @@ function addGroup() {
1139
902
  }
1140
903
  function addField(type) {
1141
904
  const draftField = createDraftField(createField(type));
1142
- const targetOwner = getInsertionOwner();
1143
- const ownerFields = getOwnerFields(targetOwner);
1144
- const currentIndex = selectedField.value && selectedFieldOwner.value && getFieldOwnerValue(selectedFieldOwner.value) === getFieldOwnerValue(targetOwner) && selectedField.value.field.type !== "container" ? ownerFields.findIndex((field) => field.draftId === selectedField.value?.draftId) : -1;
1145
- insertFieldIntoOwner(targetOwner, draftField, currentIndex >= 0 ? currentIndex + 1 : ownerFields.length);
905
+ const targetGroupDraftId = getInsertionGroupDraftId();
906
+ if (targetGroupDraftId) {
907
+ draftGroups.value = draftGroups.value.map((group) => {
908
+ if (group.draftId !== targetGroupDraftId) {
909
+ return group;
910
+ }
911
+ if (selectedFieldGroup.value?.draftId === targetGroupDraftId && selectedField.value) {
912
+ const currentIndex = group.fields.findIndex((field) => field.draftId === selectedField.value?.draftId);
913
+ if (currentIndex >= 0) {
914
+ const nextFields = group.fields.slice();
915
+ nextFields.splice(currentIndex + 1, 0, draftField);
916
+ return {
917
+ ...group,
918
+ fields: nextFields
919
+ };
920
+ }
921
+ }
922
+ return {
923
+ ...group,
924
+ fields: [...group.fields, draftField]
925
+ };
926
+ });
927
+ } else if (selectedField.value && !selectedFieldGroup.value) {
928
+ const currentIndex = draftFields.value.findIndex((field) => field.draftId === selectedField.value?.draftId);
929
+ const nextFields = draftFields.value.slice();
930
+ nextFields.splice(currentIndex >= 0 ? currentIndex + 1 : nextFields.length, 0, draftField);
931
+ draftFields.value = nextFields;
932
+ } else {
933
+ draftFields.value = [...draftFields.value, draftField];
934
+ }
1146
935
  selectedItemId.value = draftField.draftId;
1147
936
  clearFieldErrors(draftField.draftId);
1148
937
  }
@@ -1157,7 +946,7 @@ function deleteGroup(itemId) {
1157
946
  if (deletedGroup) {
1158
947
  clearFieldErrors(deletedGroup.draftId);
1159
948
  for (const field of deletedGroup.fields) {
1160
- clearNestedFieldErrors(field);
949
+ clearFieldErrors(field.draftId);
1161
950
  }
1162
951
  }
1163
952
  if (selectedItemId.value !== itemId) {
@@ -1167,33 +956,30 @@ function deleteGroup(itemId) {
1167
956
  selectedItemId.value = nextGroup?.draftId ?? "general";
1168
957
  }
1169
958
  function deleteField(itemId) {
1170
- const owner = selectedItemId.value === itemId ? selectedFieldOwner.value : findFieldOwnerByDraftId(itemId);
1171
- if (!owner) {
1172
- return;
1173
- }
1174
- const currentFields = getOwnerFields(owner);
1175
- const deleteIndex = currentFields.findIndex((field) => field.draftId === itemId);
1176
- if (deleteIndex < 0) {
1177
- return;
1178
- }
1179
- removeFieldFromOwner(owner, itemId);
1180
- const nextFields = getOwnerFields(owner);
1181
- const nextField = nextFields[deleteIndex] ?? nextFields[deleteIndex - 1];
959
+ let nextSelectedItemId;
960
+ const rootDeleteIndex = draftFields.value.findIndex((field) => field.draftId === itemId);
961
+ if (rootDeleteIndex >= 0) {
962
+ const nextFields = draftFields.value.filter((field) => field.draftId !== itemId);
963
+ const nextField = nextFields[rootDeleteIndex] ?? nextFields[rootDeleteIndex - 1];
964
+ draftFields.value = nextFields;
965
+ nextSelectedItemId = nextField?.draftId ?? "general";
966
+ }
967
+ draftGroups.value = draftGroups.value.map((group) => {
968
+ const deleteIndex = group.fields.findIndex((field) => field.draftId === itemId);
969
+ if (deleteIndex < 0) {
970
+ return group;
971
+ }
972
+ const nextFields = group.fields.filter((field) => field.draftId !== itemId);
973
+ const nextField = nextFields[deleteIndex] ?? nextFields[deleteIndex - 1];
974
+ nextSelectedItemId = nextField?.draftId ?? group.draftId;
975
+ return {
976
+ ...group,
977
+ fields: nextFields
978
+ };
979
+ });
1182
980
  clearFieldErrors(itemId);
1183
981
  if (selectedItemId.value === itemId) {
1184
- if (nextField) {
1185
- selectedItemId.value = nextField.draftId;
1186
- return;
1187
- }
1188
- if (owner.kind === "group") {
1189
- selectedItemId.value = owner.draftId;
1190
- return;
1191
- }
1192
- if (owner.kind === "container") {
1193
- selectedItemId.value = owner.draftId;
1194
- return;
1195
- }
1196
- selectedItemId.value = "general";
982
+ selectedItemId.value = nextSelectedItemId ?? "general";
1197
983
  }
1198
984
  }
1199
985
  function handleAddItem(type) {
@@ -1206,9 +992,6 @@ function handleAddItem(type) {
1206
992
  function isFieldLabelConfigurable(field) {
1207
993
  return hasFieldLabel(field);
1208
994
  }
1209
- function hasDirectFieldStyle(field) {
1210
- return field.type !== "container";
1211
- }
1212
995
  function getFieldHideLabelValue(field) {
1213
996
  if (!isFieldLabelConfigurable(field)) {
1214
997
  return false;
@@ -1296,51 +1079,14 @@ function updateSelectedFieldPath(value) {
1296
1079
  }
1297
1080
  function updateSelectedFieldStyle(value) {
1298
1081
  const selected = selectedField.value;
1299
- if (!selected || !hasDirectFieldStyle(selected.field)) {
1082
+ if (!selected) {
1300
1083
  return;
1301
1084
  }
1302
1085
  clearFieldError(selected.draftId, "style");
1303
- updateDraftField(selected.draftId, (field) => {
1304
- if (!hasDirectFieldStyle(field)) {
1305
- return field;
1306
- }
1307
- return {
1308
- ...field,
1309
- style: normalizeOptionalString(String(value))
1310
- };
1311
- });
1312
- }
1313
- function updateSelectedContainerBodyOrientation(value) {
1314
- const selected = selectedField.value;
1315
- if (!selected || selected.field.type !== "container") {
1316
- return;
1317
- }
1318
- const normalizedValue = normalizeOrientation(value);
1319
- updateDraftField(selected.draftId, (field) => field.type === "container" ? {
1320
- ...field,
1321
- bodyOrientation: normalizedValue === "horizontal" ? void 0 : normalizedValue
1322
- } : field);
1323
- }
1324
- function updateSelectedContainerBodyBordered(value) {
1325
- const selected = selectedField.value;
1326
- if (!selected || selected.field.type !== "container") {
1327
- return;
1328
- }
1329
- updateDraftField(selected.draftId, (field) => field.type === "container" ? {
1330
- ...field,
1331
- bodyBordered: value ? true : void 0
1332
- } : field);
1333
- }
1334
- function updateSelectedContainerBodyStyle(value) {
1335
- const selected = selectedField.value;
1336
- if (!selected || selected.field.type !== "container") {
1337
- return;
1338
- }
1339
- clearFieldError(selected.draftId, "bodyStyle");
1340
- updateDraftField(selected.draftId, (field) => field.type === "container" ? {
1086
+ updateDraftField(selected.draftId, (field) => ({
1341
1087
  ...field,
1342
- bodyStyle: normalizeOptionalString(String(value))
1343
- } : field);
1088
+ style: normalizeOptionalString(String(value))
1089
+ }));
1344
1090
  }
1345
1091
  function updateSelectedFieldLabelStyle(value) {
1346
1092
  const selected = selectedField.value;
@@ -1399,17 +1145,17 @@ function updateSelectedFieldInitialValue(value) {
1399
1145
  }
1400
1146
  function updateSelectedFieldRequired(value) {
1401
1147
  const selected = selectedField.value;
1402
- if (!selected || selected.field.type !== "slot" && selected.field.type !== "container" && !isInteractiveField(selected.field)) {
1148
+ if (!selected || !isInteractiveField(selected.field)) {
1403
1149
  return;
1404
1150
  }
1405
1151
  updateDraftField(selected.draftId, (field) => {
1406
- if (field.type === "slot" || field.type === "container" || isInteractiveField(field)) {
1407
- return {
1408
- ...field,
1409
- required: value ? true : void 0
1410
- };
1152
+ if (!isInteractiveField(field)) {
1153
+ return field;
1411
1154
  }
1412
- return field;
1155
+ return {
1156
+ ...field,
1157
+ required: value ? true : void 0
1158
+ };
1413
1159
  });
1414
1160
  }
1415
1161
  function updateSelectedStringDiscardEmpty(value) {
@@ -1881,10 +1627,6 @@ function getSchemaIssues(field) {
1881
1627
  const result = SlotFieldC.safeParse(field);
1882
1628
  return result.success ? [] : result.error.issues;
1883
1629
  }
1884
- case "container": {
1885
- const result = ContainerFieldC.safeParse(field);
1886
- return result.success ? [] : result.error.issues;
1887
- }
1888
1630
  case "empty": {
1889
1631
  const result = EmptyFieldC.safeParse(field);
1890
1632
  return result.success ? [] : result.error.issues;
@@ -1920,32 +1662,9 @@ function normalizeGroup(group) {
1920
1662
  return {
1921
1663
  ...group,
1922
1664
  style: normalizeOptionalString(group.style ?? ""),
1923
- fields: group.fields
1665
+ fields: group.fields.map((field) => normalizeField(field))
1924
1666
  };
1925
1667
  }
1926
- function normalizeDraftField(item) {
1927
- const normalizedField = normalizeField(item.field);
1928
- return {
1929
- ...item,
1930
- field: normalizedField,
1931
- children: item.children.map((child) => normalizeDraftField(child))
1932
- };
1933
- }
1934
- function buildFieldFromDraft(item) {
1935
- if (item.field.type !== "container") {
1936
- return item.field;
1937
- }
1938
- return {
1939
- ...item.field,
1940
- fields: item.children.map((child) => buildFieldFromDraft(child))
1941
- };
1942
- }
1943
- function clearNestedFieldErrors(item) {
1944
- clearFieldErrors(item.draftId);
1945
- for (const child of item.children) {
1946
- clearNestedFieldErrors(child);
1947
- }
1948
- }
1949
1668
  function validateDraftFields(fields, errors, idOwners, pathOwners) {
1950
1669
  let firstInvalidItemId;
1951
1670
  for (const item of fields) {
@@ -1983,21 +1702,25 @@ function validateDraftFields(fields, errors, idOwners, pathOwners) {
1983
1702
  setError(errors, issueKey, getSchemaIssueMessage(issue, issuePath));
1984
1703
  firstInvalidItemId = firstInvalidItemId ?? item.draftId;
1985
1704
  }
1986
- const childInvalidItemId = validateDraftFields(item.children, errors, idOwners, pathOwners);
1987
- firstInvalidItemId = firstInvalidItemId ?? childInvalidItemId;
1988
1705
  }
1989
1706
  return firstInvalidItemId;
1990
1707
  }
1991
1708
  function validateDraftState() {
1992
1709
  const errors = {};
1993
- const normalizedFields = draftFields.value.map((item) => normalizeDraftField(item));
1710
+ const normalizedFields = draftFields.value.map((item) => ({
1711
+ draftId: item.draftId,
1712
+ field: normalizeField(item.field)
1713
+ }));
1994
1714
  const normalizedGroups = draftGroups.value.map((group) => ({
1995
1715
  draftId: group.draftId,
1996
1716
  group: normalizeGroup({
1997
1717
  ...group.group,
1998
- fields: group.fields.map((item) => buildFieldFromDraft(normalizeDraftField(item)))
1718
+ fields: group.fields.map((item) => item.field)
1999
1719
  }),
2000
- fields: group.fields.map((item) => normalizeDraftField(item))
1720
+ fields: group.fields.map((item) => ({
1721
+ draftId: item.draftId,
1722
+ field: normalizeField(item.field)
1723
+ }))
2001
1724
  }));
2002
1725
  const groupIdOwners = {};
2003
1726
  const idOwners = {};
@@ -2059,10 +1782,10 @@ function buildDraftConfig() {
2059
1782
  return void 0;
2060
1783
  }
2061
1784
  const nextBody = {
2062
- fields: validatedDraftState.normalizedFields.map((item) => buildFieldFromDraft(item)),
1785
+ fields: validatedDraftState.normalizedFields.map((item) => item.field),
2063
1786
  groups: validatedDraftState.normalizedGroups.map((group) => ({
2064
1787
  ...group.group,
2065
- fields: group.fields.map((item) => buildFieldFromDraft(item))
1788
+ fields: group.fields.map((item) => item.field)
2066
1789
  }))
2067
1790
  };
2068
1791
  if (draftOrientation.value !== "horizontal") {
@@ -2147,12 +1870,10 @@ function buildDslGuideMarkdown() {
2147
1870
  "- \u4EE3\u7801\u91CC\u5E94\u5148\u751F\u6210\u5E76\u4F7F\u7528 UUID\uFF0C\u518D\u628A\u540C\u4E00\u4E2A `id` \u7C98\u8D34\u56DE\u5B57\u6BB5\u914D\u7F6E\u3002",
2148
1871
  "- \u6240\u6709\u5B57\u6BB5\u90FD\u5FC5\u987B\u5305\u542B\u552F\u4E00\u4E14\u5408\u6CD5\u7684 UUID `id`\u3002",
2149
1872
  "- \u53EA\u6709\u53EF\u7ED1\u5B9A\u503C\u7684\u5B57\u6BB5\u53EF\u4EE5\u914D\u7F6E `path`\uFF0C\u5E76\u53C2\u4E0E\u8868\u5355\u503C\u8BFB\u5199\u3002",
2150
- "- `slot` \u5B57\u6BB5\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF1B\u53EF\u9009 `title`\u3001`hideLabel`\u3001`required`\u3001`hidden`\u3001`labelStyle`\u3001`contentStyle` \u4E0E `style`\u3002",
2151
- "- `container` \u5B57\u6BB5\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF1B\u4F7F\u7528 `fields` \u627F\u8F7D\u9012\u5F52\u5D4C\u5957\u5B57\u6BB5\uFF0C\u53EF\u9009 `bodyOrientation`\u3001`bodyBordered` \u4E0E `bodyStyle` \u63A7\u5236\u5185\u90E8\u5E03\u5C40\u3002",
2152
- "- `empty` \u5B57\u6BB5\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF0C\u53EA\u5141\u8BB8 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002",
1873
+ "- `slot` \u548C `empty` \u5B57\u6BB5\u90FD\u4E0D\u4F1A\u7ED1\u5B9A\u6A21\u578B\u503C\uFF0C\u53EA\u5141\u8BB8 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002",
2153
1874
  "- `markdown` \u5B57\u6BB5\u4F7F\u7528 `title` \u4E0E `locale` \u5C55\u793A\u5E26\u6807\u7B7E\u7684 Markdown \u5185\u5BB9\uFF0C\u4E0D\u7ED1\u5B9A `path`\u3002",
2154
1875
  "- `markdown-body` \u5B57\u6BB5\u4F7F\u7528 `locale` \u5C55\u793A\u65E0\u6807\u7B7E\u7684\u7EAF Markdown \u5185\u5BB9\uFF0C\u53EF\u9009 `inline` \u63A7\u5236\u5185\u8054\u6E32\u67D3\uFF0C\u4E0D\u7ED1\u5B9A `path`\u3002",
2155
- "- \u9664 `empty` \u4E0E `markdown-body` \u5916\uFF0C\u5176\u5B83\u5E26\u6807\u7B7E\u5B57\u6BB5\u90FD\u53EF\u4EE5\u8BBE\u7F6E `hideLabel` \u9690\u85CF\u6807\u7B7E\u3002",
1876
+ "- \u9664 `slot`\u3001`empty` \u4E0E `markdown-body` \u5916\uFF0C\u5176\u5B83\u5E26\u6807\u7B7E\u5B57\u6BB5\u90FD\u53EF\u4EE5\u8BBE\u7F6E `hideLabel` \u9690\u85CF\u6807\u7B7E\u3002",
2156
1877
  "- \u666E\u901A\u5B57\u6BB5\u53EF\u989D\u5916\u4F7F\u7528 `labelStyle` \u4E0E `contentStyle`\uFF0C\u7528\u4E8E contents \u5E03\u5C40\u6A21\u5F0F\u4E0B\u5206\u522B\u63A7\u5236\u6807\u7B7E\u4E0E\u5185\u5BB9\u5355\u5143\u683C\u3002"
2157
1878
  ].join("\n");
2158
1879
  }
@@ -2164,12 +1885,10 @@ function buildMarkdownNotes() {
2164
1885
  "- \u6240\u6709\u5B57\u6BB5\u7EC4 `id` \u90FD\u5FC5\u987B\u552F\u4E00\u4E14\u7B26\u5408 UUID \u683C\u5F0F\u3002",
2165
1886
  "- \u6240\u6709\u5B57\u6BB5 `id` \u90FD\u5FC5\u987B\u552F\u4E00\u4E14\u7B26\u5408 UUID \u683C\u5F0F\u3002",
2166
1887
  "- \u5B57\u6BB5\u7EC4\u6CA1\u6709\u6807\u9898\uFF1B\u5982\u679C\u9700\u8981\u5206\u6BB5\u6807\u9898\u6216\u8BF4\u660E\uFF0C\u4F18\u5148\u63D2\u5165 `markdown-body` \u5B57\u6BB5\uFF1B\u9700\u8981\u6807\u7B7E\u884C\u65F6\u518D\u4F7F\u7528 `markdown` \u5B57\u6BB5\u3002",
2167
- "- `slot` \u5B57\u6BB5\u4E0D\u7ED1\u5B9A `path`\uFF0C\u53EF\u9009 `title`\u3001`hideLabel`\u3001`required`\u3001`hidden`\u3001`labelStyle`\u3001`contentStyle` \u4E0E `style`\u3002",
2168
- "- `container` \u5B57\u6BB5\u4E0D\u7ED1\u5B9A `path`\uFF0C\u901A\u8FC7 `fields` \u9012\u5F52\u5D4C\u5957\u5B50\u5B57\u6BB5\uFF0C\u4E0D\u652F\u6301\u5D4C\u5957 `groups`\u3002",
2169
- "- `empty` \u5B57\u6BB5\u53EA\u80FD\u4F7F\u7528 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002",
1888
+ "- `slot` \u4E0E `empty` \u5B57\u6BB5\u53EA\u80FD\u4F7F\u7528 `id`\u3001`type` \u548C\u53EF\u9009\u7684 `style`\u3002",
2170
1889
  "- `markdown` \u5B57\u6BB5\u4E0D\u4F7F\u7528 `path`\uFF0C\u5185\u5BB9\u6765\u81EA `title` \u4E0E `locale` \u672C\u5730\u5316 Markdown\u3002",
2171
1890
  "- `markdown-body` \u5B57\u6BB5\u4E0D\u4F7F\u7528 `path`\uFF0C\u5185\u5BB9\u6765\u81EA `locale` \u672C\u5730\u5316 Markdown\uFF0C\u53EF\u9009 `inline` \u63A7\u5236\u6E32\u67D3\u65B9\u5F0F\u3002",
2172
- "- \u9664 `empty` \u4E0E `markdown-body` \u5916\uFF0C\u5176\u5B83\u5E26\u6807\u7B7E\u5B57\u6BB5\u90FD\u53EF\u4EE5\u8BBE\u7F6E `hideLabel`\u3002",
1891
+ "- \u9664 `slot`\u3001`empty` \u4E0E `markdown-body` \u5916\uFF0C\u5176\u5B83\u5E26\u6807\u7B7E\u5B57\u6BB5\u90FD\u53EF\u4EE5\u8BBE\u7F6E `hideLabel`\u3002",
2173
1892
  "- \u666E\u901A\u5B57\u6BB5\u5728 contents \u5E03\u5C40\u6A21\u5F0F\u4E0B\u53EF\u989D\u5916\u4F7F\u7528 `labelStyle` \u4E0E `contentStyle`\u3002",
2174
1893
  "- \u53EA\u6709\u5E26 `path` \u7684\u5B57\u6BB5\u624D\u8981\u6C42 `path` \u552F\u4E00\u4E14\u4E0D\u80FD\u4E3A\u7A7A\u3002",
2175
1894
  "- \u8868\u8FBE\u5F0F\u5B57\u6BB5\u5FC5\u987B\u4E25\u683C\u9075\u5B88 schema \u7EA6\u675F\uFF1B\u5982\u679C schema \u4E0D\u652F\u6301\uFF0C\u5C31\u76F4\u63A5\u8BF4\u660E\u9650\u5236\u3002"
@@ -2328,10 +2047,10 @@ function confirmChanges() {
2328
2047
  if (!result) {
2329
2048
  return;
2330
2049
  }
2331
- draftFields.value = result.normalizedFields.map((item) => createDraftField(buildFieldFromDraft(item)));
2050
+ draftFields.value = result.normalizedFields.map((item) => createDraftField(item.field));
2332
2051
  draftGroups.value = result.normalizedGroups.map((group) => createDraftGroup({
2333
2052
  ...group.group,
2334
- fields: group.fields.map((item) => buildFieldFromDraft(item))
2053
+ fields: group.fields.map((item) => item.field)
2335
2054
  }));
2336
2055
  emit("confirm", result.config);
2337
2056
  open.value = false;
@@ -2441,7 +2160,6 @@ function confirmChanges() {
2441
2160
  :data-field-id="item.fieldId"
2442
2161
  :data-field-path="item.path"
2443
2162
  :data-selected="selectedItemId === item.itemId ? 'true' : 'false'"
2444
- :style="{ paddingLeft: `${item.depth * 12 + 4}px` }"
2445
2163
  :class="cn(
2446
2164
  'flex min-w-0 items-center gap-2 rounded-md border p-1 transition-colors',
2447
2165
  selectedItemId === item.itemId ? 'border-(--primary)/25 bg-[color-mix(in_srgb,var(--primary)_10%,white)]' : 'border-transparent hover:border-zinc-200 hover:bg-zinc-50'
@@ -2554,9 +2272,8 @@ function confirmChanges() {
2554
2272
  :data-field-id="item.fieldId"
2555
2273
  :data-field-path="item.path"
2556
2274
  :data-selected="selectedItemId === item.itemId ? 'true' : 'false'"
2557
- :style="{ paddingLeft: `${item.depth * 12 + 16}px` }"
2558
2275
  :class="cn(
2559
- 'flex min-w-0 items-center gap-2 rounded-md border p-1 transition-colors',
2276
+ 'flex min-w-0 items-center gap-2 rounded-md border p-1 pl-4 transition-colors',
2560
2277
  selectedItemId === item.itemId ? 'border-(--primary)/25 bg-[color-mix(in_srgb,var(--primary)_10%,white)]' : 'border-transparent hover:border-zinc-200 hover:bg-zinc-50'
2561
2278
  )"
2562
2279
  >
@@ -2822,15 +2539,18 @@ function confirmChanges() {
2822
2539
  </span>
2823
2540
  <NativeSelect
2824
2541
  data-slot="fields-configurator-field-group-select"
2825
- :model-value="selectedFieldOwner ? getFieldOwnerValue(selectedFieldOwner) : ROOT_FIELD_GROUP_VALUE"
2542
+ :model-value="selectedFieldGroup?.draftId ?? ROOT_FIELD_GROUP_VALUE"
2826
2543
  @update:model-value="updateSelectedFieldGroup"
2827
2544
  >
2545
+ <NativeSelectOption :value="ROOT_FIELD_GROUP_VALUE">
2546
+ {{ t("field-group-none") }}
2547
+ </NativeSelectOption>
2828
2548
  <NativeSelectOption
2829
- v-for="option in selectedFieldOwnerOptions"
2830
- :key="option.value"
2831
- :value="option.value"
2549
+ v-for="group in groupItems"
2550
+ :key="group.itemId"
2551
+ :value="group.itemId"
2832
2552
  >
2833
- {{ option.label }}
2553
+ {{ group.label }}
2834
2554
  </NativeSelectOption>
2835
2555
  </NativeSelect>
2836
2556
  </label>
@@ -2847,7 +2567,7 @@ function confirmChanges() {
2847
2567
 
2848
2568
  <Locale
2849
2569
  data-slot="fields-configurator-field-title-locale"
2850
- :model-value="getFieldTitleValue(selectedField.field)"
2570
+ :model-value="selectedField.field.title"
2851
2571
  @update:model-value="updateSelectedFieldTitle"
2852
2572
  />
2853
2573
 
@@ -2937,7 +2657,7 @@ function confirmChanges() {
2937
2657
  class="grid gap-4 md:grid-cols-2"
2938
2658
  >
2939
2659
  <label
2940
- v-if="isInteractiveField(selectedField.field) || selectedField.field.type === 'slot' || selectedField.field.type === 'container'"
2660
+ v-if="isInteractiveField(selectedField.field)"
2941
2661
  class="flex items-center justify-between gap-3 rounded-md border border-zinc-200 px-3 py-2 md:col-span-2"
2942
2662
  >
2943
2663
  <div class="flex flex-col gap-1">
@@ -2967,7 +2687,7 @@ function confirmChanges() {
2967
2687
  </label>
2968
2688
 
2969
2689
  <label
2970
- v-if="hasDirectFieldStyle(selectedField.field) && (!usesContentsOrientation || isMarkdownBodyField(selectedField.field) || selectedField.field.type === 'slot')"
2690
+ v-if="!usesContentsOrientation || isMarkdownBodyField(selectedField.field)"
2971
2691
  class="flex flex-col gap-2"
2972
2692
  >
2973
2693
  <span class="text-xs font-medium text-zinc-500">
@@ -2975,7 +2695,7 @@ function confirmChanges() {
2975
2695
  </span>
2976
2696
  <Textarea
2977
2697
  data-slot="fields-configurator-field-style-input"
2978
- :model-value="hasDirectFieldStyle(selectedField.field) ? selectedField.field.style ?? '' : ''"
2698
+ :model-value="selectedField.field.style ?? ''"
2979
2699
  :aria-invalid="validationErrors[getFieldErrorKey(selectedField.draftId, 'style')] ? 'true' : void 0"
2980
2700
  :placeholder="t('field-style-placeholder')"
2981
2701
  class="min-h-20 font-mono text-sm"
@@ -3102,99 +2822,6 @@ function confirmChanges() {
3102
2822
  </label>
3103
2823
  </section>
3104
2824
 
3105
- <section
3106
- v-if="selectedField.field.type === 'container'"
3107
- data-slot="fields-configurator-container-options"
3108
- class="grid gap-4 md:grid-cols-2"
3109
- >
3110
- <label class="flex flex-col gap-2">
3111
- <span class="text-xs font-medium text-zinc-500">
3112
- {{ t("container-body-orientation") }}
3113
- </span>
3114
- <NativeSelect
3115
- data-slot="fields-configurator-container-body-orientation-select"
3116
- :model-value="selectedField.field.bodyOrientation ?? 'horizontal'"
3117
- @update:model-value="updateSelectedContainerBodyOrientation"
3118
- >
3119
- <NativeSelectOption value="horizontal">
3120
- {{ t("fields-orientation-horizontal") }}
3121
- </NativeSelectOption>
3122
- <NativeSelectOption value="vertical">
3123
- {{ t("fields-orientation-vertical") }}
3124
- </NativeSelectOption>
3125
- <NativeSelectOption value="floating">
3126
- {{ t("fields-orientation-floating") }}
3127
- </NativeSelectOption>
3128
- <NativeSelectOption value="contents">
3129
- {{ t("fields-orientation-contents") }}
3130
- </NativeSelectOption>
3131
- </NativeSelect>
3132
- </label>
3133
-
3134
- <label class="flex items-center justify-between gap-3 rounded-md border border-zinc-200 px-3 py-2">
3135
- <div class="flex flex-col gap-1">
3136
- <span class="text-sm font-medium text-zinc-800">{{ t("container-body-bordered") }}</span>
3137
- <span class="text-xs text-zinc-500">{{ t("container-body-bordered-description") }}</span>
3138
- </div>
3139
- <Switch
3140
- data-slot="fields-configurator-container-body-bordered-switch"
3141
- :model-value="selectedField.field.bodyBordered ?? false"
3142
- @update:model-value="updateSelectedContainerBodyBordered"
3143
- />
3144
- </label>
3145
-
3146
- <label class="flex flex-col gap-2 md:col-span-2">
3147
- <span class="text-xs font-medium text-zinc-500">
3148
- {{ t("container-body-style") }}
3149
- </span>
3150
- <Textarea
3151
- data-slot="fields-configurator-container-body-style-input"
3152
- :model-value="selectedField.field.bodyStyle ?? ''"
3153
- :aria-invalid="validationErrors[getFieldErrorKey(selectedField.draftId, 'bodyStyle')] ? 'true' : void 0"
3154
- :placeholder="t('group-style-placeholder')"
3155
- class="min-h-20 font-mono text-sm"
3156
- @update:model-value="updateSelectedContainerBodyStyle"
3157
- />
3158
- <p
3159
- v-if="validationErrors[getFieldErrorKey(selectedField.draftId, 'bodyStyle')]"
3160
- class="text-xs text-red-500"
3161
- >
3162
- {{ validationErrors[getFieldErrorKey(selectedField.draftId, "bodyStyle")] }}
3163
- </p>
3164
- </label>
3165
-
3166
- <div
3167
- data-slot="fields-configurator-container-children"
3168
- class="flex flex-col gap-2 md:col-span-2"
3169
- >
3170
- <p class="text-xs font-medium text-zinc-500">
3171
- {{ t("field-children") }}
3172
- </p>
3173
- <div
3174
- v-if="selectedContainerChildItems.length > 0"
3175
- class="flex flex-col gap-1"
3176
- >
3177
- <button
3178
- v-for="item in selectedContainerChildItems"
3179
- :key="item.itemId"
3180
- type="button"
3181
- data-slot="fields-configurator-container-child"
3182
- class="rounded-md border border-zinc-200 px-3 py-2 text-left text-sm text-zinc-700 transition-colors hover:border-zinc-300 hover:bg-zinc-50"
3183
- :style="{ paddingLeft: `${item.depth * 12 + 12}px` }"
3184
- @click="selectItem(item.itemId)"
3185
- >
3186
- {{ item.label }}
3187
- </button>
3188
- </div>
3189
- <p
3190
- v-else
3191
- class="text-xs text-zinc-500"
3192
- >
3193
- {{ t("field-children-empty") }}
3194
- </p>
3195
- </div>
3196
- </section>
3197
-
3198
2825
  <section
3199
2826
  v-if="selectedField.field.type === 'string' || selectedField.field.type === 'textarea'"
3200
2827
  data-slot="fields-configurator-string-options"
@@ -3794,7 +3421,6 @@ function confirmChanges() {
3794
3421
  "field-type-radio": "单选按钮组",
3795
3422
  "field-type-calendar": "日期",
3796
3423
  "field-type-upload": "上传",
3797
- "field-type-container": "容器",
3798
3424
  "field-type-empty": "空白",
3799
3425
  "field-type-slot": "插槽",
3800
3426
  "field-id": "字段 ID",
@@ -3812,8 +3438,6 @@ function confirmChanges() {
3812
3438
  "copy-field-id-failed": "复制字段 ID 失败,请检查剪贴板权限。",
3813
3439
  "field-group": "所属分组",
3814
3440
  "field-group-none": "不分组",
3815
- "field-children": "子字段",
3816
- "field-children-empty": "这个容器还没有子字段。",
3817
3441
  "field-label": "字段标题",
3818
3442
  "group-style": "分组样式表达式",
3819
3443
  "group-style-placeholder": "例如返回一个 style map,例如 display: grid",
@@ -3831,10 +3455,6 @@ function confirmChanges() {
3831
3455
  "field-style": "样式表达式",
3832
3456
  "field-label-style": "标签样式表达式",
3833
3457
  "field-content-style": "内容样式表达式",
3834
- "container-body-orientation": "容器内部布局",
3835
- "container-body-bordered": "容器内部表格式边框",
3836
- "container-body-bordered-description": "仅在 contents 布局下生效,用于容器内部字段网格。",
3837
- "container-body-style": "容器内部样式表达式",
3838
3458
  "field-style-placeholder": "例如 width: 100%",
3839
3459
  "field-hidden": "隐藏条件",
3840
3460
  "field-hidden-placeholder": "返回 true 时隐藏字段",
@@ -3939,7 +3559,6 @@ function confirmChanges() {
3939
3559
  "field-type-radio": "ラジオグループ",
3940
3560
  "field-type-calendar": "日付",
3941
3561
  "field-type-upload": "アップロード",
3942
- "field-type-container": "コンテナ",
3943
3562
  "field-type-empty": "空白",
3944
3563
  "field-type-slot": "スロット",
3945
3564
  "field-id": "フィールド ID",
@@ -3957,8 +3576,6 @@ function confirmChanges() {
3957
3576
  "copy-field-id-failed": "フィールド ID のコピーに失敗しました。クリップボード権限を確認してください。",
3958
3577
  "field-group": "所属グループ",
3959
3578
  "field-group-none": "グループなし",
3960
- "field-children": "子フィールド",
3961
- "field-children-empty": "このコンテナにはまだ子フィールドがありません。",
3962
3579
  "field-label": "フィールドラベル",
3963
3580
  "group-style": "グループスタイル式",
3964
3581
  "group-style-placeholder": "例: style map を返す式。例: display: grid",
@@ -3976,10 +3593,6 @@ function confirmChanges() {
3976
3593
  "field-style": "スタイル式",
3977
3594
  "field-label-style": "ラベルスタイル式",
3978
3595
  "field-content-style": "コンテンツスタイル式",
3979
- "container-body-orientation": "内部レイアウト",
3980
- "container-body-bordered": "内部テーブル枠線",
3981
- "container-body-bordered-description": "contents レイアウト時のみ有効で、内部フィールドグリッドに適用します。",
3982
- "container-body-style": "内部スタイル式",
3983
3596
  "field-style-placeholder": "例: width: 100%",
3984
3597
  "field-hidden": "非表示条件",
3985
3598
  "field-hidden-placeholder": "true を返すと非表示になります",
@@ -4084,7 +3697,6 @@ function confirmChanges() {
4084
3697
  "field-type-radio": "Radio Group",
4085
3698
  "field-type-calendar": "Date",
4086
3699
  "field-type-upload": "Upload",
4087
- "field-type-container": "Container",
4088
3700
  "field-type-empty": "Empty",
4089
3701
  "field-type-slot": "Slot",
4090
3702
  "field-id": "Field ID",
@@ -4102,8 +3714,6 @@ function confirmChanges() {
4102
3714
  "copy-field-id-failed": "Failed to copy the field ID. Check clipboard permissions.",
4103
3715
  "field-group": "Belong group",
4104
3716
  "field-group-none": "No group",
4105
- "field-children": "Child fields",
4106
- "field-children-empty": "This container does not have child fields yet.",
4107
3717
  "field-label": "Field label",
4108
3718
  "group-style": "Group style expression",
4109
3719
  "group-style-placeholder": "Return a style map, for example display: grid",
@@ -4121,10 +3731,6 @@ function confirmChanges() {
4121
3731
  "field-style": "Style expression",
4122
3732
  "field-label-style": "Label style expression",
4123
3733
  "field-content-style": "Content style expression",
4124
- "container-body-orientation": "Nested layout",
4125
- "container-body-bordered": "Nested table borders",
4126
- "container-body-bordered-description": "Only applies in contents layout for the nested field grid.",
4127
- "container-body-style": "Nested style expression",
4128
3734
  "field-style-placeholder": "For example width: 100%",
4129
3735
  "field-hidden": "Hidden expression",
4130
3736
  "field-hidden-placeholder": "Return true to hide the field",