@shwfed/config 2.7.4 → 2.7.6

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 (91) hide show
  1. package/dist/mcp.mjs +25 -5
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{badge-BKq7Eh7r.js → badge-C-IvPZBx.js} +1 -1
  4. package/dist/preview/assets/{config-DD3McP6M.js → config-B7hXY5FF.js} +1 -1
  5. package/dist/preview/assets/{config-CXomiRuI.js → config-Bl8L6943.js} +1 -1
  6. package/dist/preview/assets/{config-Dg3cJb4i.js → config-C947O8za.js} +1 -1
  7. package/dist/preview/assets/{config-De_RAxft.js → config-DXlCQMVi.js} +1 -1
  8. package/dist/preview/assets/{config-DpTBe8_L.js → config-DhAntnE5.js} +1 -1
  9. package/dist/preview/assets/{config-DM58--pQ.js → config-Dj0rEZRq.js} +1 -1
  10. package/dist/preview/assets/{config-C2XmKu42.js → config-DppExb4h.js} +1 -1
  11. package/dist/preview/assets/{config-CnsvNcA2.js → config-_aVQvlhc.js} +1 -1
  12. package/dist/preview/assets/{config-C31gRv6X.js → config-l01zamcS.js} +1 -1
  13. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-D-K8Bmbj.js → definition.vue_vue_type_script_setup_true_lang-BbuC0qEM.js} +1 -1
  14. package/dist/preview/assets/index-B0PL01fm.css +1 -0
  15. package/dist/preview/assets/index-BNaI1T0H.js +680 -0
  16. package/dist/preview/assets/index-BwoBmSxu.js +1 -0
  17. package/dist/preview/assets/{index-4Jigs5K_.js → index-DiC1rvCq.js} +1 -1
  18. package/dist/preview/assets/{item-DnUV5B-b.js → item-GFiAkFW6.js} +1 -1
  19. package/dist/preview/assets/{runtime-ChaoQZI9.js → runtime-5h5U6Ozr.js} +1 -1
  20. package/dist/preview/assets/{runtime-CG4uOgGu.js → runtime-B6dXW6zW.js} +1 -1
  21. package/dist/preview/assets/{runtime-BqhvXsJ-.js → runtime-BEOIc4zU.js} +1 -1
  22. package/dist/preview/assets/{runtime-DnlIppMg.js → runtime-BQnHKogz.js} +1 -1
  23. package/dist/preview/assets/{runtime-W5CcSnyo.js → runtime-Bx7G-5dR.js} +1 -1
  24. package/dist/preview/assets/{runtime-Dj43RjZC.js → runtime-DmV_M4B_.js} +1 -1
  25. package/dist/preview/assets/{runtime-Dhi2Tk84.js → runtime-TNDFpOlo.js} +1 -1
  26. package/dist/preview/assets/{runtime-DAfJmoV1.js → runtime-g9hb36Vh.js} +1 -1
  27. package/dist/preview/assets/{runtime-BCxzICuW.js → runtime-kLWO8JbC.js} +1 -1
  28. package/dist/preview/index.html +2 -2
  29. package/dist/runtime/components/block-layout-editor/index.d.vue.ts +19 -1
  30. package/dist/runtime/components/block-layout-editor/index.vue +131 -38
  31. package/dist/runtime/components/block-layout-editor/index.vue.d.ts +19 -1
  32. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/config.d.vue.ts +4 -0
  33. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/config.vue.d.ts +4 -0
  34. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/runtime.d.vue.ts +4 -0
  35. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/runtime.vue.d.ts +4 -0
  36. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.form/schema.d.ts +4 -0
  37. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +4 -0
  38. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +4 -0
  39. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +4 -0
  40. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +4 -0
  41. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +6 -0
  42. package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/runtime.vue +46 -26
  43. package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.js +1 -1
  44. package/dist/runtime/components/config/config.vue +9 -1
  45. package/dist/runtime/components/config/index.vue +11 -1
  46. package/dist/runtime/components/config/schema.d.ts +25 -0
  47. package/dist/runtime/components/config/schema.js +8 -0
  48. package/dist/runtime/components/form/config.vue +49 -1
  49. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.actions/schema.d.ts +1 -0
  50. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.actions/schema.js +4 -1
  51. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.d.ts +1 -0
  52. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.list/schema.js +4 -1
  53. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.d.ts +1 -0
  54. package/dist/runtime/components/form/fields/2026-05-18/com.shwfed.form.field.table/schema.js +4 -1
  55. package/dist/runtime/components/form/fields/2026-05-20/com.shwfed.form.field.collapsible/schema.d.ts +1 -0
  56. package/dist/runtime/components/form/fields/2026-05-20/com.shwfed.form.field.collapsible/schema.js +4 -1
  57. package/dist/runtime/components/form/index.d.vue.ts +1 -0
  58. package/dist/runtime/components/form/index.vue +8 -0
  59. package/dist/runtime/components/form/index.vue.d.ts +1 -0
  60. package/dist/runtime/components/form/schema.d.ts +25 -0
  61. package/dist/runtime/components/form/schema.js +17 -0
  62. package/dist/runtime/components/form/unit-config.vue +32 -4
  63. package/dist/runtime/components/form/utils/history.d.ts +8 -0
  64. package/dist/runtime/components/form/utils/history.js +8 -0
  65. package/dist/runtime/components/form/utils/resolve.d.ts +9 -0
  66. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +26 -26
  67. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +26 -26
  68. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +26 -26
  69. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +26 -26
  70. package/dist/runtime/components/table/schema.d.ts +8 -0
  71. package/dist/runtime/components/ui/command/CommandItem.d.vue.ts +2 -2
  72. package/dist/runtime/components/ui/command/CommandItem.vue +1 -0
  73. package/dist/runtime/components/ui/command/CommandItem.vue.d.ts +2 -2
  74. package/dist/runtime/components/ui/context-menu/ContextMenuContent.d.vue.ts +0 -1
  75. package/dist/runtime/components/ui/context-menu/ContextMenuContent.vue +3 -4
  76. package/dist/runtime/components/ui/context-menu/ContextMenuContent.vue.d.ts +0 -1
  77. package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.vue +17 -2
  78. package/dist/runtime/components/ui/input-group/InputGroupCombobox.d.vue.ts +2 -8
  79. package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue +6 -5
  80. package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue.d.ts +2 -8
  81. package/dist/runtime/components/ui/popover/PopoverContent.d.vue.ts +0 -1
  82. package/dist/runtime/components/ui/popover/PopoverContent.vue +3 -4
  83. package/dist/runtime/components/ui/popover/PopoverContent.vue.d.ts +0 -1
  84. package/dist/runtime/components/ui/tooltip/TooltipContent.d.vue.ts +0 -1
  85. package/dist/runtime/components/ui/tooltip/TooltipContent.vue +3 -4
  86. package/dist/runtime/components/ui/tooltip/TooltipContent.vue.d.ts +0 -1
  87. package/dist/runtime/share/event-bus.d.ts +23 -4
  88. package/package.json +1 -1
  89. package/dist/preview/assets/index-CfwL2UCH.js +0 -680
  90. package/dist/preview/assets/index-DNHGrCDe.css +0 -1
  91. package/dist/preview/assets/index-DUo1pTg2.js +0 -1
