@shwfed/config 2.5.3 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/mcp.mjs +8 -0
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +6 -1
  4. package/dist/preview/assets/{config-U359oLg8.js → config-BF-HYbrD.js} +1 -1
  5. package/dist/preview/assets/{config-C5TWIUX-.js → config-CevoqLCe.js} +1 -1
  6. package/dist/preview/assets/{config-ekMG8PO0.js → config-Co--BPbb.js} +1 -1
  7. package/dist/preview/assets/{config-CH28q4_H.js → config-DMOAQ9zl.js} +1 -1
  8. package/dist/preview/assets/{config-DN6k6pjm.js → config-Du7AdGIY.js} +1 -1
  9. package/dist/preview/assets/{config-CtGduGcR.js → config-LdNKbqCx.js} +1 -1
  10. package/dist/preview/assets/{config-D9tBv8LD.js → config-RACtdV3v.js} +1 -1
  11. package/dist/preview/assets/{config-BVjCjkAL.js → config-VChcvg_y.js} +1 -1
  12. package/dist/preview/assets/{config-DxB8qwAu.js → config-oBOXGUjR.js} +1 -1
  13. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-I7unZVnH.js → definition.vue_vue_type_script_setup_true_lang-Ma8i-2ox.js} +1 -1
  14. package/dist/preview/assets/index-C-nzF9-u.js +1 -0
  15. package/dist/preview/assets/index-CHEiFlnE.css +1 -0
  16. package/dist/preview/assets/index-rxUrWg1Y.js +680 -0
  17. package/dist/preview/assets/{runtime-CQly-3c3.js → runtime-BNzaUtd-.js} +1 -1
  18. package/dist/preview/assets/{runtime-BKQvzSax.js → runtime-CAj4SjAs.js} +1 -1
  19. package/dist/preview/assets/{runtime-BafXFP0s.js → runtime-CE_42oyr.js} +1 -1
  20. package/dist/preview/assets/{runtime-DJgDXKfE.js → runtime-CLMz0SYI.js} +1 -1
  21. package/dist/preview/assets/{runtime-x8IdC454.js → runtime-COCfVWBL.js} +1 -1
  22. package/dist/preview/assets/{runtime-CAzVJ-if.js → runtime-GfHY6wxJ.js} +1 -1
  23. package/dist/preview/assets/{runtime-BAQ6ezPo.js → runtime-Y00C-S73.js} +1 -1
  24. package/dist/preview/assets/{runtime-Dhd51Wyr.js → runtime-llw5ZA1Z.js} +1 -1
  25. package/dist/preview/assets/{runtime-27bDIkKv.js → runtime-wAJ77Q3a.js} +1 -1
  26. package/dist/preview/index.html +2 -2
  27. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.d.vue.ts +4 -4
  28. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.vue.d.ts +4 -4
  29. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.d.vue.ts +6 -6
  30. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.vue.d.ts +6 -6
  31. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.d.vue.ts +2 -2
  32. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.timerange/config.vue.d.ts +2 -2
  33. package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.d.vue.ts +4 -4
  34. package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.vue.d.ts +4 -4
  35. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
  36. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
  37. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
  38. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
  39. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
  40. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
  41. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
  42. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
  43. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
  44. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
  45. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
  46. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
  47. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  48. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  49. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  50. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  51. package/dist/runtime/components/table/config.vue +17 -1
  52. package/dist/runtime/components/table/index.vue +1 -0
  53. package/dist/runtime/components/table/row-provider.d.vue.ts +1 -0
  54. package/dist/runtime/components/table/row-provider.vue +9 -2
  55. package/dist/runtime/components/table/row-provider.vue.d.ts +1 -0
  56. package/dist/runtime/components/ui/date-picker/DatePickerInput.d.vue.ts +1 -1
  57. package/dist/runtime/components/ui/date-picker/DatePickerInput.vue.d.ts +1 -1
  58. package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.d.vue.ts +1 -1
  59. package/dist/runtime/components/ui/date-picker/DatePickerTimeInput.vue.d.ts +1 -1
  60. package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.d.vue.ts +1 -1
  61. package/dist/runtime/components/ui/date-range-picker/DateRangePickerInput.vue.d.ts +1 -1
  62. package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.d.vue.ts +2 -2
  63. package/dist/runtime/components/ui/date-range-picker/DateRangePickerTimeInput.vue.d.ts +2 -2
  64. package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.d.vue.ts +22 -0
  65. package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.vue +134 -0
  66. package/dist/runtime/components/ui/expression-editor/CodeMirrorInput.vue.d.ts +22 -0
  67. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.d.vue.ts +2 -2
  68. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +71 -50
  69. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue.d.ts +2 -2
  70. package/dist/runtime/components/ui/expression-editor/cel-language.d.ts +16 -0
  71. package/dist/runtime/components/ui/expression-editor/cel-language.js +114 -0
  72. package/dist/runtime/components/ui/expression-editor/chip-extension.d.ts +5 -0
  73. package/dist/runtime/components/ui/expression-editor/chip-extension.js +123 -0
  74. package/dist/runtime/components/ui/expression-editor/picker-entries.d.ts +17 -0
  75. package/dist/runtime/components/ui/expression-editor/picker-entries.js +34 -0
  76. package/dist/runtime/components/ui/expression-editor/scope-refs.d.ts +20 -0
  77. package/dist/runtime/components/ui/expression-editor/scope-refs.js +39 -0
  78. package/dist/runtime/share/expression.js +9 -0
  79. package/dist/runtime/utils/cel-context.d.ts +36 -0
  80. package/dist/runtime/utils/cel-context.js +39 -0
  81. package/package.json +6 -1
  82. package/dist/preview/assets/index-CZ-XSjS_.js +0 -668
  83. package/dist/preview/assets/index-HfGseg4M.js +0 -1
  84. package/dist/preview/assets/index-nvAUAYGM.css +0 -1
