@shwfed/config 2.10.8 → 2.10.10

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 (95) hide show
  1. package/dist/mcp.mjs +1143 -1024
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-BX_UfcPb.js → FieldGroup.vue_vue_type_script_setup_true_lang-CsPU4iZU.js} +1 -1
  4. package/dist/preview/assets/{badge-obDKnV3E.js → badge-B953zx7V.js} +1 -1
  5. package/dist/preview/assets/{config-DbdgS5Ng.js → config-B-o7DV04.js} +1 -1
  6. package/dist/preview/assets/{config-C6IfQR2K.js → config-BajA-dJ1.js} +1 -1
  7. package/dist/preview/assets/{config-jBRCpIX5.js → config-BjdMNJwa.js} +1 -1
  8. package/dist/preview/assets/{config-CaaIte9f.js → config-C0xCcVfy.js} +1 -1
  9. package/dist/preview/assets/{config-BYhrPimZ.js → config-C2-lrcCq.js} +1 -1
  10. package/dist/preview/assets/{config-DGJLbdm3.js → config-C3v6QvLS.js} +1 -1
  11. package/dist/preview/assets/{config-DSD3RZZt.js → config-C4Twz5UA.js} +1 -1
  12. package/dist/preview/assets/{config-9weuJKPA.js → config-CFWXRIOe.js} +1 -1
  13. package/dist/preview/assets/{config-BKVK2els.js → config-CqMqqE_9.js} +1 -1
  14. package/dist/preview/assets/{config-DxmfhxW9.js → config-D5m2C0xK.js} +1 -1
  15. package/dist/preview/assets/{config-xdKDKKAa.js → config-DAJ25V43.js} +1 -1
  16. package/dist/preview/assets/{config-CnpY7wA_.js → config-DmgHMdSz.js} +1 -1
  17. package/dist/preview/assets/{config-CYdIN2D7.js → config-DpEkjTKt.js} +1 -1
  18. package/dist/preview/assets/{config-B27gvYuN.js → config-DqAigk_E.js} +1 -1
  19. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-C97mjLAr.js → definition.vue_vue_type_script_setup_true_lang-WNrh1xWy.js} +1 -1
  20. package/dist/preview/assets/index-BdS7dokp.js +763 -0
  21. package/dist/preview/assets/index-BkwnC_tl.js +1 -0
  22. package/dist/preview/assets/{index-BWc0rZ2y.js → index-Bv_Ig-Tl.js} +1 -1
  23. package/dist/preview/assets/index-Cc4BT5dc.css +1 -0
  24. package/dist/preview/assets/{item-BRGONTEu.js → item-caTb4x-x.js} +1 -1
  25. package/dist/preview/assets/{runtime-Czg0F_NN.js → runtime-7ThCZ17X.js} +1 -1
  26. package/dist/preview/assets/{runtime-CJVZpawP.js → runtime-B-tUuLEY.js} +1 -1
  27. package/dist/preview/assets/{runtime-D-9NZJ0Z.js → runtime-Bnaxoocd.js} +1 -1
  28. package/dist/preview/assets/{runtime-BGRgWBLF.js → runtime-C8_u1NyC.js} +1 -1
  29. package/dist/preview/assets/{runtime-DqhT5NCm.js → runtime-C9lZq_oo.js} +1 -1
  30. package/dist/preview/assets/{runtime-CHOWqPGP.js → runtime-CIWhgS6a.js} +1 -1
  31. package/dist/preview/assets/{runtime-DcQjFFJx.js → runtime-CZrQz2RJ.js} +1 -1
  32. package/dist/preview/assets/{runtime-BoiTEUZt.js → runtime-D6EIpId9.js} +1 -1
  33. package/dist/preview/assets/{runtime-Ci3L--AW.js → runtime-DELhNsaH.js} +1 -1
  34. package/dist/preview/assets/{runtime-DZtGKJgS.js → runtime-d4XHvjgW.js} +1 -1
  35. package/dist/preview/assets/{schema-meta-xFd44RnL.js → schema-meta-Cf59HabB.js} +1 -1
  36. package/dist/preview/index.html +2 -2
  37. package/dist/runtime/components/actions/components/group.d.vue.ts +9 -0
  38. package/dist/runtime/components/actions/components/group.vue +20 -1
  39. package/dist/runtime/components/actions/components/group.vue.d.ts +9 -0
  40. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.actions/runtime.vue +1 -0
  41. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.d.vue.ts +16 -16
  42. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.vue.d.ts +16 -16
  43. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.d.vue.ts +16 -16
  44. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.vue.d.ts +16 -16
  45. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.d.vue.ts +2 -0
  46. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.vue +32 -1
  47. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/config.vue.d.ts +2 -0
  48. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/runtime.vue +2 -0
  49. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.d.ts +2 -0
  50. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.js +4 -0
  51. package/dist/runtime/components/form/fields/2026-05-17/com.shwfed.form.field.checkbox.group/config.vue +202 -112
  52. package/dist/runtime/components/form/fields/2026-05-17/com.shwfed.form.field.radio.group/config.vue +202 -112
  53. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.d.vue.ts +16 -16
  54. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.vue.d.ts +16 -16
  55. package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.multi/config.vue +223 -132
  56. package/dist/runtime/components/form/fields/2026-06-14/com.shwfed.form.field.combobox.single/config.vue +223 -132
  57. package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/config.d.vue.ts +59 -0
  58. package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/config.vue +345 -0
  59. package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/config.vue.d.ts +59 -0
  60. package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/runtime.d.vue.ts +8 -0
  61. package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/runtime.vue +113 -0
  62. package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/runtime.vue.d.ts +8 -0
  63. package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/schema.d.ts +79 -0
  64. package/dist/runtime/components/form/fields/2026-06-20/com.shwfed.form.field.tabs/schema.js +86 -0
  65. package/dist/runtime/components/form/unit-config.d.vue.ts +27 -0
  66. package/dist/runtime/components/form/unit-config.vue +117 -73
  67. package/dist/runtime/components/form/unit-config.vue.d.ts +27 -0
  68. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
  69. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
  70. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
  71. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
  72. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
  73. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
  74. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
  75. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
  76. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
  77. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
  78. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
  79. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
  80. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  81. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  82. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  83. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  84. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  85. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  86. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  87. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  88. package/dist/runtime/components/ui/markdown/Markdown.vue +19 -16
  89. package/dist/runtime/style.css +1 -1
  90. package/dist/runtime/utils/markdown.d.ts +5 -2
  91. package/dist/runtime/utils/markdown.js +22 -1
  92. package/package.json +1 -1
  93. package/dist/preview/assets/index-ADrQrdaQ.js +0 -1
  94. package/dist/preview/assets/index-Cj7bRG7B.css +0 -1
  95. package/dist/preview/assets/index-DFmBrVzd.js +0 -763