@@ -20,6 +20,13 @@ declare const __VLS_export: <TItem extends {
20
20
  min: number;
21
21
  max: number;
22
22
  }>;
23
+ /**
24
+ * When `false`, this item opts out of the fullscreen inline-config pane —
25
+ * a drill request falls back to emitting `drill-down` (which exits
26
+ * fullscreen). Absent / `true` → inline editing is offered while the host
27
+ * provides the `inline-config` slot. See the "Inline config" section below.
28
+ */
29
+ inlineConfig?: boolean;
23
30
  }>;
24
31
  }> | undefined;
25
32
  getItemLabel?: (item: TItem) => string;
@@ -70,7 +77,18 @@ declare const __VLS_export: <TItem extends {
70
77
  } ? P : {});
71
78
  expose: (exposed: {}) => void;
72
79
  attrs: any;
73
- slots: {};
80
+ slots: {
81
+ /**
82
+ * Body of the right-docked config pane shown when a field is opened inline
83
+ * in fullscreen. Rendered inside the fullscreen element so editing doesn't
84
+ * unmount the canvas. Receives the item being edited and a `close` hook.
85
+ */
86
+ 'inline-config'(props: {
87
+ itemId: string;
88
+ item: TItem;
89
+ close: () => void;
90
+ }): unknown;
91
+ };
74
92
  emit: (((evt: "paste", target: {
75
93
  x: number;
76
94
  y: number;
@@ -11,10 +11,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
11
11
  "update:modelValue": (value: {
12
12
  readonly form: {
13
13
  readonly style?: string | undefined;
14
+ readonly id?: string | undefined;
14
15
  readonly initial?: {
15
16
  readonly data: string;
16
17
  readonly request?: string | undefined;
17
18
  } | undefined;
19
+ readonly displayName?: string | undefined;
18
20
  readonly kind: "shwfed.component.form";
19
21
  readonly fields: readonly any[];
20
22
  readonly layouts: readonly {
@@ -44,10 +46,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
44
46
  "onUpdate:modelValue"?: ((value: {
45
47
  readonly form: {
46
48
  readonly style?: string | undefined;
49
+ readonly id?: string | undefined;
47
50
  readonly initial?: {
48
51
  readonly data: string;
49
52
  readonly request?: string | undefined;
50
53
  } | undefined;
54
+ readonly displayName?: string | undefined;
51
55
  readonly kind: "shwfed.component.form";
52
56
  readonly fields: readonly any[];
53
57
  readonly layouts: readonly {
@@ -11,10 +11,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
11
11
  "update:modelValue": (value: {
12
12
  readonly form: {
13
13
  readonly style?: string | undefined;
14
+ readonly id?: string | undefined;
14
15
  readonly initial?: {
15
16
  readonly data: string;
16
17
  readonly request?: string | undefined;
17
18
  } | undefined;
19
+ readonly displayName?: string | undefined;
18
20
  readonly kind: "shwfed.component.form";
19
21
  readonly fields: readonly any[];
20
22
  readonly layouts: readonly {
@@ -44,10 +46,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
44
46
  "onUpdate:modelValue"?: ((value: {
45
47
  readonly form: {
46
48
  readonly style?: string | undefined;
49
+ readonly id?: string | undefined;
47
50
  readonly initial?: {
48
51
  readonly data: string;
49
52
  readonly request?: string | undefined;
50
53
  } | undefined;
54
+ readonly displayName?: string | undefined;
51
55
  readonly kind: "shwfed.component.form";
52
56
  readonly fields: readonly any[];
53
57
  readonly layouts: readonly {
@@ -13,10 +13,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
13
13
  "update:block": (value: {
14
14
  readonly form: {
15
15
  readonly style?: string | undefined;
16
+ readonly id?: string | undefined;
16
17
  readonly initial?: {
17
18
  readonly data: string;
18
19
  readonly request?: string | undefined;
19
20
  } | undefined;
21
+ readonly displayName?: string | undefined;
20
22
  readonly kind: "shwfed.component.form";
21
23
  readonly fields: readonly any[];
22
24
  readonly layouts: readonly {
@@ -47,10 +49,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
47
49
  "onUpdate:block"?: ((value: {
48
50
  readonly form: {
49
51
  readonly style?: string | undefined;
52
+ readonly id?: string | undefined;
50
53
  readonly initial?: {
51
54
  readonly data: string;
52
55
  readonly request?: string | undefined;
53
56
  } | undefined;
57
+ readonly displayName?: string | undefined;
54
58
  readonly kind: "shwfed.component.form";
55
59
  readonly fields: readonly any[];
56
60
  readonly layouts: readonly {
@@ -13,10 +13,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
13
13
  "update:block": (value: {
14
14
  readonly form: {
15
15
  readonly style?: string | undefined;
16
+ readonly id?: string | undefined;
16
17
  readonly initial?: {
17
18
  readonly data: string;
18
19
  readonly request?: string | undefined;
19
20
  } | undefined;
21
+ readonly displayName?: string | undefined;
20
22
  readonly kind: "shwfed.component.form";
21
23
  readonly fields: readonly any[];
22
24
  readonly layouts: readonly {
@@ -47,10 +49,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
47
49
  "onUpdate:block"?: ((value: {
48
50
  readonly form: {
49
51
  readonly style?: string | undefined;
52
+ readonly id?: string | undefined;
50
53
  readonly initial?: {
51
54
  readonly data: string;
52
55
  readonly request?: string | undefined;
53
56
  } | undefined;
57
+ readonly displayName?: string | undefined;
54
58
  readonly kind: "shwfed.component.form";
55
59
  readonly fields: readonly any[];
56
60
  readonly layouts: readonly {
@@ -23,10 +23,12 @@ export declare function schema(configure: (env: Environment) => void, _blockRef:
23
23
  compatibilityDate: Schema.tag<"2026-05-06">;
24
24
  form: Schema.refine<{
25
25
  readonly style?: string | undefined;
26
+ readonly id?: string | undefined;
26
27
  readonly initial?: {
27
28
  readonly data: string;
28
29
  readonly request?: string | undefined;
29
30
  } | undefined;
31
+ readonly displayName?: string | undefined;
30
32
  readonly kind: "shwfed.component.form";
31
33
  readonly fields: readonly any[];
32
34
  readonly layouts: readonly {
@@ -81,6 +83,8 @@ export declare function schema(configure: (env: Environment) => void, _blockRef:
81
83
  }>;
82
84
  }>>>;
83
85
  kind: Schema.tag<"shwfed.component.form">;
86
+ id: Schema.optional<Schema.refine<string, typeof Schema.String>>;
87
+ displayName: Schema.optional<Schema.SchemaClass<string, string, never>>;
84
88
  initial: Schema.optional<Schema.transform<Schema.Union<[Schema.Schema<string, string, never>, Schema.Struct<{
85
89
  request: Schema.optional<Schema.Schema<string, string, never>>;
86
90
  data: Schema.Schema<string, string, never>;
@@ -36,10 +36,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
36
36
  }[];
37
37
  readonly query?: {
38
38
  readonly style?: string | undefined;
39
+ readonly id?: string | undefined;
39
40
  readonly initial?: {
40
41
  readonly data: string;
41
42
  readonly request?: string | undefined;
42
43
  } | undefined;
44
+ readonly displayName?: string | undefined;
43
45
  readonly kind: "shwfed.component.form";
44
46
  readonly fields: readonly any[];
45
47
  readonly layouts: readonly {
@@ -214,10 +216,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
214
216
  }[];
215
217
  readonly query?: {
216
218
  readonly style?: string | undefined;
219
+ readonly id?: string | undefined;
217
220
  readonly initial?: {
218
221
  readonly data: string;
219
222
  readonly request?: string | undefined;
220
223
  } | undefined;
224
+ readonly displayName?: string | undefined;
221
225
  readonly kind: "shwfed.component.form";
222
226
  readonly fields: readonly any[];
223
227
  readonly layouts: readonly {
@@ -36,10 +36,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
36
36
  }[];
37
37
  readonly query?: {
38
38
  readonly style?: string | undefined;
39
+ readonly id?: string | undefined;
39
40
  readonly initial?: {
40
41
  readonly data: string;
41
42
  readonly request?: string | undefined;
42
43
  } | undefined;
44
+ readonly displayName?: string | undefined;
43
45
  readonly kind: "shwfed.component.form";
44
46
  readonly fields: readonly any[];
45
47
  readonly layouts: readonly {
@@ -214,10 +216,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
214
216
  }[];
215
217
  readonly query?: {
216
218
  readonly style?: string | undefined;
219
+ readonly id?: string | undefined;
217
220
  readonly initial?: {
218
221
  readonly data: string;
219
222
  readonly request?: string | undefined;
220
223
  } | undefined;
224
+ readonly displayName?: string | undefined;
221
225
  readonly kind: "shwfed.component.form";
222
226
  readonly fields: readonly any[];
223
227
  readonly layouts: readonly {
@@ -31,10 +31,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
31
31
  }[];
32
32
  readonly query?: {
33
33
  readonly style?: string | undefined;
34
+ readonly id?: string | undefined;
34
35
  readonly initial?: {
35
36
  readonly data: string;
36
37
  readonly request?: string | undefined;
37
38
  } | undefined;
39
+ readonly displayName?: string | undefined;
38
40
  readonly kind: "shwfed.component.form";
39
41
  readonly fields: readonly any[];
40
42
  readonly layouts: readonly {
@@ -209,10 +211,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
209
211
  }[];
210
212
  readonly query?: {
211
213
  readonly style?: string | undefined;
214
+ readonly id?: string | undefined;
212
215
  readonly initial?: {
213
216
  readonly data: string;
214
217
  readonly request?: string | undefined;
215
218
  } | undefined;
219
+ readonly displayName?: string | undefined;
216
220
  readonly kind: "shwfed.component.form";
217
221
  readonly fields: readonly any[];
218
222
  readonly layouts: readonly {
@@ -31,10 +31,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
31
31
  }[];
32
32
  readonly query?: {
33
33
  readonly style?: string | undefined;
34
+ readonly id?: string | undefined;
34
35
  readonly initial?: {
35
36
  readonly data: string;
36
37
  readonly request?: string | undefined;
37
38
  } | undefined;
39
+ readonly displayName?: string | undefined;
38
40
  readonly kind: "shwfed.component.form";
39
41
  readonly fields: readonly any[];
40
42
  readonly layouts: readonly {
@@ -209,10 +211,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
209
211
  }[];
210
212
  readonly query?: {
211
213
  readonly style?: string | undefined;
214
+ readonly id?: string | undefined;
212
215
  readonly initial?: {
213
216
  readonly data: string;
214
217
  readonly request?: string | undefined;
215
218
  } | undefined;
219
+ readonly displayName?: string | undefined;
216
220
  readonly kind: "shwfed.component.form";
217
221
  readonly fields: readonly any[];
218
222
  readonly layouts: readonly {
@@ -46,10 +46,12 @@ export declare function schema(configure: (env: Environment) => void, _blockRef:
46
46
  }[];
47
47
  readonly query?: {
48
48
  readonly style?: string | undefined;
49
+ readonly id?: string | undefined;
49
50
  readonly initial?: {
50
51
  readonly data: string;
51
52
  readonly request?: string | undefined;
52
53
  } | undefined;
54
+ readonly displayName?: string | undefined;
53
55
  readonly kind: "shwfed.component.form";
54
56
  readonly fields: readonly any[];
55
57
  readonly layouts: readonly {
@@ -351,10 +353,12 @@ export declare function schema(configure: (env: Environment) => void, _blockRef:
351
353
  }>>;
352
354
  query: Schema.optional<Schema.refine<{
353
355
  readonly style?: string | undefined;
356
+ readonly id?: string | undefined;
354
357
  readonly initial?: {
355
358
  readonly data: string;
356
359
  readonly request?: string | undefined;
357
360
  } | undefined;
361
+ readonly displayName?: string | undefined;
358
362
  readonly kind: "shwfed.component.form";
359
363
  readonly fields: readonly any[];
360
364
  readonly layouts: readonly {
@@ -409,6 +413,8 @@ export declare function schema(configure: (env: Environment) => void, _blockRef:
409
413
  }>;
410
414
  }>>>;
411
415
  kind: Schema.tag<"shwfed.component.form">;
416
+ id: Schema.optional<Schema.refine<string, typeof Schema.String>>;
417
+ displayName: Schema.optional<Schema.SchemaClass<string, string, never>>;
412
418
  initial: Schema.optional<Schema.transform<Schema.Union<[Schema.Schema<string, string, never>, Schema.Struct<{
413
419
  request: Schema.optional<Schema.Schema<string, string, never>>;
414
420
  data: Schema.Schema<string, string, never>;
@@ -30,17 +30,23 @@ function evalStyle(expression) {
30
30
  }
31
31
  }
32
32
  const styleValue = computed(() => evalStyle(block.value.style));
33
- const hasUrl = computed(() => !!block.value.url && block.value.url.trim().length > 0);
34
- function onCardClick(e) {
35
- if (!hasUrl.value) return;
36
- const target = e.target;
37
- if (target?.closest('a, button, input, select, textarea, label, [role="button"]')) return;
33
+ const resolvedUrl = computed(() => {
34
+ const expr = block.value.url;
35
+ if (!expr || expr.trim().length === 0) return void 0;
38
36
  try {
39
- const url = Effect.runSync(cel(block.value.url, baseContext()));
40
- if (typeof url === "string" && url) window.open(url, "_self");
37
+ const url = Effect.runSync(cel(expr, baseContext()));
38
+ return typeof url === "string" && url ? url : void 0;
41
39
  } catch (err) {
42
40
  console.warn("[shwfed-card] url evaluation failed", err);
41
+ return void 0;
43
42
  }
43
+ });
44
+ const hasUrl = computed(() => !!block.value.url && block.value.url.trim().length > 0);
45
+ function onCardClick(e, navigate) {
46
+ if (!resolvedUrl.value) return;
47
+ const target = e.target;
48
+ if (target?.closest('a, button, input, select, textarea, label, [role="button"]')) return;
49
+ navigate(e);
44
50
  }
45
51
  function updateSlot(next) {
46
52
  block.value = { ...block.value, slot: next };
@@ -48,25 +54,39 @@ function updateSlot(next) {
48
54
  </script>
49
55
 
50
56
  <template>
51
- <div
52
- class="relative h-full rounded-sm border border-zinc-200 bg-white p-4"
53
- :class="hasUrl ? 'cursor-pointer' : ''"
54
- :style="styleValue"
55
- @click="onCardClick"
57
+ <!--
58
+ `custom` makes NuxtLink render no anchor of its own — it just hands us a
59
+ baseURL-aware `navigate()`. We keep the card a `<div>` so clicks on
60
+ interactive descendants stay untouched, and only follow the link from the
61
+ guarded handler. `to` is `''` when no URL is configured (navigation is then
62
+ short-circuited in `onCardClick`).
63
+ -->
64
+ <NuxtLink
65
+ :to="resolvedUrl ?? ''"
66
+ custom
56
67
  >
57
- <ClientOnly>
58
- <CardBadge
59
- v-if="block.badge"
60
- :badge="block.badge"
61
- class="absolute -right-2 -top-2 z-10"
62
- />
63
- </ClientOnly>
68
+ <template #default="{ navigate }">
69
+ <div
70
+ class="relative h-full rounded-sm border border-zinc-200 bg-white p-4"
71
+ :class="hasUrl ? 'cursor-pointer' : ''"
72
+ :style="styleValue"
73
+ @click="(e) => onCardClick(e, navigate)"
74
+ >
75
+ <ClientOnly>
76
+ <CardBadge
77
+ v-if="block.badge"
78
+ :badge="block.badge"
79
+ class="absolute -right-2 -top-2 z-10"
80
+ />
81
+ </ClientOnly>
64
82
 
65
- <SlotRenderer
66
- :slot-value="block.slot"
67
- :configure="configure"
68
- :find-entry="findBlock"
69
- @update:slot-value="(s) => updateSlot(s)"
70
- />
71
- </div>
83
+ <SlotRenderer
84
+ :slot-value="block.slot"
85
+ :configure="configure"
86
+ :find-entry="findBlock"
87
+ @update:slot-value="(s) => updateSlot(s)"
88
+ />
89
+ </div>
90
+ </template>
91
+ </NuxtLink>
72
92
  </template>
@@ -91,7 +91,7 @@ export function schema(configure, blockRef) {
91
91
  }),
92
92
  url: Schema.optional(CelUrl).annotations({
93
93
  title: "\u94FE\u63A5",
94
- description: "\u8FD4\u56DE `string` \u7684 CEL \u8868\u8FBE\u5F0F\uFF1B\u914D\u7F6E\u540E\u70B9\u51FB\u5361\u7247\u7A7A\u767D\u5904\u5C06\u5728\u5F53\u524D\u6807\u7B7E\u9875\u6253\u5F00\u8BE5\u94FE\u63A5\u3002\u70B9\u51FB\u5361\u7247\u5185\u7684\u6309\u94AE\u3001\u94FE\u63A5\u7B49\u4EA4\u4E92\u5143\u7D20\u4E0D\u4F1A\u89E6\u53D1"
94
+ description: "\u8FD4\u56DE `string` \u7684 CEL \u8868\u8FBE\u5F0F\uFF1B\u914D\u7F6E\u540E\u70B9\u51FB\u5361\u7247\u7A7A\u767D\u5904\u5C06\u901A\u8FC7\u8DEF\u7531\u8DF3\u8F6C\u5230\u8BE5\u94FE\u63A5\uFF08\u7ECF `NuxtLink`\uFF0C\u9075\u5FAA\u5E94\u7528 base URL\uFF09\u3002\u70B9\u51FB\u5361\u7247\u5185\u7684\u6309\u94AE\u3001\u94FE\u63A5\u7B49\u4EA4\u4E92\u5143\u7D20\u4E0D\u4F1A\u89E6\u53D1"
95
95
  }),
96
96
  badge: Schema.optional(badgeSchema(configure)).annotations({
97
97
  title: "\u5FBD\u7AE0",
@@ -13,8 +13,9 @@ import { Locale as LocaleField } from "../ui/locale";
13
13
  import { Markdown } from "../ui/markdown";
14
14
  import { ScrollArea } from "../ui/scroll-area";
15
15
  import { Separator } from "../ui/separator";
16
+ import { provideEventAncestor } from "../../share/event-bus";
16
17
  import { BREADCRUMB_EXTENSION_KEY } from "./breadcrumb-extension";
17
- import { PageConfig, getStructFieldDescription, getStructFieldTitle } from "./schema";
18
+ import { PAGE_TARGET_ID, PageConfig, getStructFieldDescription, getStructFieldTitle, metadata as pageMetadata } from "./schema";
18
19
  defineOptions({ name: "ShwfedConfigConfig" });
19
20
  const props = defineProps({
20
21
  state: { type: Object, required: true }
@@ -82,6 +83,13 @@ provide(BREADCRUMB_EXTENSION_KEY, {
82
83
  add: props.state.addCrumb,
83
84
  addParentSuffix: props.state.addParentSuffix
84
85
  });
86
+ const pageEventAncestor = computed(() => ({
87
+ instanceId: PAGE_TARGET_ID,
88
+ typeName: pageMetadata.name,
89
+ typeIcon: pageMetadata.icon,
90
+ operations: pageMetadata.operations
91
+ }));
92
+ provideEventAncestor(pageEventAncestor);
85
93
  const sidebarRef = useTemplateRef("sidebarRef");
86
94
  function addLayout() {
87
95
  sidebarRef.value?.addLayout();
@@ -11,7 +11,8 @@ import ShwfedModal from "../modal.vue";
11
11
  import EditorBody from "./config.vue";
12
12
  import EditorBreadcrumb from "./breadcrumb.vue";
13
13
  import EditorFooter from "./footer.vue";
14
- import { createPageConfig } from "./schema";
14
+ import { provideEventTarget } from "../../share/event-bus";
15
+ import { PAGE_TARGET_ID, createPageConfig } from "./schema";
15
16
  import { useConfigEditor } from "./use-editor";
16
17
  import { findBlock } from "./utils/resolve";
17
18
  defineOptions({ name: "ShwfedConfig" });
@@ -37,6 +38,15 @@ const mergedConfigure = (env) => {
37
38
  env.registerVariable(name, v.type, { description: v.description, label: v.label });
38
39
  }
39
40
  };
41
+ class PageClosed {
42
+ _tag = "PageClosed";
43
+ }
44
+ provideEventTarget(PAGE_TARGET_ID, {
45
+ close: () => Effect.gen(function* () {
46
+ window.close();
47
+ return yield* Effect.die(new PageClosed());
48
+ })
49
+ });
40
50
  const editorOpen = ref(false);
41
51
  const editorState = useConfigEditor(config, {
42
52
  configure: mergedConfigure,
@@ -3,6 +3,31 @@ import type { Environment } from '../../vendor/cel-js/lib/index.js';
3
3
  import { type LocaleValue } from '../../share/locale.js';
4
4
  export { getStructFieldDescription, getStructFieldTitle } from '../table/utils/schema-meta.js';
5
5
  declare const KIND = "shwfed.component.page";
6
+ /**
7
+ * Reserved sentinel instance id for the singleton page operation target. The
8
+ * page is the outermost `ShwfedConfig` — there is only ever one per tree, so it
9
+ * needs no stored, per-config id (which would force a migration of every
10
+ * existing page config). The nil UUID can never collide with a block id:
11
+ * `crypto.randomUUID()` always sets version-4 + variant bits, so it never
12
+ * emits all-zeros. It also passes `Schema.UUID`'s lenient hex-layout regex, so
13
+ * stored triggers targeting it decode cleanly.
14
+ */
15
+ export declare const PAGE_TARGET_ID = "00000000-0000-0000-0000-000000000000";
16
+ /**
17
+ * Capability manifest — type-level display info plus the operations the page
18
+ * instance exposes to op-requests bubbled up from its descendants. Mirrors the
19
+ * form/table manifests. `close` closes the surrounding browser tab/window; see
20
+ * the runtime in `index.vue` for its deliberate-halt semantics.
21
+ */
22
+ export declare const metadata: {
23
+ readonly name: "页面";
24
+ readonly icon: "fluent:document-20-regular";
25
+ readonly operations: readonly [{
26
+ readonly id: "close";
27
+ readonly name: "关闭标签页";
28
+ readonly icon: "fluent:dismiss-20-regular";
29
+ }];
30
+ };
6
31
  export declare function PageConfig(configure: (env: Environment) => void): Schema.Struct<{
7
32
  kind: Schema.tag<"shwfed.component.page">;
8
33
  title: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
@@ -4,6 +4,14 @@ import { Locale } from "../../share/locale.js";
4
4
  import { blockRef } from "./utils/resolve.js";
5
5
  export { getStructFieldDescription, getStructFieldTitle } from "../table/utils/schema-meta.js";
6
6
  const KIND = "shwfed.component.page";
7
+ export const PAGE_TARGET_ID = "00000000-0000-0000-0000-000000000000";
8
+ export const metadata = {
9
+ name: "\u9875\u9762",
10
+ icon: "fluent:document-20-regular",
11
+ operations: [
12
+ { id: "close", name: "\u5173\u95ED\u6807\u7B7E\u9875", icon: "fluent:dismiss-20-regular" }
13
+ ]
14
+ };
7
15
  export function PageConfig(configure) {
8
16
  const Block = blockRef(configure).annotations({
9
17
  identifier: "PageBlock",
@@ -3,12 +3,15 @@ import { computed, ref } from "vue";
3
3
  import { provideCELContext } from "../../utils/cel-context";
4
4
  import { ExpressionEditor } from "../ui/expression-editor";
5
5
  import { Field, FieldLabel } from "../ui/field";
6
+ import { Input } from "../ui/input";
6
7
  import { Markdown } from "../ui/markdown";
7
8
  import { Textarea } from "../ui/textarea";
9
+ import { provideEventAncestor } from "../../share/event-bus";
8
10
  import {
9
11
  FormConfig,
10
12
  getStructFieldDescription,
11
- getStructFieldTitle
13
+ getStructFieldTitle,
14
+ metadata as formMetadata
12
15
  } from "./schema";
13
16
  import ShwfedFormUnitConfig, {} from "./unit-config.vue";
14
17
  import { buildFormCelScope } from "./utils/cel-scope";
@@ -23,6 +26,21 @@ const formConfigSchema = FormConfig(configure);
23
26
  const generalFieldTitle = (f) => getStructFieldTitle(formConfigSchema, f) ?? f;
24
27
  const generalFieldDescription = (f) => getStructFieldDescription(formConfigSchema, f);
25
28
  provideCELContext(buildFormCelScope(configure));
29
+ const formEventAncestor = computed(() => {
30
+ const id = config.value.id;
31
+ if (!id) return null;
32
+ const displayName = config.value.displayName;
33
+ return {
34
+ instanceId: id,
35
+ // Left undefined when the configurer wrote no 内部名称 — the trigger UI
36
+ // then shows just the type name rather than a redundant 「表单」.
37
+ name: displayName && displayName.length > 0 ? displayName : void 0,
38
+ typeName: formMetadata.name,
39
+ typeIcon: formMetadata.icon,
40
+ operations: formMetadata.operations
41
+ };
42
+ });
43
+ provideEventAncestor(formEventAncestor);
26
44
  const unitModel = computed({
27
45
  get: () => ({ fields: config.value.fields, layouts: config.value.layouts }),
28
46
  set: (next) => {
@@ -44,6 +62,15 @@ function setInitialField(key, value) {
44
62
  config.value = { ...config.value, initial: next };
45
63
  }
46
64
  }
65
+ function updateDisplayName(value) {
66
+ const next = { ...config.value };
67
+ if (value.trim() === "") {
68
+ const { displayName: _omit, ...rest } = next;
69
+ config.value = rest;
70
+ } else {
71
+ config.value = { ...next, displayName: value };
72
+ }
73
+ }
47
74
  function updateReadonly(value) {
48
75
  const next = { ...config.value };
49
76
  if (value.trim() === "") {
@@ -73,6 +100,27 @@ function updateStyle(value) {
73
100
  >
74
101
  <template #extras-pane>
75
102
  <div class="flex flex-col gap-4">
103
+ <Field orientation="vertical">
104
+ <FieldLabel class="text-xs text-zinc-500">
105
+ <template
106
+ v-if="generalFieldDescription('displayName')"
107
+ #tooltip
108
+ >
109
+ <Markdown
110
+ :source="generalFieldDescription('displayName')"
111
+ block
112
+ class="prose prose-sm prose-zinc"
113
+ />
114
+ </template>
115
+ {{ generalFieldTitle("displayName") }}
116
+ </FieldLabel>
117
+ <Input
118
+ :model-value="config.displayName ?? ''"
119
+ placeholder="如 用户信息表单"
120
+ @update:model-value="(v) => updateDisplayName(String(v))"
121
+ />
122
+ </Field>
123
+
76
124
  <Field orientation="vertical">
77
125
  <FieldLabel class="text-xs text-zinc-500">
78
126
  <template
@@ -15,6 +15,7 @@ export declare const metadata: {
15
15
  readonly min: 2;
16
16
  readonly max: number;
17
17
  };
18
+ readonly inlineConfig: false;
18
19
  };
19
20
  export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
20
21
  groups: Schema.optionalWith<Schema.Array$<Schema.Struct<{
@@ -7,7 +7,10 @@ export const metadata = {
7
7
  name: "\u64CD\u4F5C",
8
8
  icon: "fluent:cursor-click-20-regular",
9
9
  w: { initial: 8, min: 4, max: Infinity },
10
- h: { initial: 2, min: 2, max: Infinity }
10
+ h: { initial: 2, min: 2, max: Infinity },
11
+ // Drills into its own nested button layout editor — too complex for the
12
+ // fullscreen inline-config pane; keep the (fullscreen-exiting) drill-down.
13
+ inlineConfig: false
11
14
  };
12
15
  export function schema(configure) {
13
16
  const { fields: actionFields } = ActionSchemaFields(configure);
@@ -16,6 +16,7 @@ export declare const metadata: {
16
16
  readonly max: number;
17
17
  readonly grow: true;
18
18
  };
19
+ readonly inlineConfig: false;
19
20
  };
20
21
  export declare function schema(configure: (env: Environment) => void): Schema.refine<{
21
22
  readonly label?: readonly [{
@@ -9,7 +9,10 @@ export const metadata = {
9
9
  name: "\u5217\u8868",
10
10
  icon: "fluent:list-20-regular",
11
11
  w: { initial: 12, min: 4, max: Infinity },
12
- h: { initial: 6, min: 4, max: Infinity, grow: true }
12
+ h: { initial: 6, min: 4, max: Infinity, grow: true },
13
+ // Hosts a nested sub-form (its own fields + layout) — too complex for the
14
+ // fullscreen inline-config pane; keep the (fullscreen-exiting) drill-down.
15
+ inlineConfig: false
13
16
  };
14
17
  export function schema(configure) {
15
18
  const CelBool = Expression({ configure, resultType: "bool" });
@@ -16,6 +16,7 @@ export declare const metadata: {
16
16
  readonly max: number;
17
17
  readonly grow: true;
18
18
  };
19
+ readonly inlineConfig: false;
19
20
  };
20
21
  export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
21
22
  label: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{