@@ -43,8 +43,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
43
43
  readonly target: string;
44
44
  readonly operation: string;
45
45
  }[] | undefined;
46
- readonly successMessage?: string | undefined;
47
46
  readonly accessor: string;
47
+ readonly successMessage?: string | undefined;
48
48
  };
49
49
  readonly grow?: boolean | undefined;
50
50
  readonly enableSorting?: boolean | undefined;
@@ -132,8 +132,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
132
132
  readonly target: string;
133
133
  readonly operation: string;
134
134
  }[] | undefined;
135
- readonly successMessage?: string | undefined;
136
135
  readonly accessor: string;
136
+ readonly successMessage?: string | undefined;
137
137
  };
138
138
  readonly grow?: boolean | undefined;
139
139
  readonly enableSorting?: boolean | undefined;
@@ -43,8 +43,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
43
43
  readonly target: string;
44
44
  readonly operation: string;
45
45
  }[] | undefined;
46
- readonly successMessage?: string | undefined;
47
46
  readonly accessor: string;
47
+ readonly successMessage?: string | undefined;
48
48
  };
49
49
  readonly grow?: boolean | undefined;
50
50
  readonly enableSorting?: boolean | undefined;
@@ -132,8 +132,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
132
132
  readonly target: string;
133
133
  readonly operation: string;
134
134
  }[] | undefined;
135
- readonly successMessage?: string | undefined;
136
135
  readonly accessor: string;
136
+ readonly successMessage?: string | undefined;
137
137
  };
138
138
  readonly grow?: boolean | undefined;
139
139
  readonly enableSorting?: boolean | undefined;
@@ -43,8 +43,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
43
43
  readonly target: string;
44
44
  readonly operation: string;
45
45
  }[] | undefined;
46
- readonly successMessage?: string | undefined;
47
46
  readonly accessor: string;
47
+ readonly successMessage?: string | undefined;
48
48
  };
49
49
  readonly grow?: boolean | undefined;
50
50
  readonly enableSorting?: boolean | undefined;
@@ -132,8 +132,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
132
132
  readonly target: string;
133
133
  readonly operation: string;
134
134
  }[] | undefined;
135
- readonly successMessage?: string | undefined;
136
135
  readonly accessor: string;
136
+ readonly successMessage?: string | undefined;
137
137
  };
138
138
  readonly grow?: boolean | undefined;
139
139
  readonly enableSorting?: boolean | undefined;
@@ -43,8 +43,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
43
43
  readonly target: string;
44
44
  readonly operation: string;
45
45
  }[] | undefined;
46
- readonly successMessage?: string | undefined;
47
46
  readonly accessor: string;