@@ -0,0 +1,86 @@
1
+ import { Schema } from "effect";
2
+ import { Locale } from "../../../../../share/locale.js";
3
+ import { FormUnit } from "../../../schema.js";
4
+ export const type = "com.shwfed.form.field.tabs";
5
+ export const compatibilityDate = "2026-06-20";
6
+ export const metadata = {
7
+ name: "\u6807\u7B7E\u9875",
8
+ icon: "fluent:tabs-20-regular",
9
+ w: { initial: 12, min: 4, max: Infinity },
10
+ h: { initial: 6, min: 2, max: Infinity, grow: true },
11
+ // Hosts a nested sub-form per tab (each tab's own fields + layout) — too
12
+ // complex for the fullscreen inline-config pane; keep the drill-down.
13
+ inlineConfig: false
14
+ };
15
+ export const TabMeta = Schema.Struct({
16
+ label: Locale.annotations({
17
+ title: "\u6807\u7B7E\u540D",
18
+ description: "\u8BE5\u6807\u7B7E\u9875\u7684\u672C\u5730\u5316\u663E\u793A\u540D"
19
+ })
20
+ });
21
+ export function schema(configure) {
22
+ const Unit = Schema.suspend(() => FormUnit(configure));
23
+ const Tab = Schema.Struct({
24
+ id: Schema.UUID.annotations({ description: "\u6807\u7B7E\u9875\u552F\u4E00\u6807\u8BC6" }),
25
+ ...TabMeta.fields,
26
+ unit: Unit.annotations({
27
+ identifier: "FormFieldTabsUnit",
28
+ title: "\u6807\u7B7E\u5185\u5BB9",
29
+ description: "\u8BE5\u6807\u7B7E\u5185\u7684\u5B57\u6BB5\u4E0E\u5E03\u5C40\uFF1B\u8FD9\u4E9B\u5B57\u6BB5\u5728\u8868\u5355\u72B6\u6001\u4E2D\u4FDD\u6301\u6241\u5E73\uFF0C\u4E0D\u4F1A\u56E0\u4E3A\u5206\u7EC4\u800C\u5F15\u5165\u65B0\u7684\u72B6\u6001\u5C42\u7EA7"
30
+ })
31
+ }).annotations({
32
+ title: "Tab",
33
+ description: "\u5355\u4E2A\u6807\u7B7E\u9875\uFF1A\u540D\u79F0 + \u5185\u5BB9 Unit"
34
+ });
35
+ return Schema.Struct({
36
+ type: Schema.Literal(type),
37
+ compatibilityDate: Schema.Literal(compatibilityDate),
38
+ id: Schema.UUID.annotations({ description: "\u5B57\u6BB5\u552F\u4E00\u6807\u8BC6\uFF1B\u5E03\u5C40\u901A\u8FC7\u8BE5 id \u5F15\u7528\u5B57\u6BB5" }),
39
+ displayName: Schema.optional(Schema.String.annotations({
40
+ title: "\u5185\u90E8\u540D\u79F0",
41
+ description: "\u4EC5\u5728\u7F16\u8F91\u5668\u5185\u53EF\u89C1\u7684\u533A\u57DF\u540D\uFF0C\u7528\u4E8E\u5728\u4FA7\u8FB9\u680F\u548C\u5E03\u5C40\u7F16\u8F91\u5668\u4E2D\u8BC6\u522B\u8BE5\u6807\u7B7E\u9875\uFF1B\u8FD0\u884C\u65F6\u4E0D\u5C55\u793A"
42
+ })),
43
+ style: Schema.optional(Schema.String.annotations({
44
+ title: "\u5BB9\u5668\u6837\u5F0F",
45
+ description: "\u5E94\u7528\u5728\u6807\u7B7E\u9875\u6700\u5916\u5C42\u5BB9\u5668\u4E0A\u7684 CSS \u6837\u5F0F\u5B57\u7B26\u4E32"
46
+ })),
47
+ tabs: Schema.Array(Tab).pipe(
48
+ Schema.minItems(1),
49
+ Schema.filter((tabs) => {
50
+ const ids = /* @__PURE__ */ new Set();
51
+ for (const t of tabs) {
52
+ if (ids.has(t.id)) return `\u6807\u7B7E\u9875 id \u91CD\u590D: ${t.id}`;
53
+ ids.add(t.id);
54
+ }
55
+ return true;
56
+ })
57
+ ).annotations({
58
+ title: "\u6807\u7B7E\u9875",
59
+ description: "\u81F3\u5C11 1 \u9879\uFF0C\u6309\u987A\u5E8F\u6E32\u67D3"
60
+ })
61
+ }).annotations({
62
+ title: "TabsField",
63
+ description: "\u5C06\u4E00\u7EC4\u5E26\u6807\u7B7E\u7684\u5B50\u8868\u5355\u5355\u5143\u4F5C\u4E3A\u6807\u7B7E\u9875\u5206\u7EC4\uFF1B\u4EC5\u7528\u4E8E\u89C6\u89C9\u5206\u7EC4\uFF0C\u4E0D\u5F71\u54CD\u5B57\u6BB5\u5728\u8868\u5355\u72B6\u6001\u4E2D\u7684\u5C42\u7EA7"
64
+ });
65
+ }
66
+ function makeId() {
67
+ if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID();
68
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
69
+ const r = Math.random() * 16 | 0;
70
+ return (c === "x" ? r : r & 3 | 8).toString(16);
71
+ });
72
+ }
73
+ export function defaults() {
74
+ return {
75
+ tabs: [
76
+ {
77
+ id: makeId(),
78
+ label: [{ locale: "zh", message: "\u6807\u7B7E 1" }],
79
+ unit: {
80
+ fields: [],
81
+ layouts: [{ name: "\u9ED8\u8BA4", layout: { columns: 1, placements: {} } }]
82
+ }
83
+ }
84
+ ]
85
+ };
86
+ }
@@ -33,12 +33,39 @@ type __VLS_Props = {
33
33
  * host component, above this provide.
34
34
  */
35
35
  fieldCelScope?: CELContext;
36
+ /**
37
+ * Identity of the unit currently bound to `v-model`. When a host swaps the
38
+ * bound unit *in place* (e.g. the tabs field switching the active tab's
39
+ * unit) the editor's drill stack / active-layout index belong to the old
40
+ * unit and would point at fields/layouts that don't exist in the new one.
41
+ * Changing `scopeKey` resets that transient view state without forcing a
42
+ * remount (which would flicker host-injected rail content). Hosts that own
43
+ * a single stable unit (collapsible, list, form root) leave it undefined.
44
+ */
45
+ scopeKey?: string;
36
46
  };
37
47
  type __VLS_Slots = {
38
48
  /** Pane content for the currently-selected extra. Receives `{ id }`. */
39
49
  'extras-pane'(props: {
40
50
  id: string;
41
51
  }): unknown;
52
+ /**
53
+ * Extra rail content rendered as its own half-height list above the layouts
54
+ * list (top-level view only — hidden while drilled into a field). The tabs
55
+ * field injects its tab list here so the rail reads as two parallel lists.
56
+ */
57
+ 'rail-extra'(): unknown;
58
+ /**
59
+ * Foot button for the `rail-extra` list, pinned below its scroll area (the
60
+ * tabs field's “新增标签页”). Mirrors the layouts list's “新增布局”.
61
+ */
62
+ 'rail-extra-foot'(): unknown;
63
+ /**
64
+ * Content rendered above the layout canvas in the 布局 view. The tabs field
65
+ * injects the active tab's label editor here, mirroring the block-tabs
66
+ * config's pane header.
67
+ */
68
+ 'pane-header'(): unknown;
42
69
  };
43
70
  type __VLS_ModelProps = {
44
71
  modelValue: FormUnitValue;
@@ -31,13 +31,18 @@ const selection = defineModel("selection", { type: Object, ...{
31
31
  const props = defineProps({
32
32
  extras: { type: Array, required: false },
33
33
  configure: { type: Function, required: false },
34
- fieldCelScope: { type: Object, required: false }
34
+ fieldCelScope: { type: Object, required: false },
35
+ scopeKey: { type: String, required: false }
35
36
  });
36
37
  defineSlots();
37
38
  const activeLayoutIndex = ref(0);
38
39
  const stack = ref([{ kind: "top" }]);
39
40
  const top = computed(() => stack.value[stack.value.length - 1]);
40
41
  const isDrilled = computed(() => stack.value.length > 1);
42
+ watch(() => props.scopeKey, () => {
43
+ if (stack.value.length > 1) stack.value = [{ kind: "top" }];
44
+ activeLayoutIndex.value = 0;
45
+ });
41
46
  function popOne() {
42
47
  if (stack.value.length <= 1) return;
43
48
  stack.value = stack.value.slice(0, -1);
@@ -313,47 +318,66 @@ function isExtraActive(id) {
313
318
  :to="takeoverTarget"
314
319
  >
315
320
  <template v-if="!isDrilled">
316
- <ScrollArea class="flex-1">
317
- <template v-if="extras && extras.length > 0">
318
- <div
319
- v-for="extra in extras"
320
- :key="extra.id"
321
- class="row general-row pl-2"
322
- :class="[
321
+ <!-- Extras rows pinned at the top of the rail. -->
322
+ <template v-if="extras && extras.length > 0">
323
+ <div
324
+ v-for="extra in extras"
325
+ :key="extra.id"
326
+ class="row general-row pl-2"
327
+ :class="[
323
328
  isExtraActive(extra.id) ? 'bg-[color-mix(in_srgb,var(--primary)_10%,white)] text-(--primary)' : 'text-zinc-600 hover:bg-zinc-50'
324
329
  ]"
325
- @click.stop="selectExtra(extra.id)"
326
- >
327
- <Icon
328
- :icon="extra.icon"
329
- class="size-4 shrink-0"
330
- />
331
- <span class="flex-1 truncate">{{ extra.label }}</span>
332
- </div>
330
+ @click.stop="selectExtra(extra.id)"
331
+ >
332
+ <Icon
333
+ :icon="extra.icon"
334
+ class="size-4 shrink-0"
335
+ />
336
+ <span class="flex-1 truncate">{{ extra.label }}</span>
337
+ </div>
333
338
 
334
- <Separator class="my-1" />
335
- </template>
339
+ <Separator class="my-1" />
340
+ </template>
336
341
 
337
- <LayoutsSidebar
338
- ref="sidebarRef"
339
- v-model="layoutsModel"
340
- v-model:active-index="activeLayoutIndex"
341
- :active="selection.kind === 'layout'"
342
- @select="selectLayout()"
343
- />
344
- </ScrollArea>
342
+ <!-- Host-injected rail list (e.g. the tabs field's tab list): its own
343
+ half-height scroll + foot button, so the rail reads as two parallel
344
+ lists rather than one long one. -->
345
+ <template v-if="$slots['rail-extra']">
346
+ <div class="flex flex-1 min-h-0 flex-col">
347
+ <ScrollArea class="flex-1">
348
+ <slot name="rail-extra" />
349
+ </ScrollArea>
350
+ <slot name="rail-extra-foot" />
351
+ </div>
345
352
 
346
- <Button
347
- variant="ghost"
348
- size="sm"
349
- @click="addLayout()"
350
- >
351
- <Icon
352
- icon="fluent:add-20-regular"
353
- class="size-4"
354
- />
355
- <span>新增布局</span>
356
- </Button>
353
+ <Separator class="my-1" />
354
+ </template>
355
+
356
+ <!-- Layouts list — its own half-height scroll + add button. -->
357
+ <div class="flex flex-1 min-h-0 flex-col">
358
+ <ScrollArea class="flex-1">
359
+ <LayoutsSidebar
360
+ ref="sidebarRef"
361
+ v-model="layoutsModel"
362
+ v-model:active-index="activeLayoutIndex"
363
+ :active="selection.kind === 'layout'"
364
+ @select="selectLayout()"
365
+ />
366
+ </ScrollArea>
367
+
368
+ <Button
369
+ variant="ghost"
370
+ size="sm"
371
+ class="w-full justify-start"
372
+ @click="addLayout()"
373
+ >
374
+ <Icon
375
+ icon="fluent:add-20-regular"
376
+ class="size-4"
377
+ />
378
+ <span>新增布局</span>
379
+ </Button>
380
+ </div>
357
381
  </template>
358
382
  <template v-else>
359
383
  <ScrollArea class="flex-1">
@@ -390,47 +414,66 @@ function isExtraActive(id) {
390
414
  class="flex w-64 shrink-0 flex-col"
391
415
  >
392
416
  <template v-if="!isDrilled">
393
- <ScrollArea class="flex-1">
394
- <template v-if="extras && extras.length > 0">
395
- <div
396
- v-for="extra in extras"
397
- :key="extra.id"
398
- class="row general-row pl-2"
399
- :class="[
417
+ <!-- Extras rows pinned at the top of the rail. -->
418
+ <template v-if="extras && extras.length > 0">
419
+ <div
420
+ v-for="extra in extras"
421
+ :key="extra.id"
422
+ class="row general-row pl-2"
423
+ :class="[
400
424
  isExtraActive(extra.id) ? 'bg-[color-mix(in_srgb,var(--primary)_10%,white)] text-(--primary)' : 'text-zinc-600 hover:bg-zinc-50'
401
425
  ]"
402
- @click.stop="selectExtra(extra.id)"
403
- >
404
- <Icon
405
- :icon="extra.icon"
406
- class="size-4 shrink-0"
407
- />
408
- <span class="flex-1 truncate">{{ extra.label }}</span>
409
- </div>
426
+ @click.stop="selectExtra(extra.id)"
427
+ >
428
+ <Icon
429
+ :icon="extra.icon"
430
+ class="size-4 shrink-0"
431
+ />
432
+ <span class="flex-1 truncate">{{ extra.label }}</span>
433
+ </div>
410
434
 
411
- <Separator class="my-1" />
412
- </template>
435
+ <Separator class="my-1" />
436
+ </template>
413
437
 
414
- <LayoutsSidebar
415
- ref="sidebarRef"
416
- v-model="layoutsModel"
417
- v-model:active-index="activeLayoutIndex"
418
- :active="selection.kind === 'layout'"
419
- @select="selectLayout()"
420
- />
421
- </ScrollArea>
438
+ <!-- Host-injected rail list (e.g. the tabs field's tab list): its own
439
+ half-height scroll + foot button, so the rail reads as two
440
+ parallel lists rather than one long one. -->
441
+ <template v-if="$slots['rail-extra']">
442
+ <div class="flex flex-1 min-h-0 flex-col">
443
+ <ScrollArea class="flex-1">
444
+ <slot name="rail-extra" />
445
+ </ScrollArea>
446
+ <slot name="rail-extra-foot" />
447
+ </div>
422
448
 
423
- <Button
424
- variant="ghost"
425
- size="sm"
426
- @click="addLayout()"
427
- >
428
- <Icon
429
- icon="fluent:add-20-regular"
430
- class="size-4"
431
- />
432
- <span>新增布局</span>
433
- </Button>
449
+ <Separator class="my-1" />
450
+ </template>
451
+
452
+ <!-- Layouts list — its own half-height scroll + add button. -->
453
+ <div class="flex flex-1 min-h-0 flex-col">
454
+ <ScrollArea class="flex-1">
455
+ <LayoutsSidebar
456
+ ref="sidebarRef"
457
+ v-model="layoutsModel"
458
+ v-model:active-index="activeLayoutIndex"
459
+ :active="selection.kind === 'layout'"
460
+ @select="selectLayout()"
461
+ />
462
+ </ScrollArea>
463
+
464
+ <Button
465
+ variant="ghost"
466
+ size="sm"
467
+ class="w-full justify-start"
468
+ @click="addLayout()"
469
+ >
470
+ <Icon
471
+ icon="fluent:add-20-regular"
472
+ class="size-4"
473
+ />
474
+ <span>新增布局</span>
475
+ </Button>
476
+ </div>
434
477
  </template>
435
478
  <template v-else>
436
479
  <ScrollArea class="flex-1">
@@ -473,6 +516,7 @@ function isExtraActive(id) {
473
516
  v-else-if="!isDrilled && selection.kind === 'layout'"
474
517
  class="flex flex-1 flex-col gap-2"
475
518
  >
519
+ <slot name="pane-header" />
476
520
  <LayoutMetaStrip
477
521
  v-model="layoutsModel"
478
522
  :index="activeLayoutIndex"
@@ -33,12 +33,39 @@ type __VLS_Props = {
33
33
  * host component, above this provide.
34
34
  */
35
35
  fieldCelScope?: CELContext;
36
+ /**
37
+ * Identity of the unit currently bound to `v-model`. When a host swaps the
38
+ * bound unit *in place* (e.g. the tabs field switching the active tab's
39
+ * unit) the editor's drill stack / active-layout index belong to the old
40
+ * unit and would point at fields/layouts that don't exist in the new one.
41
+ * Changing `scopeKey` resets that transient view state without forcing a
42
+ * remount (which would flicker host-injected rail content). Hosts that own
43
+ * a single stable unit (collapsible, list, form root) leave it undefined.
44
+ */
45
+ scopeKey?: string;
36
46
  };
37
47
  type __VLS_Slots = {
38
48
  /** Pane content for the currently-selected extra. Receives `{ id }`. */
39
49
  'extras-pane'(props: {
40
50
  id: string;
41
51
  }): unknown;
52
+ /**
53
+ * Extra rail content rendered as its own half-height list above the layouts
54
+ * list (top-level view only — hidden while drilled into a field). The tabs
55
+ * field injects its tab list here so the rail reads as two parallel lists.
56
+ */
57
+ 'rail-extra'(): unknown;
58
+ /**
59
+ * Foot button for the `rail-extra` list, pinned below its scroll area (the
60
+ * tabs field's “新增标签页”). Mirrors the layouts list's “新增布局”.
61
+ */
62
+ 'rail-extra-foot'(): unknown;
63
+ /**
64
+ * Content rendered above the layout canvas in the 布局 view. The tabs field
65
+ * injects the active tab's label editor here, mirroring the block-tabs
66
+ * config's pane header.
67
+ */
68
+ 'pane-header'(): unknown;
42
69
  };
43
70
  type __VLS_ModelProps = {
44
71
  modelValue: FormUnitValue;
@@ -53,9 +53,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
53
53
  readonly locale: "en" | "ja" | "ko";
54
54
  readonly message: string;
55
55
  }[]];
56
- readonly successMessage?: string | undefined;
57
56
  readonly accessor: string;
58
57
  readonly sortKey?: string | undefined;
58
+ readonly successMessage?: string | undefined;
59
59
  }) => any;
60
60
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
61
61
  "onUpdate:modelValue"?: ((value: {
@@ -108,9 +108,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
108
108
  readonly locale: "en" | "ja" | "ko";
109
109
  readonly message: string;
110
110
  }[]];
111
- readonly successMessage?: string | undefined;
112
111
  readonly accessor: string;
113
112
  readonly sortKey?: string | undefined;
113
+ readonly successMessage?: string | undefined;
114
114
  }) => any) | undefined;
115
115
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
116
116
  declare const _default: typeof __VLS_export;
@@ -53,9 +53,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
53
53
  readonly locale: "en" | "ja" | "ko";
54
54
  readonly message: string;
55
55
  }[]];
56
- readonly successMessage?: string | undefined;
57
56
  readonly accessor: string;
58
57
  readonly sortKey?: string | undefined;
58
+ readonly successMessage?: string | undefined;
59
59
  }) => any;