47
+ readonly successMessage?: string | undefined;
48
48
  };
49
49
  readonly grow?: boolean | undefined;
50
50
  readonly enableSorting?: boolean | undefined;
@@ -132,8 +132,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
132
132
  readonly target: string;
133
133
  readonly operation: string;
134
134
  }[] | undefined;
135
- readonly successMessage?: string | undefined;
136
135
  readonly accessor: string;
136
+ readonly successMessage?: string | undefined;
137
137
  };
138
138
  readonly grow?: boolean | undefined;
139
139
  readonly enableSorting?: boolean | undefined;
@@ -1,6 +1,6 @@
1
1
  <script setup>
2
2
  import { computed, defineComponent, inject, onBeforeUnmount, provide, ref, watch } from "vue";
3
- import { provideCELContext } from "../../utils/cel-context";
3
+ import { provideCELContext, provideScopeAncestor } from "../../utils/cel-context";
4
4
  import { BREADCRUMB_EXTENSION_KEY } from "../config/breadcrumb-extension";
5
5
  import { TABLE_COLUMN_LAYOUT_KEY } from "./column-layout";
6
6
  import { Icon } from "@iconify/vue";
@@ -272,6 +272,22 @@ const tableEventAncestor = computed(() => {
272
272
  };
273
273
  });
274
274
  provideEventAncestor(tableEventAncestor);
275
+ const tableScopeAncestor = computed(() => {
276
+ const id = config.value.id;
277
+ if (!id) return null;
278
+ const displayName = config.value.displayName;
279
+ return {
280
+ id,
281
+ name: displayName && displayName.length > 0 ? displayName : void 0,
282
+ typeName: tableMetadata.name,
283
+ typeIcon: tableMetadata.icon,
284
+ members: [
285
+ { key: "row", label: "\u5F53\u524D\u884C", type: "dyn", description: "\u8BE5\u8868\u683C\u5F53\u524D\u884C\u7684\u6574\u884C\u6570\u636E" },
286
+ { key: "index", label: "\u884C\u5E8F\u53F7", type: "number", description: "\u8BE5\u8868\u683C\u5F53\u524D\u884C\u7684\u5E8F\u53F7\uFF0C\u4ECE `0` \u5F00\u59CB" }
287
+ ]
288
+ };
289
+ });
290
+ provideScopeAncestor(tableScopeAncestor);
275
291
  const isDrilled = computed(
276
292
  () => selectedActions.value || selectedQuery.value || columnFullPane.value
277
293
  );
@@ -809,6 +809,7 @@ export { TableConfig, createTableConfig, getColumnTechnicalKey } from "./schema"
809
809
  :derived-columns="derivedEditableColumns"
810
810
  :get-row="getRowAt"
811
811
  :set-row="setRowAt"
812
+ :scope-id="config?.id"
812
813
  >
813
814
  <tr
814
815
  :ref="getRowRefFn(rows[r.index].id)"
@@ -5,6 +5,7 @@ type __VLS_Props = {
5
5
  derivedColumns: ReadonlyArray<FieldValue>;
6
6
  getRow: (i: number) => unknown;
7
7
  setRow: (i: number, value: unknown) => void;
8
+ scopeId?: string;
8
9
  };
9
10
  declare var __VLS_1: {};