60
60
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
61
61
  "onUpdate:modelValue"?: ((value: {
@@ -108,9 +108,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
108
108
  readonly locale: "en" | "ja" | "ko";
109
109
  readonly message: string;
110
110
  }[]];
111
- readonly successMessage?: string | undefined;
112
111
  readonly accessor: string;
113
112
  readonly sortKey?: string | undefined;
113
+ readonly successMessage?: string | undefined;
114
114
  }) => any) | undefined;
115
115
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
116
116
  declare const _default: typeof __VLS_export;
@@ -67,9 +67,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
67
67
  }[]] | undefined;
68
68
  readonly readonly?: string | undefined;
69
69
  readonly enableSorting?: boolean | undefined;
70
- readonly successMessage?: string | undefined;
71
70
  readonly accessor: string;
72
71
  readonly sortKey?: string | undefined;
72
+ readonly successMessage?: string | undefined;
73
73
  }) => any;
74
74
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
75
75
  "onUpdate:modelValue"?: ((value: {
@@ -136,9 +136,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
136
136
  }[]] | undefined;
137
137
  readonly readonly?: string | undefined;
138
138
  readonly enableSorting?: boolean | undefined;
139
- readonly successMessage?: string | undefined;
140
139
  readonly accessor: string;
141
140
  readonly sortKey?: string | undefined;
141
+ readonly successMessage?: string | undefined;
142
142
  }) => any) | undefined;
143
143
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
144
144
  declare const _default: typeof __VLS_export;
@@ -67,9 +67,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
67
67
  }[]] | undefined;
68
68
  readonly readonly?: string | undefined;
69
69
  readonly enableSorting?: boolean | undefined;
70
- readonly successMessage?: string | undefined;
71
70
  readonly accessor: string;
72
71
  readonly sortKey?: string | undefined;
72
+ readonly successMessage?: string | undefined;
73
73
  }) => any;
74
74
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
75
75
  "onUpdate:modelValue"?: ((value: {
@@ -136,9 +136,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
136
136
  }[]] | undefined;
137
137
  readonly readonly?: string | undefined;
138
138
  readonly enableSorting?: boolean | undefined;
139
- readonly successMessage?: string | undefined;
140
139
  readonly accessor: string;
141
140
  readonly sortKey?: string | undefined;
141
+ readonly successMessage?: string | undefined;
142
142
  }) => any) | undefined;
143
143
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
144
144
  declare const _default: typeof __VLS_export;
@@ -53,9 +53,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
53
53
  readonly locale: "en" | "ja" | "ko";
54
54
  readonly message: string;
55
55
  }[]];
56
- readonly successMessage?: string | undefined;
57
56
  readonly accessor: string;
58
57
  readonly sortKey?: string | undefined;