10
11
  type __VLS_Slots = {} & {
@@ -2,7 +2,7 @@
2
2
  import { Effect } from "effect";
3
3
  import { customRef } from "vue";
4
4
  import { cel as _rawCel } from "../../utils/cel";
5
- import { celBindings, injectCELContext, provideCELContext } from "../../utils/cel-context";
5
+ import { celBindings, injectCELContext, provideCELContext, provideScopeAddress } from "../../utils/cel-context";
6
6
  import { useDerived, useDerivedQuiescence } from "../form/utils/derived";
7
7
  import { provideFormState } from "../form/utils/state";
8
8
  defineOptions({ name: "ShwfedTableRowProvider" });
@@ -11,7 +11,8 @@ const props = defineProps({
11
11
  displayIndex: { type: Number, required: true },
12
12
  derivedColumns: { type: Array, required: true },
13
13
  getRow: { type: Function, required: true },
14
- setRow: { type: Function, required: true }
14
+ setRow: { type: Function, required: true },
15
+ scopeId: { type: String, required: false }
15
16
  });
16
17
  const rowRef = customRef((track, trigger) => ({
17
18
  get() {
@@ -37,6 +38,12 @@ provideCELContext({
37
38
  value: () => props.displayIndex
38
39
  }
39
40
  });
41
+ if (props.scopeId) {
42
+ provideScopeAddress(props.scopeId, {
43
+ row: () => rowRef.value,
44
+ index: () => props.displayIndex
45
+ });
46
+ }
40
47
  const inherited = injectCELContext();
41
48
  const $cel = (expression, context) => _rawCel(expression, { ...celBindings(inherited), ...context });
42
49
  const formState = provideFormState(rowRef, "row");
@@ -5,6 +5,7 @@ type __VLS_Props = {
5
5
  derivedColumns: ReadonlyArray<FieldValue>;
6
6
  getRow: (i: number) => unknown;
7
7
  setRow: (i: number, value: unknown) => void;
8
+ scopeId?: string;
8
9
  };
9
10
  declare var __VLS_1: {};
10
11
  type __VLS_Slots = {} & {
@@ -24,8 +24,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
24
24
  "onUpdate:modelValue"?: ((args_0: Date | undefined) => any) | undefined;
25
25
  }>, {
26
26
  size: "sm" | "md" | "lg";
27
- clearIcon: string;
28
27
  clearable: boolean;
28
+ clearIcon: string;
29
29
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
30
  declare const _default: typeof __VLS_export;
31
31
  export default _default;
@@ -24,8 +24,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
24
24
  "onUpdate:modelValue"?: ((args_0: Date | undefined) => any) | undefined;
25
25
  }>, {
26
26
  size: "sm" | "md" | "lg";
27
- clearIcon: string;
28
27
  clearable: boolean;
28
+ clearIcon: string;
29
29
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
30
  declare const _default: typeof __VLS_export;
31
31
  export default _default;
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
22
22
  size: "sm" | "md" | "lg";
23
23
  granularity: "hour" | "minute" | "second";
24
24
  hourCycle: 12 | 24;
25
- clearIcon: string;
26
25
  clearable: boolean;
26
+ clearIcon: string;
27
27
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
28
  declare const _default: typeof __VLS_export;
29
29
  export default _default;
@@ -22,8 +22,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
22
22
  size: "sm" | "md" | "lg";
23
23
  granularity: "hour" | "minute" | "second";
24
24
  hourCycle: 12 | 24;
25
- clearIcon: string;
26
25
  clearable: boolean;
26
+ clearIcon: string;
27
27
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
28
  declare const _default: typeof __VLS_export;
29
29
  export default _default;
@@ -29,8 +29,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
29
29
  "onUpdate:endValue"?: ((args_0: Date | undefined) => any) | undefined;
30
30
  }>, {
31
31
  size: "sm" | "md" | "lg";
32
- clearIcon: string;
33
32
  clearable: boolean;
33
+ clearIcon: string;
34
34
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
35
  declare const _default: typeof __VLS_export;
36
36
  export default _default;
@@ -29,8 +29,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
29
29
  "onUpdate:endValue"?: ((args_0: Date | undefined) => any) | undefined;
30
30
  }>, {
31
31
  size: "sm" | "md" | "lg";
32
- clearIcon: string;
33
32
  clearable: boolean;
33
+ clearIcon: string;
34
34
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
35
  declare const _default: typeof __VLS_export;
36
36
  export default _default;
@@ -26,9 +26,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
26
26
  size: "sm" | "md" | "lg";
27
27
  granularity: "hour" | "minute" | "second";
28
28
  hourCycle: 12 | 24;
29
- rangeSeparatorIcon: string;
30
- clearIcon: string;
31
29
  clearable: boolean;
30
+ clearIcon: string;
31
+ rangeSeparatorIcon: string;
32
32
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
33
  declare const _default: typeof __VLS_export;
34
34
  export default _default;
@@ -26,9 +26,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
26
26
  size: "sm" | "md" | "lg";
27
27
  granularity: "hour" | "minute" | "second";
28
28
  hourCycle: 12 | 24;
29
- rangeSeparatorIcon: string;
30
- clearIcon: string;
31
29
  clearable: boolean;
30
+ clearIcon: string;
31
+ rangeSeparatorIcon: string;
32
32
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
33
  declare const _default: typeof __VLS_export;
34
34
  export default _default;
@@ -0,0 +1,22 @@
1
+ import type { HTMLAttributes } from 'vue';
2
+ import type { ScopeInfo } from './scope-refs.js';
3
+ type __VLS_Props = {
4
+ class?: HTMLAttributes['class'];
5
+ defaultValue?: string;
6
+ modelValue?: string;
7
+ multiline?: boolean;
8
+ placeholder?: string;
9
+ scopeLookup: Map<string, ScopeInfo>;
10
+ };
11
+ declare function insertAtSelection(text: string): void;
12
+ declare function focus(): void;
13
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
14
+ insertAtSelection: typeof insertAtSelection;
15
+ focus: typeof focus;
16
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
17
+ "update:modelValue": (payload: string) => any;
18
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
19
+ "onUpdate:modelValue"?: ((payload: string) => any) | undefined;
20
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
@@ -0,0 +1,134 @@
1
+ <script setup>
2
+ import { Compartment, EditorState } from "@codemirror/state";
3
+ import { EditorView, keymap, placeholder as cmPlaceholder } from "@codemirror/view";
4
+ import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
5
+ import { onBeforeUnmount, onMounted, useTemplateRef, watch } from "vue";
6
+ import { cn } from "../../../utils/cn";
7
+ import { celHighlighting } from "./cel-language";
8
+ import { scopeChips, scopeLookupFacet } from "./chip-extension";
9
+ defineOptions({ name: "UiCodeMirrorInput" });
10
+ const props = defineProps({
11
+ class: { type: [Boolean, null, String, Object, Array], required: false, skipCheck: true },
12
+ defaultValue: { type: String, required: false },
13
+ modelValue: { type: String, required: false },
14
+ multiline: { type: Boolean, required: false },
15
+ placeholder: { type: String, required: false },
16
+ scopeLookup: { type: Map, required: true }
17
+ });
18
+ const emits = defineEmits(["update:modelValue"]);
19
+ const host = useTemplateRef("host");
20
+ let view = null;
21
+ const lookupCompartment = new Compartment();
22
+ const modeCompartment = new Compartment();
23
+ let applyingExternal = false;
24
+ const editorTheme = EditorView.theme({
25
+ "&": {
26
+ fontSize: "0.875rem",
27
+ color: "var(--color-zinc-700)",
28
+ backgroundColor: "transparent"
29
+ },
30
+ "&.cm-focused": {
31
+ outline: "none"
32
+ },
33
+ ".cm-content": {
34
+ fontFamily: "var(--font-mono)",
35
+ padding: "7px 0",
36
+ lineHeight: "1.5",
37
+ caretColor: "var(--color-zinc-700)"
38
+ },
39
+ ".cm-placeholder": {
40
+ color: "var(--color-zinc-200)"
41
+ },
42
+ ".cm-scroller": {
43
+ fontFamily: "var(--font-mono)",
44
+ lineHeight: "1.5"
45
+ },
46
+ ".cm-line": {
47
+ padding: "0"
48
+ }
49
+ });
50
+ function modeExtension(multiline) {
51
+ if (multiline) return EditorView.lineWrapping;
52
+ return EditorState.transactionFilter.of((tr) => {
53
+ if (!tr.docChanged) return tr;
54
+ let hasNewline = false;
55
+ tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {
56
+ if (inserted.lines > 1) hasNewline = true;
57
+ });
58
+ return hasNewline ? [] : tr;
59
+ });
60
+ }
61
+ function makeState(doc) {
62
+ return EditorState.create({
63
+ doc,
64
+ extensions: [
65
+ history(),
66
+ keymap.of([...defaultKeymap, ...historyKeymap]),
67
+ cmPlaceholder(props.placeholder ?? ""),
68
+ lookupCompartment.of(scopeLookupFacet.of(props.scopeLookup)),
69
+ modeCompartment.of(modeExtension(!!props.multiline)),
70
+ editorTheme,
71
+ // CEL syntax colours sit *under* the chips: the chip plugin's
72
+ // `Decoration.replace` widgets hide the `__scopes__[...]` spans, so the
73
+ // marks here only show through on ordinary expression text.
74
+ celHighlighting(),
75
+ scopeChips(),
76
+ EditorView.contentAttributes.of({ "aria-label": props.placeholder ?? "Expression" }),
77
+ EditorView.updateListener.of((update) => {
78
+ if (!update.docChanged || applyingExternal) return;
79
+ emits("update:modelValue", update.state.doc.toString());
80
+ })
81
+ ]
82
+ });
83
+ }
84
+ onMounted(() => {
85
+ if (!host.value) return;
86
+ view = new EditorView({
87
+ state: makeState(props.modelValue ?? props.defaultValue ?? ""),
88
+ parent: host.value
89
+ });
90
+ });
91
+ onBeforeUnmount(() => {
92
+ view?.destroy();
93
+ view = null;
94
+ });
95
+ watch(() => props.modelValue, (next) => {
96
+ if (!view) return;
97
+ const incoming = next ?? "";
98
+ if (incoming === view.state.doc.toString()) return;
99
+ applyingExternal = true;
100
+ view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: incoming } });
101
+ applyingExternal = false;
102
+ });
103
+ watch(() => props.scopeLookup, (lookup) => {
104
+ view?.dispatch({ effects: lookupCompartment.reconfigure(scopeLookupFacet.of(lookup)) });
105
+ });
106
+ watch(() => props.multiline, (multiline) => {
107
+ view?.dispatch({ effects: modeCompartment.reconfigure(modeExtension(!!multiline)) });
108
+ });
109
+ function insertAtSelection(text) {
110
+ if (!view) return;
111
+ const { from, to } = view.state.selection.main;
112
+ view.dispatch({
113
+ changes: { from, to, insert: text },
114
+ selection: { anchor: from + text.length }
115
+ });
116
+ view.focus();
117
+ }
118
+ function focus() {
119
+ view?.focus();
120
+ }
121
+ defineExpose({ insertAtSelection, focus });
122
+ </script>
123
+
124
+ <template>
125
+ <div
126
+ ref="host"
127
+ data-slot="input-group-control"
128
+ :class="cn(
129
+ 'flex-1 min-w-0 self-stretch overflow-x-auto px-3',
130
+ props.multiline ? '[&_.cm-content]:min-h-16' : '[&_.cm-scroller]:items-center',
131
+ props.class
132
+ )"
133
+ />
134
+ </template>
@@ -0,0 +1,22 @@
1
+ import type { HTMLAttributes } from 'vue';
2
+ import type { ScopeInfo } from './scope-refs.js';
3
+ type __VLS_Props = {
4
+ class?: HTMLAttributes['class'];
5
+ defaultValue?: string;
6
+ modelValue?: string;
7
+ multiline?: boolean;
8
+ placeholder?: string;
9
+ scopeLookup: Map<string, ScopeInfo>;
10
+ };
11
+ declare function insertAtSelection(text: string): void;
12
+ declare function focus(): void;
13
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
14
+ insertAtSelection: typeof insertAtSelection;
15
+ focus: typeof focus;
16
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
17
+ "update:modelValue": (payload: string) => any;
18
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
19
+ "onUpdate:modelValue"?: ((payload: string) => any) | undefined;
20
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
@@ -13,11 +13,11 @@ type __VLS_Props = {
13
13
  resultType?: string | string[];
14
14
  extraVars?: Record<string, VarSpec>;
15
15
  };
16
- declare var __VLS_14: {}, __VLS_108: {};
16
+ declare var __VLS_14: {}, __VLS_130: {};
17
17
  type __VLS_Slots = {} & {
18
18
  leading?: (props: typeof __VLS_14) => any;
19
19
  } & {
20
- trailing?: (props: typeof __VLS_108) => any;
20
+ trailing?: (props: typeof __VLS_130) => any;
21
21
  };
22
22
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
23
23
  "update:modelValue": (payload: string) => any;
@@ -1,11 +1,13 @@
1
1
  <script setup>
2
2
  import { Icon } from "@iconify/vue";
3
- import { computed, ref, useSlots, watch } from "vue";
4
- import { injectCELContext } from "../../../utils/cel-context";
3
+ import { computed, ref, useSlots, useTemplateRef, watch } from "vue";
4
+ import { injectCELContext, useScopeAncestry } from "../../../utils/cel-context";
5
5
  import { Markdown } from "../markdown";
6
- import { cn } from "../../../utils/cn";
6
+ import CodeMirrorInput from "./CodeMirrorInput.vue";
7
+ import { buildScopeLookup } from "./scope-refs";
8
+ import { buildScopeEntries, buildVarEntries } from "./picker-entries";
7
9
  import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "../command";
8
- import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupTextarea } from "../input-group";
10
+ import { InputGroup, InputGroupAddon, InputGroupButton } from "../input-group";
9
11
  import { Popover, PopoverContent, PopoverTrigger } from "../popover";