58
+ readonly successMessage?: string | undefined;
59
59
  }) => any;
60
60
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
61
61
  "onUpdate:modelValue"?: ((value: {
@@ -108,9 +108,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
108
108
  readonly locale: "en" | "ja" | "ko";
109
109
  readonly message: string;
110
110
  }[]];
111
- readonly successMessage?: string | undefined;
112
111
  readonly accessor: string;
113
112
  readonly sortKey?: string | undefined;
113
+ readonly successMessage?: string | undefined;
114
114
  }) => any) | undefined;
115
115
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
116
116
  declare const _default: typeof __VLS_export;
@@ -53,9 +53,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
53
53
  readonly locale: "en" | "ja" | "ko";
54
54
  readonly message: string;
55
55
  }[]];
56
- readonly successMessage?: string | undefined;
57
56
  readonly accessor: string;
58
57
  readonly sortKey?: string | undefined;
58
+ readonly successMessage?: string | undefined;
59
59
  }) => any;
60
60
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
61
61
  "onUpdate:modelValue"?: ((value: {
@@ -108,9 +108,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
108
108
  readonly locale: "en" | "ja" | "ko";
109
109
  readonly message: string;
110
110
  }[]];
111
- readonly successMessage?: string | undefined;
112
111
  readonly accessor: string;
113
112
  readonly sortKey?: string | undefined;
113
+ readonly successMessage?: string | undefined;
114
114
  }) => any) | undefined;
115
115
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
116
116
  declare const _default: typeof __VLS_export;
@@ -67,9 +67,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
67
67
  }[]] | undefined;
68
68
  readonly readonly?: string | undefined;
69
69
  readonly enableSorting?: boolean | undefined;
70
- readonly successMessage?: string | undefined;
71
70
  readonly accessor: string;
72
71
  readonly sortKey?: string | undefined;
72
+ readonly successMessage?: string | undefined;
73
73
  }) => any;
74
74
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
75
75
  "onUpdate:modelValue"?: ((value: {
@@ -136,9 +136,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
136
136
  }[]] | undefined;
137
137
  readonly readonly?: string | undefined;
138
138
  readonly enableSorting?: boolean | undefined;
139
- readonly successMessage?: string | undefined;
140
139
  readonly accessor: string;
141
140
  readonly sortKey?: string | undefined;
141
+ readonly successMessage?: string | undefined;
142
142
  }) => any) | undefined;
143
143
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
144
144
  declare const _default: typeof __VLS_export;
@@ -67,9 +67,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
67
67
  }[]] | undefined;
68
68
  readonly readonly?: string | undefined;
69
69
  readonly enableSorting?: boolean | undefined;
70
- readonly successMessage?: string | undefined;
71
70
  readonly accessor: string;