10
12
  defineOptions({ name: "UiExpressionEditor" });
11
13
  const props = defineProps({
@@ -19,31 +21,31 @@ const props = defineProps({
19
21
  });
20
22
  const emits = defineEmits(["update:modelValue"]);
21
23
  const celContext = injectCELContext();
22
- const mergedEntries = computed(() => {
23
- const out = Object.entries(celContext).map(
24
- ([name, meta]) => ({ name, meta })
25
- );
26
- const seen = new Set(out.map((e) => e.name));
27
- for (const [name, meta] of Object.entries(props.extraVars ?? {})) {
28
- if (seen.has(name)) continue;
29
- out.push({ name, meta });
30
- }
31
- return out;
32
- });
33
- const hasVars = computed(() => mergedEntries.value.length > 0);
24
+ const scopeAncestry = useScopeAncestry();
25
+ const varEntries = computed(() => buildVarEntries(celContext, props.extraVars));
26
+ const scopeEntries = computed(() => buildScopeEntries(scopeAncestry.value.slice(1)));
27
+ const scopeLookup = computed(() => buildScopeLookup(scopeAncestry.value));
28
+ const hasVars = computed(() => varEntries.value.length > 0 || scopeEntries.value.length > 0);
34
29
  const open = ref(false);
35
30
  const entries = ref([]);
31
+ const shownVars = computed(() => entries.value.filter((e) => e.group === "var"));
32
+ const shownScopes = computed(() => entries.value.filter((e) => e.group === "scope"));
36
33
  const hoveredName = ref(null);
34
+ const editorRef = useTemplateRef("editor");
35
+ function insertVariable(text) {
36
+ editorRef.value?.insertAtSelection(text);
37
+ open.value = false;
38
+ }
37
39
  watch(open, (v) => {
38
40
  if (v) {
39
- entries.value = mergedEntries.value;
40
- hoveredName.value = entries.value[0]?.name ?? null;
41
+ entries.value = [...varEntries.value, ...scopeEntries.value];
42
+ hoveredName.value = entries.value[0]?.id ?? null;
41
43
  }
42
44
  });
43
- const hoveredMeta = computed(
44
- () => entries.value.find((e) => e.name === hoveredName.value)?.meta ?? null
45
+ const hoveredEntry = computed(
46
+ () => entries.value.find((e) => e.id === hoveredName.value) ?? null
45
47
  );
46
- const hoveredDescription = computed(() => hoveredMeta.value?.description ?? "");
48
+ const hoveredDescription = computed(() => hoveredEntry.value?.description ?? "");
47
49
  const resultTypeLabel = computed(() => {
48
50
  const rt = props.resultType;
49
51
  if (!rt) return null;
@@ -65,21 +67,15 @@ const addonAlign = computed(
65
67
  >
66
68
  <slot name="leading" />
67
69
  </InputGroupAddon>
68
- <InputGroupTextarea
69
- v-if="props.multiline"
70
+ <CodeMirrorInput
71
+ ref="editor"
70
72
  :model-value="props.modelValue"
71
73
  :default-value="props.defaultValue"
72
74
  :placeholder="props.placeholder"
73
- :class="cn('font-mono text-xs', props.class)"
74
- @update:model-value="(v) => emits('update:modelValue', String(v))"
75
- />
76
- <InputGroupInput
77
- v-else
78
- :model-value="props.modelValue"
79
- :default-value="props.defaultValue"
80
- :placeholder="props.placeholder"
81
- :class="cn('font-mono text-xs', props.class)"
82
- @update:model-value="(v) => emits('update:modelValue', String(v))"
75
+ :multiline="props.multiline"
76
+ :scope-lookup="scopeLookup"
77
+ :class="props.class"
78
+ @update:model-value="(v) => emits('update:modelValue', v)"
83
79
  />
84
80
  <InputGroupAddon
85
81
  v-if="showAddon"
@@ -109,34 +105,59 @@ const addonAlign = computed(
109
105
  <CommandEmpty>No variables.</CommandEmpty>
110
106
  <CommandGroup>
111
107
  <CommandItem
112
- v-for="entry in entries"
113
- :key="entry.name"
114
- :value="entry.name"
115
- class="cursor-default gap-2"
116
- @mouseenter="hoveredName = entry.name"
117
- @focus="hoveredName = entry.name"
108
+ v-for="entry in shownVars"
109
+ :key="entry.id"
110
+ :value="entry.display"
111
+ class="cursor-pointer gap-2"
112
+ @select="insertVariable(entry.insert)"
113
+ @mouseenter="hoveredName = entry.id"
114
+ @focus="hoveredName = entry.id"
118
115
  >
119
- <span class="font-mono text-xs text-zinc-800">{{ entry.name }}</span>
120
- <span class="flex-1 truncate text-xs text-zinc-500">{{ entry.meta.label }}</span>
116
+ <Icon
117
+ icon="fluent:braces-variable-20-regular"
118
+ class="size-3.5 shrink-0 text-zinc-400"
119
+ />
120
+ <span class="font-mono text-xs text-zinc-800">{{ entry.display }}</span>
121
+ <span class="flex-1 truncate text-xs text-zinc-500">{{ entry.label }}</span>
121
122
  <span class="rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
122
- {{ entry.meta.type }}
123
+ {{ entry.type }}
124
+ </span>
125
+ </CommandItem>
126
+ </CommandGroup>
127
+ <CommandGroup
128
+ v-if="shownScopes.length > 0"
129
+ heading="跨层引用"
130
+ >
131
+ <CommandItem
132
+ v-for="entry in shownScopes"
133
+ :key="entry.id"
134
+ :value="`${entry.display} ${entry.id}`"
135
+ class="cursor-pointer gap-2"
136
+ @select="insertVariable(entry.insert)"
137
+ @mouseenter="hoveredName = entry.id"
138
+ @focus="hoveredName = entry.id"
139
+ >
140
+ <Icon
141
+ icon="fluent:link-20-regular"
142
+ class="size-3.5 shrink-0 text-zinc-400"
143
+ />
144
+ <span class="flex-1 truncate text-xs text-zinc-700">{{ entry.display }}</span>
145
+ <span class="rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
146
+ {{ entry.type }}
123
147
  </span>
124
148
  </CommandItem>
125
149
  </CommandGroup>
126
150
  </CommandList>
127
151
  <div
128
- v-if="hoveredMeta"
152
+ v-if="hoveredEntry"
129
153
  class="border-t border-zinc-200 px-3 py-2 group-data-[side=top]/popover:border-t-0 group-data-[side=top]/popover:border-b"
130
154
  >
131
- <div class="mb-1 flex items-center gap-2">
132
- <span class="font-mono text-xs text-zinc-800">{{ hoveredName }}</span>
133
- <span class="rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
134
- {{ hoveredMeta.type }}
155
+ <div class="flex items-center gap-2">
156
+ <span class="text-xs font-medium text-zinc-700">{{ hoveredEntry.label }}</span>
157
+ <span class="ml-auto shrink-0 rounded bg-purple-100 px-1.5 py-0.5 font-mono text-[10px] leading-none text-purple-700 select-none">
158
+ {{ hoveredEntry.type }}
135
159
  </span>
136
160
  </div>
137
- <div class="text-xs font-medium text-zinc-700">
138
- {{ hoveredMeta.label }}
139
- </div>
140
161
  <Markdown
141
162
  v-if="hoveredDescription"
142
163
  :source="hoveredDescription"
@@ -13,11 +13,11 @@ type __VLS_Props = {
13
13
  resultType?: string | string[];
14
14
  extraVars?: Record<string, VarSpec>;
15
15
  };
16
- declare var __VLS_14: {}, __VLS_108: {};
16
+ declare var __VLS_14: {}, __VLS_130: {};
17
17
  type __VLS_Slots = {} & {
18
18
  leading?: (props: typeof __VLS_14) => any;
19
19
  } & {
20
- trailing?: (props: typeof __VLS_108) => any;
20
+ trailing?: (props: typeof __VLS_130) => any;
21
21
  };
22
22
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
23
23
  "update:modelValue": (payload: string) => any;