72
71
  readonly sortKey?: string | undefined;
72
+ readonly successMessage?: string | undefined;
73
73
  }) => any;
74
74
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
75
75
  "onUpdate:modelValue"?: ((value: {
@@ -136,9 +136,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
136
136
  }[]] | undefined;
137
137
  readonly readonly?: string | undefined;
138
138
  readonly enableSorting?: boolean | undefined;
139
- readonly successMessage?: string | undefined;
140
139
  readonly accessor: string;
141
140
  readonly sortKey?: string | undefined;
141
+ readonly successMessage?: string | undefined;
142
142
  }) => any) | undefined;
143
143
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
144
144
  declare const _default: typeof __VLS_export;
@@ -82,9 +82,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
82
82
  };
83
83
  }[];
84
84
  };
85
- readonly successMessage?: string | undefined;
86
85
  readonly accessor: string;
87
86
  readonly sortKey?: string | undefined;
87
+ readonly successMessage?: string | undefined;
88
88
  }) => any;
89
89
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
90
90
  "onUpdate:modelValue"?: ((value: {
@@ -166,9 +166,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
166
166
  };
167
167
  }[];
168
168
  };
169
- readonly successMessage?: string | undefined;
170
169
  readonly accessor: string;
171
170
  readonly sortKey?: string | undefined;
171
+ readonly successMessage?: string | undefined;
172
172
  }) => any) | undefined;
173
173
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
174
174
  declare const _default: typeof __VLS_export;
@@ -82,9 +82,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
82
82
  };
83
83
  }[];
84
84
  };
85
- readonly successMessage?: string | undefined;
86
85
  readonly accessor: string;
87
86
  readonly sortKey?: string | undefined;
87
+ readonly successMessage?: string | undefined;
88
88
  }) => any;
89
89
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
90
90
  "onUpdate:modelValue"?: ((value: {
@@ -166,9 +166,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
166
166
  };
167
167
  }[];
168
168
  };
169
- readonly successMessage?: string | undefined;
170
169
  readonly accessor: string;
171
170
  readonly sortKey?: string | undefined;
171
+ readonly successMessage?: string | undefined;
172
172
  }) => any) | undefined;
173
173
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
174
174
  declare const _default: typeof __VLS_export;
@@ -82,9 +82,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
82
82
  };
83
83
  }[];
84
84
  };
85
- readonly successMessage?: string | undefined;
86
85
  readonly accessor: string;
87
86
  readonly sortKey?: string | undefined;
87
+ readonly successMessage?: string | undefined;
88
88
  }) => any;
89
89
  }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
90
90
  "onUpdate:modelValue"?: ((value: {
@@ -166,9 +166,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
166
166
  };
167
167
  }[];
168
168
  };
169
- readonly successMessage?: string | undefined;
170
169
  readonly accessor: string;
171
170
  readonly sortKey?: string | undefined;
171
+ readonly successMessage?: string | undefined;
172
172
  }) => any) | undefined;
173
173
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
174
174
  declare const _default: typeof __VLS_export;