@api-client/ui 0.5.14 → 0.5.16

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 (22) hide show
  1. package/build/src/elements/code-editor/internals/{PlaceholderWidget.d.ts → ChipWidget.d.ts} +1 -1
  2. package/build/src/elements/code-editor/internals/ChipWidget.d.ts.map +1 -0
  3. package/build/src/elements/code-editor/internals/{PlaceholderWidget.js → ChipWidget.js} +2 -2
  4. package/build/src/elements/code-editor/internals/ChipWidget.js.map +1 -0
  5. package/build/src/elements/code-editor/internals/CodeEditor.d.ts +8 -5
  6. package/build/src/elements/code-editor/internals/CodeEditor.d.ts.map +1 -1
  7. package/build/src/elements/code-editor/internals/CodeEditor.js +46 -46
  8. package/build/src/elements/code-editor/internals/CodeEditor.js.map +1 -1
  9. package/build/src/elements/code-editor/internals/CodeEditor.styles.d.ts.map +1 -1
  10. package/build/src/elements/code-editor/internals/CodeEditor.styles.js +55 -0
  11. package/build/src/elements/code-editor/internals/CodeEditor.styles.js.map +1 -1
  12. package/build/src/elements/code-editor/internals/SuggestionMatchDecorator.d.ts.map +1 -1
  13. package/build/src/elements/code-editor/internals/SuggestionMatchDecorator.js +4 -4
  14. package/build/src/elements/code-editor/internals/SuggestionMatchDecorator.js.map +1 -1
  15. package/demo/elements/code-editor/CodeEditorDemo.ts +52 -82
  16. package/package.json +1 -1
  17. package/src/elements/code-editor/internals/{PlaceholderWidget.ts → ChipWidget.ts} +1 -1
  18. package/src/elements/code-editor/internals/CodeEditor.styles.ts +55 -0
  19. package/src/elements/code-editor/internals/CodeEditor.ts +42 -32
  20. package/src/elements/code-editor/internals/SuggestionMatchDecorator.ts +4 -5
  21. package/build/src/elements/code-editor/internals/PlaceholderWidget.d.ts.map +0 -1
  22. package/build/src/elements/code-editor/internals/PlaceholderWidget.js.map +0 -1
@@ -17,4 +17,4 @@ export declare class ChipWidget extends WidgetType {
17
17
  toDOM(view: EditorView): HTMLElement;
18
18
  ignoreEvent(): boolean;
19
19
  }
20
- //# sourceMappingURL=PlaceholderWidget.d.ts.map
20
+ //# sourceMappingURL=ChipWidget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChipWidget.d.ts","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/ChipWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,6BAA6B,CAAA;AAEpC;;;;;;;;GAQG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACrB,UAAU,EAAE,UAAU;gBAAtB,UAAU,EAAE,UAAU;IAIhC,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAIvC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW;IAwB3B,WAAW,IAAI,OAAO;CAGhC"}
@@ -30,7 +30,7 @@ export class ChipWidget extends WidgetType {
30
30
  const pos = view.posAtDOM(wrapper);
31
31
  if (pos === null)
32
32
  return;
33
- const originalText = `{{${this.suggestion.label}}}`;
33
+ const originalText = `{{${this.suggestion.id}}}`;
34
34
  view.dispatch({
35
35
  changes: { from: pos, to: pos + originalText.length, insert: '' },
36
36
  });
@@ -43,4 +43,4 @@ export class ChipWidget extends WidgetType {
43
43
  return false;
44
44
  }
45
45
  }
46
- //# sourceMappingURL=PlaceholderWidget.js.map
46
+ //# sourceMappingURL=ChipWidget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChipWidget.js","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/ChipWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAEzD,OAAO,6BAA6B,CAAA;AAEpC;;;;;;;;GAQG;AACH,MAAM,OAAO,UAAW,SAAQ,UAAU;IACrB;IAAnB,YAAmB,UAAsB;QACvC,KAAK,EAAE,CAAA;QADU,eAAU,GAAV,UAAU,CAAY;IAEzC,CAAC;IAEQ,EAAE,CAAC,KAAiB;QAC3B,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,IAAK,KAAoB,CAAC,UAAU,CAAC,EAAE,CAAA;IAClE,CAAC;IAED,KAAK,CAAC,IAAgB;QACpB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;QAC9C,OAAO,CAAC,SAAS,GAAG,cAAc,CAAA;QAClC,OAAO,CAAC,YAAY,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QAE3D,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;QAC9C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAClC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAA;QACxC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAClC,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAM;YAExB,MAAM,YAAY,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAA;YAChD,IAAI,CAAC,QAAQ,CAAC;gBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;aAClE,CAAC,CAAA;YACF,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC,CAAC,CAAA;QAEF,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QACzB,OAAO,OAAO,CAAA;IAChB,CAAC;IAEQ,WAAW;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;CACF","sourcesContent":["import { EditorView, WidgetType } from '@codemirror/view'\nimport type { Suggestion } from './types.js'\nimport '../../../md/chip/ui-chip.js'\n\n/**\n * A widget that represents a placeholder in the code editor,\n * specifically for suggestions that are replaced with chips.\n *\n * This widget is used to create a visual representation of a suggestion\n * in the code editor, allowing users to see and interact with suggestions\n * as chips. When a chip is removed, the corresponding text in the editor\n * is also removed.\n */\nexport class ChipWidget extends WidgetType {\n constructor(public suggestion: Suggestion) {\n super()\n }\n\n override eq(other: WidgetType): boolean {\n return this.suggestion.id == (other as ChipWidget).suggestion.id\n }\n\n toDOM(view: EditorView): HTMLElement {\n const wrapper = document.createElement('span')\n wrapper.className = 'mention-chip'\n wrapper.setAttribute('data-mention-id', this.suggestion.id)\n\n const chip = document.createElement('ui-chip')\n chip.setAttribute('type', 'input')\n chip.setAttribute('removable', 'true')\n chip.textContent = this.suggestion.label\n chip.addEventListener('remove', () => {\n const pos = view.posAtDOM(wrapper)\n if (pos === null) return\n\n const originalText = `{{${this.suggestion.id}}}`\n view.dispatch({\n changes: { from: pos, to: pos + originalText.length, insert: '' },\n })\n view.focus()\n })\n\n wrapper.appendChild(chip)\n return wrapper\n }\n\n override ignoreEvent(): boolean {\n return false\n }\n}\n"]}
@@ -18,6 +18,7 @@ import { SuggestionMatchDecorator } from './SuggestionMatchDecorator.js';
18
18
  * @fires change - When the editor loses focus and content has changed
19
19
  */
20
20
  export default class CodeEditor extends LitElement {
21
+ #private;
21
22
  /**
22
23
  * Shadow root configuration for the component.
23
24
  * Uses 'open' mode for accessibility and delegates focus to enable proper focus management.
@@ -54,7 +55,8 @@ export default class CodeEditor extends LitElement {
54
55
  /**
55
56
  * The editor content value
56
57
  */
57
- accessor value: string;
58
+ get value(): string;
59
+ set value(newValue: string);
58
60
  /**
59
61
  * Available function schemas for autocomplete
60
62
  */
@@ -75,6 +77,10 @@ export default class CodeEditor extends LitElement {
75
77
  private accessor hasContent;
76
78
  private accessor isEditorFocus;
77
79
  private editorView?;
80
+ /**
81
+ * A control value to track previous value of the editor.
82
+ * This is used to detect when change event should be dispatched.
83
+ */
78
84
  private _previousValue;
79
85
  /**
80
86
  * Matcher for suggestion placeholders in the editor.
@@ -84,6 +90,7 @@ export default class CodeEditor extends LitElement {
84
90
  * Get all suggestions (placeholders) currently in the editor
85
91
  */
86
92
  get activeSuggestions(): Suggestion[];
93
+ private readonlyState;
87
94
  disconnectedCallback(): void;
88
95
  firstUpdated(): void;
89
96
  willUpdate(changedProperties: PropertyValues): void;
@@ -120,10 +127,6 @@ export default class CodeEditor extends LitElement {
120
127
  * Update editor content when value changes
121
128
  */
122
129
  private updateEditorContent;
123
- /**
124
- * Update editor state (e.g., disabled state)
125
- */
126
- private updateEditorState;
127
130
  /**
128
131
  * Handle editor content change
129
132
  */
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEditor.d.ts","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/CodeEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,cAAc,EAAE,cAAc,EAAW,MAAM,KAAK,CAAA;AA0B/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAGrE,OAAO,KAAK,EAAuB,UAAU,EAAyB,MAAM,YAAY,CAAA;AACxF,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAExE;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,UAAU;IAChD;;;OAGG;IACH,OAAgB,iBAAiB,EAAE,cAAc,CAGhD;IAED;;OAEG;IAEH,QAAQ,CAAC,KAAK,SAAK;IAEnB;;OAEG;IAEH,QAAQ,CAAC,cAAc,SAAK;IAE5B;;OAEG;IAEH,QAAQ,CAAC,QAAQ,UAAQ;IAEzB;;OAEG;IAEH,QAAQ,CAAC,OAAO,UAAQ;IAExB;;OAEG;IAEH,QAAQ,CAAC,IAAI,SAAK;IAElB;;OAEG;IAEH,QAAQ,CAAC,QAAQ,UAAQ;IAEzB;;OAEG;IAEH,QAAQ,CAAC,WAAW,SAAK;IAEzB;;OAEG;IAEH,QAAQ,CAAC,KAAK,SAAK;IAEnB;;OAEG;IAEH,QAAQ,CAAC,eAAe,EAAE,cAAc,EAAE,CAAK;IAE/C;;OAEG;IAEH,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAK;IAEvC;;OAEG;IAEH,QAAQ,CAAC,SAAS,UAAQ;IAE1B;;OAEG;IAEH,QAAQ,CAAC,QAAQ,SAAe;IAGhC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IAGjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IAGnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IAEtC,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,cAAc,CAAK;IAC3B;;OAEG;IACH,kBAAkB,CAAC,EAAE,wBAAwB,CAAA;IAE7C;;OAEG;IACH,IAAI,iBAAiB,IAAI,UAAU,EAAE,CAapC;IAEQ,oBAAoB,IAAI,IAAI;IAK5B,YAAY,IAAI,IAAI;IAKpB,UAAU,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI;IAkB5D;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAoD5B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAoB/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA0C9B,OAAO,CAAC,wBAAwB;IAkBhC,OAAO,CAAC,0BAA0B;IAkBlC;;;OAGG;IACH,OAAO,CAAC,wBAAwB,CAmB/B;IAED;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAgEjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAQhC;;OAEG;IACM,KAAK,IAAI,IAAI;IAItB;;OAEG;IACH,YAAY,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAMnD;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAUrB,MAAM,IAAI,cAAc;CAgBlC"}
1
+ {"version":3,"file":"CodeEditor.d.ts","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/CodeEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,cAAc,EAAE,cAAc,EAAW,MAAM,KAAK,CAAA;AA0B/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAGrE,OAAO,KAAK,EAAuB,UAAU,EAAyB,MAAM,YAAY,CAAA;AACxF,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAExE;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,UAAU;;IAChD;;;OAGG;IACH,OAAgB,iBAAiB,EAAE,cAAc,CAGhD;IAED;;OAEG;IAEH,QAAQ,CAAC,KAAK,SAAK;IAEnB;;OAEG;IAEH,QAAQ,CAAC,cAAc,SAAK;IAE5B;;OAEG;IAEH,QAAQ,CAAC,QAAQ,UAAQ;IAEzB;;OAEG;IAEH,QAAQ,CAAC,OAAO,UAAQ;IAExB;;OAEG;IAEH,QAAQ,CAAC,IAAI,SAAK;IAElB;;OAEG;IAEH,QAAQ,CAAC,QAAQ,UAAQ;IAEzB;;OAEG;IAEH,QAAQ,CAAC,WAAW,SAAK;IAOzB;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IACI,KAAK,CAAC,QAAQ,EAAE,MAAM,EAOzB;IAED;;OAEG;IAEH,QAAQ,CAAC,eAAe,EAAE,cAAc,EAAE,CAAK;IAE/C;;OAEG;IAEH,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAK;IAEvC;;OAEG;IAEH,QAAQ,CAAC,SAAS,UAAQ;IAE1B;;OAEG;IAEH,QAAQ,CAAC,QAAQ,SAAe;IAGhC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IAGjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IAGnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IAEtC,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B;;;OAGG;IACH,OAAO,CAAC,cAAc,CAAK;IAC3B;;OAEG;IACH,kBAAkB,CAAC,EAAE,wBAAwB,CAAA;IAE7C;;OAEG;IACH,IAAI,iBAAiB,IAAI,UAAU,EAAE,CAapC;IAED,OAAO,CAAC,aAAa,CAAoB;IAEhC,oBAAoB,IAAI,IAAI;IAK5B,YAAY,IAAI,IAAI;IAKpB,UAAU,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI;IAoB5D;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqD5B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAoB/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA0C9B,OAAO,CAAC,wBAAwB;IAmBhC,OAAO,CAAC,0BAA0B;IAmBlC;;;OAGG;IACH,OAAO,CAAC,wBAAwB,CAmB/B;IAED;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAgEjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAQhC;;OAEG;IACM,KAAK,IAAI,IAAI;IAItB;;OAEG;IACH,YAAY,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAMnD;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAUrB,MAAM,IAAI,cAAc;CAgBlC"}
@@ -3,7 +3,7 @@ import { html, LitElement, nothing } from 'lit';
3
3
  import { property, query, state } from 'lit/decorators.js';
4
4
  import { classMap } from 'lit/directives/class-map.js';
5
5
  import { linter } from '@codemirror/lint';
6
- import { EditorState } from '@codemirror/state';
6
+ import { Compartment, EditorState } from '@codemirror/state';
7
7
  import { autocompletion, } from '@codemirror/autocomplete';
8
8
  import { javascript } from '@codemirror/lang-javascript';
9
9
  import { syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language';
@@ -16,6 +16,7 @@ import { functionLinter } from './Linter.js';
16
16
  import { SuggestionMatchDecorator } from './SuggestionMatchDecorator.js';
17
17
  let CodeEditor = (() => {
18
18
  let _classSuper = LitElement;
19
+ let _instanceExtraInitializers = [];
19
20
  let _label_decorators;
20
21
  let _label_initializers = [];
21
22
  let _label_extraInitializers = [];
@@ -37,9 +38,7 @@ let CodeEditor = (() => {
37
38
  let _placeholder_decorators;
38
39
  let _placeholder_initializers = [];
39
40
  let _placeholder_extraInitializers = [];
40
- let _value_decorators;
41
- let _value_initializers = [];
42
- let _value_extraInitializers = [];
41
+ let _set_value_decorators;
43
42
  let _functionSchemas_decorators;
44
43
  let _functionSchemas_initializers = [];
45
44
  let _functionSchemas_extraInitializers = [];
@@ -71,7 +70,7 @@ let CodeEditor = (() => {
71
70
  _name_decorators = [property({ type: String })];
72
71
  _required_decorators = [property({ type: Boolean })];
73
72
  _placeholder_decorators = [property({ type: String })];
74
- _value_decorators = [property({ type: String })];
73
+ _set_value_decorators = [property({ type: String })];
75
74
  _functionSchemas_decorators = [property({ type: Array, attribute: false })];
76
75
  _suggestions_decorators = [property({ type: Array, attribute: false })];
77
76
  _darkTheme_decorators = [property({ type: Boolean, attribute: 'dark-theme' })];
@@ -86,7 +85,7 @@ let CodeEditor = (() => {
86
85
  __esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
87
86
  __esDecorate(this, null, _required_decorators, { kind: "accessor", name: "required", static: false, private: false, access: { has: obj => "required" in obj, get: obj => obj.required, set: (obj, value) => { obj.required = value; } }, metadata: _metadata }, _required_initializers, _required_extraInitializers);
88
87
  __esDecorate(this, null, _placeholder_decorators, { kind: "accessor", name: "placeholder", static: false, private: false, access: { has: obj => "placeholder" in obj, get: obj => obj.placeholder, set: (obj, value) => { obj.placeholder = value; } }, metadata: _metadata }, _placeholder_initializers, _placeholder_extraInitializers);
89
- __esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
88
+ __esDecorate(this, null, _set_value_decorators, { kind: "setter", name: "value", static: false, private: false, access: { has: obj => "value" in obj, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, null, _instanceExtraInitializers);
90
89
  __esDecorate(this, null, _functionSchemas_decorators, { kind: "accessor", name: "functionSchemas", static: false, private: false, access: { has: obj => "functionSchemas" in obj, get: obj => obj.functionSchemas, set: (obj, value) => { obj.functionSchemas = value; } }, metadata: _metadata }, _functionSchemas_initializers, _functionSchemas_extraInitializers);
91
90
  __esDecorate(this, null, _suggestions_decorators, { kind: "accessor", name: "suggestions", static: false, private: false, access: { has: obj => "suggestions" in obj, get: obj => obj.suggestions, set: (obj, value) => { obj.suggestions = value; } }, metadata: _metadata }, _suggestions_initializers, _suggestions_extraInitializers);
92
91
  __esDecorate(this, null, _darkTheme_decorators, { kind: "accessor", name: "darkTheme", static: false, private: false, access: { has: obj => "darkTheme" in obj, get: obj => obj.darkTheme, set: (obj, value) => { obj.darkTheme = value; } }, metadata: _metadata }, _darkTheme_initializers, _darkTheme_extraInitializers);
@@ -104,11 +103,11 @@ let CodeEditor = (() => {
104
103
  mode: 'open',
105
104
  delegatesFocus: true,
106
105
  };
107
- #label_accessor_storage = __runInitializers(this, _label_initializers, ''
106
+ #label_accessor_storage = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _label_initializers, ''
108
107
  /**
109
108
  * Supporting text displayed below the editor
110
109
  */
111
- );
110
+ ));
112
111
  /**
113
112
  * The label text displayed as placeholder/floating label
114
113
  */
@@ -166,7 +165,7 @@ let CodeEditor = (() => {
166
165
  set required(value) { this.#required_accessor_storage = value; }
167
166
  #placeholder_accessor_storage = (__runInitializers(this, _required_extraInitializers), __runInitializers(this, _placeholder_initializers, ''
168
167
  /**
169
- * The editor content value
168
+ * This property is used internally to set value without triggering updates.
170
169
  */
171
170
  ));
172
171
  /**
@@ -174,21 +173,29 @@ let CodeEditor = (() => {
174
173
  */
175
174
  get placeholder() { return this.#placeholder_accessor_storage; }
176
175
  set placeholder(value) { this.#placeholder_accessor_storage = value; }
177
- #value_accessor_storage = (__runInitializers(this, _placeholder_extraInitializers), __runInitializers(this, _value_initializers, ''
178
176
  /**
179
- * Available function schemas for autocomplete
177
+ * This property is used internally to set value without triggering updates.
180
178
  */
181
- ));
179
+ #value = (__runInitializers(this, _placeholder_extraInitializers), '');
182
180
  /**
183
181
  * The editor content value
184
182
  */
185
- get value() { return this.#value_accessor_storage; }
186
- set value(value) { this.#value_accessor_storage = value; }
187
- #functionSchemas_accessor_storage = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _functionSchemas_initializers, []
183
+ get value() {
184
+ return this.#value;
185
+ }
186
+ set value(newValue) {
187
+ const oldValue = this.#value;
188
+ if (newValue !== oldValue) {
189
+ this.#value = newValue;
190
+ this._previousValue = newValue;
191
+ this.requestUpdate('value', oldValue);
192
+ }
193
+ }
194
+ #functionSchemas_accessor_storage = __runInitializers(this, _functionSchemas_initializers, []
188
195
  /**
189
196
  * Available suggestions for autocomplete
190
197
  */
191
- ));
198
+ );
192
199
  /**
193
200
  * Available function schemas for autocomplete
194
201
  */
@@ -230,6 +237,10 @@ let CodeEditor = (() => {
230
237
  get isEditorFocus() { return this.#isEditorFocus_accessor_storage; }
231
238
  set isEditorFocus(value) { this.#isEditorFocus_accessor_storage = value; }
232
239
  editorView = __runInitializers(this, _isEditorFocus_extraInitializers);
240
+ /**
241
+ * A control value to track previous value of the editor.
242
+ * This is used to detect when change event should be dispatched.
243
+ */
233
244
  _previousValue = '';
234
245
  /**
235
246
  * Matcher for suggestion placeholders in the editor.
@@ -240,18 +251,19 @@ let CodeEditor = (() => {
240
251
  */
241
252
  get activeSuggestions() {
242
253
  const suggestions = [];
243
- const placeholderPattern = /\{\{(\w+)\}\}/g;
254
+ const placeholderPattern = /\{\{([^}]+)\}\}/g;
244
255
  let match;
245
256
  while ((match = placeholderPattern.exec(this.value)) !== null) {
246
257
  const placeholderText = match[1];
247
- // Find suggestion by label
248
- const suggestion = this.suggestions.find((s) => s.label.toLowerCase() === placeholderText.toLowerCase());
258
+ // Find suggestion by id
259
+ const suggestion = this.suggestions.find((s) => s.id === placeholderText);
249
260
  if (suggestion) {
250
261
  suggestions.push(suggestion);
251
262
  }
252
263
  }
253
264
  return suggestions;
254
265
  }
266
+ readonlyState = new Compartment();
255
267
  disconnectedCallback() {
256
268
  super.disconnectedCallback();
257
269
  this.editorView?.destroy();
@@ -271,7 +283,9 @@ let CodeEditor = (() => {
271
283
  this.updateEditorContent();
272
284
  }
273
285
  if (changedProperties.has('disabled')) {
274
- this.updateEditorState();
286
+ this.editorView?.dispatch({
287
+ effects: this.readonlyState.reconfigure(EditorState.readOnly.of(this.disabled)),
288
+ });
275
289
  }
276
290
  }
277
291
  /**
@@ -297,6 +311,7 @@ let CodeEditor = (() => {
297
311
  this.createPlaceholderPlugin(),
298
312
  hoverTooltip(this.createHoverTooltipSource),
299
313
  linter((view) => functionLinter(view, this.functionSchemas, (e) => this.dispatchEvent(e))),
314
+ this.readonlyState.of(EditorState.readOnly.of(this.disabled)),
300
315
  ];
301
316
  // Add language support
302
317
  if (this.language === 'javascript') {
@@ -326,7 +341,7 @@ let CodeEditor = (() => {
326
341
  * This is created as a method to get access to the component's `suggestions`.
327
342
  */
328
343
  createPlaceholderPlugin() {
329
- const placeholderMatcher = new SuggestionMatchDecorator(/\{\{(\w+)\}\}/g, this.suggestions);
344
+ const placeholderMatcher = new SuggestionMatchDecorator(/\{\{([^}]+)\}\}/g, this.suggestions);
330
345
  this.placeholderMatcher = placeholderMatcher;
331
346
  // This class needs to be defined here to have access to the `placeholderMatcher`
332
347
  class AtomicDecorationRange {
@@ -366,7 +381,7 @@ let CodeEditor = (() => {
366
381
  }
367
382
  }
368
383
  // Check if we're typing a suggestion trigger (e.g., {{)
369
- const suggestionMatch = textBefore.match(/\{\{(\w*)$/);
384
+ const suggestionMatch = textBefore.match(/\{\{([^}]*)$/);
370
385
  if (suggestionMatch) {
371
386
  const prefix = suggestionMatch[1];
372
387
  const suggestions = this.suggestions
@@ -386,6 +401,7 @@ let CodeEditor = (() => {
386
401
  const result = {
387
402
  label: schema.name,
388
403
  detail: schema.description || '',
404
+ type: 'function',
389
405
  info: () => this.createFunctionInfoElement(schema),
390
406
  apply: (view, completion, from, to) => {
391
407
  const functionCall = this.formatFunctionCall(schema);
@@ -403,8 +419,9 @@ let CodeEditor = (() => {
403
419
  label: suggestion.label,
404
420
  detail: suggestion.description || '',
405
421
  info: suggestion.suffix || '',
422
+ type: 'variable',
406
423
  apply: (view, completion, from, to) => {
407
- const placeholderText = `{{${suggestion.label}}}`;
424
+ const placeholderText = `{{${suggestion.id}}}`;
408
425
  view.dispatch({
409
426
  changes: { from: from - 2, to, insert: placeholderText }, // -2 to include the {{
410
427
  selection: { anchor: from - 2 + placeholderText.length },
@@ -524,21 +541,6 @@ let CodeEditor = (() => {
524
541
  });
525
542
  }
526
543
  }
527
- /**
528
- * Update editor state (e.g., disabled state)
529
- */
530
- updateEditorState() {
531
- if (!this.editorView)
532
- return;
533
- // For now, we'll handle disabled state differently
534
- // CodeMirror 6 doesn't use reconfigure for editable
535
- if (this.disabled) {
536
- this.editorView.contentDOM.setAttribute('contenteditable', 'false');
537
- }
538
- else {
539
- this.editorView.contentDOM.setAttribute('contenteditable', 'true');
540
- }
541
- }
542
544
  /**
543
545
  * Handle editor content change
544
546
  */
@@ -546,20 +548,18 @@ let CodeEditor = (() => {
546
548
  if (!this.editorView)
547
549
  return;
548
550
  const newValue = this.editorView.state.doc.toString();
549
- if (newValue !== this._previousValue) {
550
- this._previousValue = newValue;
551
- this.value = newValue;
552
- this.hasContent = newValue.length > 0;
553
- this.dispatchEvent(new Event('input', { bubbles: true }));
554
- }
551
+ this.#value = newValue;
552
+ this.hasContent = newValue.length > 0;
553
+ this.dispatchEvent(new Event('input', { bubbles: true }));
555
554
  }
556
555
  /**
557
556
  * Handle focus change
558
557
  */
559
558
  handleFocusChange(hasFocus) {
560
559
  this.isEditorFocus = hasFocus;
561
- if (!hasFocus && this.value !== this._previousValue) {
562
- this.dispatchEvent(new Event('change', { bubbles: true }));
560
+ if (!hasFocus && this.#value !== this._previousValue) {
561
+ this._previousValue = this.#value;
562
+ this.dispatchEvent(new Event('change'));
563
563
  }
564
564
  }
565
565
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEditor.js","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/CodeEditor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAkC,OAAO,EAAE,MAAM,KAAK,CAAA;AAC/E,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAa,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EACL,cAAc,GAKf,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EACL,UAAU,EACV,UAAU,EAEV,UAAU,EAEV,YAAY,GAEb,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;;sBAiBhC,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA7B,UAAW,SAAQ,WAAU;;;iCAa/C,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAM1B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;oCAMxD,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;mCAM1C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gCAM1C,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAM1B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;uCAM3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iCAM1B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CAM1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;uCAM3C,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;qCAM3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;oCAMpD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CAG1B,KAAK,CAAC,mBAAmB,CAAC;sCAG1B,KAAK,EAAE;yCAGP,KAAK,EAAE;YA1ER,oKAAS,KAAK,6BAAL,KAAK,qFAAK;YAMnB,+LAAS,cAAc,6BAAd,cAAc,uGAAK;YAM5B,6KAAS,QAAQ,6BAAR,QAAQ,2FAAQ;YAMzB,0KAAS,OAAO,6BAAP,OAAO,yFAAQ;YAMxB,iKAAS,IAAI,6BAAJ,IAAI,mFAAK;YAMlB,6KAAS,QAAQ,6BAAR,QAAQ,2FAAQ;YAMzB,sLAAS,WAAW,6BAAX,WAAW,iGAAK;YAMzB,oKAAS,KAAK,6BAAL,KAAK,qFAAK;YAMnB,kMAAS,eAAe,6BAAf,eAAe,yGAAuB;YAM/C,sLAAS,WAAW,6BAAX,WAAW,iGAAmB;YAMvC,gLAAS,SAAS,6BAAT,SAAS,6FAAQ;YAM1B,6KAAS,QAAQ,6BAAR,QAAQ,2FAAe;YAGhC,kMAAiB,eAAe,6BAAf,eAAe,yGAAiB;YAGjD,mLAAiB,UAAU,6BAAV,UAAU,+FAAQ;YAGnC,4LAAiB,aAAa,6BAAb,aAAa,qGAAQ;;;QAxFtC;;;WAGG;QACH,MAAM,CAAU,iBAAiB,GAAmB;YAClD,IAAI,EAAE,MAAM;YACZ,cAAc,EAAE,IAAI;SACrB,CAAA;QAMD,uEAAiB,EAAE;QAEnB;;WAEG;UAJgB;QAJnB;;WAEG;QAEH,IAAS,KAAK,2CAAK;QAAnB,IAAS,KAAK,iDAAK;QAMnB,6IAA0B,EAAE;QAE5B;;WAEG;WAJyB;QAJ5B;;WAEG;QAEH,IAAS,cAAc,oDAAK;QAA5B,IAAS,cAAc,0DAAK;QAM5B,0IAAoB,KAAK;QAEzB;;WAEG;WAJsB;QAJzB;;WAEG;QAEH,IAAS,QAAQ,8CAAQ;QAAzB,IAAS,QAAQ,oDAAQ;QAMzB,kIAAmB,KAAK;QAExB;;WAEG;WAJqB;QAJxB;;WAEG;QAEH,IAAS,OAAO,6CAAQ;QAAxB,IAAS,OAAO,mDAAQ;QAMxB,2HAAgB,EAAE;QAElB;;WAEG;WAJe;QAJlB;;WAEG;QAEH,IAAS,IAAI,0CAAK;QAAlB,IAAS,IAAI,gDAAK;QAMlB,gIAAoB,KAAK;QAEzB;;WAEG;WAJsB;QAJzB;;WAEG;QAEH,IAAS,QAAQ,8CAAQ;QAAzB,IAAS,QAAQ,oDAAQ;QAMzB,0IAAuB,EAAE;QAEzB;;WAEG;WAJsB;QAJzB;;WAEG;QAEH,IAAS,WAAW,iDAAK;QAAzB,IAAS,WAAW,uDAAK;QAMzB,iIAAiB,EAAE;QAEnB;;WAEG;WAJgB;QAJnB;;WAEG;QAEH,IAAS,KAAK,2CAAK;QAAnB,IAAS,KAAK,iDAAK;QAMnB,+IAA6C,EAAE;QAE/C;;WAEG;WAJ4C;QAJ/C;;WAEG;QAEH,IAAS,eAAe,qDAAuB;QAA/C,IAAS,eAAe,2DAAuB;QAM/C,iJAAqC,EAAE;QAEvC;;WAEG;WAJoC;QAJvC;;WAEG;QAEH,IAAS,WAAW,iDAAmB;QAAvC,IAAS,WAAW,uDAAmB;QAMvC,yIAAqB,KAAK;QAE1B;;WAEG;WAJuB;QAJ1B;;WAEG;QAEH,IAAS,SAAS,+CAAQ;QAA1B,IAAS,SAAS,qDAAQ;QAM1B,qIAAoB,YAAY,GAAA;QAJhC;;WAEG;QAEH,IAAS,QAAQ,8CAAe;QAAhC,IAAS,QAAQ,oDAAe;QAGhC,2JAAiD;QAAjD,IAAiB,eAAe,qDAAiB;QAAjD,IAAiB,eAAe,2DAAiB;QAGjD,+IAA8B,KAAK,GAAA;QAAnC,IAAiB,UAAU,gDAAQ;QAAnC,IAAiB,UAAU,sDAAQ;QAGnC,gJAAiC,KAAK,GAAA;QAAtC,IAAiB,aAAa,mDAAQ;QAAtC,IAAiB,aAAa,yDAAQ;QAE9B,UAAU,6DAAa;QACvB,cAAc,GAAG,EAAE,CAAA;QAC3B;;WAEG;QACH,kBAAkB,CAA2B;QAE7C;;WAEG;QACH,IAAI,iBAAiB;YACnB,MAAM,WAAW,GAAiB,EAAE,CAAA;YACpC,MAAM,kBAAkB,GAAG,gBAAgB,CAAA;YAC3C,IAAI,KAA6B,CAAA;YACjC,OAAO,CAAC,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC9D,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gBAChC,2BAA2B;gBAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,eAAe,CAAC,WAAW,EAAE,CAAC,CAAA;gBACxG,IAAI,UAAU,EAAE,CAAC;oBACf,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;gBAC9B,CAAC;YACH,CAAC;YACD,OAAO,WAAW,CAAA;QACpB,CAAC;QAEQ,oBAAoB;YAC3B,KAAK,CAAC,oBAAoB,EAAE,CAAA;YAC5B,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAA;QAC5B,CAAC;QAEQ,YAAY;YACnB,IAAI,CAAC,oBAAoB,EAAE,CAAA;YAC3B,IAAI,CAAC,mBAAmB,EAAE,CAAA;QAC5B,CAAC;QAEQ,UAAU,CAAC,iBAAiC;YACnD,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAA;YAEnC,IAAI,iBAAiB,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;gBACzC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAC5B,IAAI,CAAC,kBAAkB,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAA;gBAC9D,CAAC;YACH,CAAC;YAED,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACtD,IAAI,CAAC,mBAAmB,EAAE,CAAA;YAC5B,CAAC;YAED,IAAI,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC,iBAAiB,EAAE,CAAA;YAC1B,CAAC;QACH,CAAC;QAED;;WAEG;QACK,oBAAoB;YAC1B,MAAM,UAAU,GAAgB;gBAC9B,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC;gBACxB,kBAAkB,CAAC,qBAAqB,CAAC;gBACzC,cAAc,CAAC;oBACb,QAAQ,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC;oBACzC,gBAAgB,EAAE,IAAI;oBACtB,kBAAkB,EAAE,EAAE;iBACvB,CAAC;gBACF,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,MAAkB,EAAE,EAAE;oBAClD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;wBACtB,IAAI,CAAC,kBAAkB,EAAE,CAAA;oBAC3B,CAAC;oBACD,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;wBACxB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;oBAC9C,CAAC;gBACH,CAAC,CAAC;gBACF,IAAI,CAAC,uBAAuB,EAAE;gBAC9B,YAAY,CAAC,IAAI,CAAC,wBAAwB,CAAC;gBAC3C,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3F,CAAA;YAED,uBAAuB;YACvB,IAAI,IAAI,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;gBACnC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;YAC/B,CAAC;YAED,YAAY;YACZ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAC1B,CAAC;YAED,kBAAkB;YAClB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,UAAU,CAAC,IAAI,CACb,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBAC9B,kBAAkB,EAAE,IAAI,CAAC,WAAW;iBACrC,CAAC,CACH,CAAA;YACH,CAAC;YAED,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC;gBAC/B,GAAG,EAAE,IAAI,CAAC,KAAK;gBACf,UAAU;aACX,CAAC,CAAA;YAEF,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC;gBAC/B,KAAK;gBACL,MAAM,EAAE,IAAI,CAAC,eAAe;aAC7B,CAAC,CAAA;QACJ,CAAC;QAED;;;WAGG;QACK,uBAAuB;YAC7B,MAAM,kBAAkB,GAAG,IAAI,wBAAwB,CAAC,gBAAgB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;YAC3F,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAA;YAC5C,iFAAiF;YACjF,MAAM,qBAAqB;gBACzB,YAAY,CAAe;gBAC3B,YAAY,IAAgB;oBAC1B,IAAI,CAAC,YAAY,GAAG,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;gBACzD,CAAC;gBACD,MAAM,CAAC,MAAkB;oBACvB,IAAI,CAAC,YAAY,GAAG,kBAAkB,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;gBAC9E,CAAC;aACF;YAED,OAAO,UAAU,CAAC,SAAS,CAAC,qBAAqB,EAAE;gBACjD,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY;gBAChD,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,IAAI,UAAU,CAAC,IAAI,CAAC;aAChH,CAAC,CAAA;QACJ,CAAC;QAED;;WAEG;QACK,sBAAsB;YAC5B,OAAO,CAAC,OAA0B,EAA2B,EAAE;gBAC7D,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAA;gBACvB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;gBAEtD,wCAAwC;gBACxC,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAChD,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;oBAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe;yBACnC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;yBACtE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAA;oBAEjD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACzB,OAAO;4BACL,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM;4BACzB,OAAO,EAAE,SAAS;yBACnB,CAAA;oBACH,CAAC;gBACH,CAAC;gBAED,wDAAwD;gBACxD,MAAM,eAAe,GAAG,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;gBACtD,IAAI,eAAe,EAAE,CAAC;oBACpB,MAAM,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;oBACjC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW;yBACjC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;yBACvF,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC,CAAA;oBAEnE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC3B,OAAO;4BACL,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM;4BACzB,OAAO,EAAE,WAAW;yBACrB,CAAA;oBACH,CAAC;gBACH,CAAC;gBAED,OAAO,IAAI,CAAA;YACb,CAAC,CAAA;QACH,CAAC;QAEO,wBAAwB,CAAC,MAAsB;YACrD,MAAM,MAAM,GAAe;gBACzB,KAAK,EAAE,MAAM,CAAC,IAAI;gBAClB,MAAM,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;gBAChC,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC;gBAClD,KAAK,EAAE,CAAC,IAAgB,EAAE,UAAmB,EAAE,IAAY,EAAE,EAAU,EAAE,EAAE;oBACzE,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;oBACpD,IAAI,CAAC,QAAQ,CAAC;wBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE;wBAC3C,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,YAAY,CAAC,MAAM,EAAE;qBAClD,CAAC,CAAA;oBACF,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;gBAC3C,CAAC;aACF,CAAA;YAED,OAAO,MAAM,CAAA;QACf,CAAC;QAEO,0BAA0B,CAAC,UAAsB;YACvD,MAAM,MAAM,GAAe;gBACzB,KAAK,EAAE,UAAU,CAAC,KAAK;gBACvB,MAAM,EAAE,UAAU,CAAC,WAAW,IAAI,EAAE;gBACpC,IAAI,EAAE,UAAU,CAAC,MAAM,IAAI,EAAE;gBAC7B,KAAK,EAAE,CAAC,IAAgB,EAAE,UAAmB,EAAE,IAAY,EAAE,EAAU,EAAE,EAAE;oBACzE,MAAM,eAAe,GAAG,KAAK,UAAU,CAAC,KAAK,IAAI,CAAA;oBACjD,IAAI,CAAC,QAAQ,CAAC;wBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,uBAAuB;wBACjF,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE;qBACzD,CAAC,CAAA;oBACF,IAAI,CAAC,wBAAwB,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;gBACrD,CAAC;aACF,CAAA;YAED,OAAO,MAAM,CAAA;QACf,CAAC;QAED;;;WAGG;QACK,wBAAwB,GAAG,CAAC,IAAgB,EAAE,GAAW,EAAkB,EAAE;YACnF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACnC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,IAAI,CAAA;YACb,CAAC;YAED,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;YACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC,CAAA;YAEpF,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,IAAI,CAAA;YACb,CAAC;YAED,OAAO;gBACL,GAAG,EAAE,IAAI,CAAC,IAAI;gBACd,GAAG,EAAE,IAAI,CAAC,EAAE;gBACZ,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,EAAE,CAAC;aAClE,CAAA;QACH,CAAC,CAAA;QAED;;;WAGG;QACK,yBAAyB,CAAC,EAAkB;YAClD,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;YAC/C,SAAS,CAAC,SAAS,GAAG,eAAe,CAAA,CAAC,cAAc;YAEpD,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBACnB,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;gBAC/C,WAAW,CAAC,SAAS,GAAG,aAAa,CAAA;gBACrC,WAAW,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAA;gBACxC,SAAS,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;YACpC,CAAC;YAED,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;gBACrD,eAAe,CAAC,SAAS,GAAG,YAAY,CAAA;gBAExC,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;gBACjD,YAAY,CAAC,WAAW,GAAG,YAAY,CAAA;gBACvC,eAAe,CAAC,WAAW,CAAC,YAAY,CAAC,CAAA;gBAEzC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;gBAC/C,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;oBAE7C,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;oBAC3C,IAAI,CAAC,SAAS,GAAG,YAAY,CAAA;oBAC7B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAA;oBAE7B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;oBAC3C,IAAI,CAAC,SAAS,GAAG,YAAY,CAAA;oBAC7B,IAAI,CAAC,WAAW,GAAG,KAAK,uBAAuB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;oBAE/D,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;oBAC1B,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;oBAE1B,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;wBAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;wBAC7C,SAAS,CAAC,SAAS,GAAG,mBAAmB,CAAA;wBACzC,SAAS,CAAC,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,CAAA;wBAChD,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;oBACjC,CAAC;oBACD,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;gBAClC,CAAC,CAAC,CAAA;gBACF,eAAe,CAAC,WAAW,CAAC,UAAU,CAAC,CAAA;gBACvC,SAAS,CAAC,WAAW,CAAC,eAAe,CAAC,CAAA;YACxC,CAAC;YAED,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;gBACf,MAAM,gBAAgB,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;gBACtD,gBAAgB,CAAC,SAAS,GAAG,SAAS,CAAA;gBAEtC,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;gBAClD,aAAa,CAAC,WAAW,GAAG,SAAS,CAAA;gBACrC,gBAAgB,CAAC,WAAW,CAAC,aAAa,CAAC,CAAA;gBAE3C,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;gBAC/C,MAAM,UAAU,GAAG,uBAAuB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAA;gBACtD,WAAW,CAAC,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;gBAC1G,gBAAgB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;gBACzC,SAAS,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAA;YACzC,CAAC;YAED,OAAO,SAAS,CAAA;QAClB,CAAC;QAED;;WAEG;QACK,kBAAkB,CAAC,EAAkB;YAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjD,OAAO,GAAG,EAAE,CAAC,IAAI,IAAI,CAAA;YACvB,CAAC;YAED,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU;iBACzB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBACb,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACnB,OAAO,KAAK,CAAC,IAAI,CAAA;gBACnB,CAAC;gBACD,OAAO,GAAG,KAAK,CAAC,IAAI,GAAG,CAAA;YACzB,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAA;YAEb,OAAO,GAAG,EAAE,CAAC,IAAI,IAAI,MAAM,GAAG,CAAA;QAChC,CAAC;QAED;;WAEG;QACK,mBAAmB;YACzB,IAAI,CAAC,IAAI,CAAC,UAAU;gBAAE,OAAM;YAE5B,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAA;YACzD,IAAI,YAAY,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;gBAChC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;oBACvB,OAAO,EAAE;wBACP,IAAI,EAAE,CAAC;wBACP,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;wBACpC,MAAM,EAAE,IAAI,CAAC,KAAK;qBACnB;iBACF,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED;;WAEG;QACK,iBAAiB;YACvB,IAAI,CAAC,IAAI,CAAC,UAAU;gBAAE,OAAM;YAE5B,mDAAmD;YACnD,oDAAoD;YACpD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;YACrE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAA;YACpE,CAAC;QACH,CAAC;QAED;;WAEG;QACK,kBAAkB;YACxB,IAAI,CAAC,IAAI,CAAC,UAAU;gBAAE,OAAM;YAE5B,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAA;YACrD,IAAI,QAAQ,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrC,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAA;gBAC9B,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAA;gBACrB,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;gBAErC,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;YAC3D,CAAC;QACH,CAAC;QAED;;WAEG;QACK,iBAAiB,CAAC,QAAiB;YACzC,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAA;YAE7B,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpD,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;YAC5D,CAAC;QACH,CAAC;QAED;;WAEG;QACK,sBAAsB,CAAC,cAA8B,EAAE,QAAgB;YAC7E,MAAM,KAAK,GAAG,IAAI,WAAW,CAAsB,iBAAiB,EAAE;gBACpE,MAAM,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE;gBACpC,OAAO,EAAE,IAAI;aACd,CAAC,CAAA;YACF,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC;QAED;;WAEG;QACK,wBAAwB,CAAC,UAAsB,EAAE,QAAgB;YACvE,MAAM,KAAK,GAAG,IAAI,WAAW,CAAwB,mBAAmB,EAAE;gBACxE,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE;gBAChC,OAAO,EAAE,IAAI;aACd,CAAC,CAAA;YACF,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC;QAED;;WAEG;QACM,KAAK;YACZ,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAA;QAC1B,CAAC;QAED;;WAEG;QACH,YAAY;YACV,IAAI,CAAC,IAAI,CAAC,UAAU;gBAAE,OAAO,IAAI,CAAA;YACjC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAA;YACzD,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;QACrB,CAAC;QAED;;WAEG;QACH,UAAU,CAAC,IAAY;YACrB,IAAI,CAAC,IAAI,CAAC,UAAU;gBAAE,OAAM;YAE5B,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAA;YACzD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBACvB,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;gBACnC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE;aAC1C,CAAC,CAAA;QACJ,CAAC;QAEQ,MAAM;YACb,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAA;YAC7B,MAAM,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC,cAAc,CAAA;YAE/C,OAAO,IAAI,CAAA;4BACa,QAAQ,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;;YAEtF,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAA,sBAAsB,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO;;;;;UAKnE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAA,gCAAgC,IAAI,CAAC,cAAc,QAAQ,CAAC,CAAC,CAAC,OAAO;;KAElG,CAAA;QACH,CAAC;;;AA9iBH;;;;;;;;;;;;;;GAcG;AACH","sourcesContent":["import { html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { linter } from '@codemirror/lint'\nimport { EditorState, Extension } from '@codemirror/state'\nimport {\n autocompletion,\n CompletionContext,\n type CompletionResult,\n type CompletionSource,\n type Completion,\n} from '@codemirror/autocomplete'\nimport { javascript } from '@codemirror/lang-javascript'\nimport { syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language'\nimport { oneDark } from '@codemirror/theme-one-dark'\nimport { keymap } from '@codemirror/view'\nimport { defaultKeymap } from '@codemirror/commands'\nimport {\n EditorView,\n Decoration,\n DecorationSet,\n ViewPlugin,\n ViewUpdate,\n hoverTooltip,\n type Tooltip,\n} from '@codemirror/view'\nimport type { FunctionSchema } from '@pawel-up/jexl/schemas/types.js'\nimport { getTypeStringFromSchema } from '@pawel-up/jexl/schemas/utils.js'\nimport { functionLinter } from './Linter.js'\nimport type { FunctionInsertEvent, Suggestion, SuggestionInsertEvent } from './types.js'\nimport { SuggestionMatchDecorator } from './SuggestionMatchDecorator.js'\n\n/**\n * A CodeMirror 6 based editor component that supports function autocomplete and suggestion placeholders.\n *\n * Features:\n * - Dynamic function schema loading\n * - Autocomplete for functions and suggestions\n * - Suggestion placeholders with double curly braces ({{suggestion}})\n * - Keyboard navigation\n * - Accessibility support\n *\n * @fires function-insert - When a function is inserted\n * @fires suggestion-insert - When a suggestion is inserted\n * @fires input - When the editor content changes\n * @fires change - When the editor loses focus and content has changed\n */\nexport default class CodeEditor extends LitElement {\n /**\n * Shadow root configuration for the component.\n * Uses 'open' mode for accessibility and delegates focus to enable proper focus management.\n */\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n }\n\n /**\n * The label text displayed as placeholder/floating label\n */\n @property({ type: String })\n accessor label = ''\n\n /**\n * Supporting text displayed below the editor\n */\n @property({ type: String, attribute: 'supporting-text' })\n accessor supportingText = ''\n\n /**\n * Whether the component is disabled\n */\n @property({ type: Boolean, reflect: true })\n accessor disabled = false\n\n /**\n * Whether the component is in an invalid state\n */\n @property({ type: Boolean, reflect: true })\n accessor invalid = false\n\n /**\n * The name attribute for form integration\n */\n @property({ type: String })\n accessor name = ''\n\n /**\n * Whether the input is required\n */\n @property({ type: Boolean })\n accessor required = false\n\n /**\n * Placeholder text shown when editor is empty\n */\n @property({ type: String })\n accessor placeholder = ''\n\n /**\n * The editor content value\n */\n @property({ type: String })\n accessor value = ''\n\n /**\n * Available function schemas for autocomplete\n */\n @property({ type: Array, attribute: false })\n accessor functionSchemas: FunctionSchema[] = []\n\n /**\n * Available suggestions for autocomplete\n */\n @property({ type: Array, attribute: false })\n accessor suggestions: Suggestion[] = []\n\n /**\n * Whether to use dark theme\n */\n @property({ type: Boolean, attribute: 'dark-theme' })\n accessor darkTheme = false\n\n /**\n * Programming language for syntax highlighting\n */\n @property({ type: String })\n accessor language = 'javascript'\n\n @query('.editor-container')\n private accessor editorContainer!: HTMLDivElement\n\n @state()\n private accessor hasContent = false\n\n @state()\n private accessor isEditorFocus = false\n\n private editorView?: EditorView\n private _previousValue = ''\n /**\n * Matcher for suggestion placeholders in the editor.\n */\n placeholderMatcher?: SuggestionMatchDecorator\n\n /**\n * Get all suggestions (placeholders) currently in the editor\n */\n get activeSuggestions(): Suggestion[] {\n const suggestions: Suggestion[] = []\n const placeholderPattern = /\\{\\{(\\w+)\\}\\}/g\n let match: RegExpExecArray | null\n while ((match = placeholderPattern.exec(this.value)) !== null) {\n const placeholderText = match[1]\n // Find suggestion by label\n const suggestion = this.suggestions.find((s) => s.label.toLowerCase() === placeholderText.toLowerCase())\n if (suggestion) {\n suggestions.push(suggestion)\n }\n }\n return suggestions\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback()\n this.editorView?.destroy()\n }\n\n override firstUpdated(): void {\n this.initializeCodeMirror()\n this.updateEditorContent()\n }\n\n override willUpdate(changedProperties: PropertyValues): void {\n super.willUpdate(changedProperties)\n\n if (changedProperties.has('suggestions')) {\n if (this.placeholderMatcher) {\n this.placeholderMatcher.suggestions = this.suggestions || []\n }\n }\n\n if (changedProperties.has('value') && this.editorView) {\n this.updateEditorContent()\n }\n\n if (changedProperties.has('disabled')) {\n this.updateEditorState()\n }\n }\n\n /**\n * Initialize CodeMirror editor with extensions\n */\n private initializeCodeMirror(): void {\n const extensions: Extension[] = [\n keymap.of(defaultKeymap),\n syntaxHighlighting(defaultHighlightStyle),\n autocompletion({\n override: [this.createCompletionSource()],\n activateOnTyping: true,\n maxRenderedOptions: 10,\n }),\n EditorView.updateListener.of((update: ViewUpdate) => {\n if (update.docChanged) {\n this.handleEditorChange()\n }\n if (update.focusChanged) {\n this.handleFocusChange(update.view.hasFocus)\n }\n }),\n this.createPlaceholderPlugin(),\n hoverTooltip(this.createHoverTooltipSource),\n linter((view) => functionLinter(view, this.functionSchemas, (e) => this.dispatchEvent(e))),\n ]\n\n // Add language support\n if (this.language === 'javascript') {\n extensions.push(javascript())\n }\n\n // Add theme\n if (this.darkTheme) {\n extensions.push(oneDark)\n }\n\n // Add placeholder\n if (this.placeholder) {\n extensions.push(\n EditorView.contentAttributes.of({\n 'aria-placeholder': this.placeholder,\n })\n )\n }\n\n const state = EditorState.create({\n doc: this.value,\n extensions,\n })\n\n this.editorView = new EditorView({\n state,\n parent: this.editorContainer,\n })\n }\n\n /**\n * Creates the ViewPlugin for rendering suggestion placeholders.\n * This is created as a method to get access to the component's `suggestions`.\n */\n private createPlaceholderPlugin(): Extension {\n const placeholderMatcher = new SuggestionMatchDecorator(/\\{\\{(\\w+)\\}\\}/g, this.suggestions)\n this.placeholderMatcher = placeholderMatcher\n // This class needs to be defined here to have access to the `placeholderMatcher`\n class AtomicDecorationRange {\n placeholders: DecorationSet\n constructor(view: EditorView) {\n this.placeholders = placeholderMatcher.createDeco(view)\n }\n update(update: ViewUpdate) {\n this.placeholders = placeholderMatcher.updateDeco(update, this.placeholders)\n }\n }\n\n return ViewPlugin.fromClass(AtomicDecorationRange, {\n decorations: (instance) => instance.placeholders,\n provide: (plugin) => EditorView.atomicRanges.of((view) => view.plugin(plugin)?.placeholders || Decoration.none),\n })\n }\n\n /**\n * Create completion source for functions and suggestions\n */\n private createCompletionSource(): CompletionSource {\n return (context: CompletionContext): CompletionResult | null => {\n const { pos } = context\n const line = context.state.doc.lineAt(pos)\n const textBefore = line.text.slice(0, pos - line.from)\n\n // Check if we're typing a function name\n const functionMatch = textBefore.match(/(\\w+)$/)\n if (functionMatch) {\n const prefix = functionMatch[1]\n const functions = this.functionSchemas\n .filter((fn) => fn.name.toLowerCase().startsWith(prefix.toLowerCase()))\n .map((fn) => this.createFunctionCompletion(fn))\n\n if (functions.length > 0) {\n return {\n from: pos - prefix.length,\n options: functions,\n }\n }\n }\n\n // Check if we're typing a suggestion trigger (e.g., {{)\n const suggestionMatch = textBefore.match(/\\{\\{(\\w*)$/)\n if (suggestionMatch) {\n const prefix = suggestionMatch[1]\n const suggestions = this.suggestions\n .filter((suggestion) => suggestion.label.toLowerCase().startsWith(prefix.toLowerCase()))\n .map((suggestion) => this.createSuggestionCompletion(suggestion))\n\n if (suggestions.length > 0) {\n return {\n from: pos - prefix.length,\n options: suggestions,\n }\n }\n }\n\n return null\n }\n }\n\n private createFunctionCompletion(schema: FunctionSchema): Completion {\n const result: Completion = {\n label: schema.name,\n detail: schema.description || '',\n info: () => this.createFunctionInfoElement(schema),\n apply: (view: EditorView, completion: unknown, from: number, to: number) => {\n const functionCall = this.formatFunctionCall(schema)\n view.dispatch({\n changes: { from, to, insert: functionCall },\n selection: { anchor: from + functionCall.length },\n })\n this.dispatchFunctionInsert(schema, from)\n },\n }\n\n return result\n }\n\n private createSuggestionCompletion(suggestion: Suggestion): Completion {\n const result: Completion = {\n label: suggestion.label,\n detail: suggestion.description || '',\n info: suggestion.suffix || '',\n apply: (view: EditorView, completion: unknown, from: number, to: number) => {\n const placeholderText = `{{${suggestion.label}}}`\n view.dispatch({\n changes: { from: from - 2, to, insert: placeholderText }, // -2 to include the {{\n selection: { anchor: from - 2 + placeholderText.length },\n })\n this.dispatchSuggestionInsert(suggestion, from - 2)\n },\n }\n\n return result\n }\n\n /**\n * Creates the source for the hover tooltips.\n * This is an arrow function to automatically bind `this`.\n */\n private createHoverTooltipSource = (view: EditorView, pos: number): Tooltip | null => {\n const word = view.state.wordAt(pos)\n if (!word) {\n return null\n }\n\n const functionName = view.state.doc.sliceString(word.from, word.to)\n const fnSchema = this.functionSchemas.find((schema) => schema.name === functionName)\n\n if (!fnSchema) {\n return null\n }\n\n return {\n pos: word.from,\n end: word.to,\n above: true,\n create: () => ({ dom: this.createFunctionInfoElement(fnSchema) }),\n }\n }\n\n /**\n * Creates a styled HTML element to display function documentation.\n * This is used for both hover tooltips and autocomplete info panels.\n */\n private createFunctionInfoElement(fn: FunctionSchema): HTMLElement {\n const container = document.createElement('div')\n container.className = 'function-info' // for styling\n\n if (fn.description) {\n const description = document.createElement('p')\n description.className = 'description'\n description.textContent = fn.description\n container.appendChild(description)\n }\n\n if (fn.parameters && fn.parameters.length > 0) {\n const paramsContainer = document.createElement('div')\n paramsContainer.className = 'parameters'\n\n const paramsHeader = document.createElement('h4')\n paramsHeader.textContent = 'Parameters'\n paramsContainer.appendChild(paramsHeader)\n\n const paramsList = document.createElement('ul')\n fn.parameters.forEach((param) => {\n const listItem = document.createElement('li')\n\n const name = document.createElement('span')\n name.className = 'param-name'\n name.textContent = param.name\n\n const type = document.createElement('span')\n type.className = 'param-type'\n type.textContent = `: ${getTypeStringFromSchema(param.schema)}`\n\n listItem.appendChild(name)\n listItem.appendChild(type)\n\n if (param.schema.description) {\n const paramDesc = document.createElement('p')\n paramDesc.className = 'param-description'\n paramDesc.textContent = param.schema.description\n listItem.appendChild(paramDesc)\n }\n paramsList.appendChild(listItem)\n })\n paramsContainer.appendChild(paramsList)\n container.appendChild(paramsContainer)\n }\n\n if (fn.returns) {\n const returnsContainer = document.createElement('div')\n returnsContainer.className = 'returns'\n\n const returnsHeader = document.createElement('h4')\n returnsHeader.textContent = 'Returns'\n returnsContainer.appendChild(returnsHeader)\n\n const returnsDesc = document.createElement('p')\n const returnType = getTypeStringFromSchema(fn.returns)\n returnsDesc.textContent = fn.returns.description ? `${returnType}: ${fn.returns.description}` : returnType\n returnsContainer.appendChild(returnsDesc)\n container.appendChild(returnsContainer)\n }\n\n return container\n }\n\n /**\n * Format function call with parameters\n */\n private formatFunctionCall(fn: FunctionSchema): string {\n if (!fn.parameters || fn.parameters.length === 0) {\n return `${fn.name}()`\n }\n\n const params = fn.parameters\n .map((param) => {\n if (param.required) {\n return param.name\n }\n return `${param.name}?`\n })\n .join(', ')\n\n return `${fn.name}(${params})`\n }\n\n /**\n * Update editor content when value changes\n */\n private updateEditorContent(): void {\n if (!this.editorView) return\n\n const currentValue = this.editorView.state.doc.toString()\n if (currentValue !== this.value) {\n this.editorView.dispatch({\n changes: {\n from: 0,\n to: this.editorView.state.doc.length,\n insert: this.value,\n },\n })\n }\n }\n\n /**\n * Update editor state (e.g., disabled state)\n */\n private updateEditorState(): void {\n if (!this.editorView) return\n\n // For now, we'll handle disabled state differently\n // CodeMirror 6 doesn't use reconfigure for editable\n if (this.disabled) {\n this.editorView.contentDOM.setAttribute('contenteditable', 'false')\n } else {\n this.editorView.contentDOM.setAttribute('contenteditable', 'true')\n }\n }\n\n /**\n * Handle editor content change\n */\n private handleEditorChange(): void {\n if (!this.editorView) return\n\n const newValue = this.editorView.state.doc.toString()\n if (newValue !== this._previousValue) {\n this._previousValue = newValue\n this.value = newValue\n this.hasContent = newValue.length > 0\n\n this.dispatchEvent(new Event('input', { bubbles: true }))\n }\n }\n\n /**\n * Handle focus change\n */\n private handleFocusChange(hasFocus: boolean): void {\n this.isEditorFocus = hasFocus\n\n if (!hasFocus && this.value !== this._previousValue) {\n this.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n /**\n * Dispatch function insert event\n */\n private dispatchFunctionInsert(functionSchema: FunctionSchema, position: number): void {\n const event = new CustomEvent<FunctionInsertEvent>('function-insert', {\n detail: { functionSchema, position },\n bubbles: true,\n })\n this.dispatchEvent(event)\n }\n\n /**\n * Dispatch suggestion insert event\n */\n private dispatchSuggestionInsert(suggestion: Suggestion, position: number): void {\n const event = new CustomEvent<SuggestionInsertEvent>('suggestion-insert', {\n detail: { suggestion, position },\n bubbles: true,\n })\n this.dispatchEvent(event)\n }\n\n /**\n * Focus the editor\n */\n override focus(): void {\n this.editorView?.focus()\n }\n\n /**\n * Get the editor's current selection\n */\n getSelection(): { from: number; to: number } | null {\n if (!this.editorView) return null\n const { from, to } = this.editorView.state.selection.main\n return { from, to }\n }\n\n /**\n * Insert text at the current cursor position\n */\n insertText(text: string): void {\n if (!this.editorView) return\n\n const { from, to } = this.editorView.state.selection.main\n this.editorView.dispatch({\n changes: { from, to, insert: text },\n selection: { anchor: from + text.length },\n })\n }\n\n override render(): TemplateResult {\n const hasLabel = !!this.label\n const hasSupportingText = !!this.supportingText\n\n return html`\n <div class=\"surface ${classMap({ 'has-focus': this.isEditorFocus, 'invalid': this.invalid })}\">\n <div class=\"content\">\n ${hasLabel ? html`<div class=\"label\">${this.label}</div>` : nothing}\n\n <div class=\"editor-container\" part=\"editor\"></div>\n </div>\n\n ${hasSupportingText ? html`<div class=\"supporting-text\">${this.supportingText}</div>` : nothing}\n </div>\n `\n }\n}\n"]}
1
+ {"version":3,"file":"CodeEditor.js","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/CodeEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { linter } from '@codemirror/lint'\nimport { Compartment, EditorState, Extension } from '@codemirror/state'\nimport {\n autocompletion,\n CompletionContext,\n type CompletionResult,\n type CompletionSource,\n type Completion,\n} from '@codemirror/autocomplete'\nimport { javascript } from '@codemirror/lang-javascript'\nimport { syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language'\nimport { oneDark } from '@codemirror/theme-one-dark'\nimport { keymap } from '@codemirror/view'\nimport { defaultKeymap } from '@codemirror/commands'\nimport {\n EditorView,\n Decoration,\n DecorationSet,\n ViewPlugin,\n ViewUpdate,\n hoverTooltip,\n type Tooltip,\n} from '@codemirror/view'\nimport type { FunctionSchema } from '@pawel-up/jexl/schemas/types.js'\nimport { getTypeStringFromSchema } from '@pawel-up/jexl/schemas/utils.js'\nimport { functionLinter } from './Linter.js'\nimport type { FunctionInsertEvent, Suggestion, SuggestionInsertEvent } from './types.js'\nimport { SuggestionMatchDecorator } from './SuggestionMatchDecorator.js'\n\n/**\n * A CodeMirror 6 based editor component that supports function autocomplete and suggestion placeholders.\n *\n * Features:\n * - Dynamic function schema loading\n * - Autocomplete for functions and suggestions\n * - Suggestion placeholders with double curly braces ({{suggestion}})\n * - Keyboard navigation\n * - Accessibility support\n *\n * @fires function-insert - When a function is inserted\n * @fires suggestion-insert - When a suggestion is inserted\n * @fires input - When the editor content changes\n * @fires change - When the editor loses focus and content has changed\n */\nexport default class CodeEditor extends LitElement {\n /**\n * Shadow root configuration for the component.\n * Uses 'open' mode for accessibility and delegates focus to enable proper focus management.\n */\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n }\n\n /**\n * The label text displayed as placeholder/floating label\n */\n @property({ type: String })\n accessor label = ''\n\n /**\n * Supporting text displayed below the editor\n */\n @property({ type: String, attribute: 'supporting-text' })\n accessor supportingText = ''\n\n /**\n * Whether the component is disabled\n */\n @property({ type: Boolean, reflect: true })\n accessor disabled = false\n\n /**\n * Whether the component is in an invalid state\n */\n @property({ type: Boolean, reflect: true })\n accessor invalid = false\n\n /**\n * The name attribute for form integration\n */\n @property({ type: String })\n accessor name = ''\n\n /**\n * Whether the input is required\n */\n @property({ type: Boolean })\n accessor required = false\n\n /**\n * Placeholder text shown when editor is empty\n */\n @property({ type: String })\n accessor placeholder = ''\n\n /**\n * This property is used internally to set value without triggering updates.\n */\n #value = ''\n\n /**\n * The editor content value\n */\n get value(): string {\n return this.#value\n }\n\n @property({ type: String })\n set value(newValue: string) {\n const oldValue = this.#value\n if (newValue !== oldValue) {\n this.#value = newValue\n this._previousValue = newValue\n this.requestUpdate('value', oldValue)\n }\n }\n\n /**\n * Available function schemas for autocomplete\n */\n @property({ type: Array, attribute: false })\n accessor functionSchemas: FunctionSchema[] = []\n\n /**\n * Available suggestions for autocomplete\n */\n @property({ type: Array, attribute: false })\n accessor suggestions: Suggestion[] = []\n\n /**\n * Whether to use dark theme\n */\n @property({ type: Boolean, attribute: 'dark-theme' })\n accessor darkTheme = false\n\n /**\n * Programming language for syntax highlighting\n */\n @property({ type: String })\n accessor language = 'javascript'\n\n @query('.editor-container')\n private accessor editorContainer!: HTMLDivElement\n\n @state()\n private accessor hasContent = false\n\n @state()\n private accessor isEditorFocus = false\n\n private editorView?: EditorView\n /**\n * A control value to track previous value of the editor.\n * This is used to detect when change event should be dispatched.\n */\n private _previousValue = ''\n /**\n * Matcher for suggestion placeholders in the editor.\n */\n placeholderMatcher?: SuggestionMatchDecorator\n\n /**\n * Get all suggestions (placeholders) currently in the editor\n */\n get activeSuggestions(): Suggestion[] {\n const suggestions: Suggestion[] = []\n const placeholderPattern = /\\{\\{([^}]+)\\}\\}/g\n let match: RegExpExecArray | null\n while ((match = placeholderPattern.exec(this.value)) !== null) {\n const placeholderText = match[1]\n // Find suggestion by id\n const suggestion = this.suggestions.find((s) => s.id === placeholderText)\n if (suggestion) {\n suggestions.push(suggestion)\n }\n }\n return suggestions\n }\n\n private readonlyState = new Compartment()\n\n override disconnectedCallback(): void {\n super.disconnectedCallback()\n this.editorView?.destroy()\n }\n\n override firstUpdated(): void {\n this.initializeCodeMirror()\n this.updateEditorContent()\n }\n\n override willUpdate(changedProperties: PropertyValues): void {\n super.willUpdate(changedProperties)\n\n if (changedProperties.has('suggestions')) {\n if (this.placeholderMatcher) {\n this.placeholderMatcher.suggestions = this.suggestions || []\n }\n }\n\n if (changedProperties.has('value') && this.editorView) {\n this.updateEditorContent()\n }\n\n if (changedProperties.has('disabled')) {\n this.editorView?.dispatch({\n effects: this.readonlyState.reconfigure(EditorState.readOnly.of(this.disabled)),\n })\n }\n }\n\n /**\n * Initialize CodeMirror editor with extensions\n */\n private initializeCodeMirror(): void {\n const extensions: Extension[] = [\n keymap.of(defaultKeymap),\n syntaxHighlighting(defaultHighlightStyle),\n autocompletion({\n override: [this.createCompletionSource()],\n activateOnTyping: true,\n maxRenderedOptions: 10,\n }),\n EditorView.updateListener.of((update: ViewUpdate) => {\n if (update.docChanged) {\n this.handleEditorChange()\n }\n if (update.focusChanged) {\n this.handleFocusChange(update.view.hasFocus)\n }\n }),\n this.createPlaceholderPlugin(),\n hoverTooltip(this.createHoverTooltipSource),\n linter((view) => functionLinter(view, this.functionSchemas, (e) => this.dispatchEvent(e))),\n this.readonlyState.of(EditorState.readOnly.of(this.disabled)),\n ]\n\n // Add language support\n if (this.language === 'javascript') {\n extensions.push(javascript())\n }\n\n // Add theme\n if (this.darkTheme) {\n extensions.push(oneDark)\n }\n\n // Add placeholder\n if (this.placeholder) {\n extensions.push(\n EditorView.contentAttributes.of({\n 'aria-placeholder': this.placeholder,\n })\n )\n }\n\n const state = EditorState.create({\n doc: this.value,\n extensions,\n })\n\n this.editorView = new EditorView({\n state,\n parent: this.editorContainer,\n })\n }\n\n /**\n * Creates the ViewPlugin for rendering suggestion placeholders.\n * This is created as a method to get access to the component's `suggestions`.\n */\n private createPlaceholderPlugin(): Extension {\n const placeholderMatcher = new SuggestionMatchDecorator(/\\{\\{([^}]+)\\}\\}/g, this.suggestions)\n this.placeholderMatcher = placeholderMatcher\n // This class needs to be defined here to have access to the `placeholderMatcher`\n class AtomicDecorationRange {\n placeholders: DecorationSet\n constructor(view: EditorView) {\n this.placeholders = placeholderMatcher.createDeco(view)\n }\n update(update: ViewUpdate) {\n this.placeholders = placeholderMatcher.updateDeco(update, this.placeholders)\n }\n }\n\n return ViewPlugin.fromClass(AtomicDecorationRange, {\n decorations: (instance) => instance.placeholders,\n provide: (plugin) => EditorView.atomicRanges.of((view) => view.plugin(plugin)?.placeholders || Decoration.none),\n })\n }\n\n /**\n * Create completion source for functions and suggestions\n */\n private createCompletionSource(): CompletionSource {\n return (context: CompletionContext): CompletionResult | null => {\n const { pos } = context\n const line = context.state.doc.lineAt(pos)\n const textBefore = line.text.slice(0, pos - line.from)\n\n // Check if we're typing a function name\n const functionMatch = textBefore.match(/(\\w+)$/)\n if (functionMatch) {\n const prefix = functionMatch[1]\n const functions = this.functionSchemas\n .filter((fn) => fn.name.toLowerCase().startsWith(prefix.toLowerCase()))\n .map((fn) => this.createFunctionCompletion(fn))\n\n if (functions.length > 0) {\n return {\n from: pos - prefix.length,\n options: functions,\n }\n }\n }\n\n // Check if we're typing a suggestion trigger (e.g., {{)\n const suggestionMatch = textBefore.match(/\\{\\{([^}]*)$/)\n if (suggestionMatch) {\n const prefix = suggestionMatch[1]\n const suggestions = this.suggestions\n .filter((suggestion) => suggestion.label.toLowerCase().startsWith(prefix.toLowerCase()))\n .map((suggestion) => this.createSuggestionCompletion(suggestion))\n\n if (suggestions.length > 0) {\n return {\n from: pos - prefix.length,\n options: suggestions,\n }\n }\n }\n\n return null\n }\n }\n\n private createFunctionCompletion(schema: FunctionSchema): Completion {\n const result: Completion = {\n label: schema.name,\n detail: schema.description || '',\n type: 'function',\n info: () => this.createFunctionInfoElement(schema),\n apply: (view: EditorView, completion: unknown, from: number, to: number) => {\n const functionCall = this.formatFunctionCall(schema)\n view.dispatch({\n changes: { from, to, insert: functionCall },\n selection: { anchor: from + functionCall.length },\n })\n this.dispatchFunctionInsert(schema, from)\n },\n }\n\n return result\n }\n\n private createSuggestionCompletion(suggestion: Suggestion): Completion {\n const result: Completion = {\n label: suggestion.label,\n detail: suggestion.description || '',\n info: suggestion.suffix || '',\n type: 'variable',\n apply: (view: EditorView, completion: unknown, from: number, to: number) => {\n const placeholderText = `{{${suggestion.id}}}`\n view.dispatch({\n changes: { from: from - 2, to, insert: placeholderText }, // -2 to include the {{\n selection: { anchor: from - 2 + placeholderText.length },\n })\n this.dispatchSuggestionInsert(suggestion, from - 2)\n },\n }\n\n return result\n }\n\n /**\n * Creates the source for the hover tooltips.\n * This is an arrow function to automatically bind `this`.\n */\n private createHoverTooltipSource = (view: EditorView, pos: number): Tooltip | null => {\n const word = view.state.wordAt(pos)\n if (!word) {\n return null\n }\n\n const functionName = view.state.doc.sliceString(word.from, word.to)\n const fnSchema = this.functionSchemas.find((schema) => schema.name === functionName)\n\n if (!fnSchema) {\n return null\n }\n\n return {\n pos: word.from,\n end: word.to,\n above: true,\n create: () => ({ dom: this.createFunctionInfoElement(fnSchema) }),\n }\n }\n\n /**\n * Creates a styled HTML element to display function documentation.\n * This is used for both hover tooltips and autocomplete info panels.\n */\n private createFunctionInfoElement(fn: FunctionSchema): HTMLElement {\n const container = document.createElement('div')\n container.className = 'function-info' // for styling\n\n if (fn.description) {\n const description = document.createElement('p')\n description.className = 'description'\n description.textContent = fn.description\n container.appendChild(description)\n }\n\n if (fn.parameters && fn.parameters.length > 0) {\n const paramsContainer = document.createElement('div')\n paramsContainer.className = 'parameters'\n\n const paramsHeader = document.createElement('h4')\n paramsHeader.textContent = 'Parameters'\n paramsContainer.appendChild(paramsHeader)\n\n const paramsList = document.createElement('ul')\n fn.parameters.forEach((param) => {\n const listItem = document.createElement('li')\n\n const name = document.createElement('span')\n name.className = 'param-name'\n name.textContent = param.name\n\n const type = document.createElement('span')\n type.className = 'param-type'\n type.textContent = `: ${getTypeStringFromSchema(param.schema)}`\n\n listItem.appendChild(name)\n listItem.appendChild(type)\n\n if (param.schema.description) {\n const paramDesc = document.createElement('p')\n paramDesc.className = 'param-description'\n paramDesc.textContent = param.schema.description\n listItem.appendChild(paramDesc)\n }\n paramsList.appendChild(listItem)\n })\n paramsContainer.appendChild(paramsList)\n container.appendChild(paramsContainer)\n }\n\n if (fn.returns) {\n const returnsContainer = document.createElement('div')\n returnsContainer.className = 'returns'\n\n const returnsHeader = document.createElement('h4')\n returnsHeader.textContent = 'Returns'\n returnsContainer.appendChild(returnsHeader)\n\n const returnsDesc = document.createElement('p')\n const returnType = getTypeStringFromSchema(fn.returns)\n returnsDesc.textContent = fn.returns.description ? `${returnType}: ${fn.returns.description}` : returnType\n returnsContainer.appendChild(returnsDesc)\n container.appendChild(returnsContainer)\n }\n\n return container\n }\n\n /**\n * Format function call with parameters\n */\n private formatFunctionCall(fn: FunctionSchema): string {\n if (!fn.parameters || fn.parameters.length === 0) {\n return `${fn.name}()`\n }\n\n const params = fn.parameters\n .map((param) => {\n if (param.required) {\n return param.name\n }\n return `${param.name}?`\n })\n .join(', ')\n\n return `${fn.name}(${params})`\n }\n\n /**\n * Update editor content when value changes\n */\n private updateEditorContent(): void {\n if (!this.editorView) return\n\n const currentValue = this.editorView.state.doc.toString()\n if (currentValue !== this.value) {\n this.editorView.dispatch({\n changes: {\n from: 0,\n to: this.editorView.state.doc.length,\n insert: this.value,\n },\n })\n }\n }\n\n /**\n * Handle editor content change\n */\n private handleEditorChange(): void {\n if (!this.editorView) return\n\n const newValue = this.editorView.state.doc.toString()\n this.#value = newValue\n this.hasContent = newValue.length > 0\n\n this.dispatchEvent(new Event('input', { bubbles: true }))\n }\n\n /**\n * Handle focus change\n */\n private handleFocusChange(hasFocus: boolean): void {\n this.isEditorFocus = hasFocus\n\n if (!hasFocus && this.#value !== this._previousValue) {\n this._previousValue = this.#value\n this.dispatchEvent(new Event('change'))\n }\n }\n\n /**\n * Dispatch function insert event\n */\n private dispatchFunctionInsert(functionSchema: FunctionSchema, position: number): void {\n const event = new CustomEvent<FunctionInsertEvent>('function-insert', {\n detail: { functionSchema, position },\n bubbles: true,\n })\n this.dispatchEvent(event)\n }\n\n /**\n * Dispatch suggestion insert event\n */\n private dispatchSuggestionInsert(suggestion: Suggestion, position: number): void {\n const event = new CustomEvent<SuggestionInsertEvent>('suggestion-insert', {\n detail: { suggestion, position },\n bubbles: true,\n })\n this.dispatchEvent(event)\n }\n\n /**\n * Focus the editor\n */\n override focus(): void {\n this.editorView?.focus()\n }\n\n /**\n * Get the editor's current selection\n */\n getSelection(): { from: number; to: number } | null {\n if (!this.editorView) return null\n const { from, to } = this.editorView.state.selection.main\n return { from, to }\n }\n\n /**\n * Insert text at the current cursor position\n */\n insertText(text: string): void {\n if (!this.editorView) return\n\n const { from, to } = this.editorView.state.selection.main\n this.editorView.dispatch({\n changes: { from, to, insert: text },\n selection: { anchor: from + text.length },\n })\n }\n\n override render(): TemplateResult {\n const hasLabel = !!this.label\n const hasSupportingText = !!this.supportingText\n\n return html`\n <div class=\"surface ${classMap({ 'has-focus': this.isEditorFocus, 'invalid': this.invalid })}\">\n <div class=\"content\">\n ${hasLabel ? html`<div class=\"label\">${this.label}</div>` : nothing}\n\n <div class=\"editor-container\" part=\"editor\"></div>\n </div>\n\n ${hasSupportingText ? html`<div class=\"supporting-text\">${this.supportingText}</div>` : nothing}\n </div>\n `\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEditor.styles.d.ts","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/CodeEditor.styles.ts"],"names":[],"mappings":";AAEA,wBAuJC"}
1
+ {"version":3,"file":"CodeEditor.styles.d.ts","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/CodeEditor.styles.ts"],"names":[],"mappings":";AAEA,wBA8MC"}
@@ -128,8 +128,63 @@ export default css `
128
128
  outline: none;
129
129
  }
130
130
 
131
+ .cm-tooltip-hover {
132
+ box-shadow: var(--md-sys-elevation-3);
133
+ }
134
+
135
+ .editor-container .cm-editor .cm-tooltip,
136
+ .cm-tooltip-lint,
137
+ .function-info {
138
+ background-color: var(--md-sys-color-surface-container-highest);
139
+ color: var(--md-sys-color-on-surface);
140
+ }
141
+
131
142
  .function-info {
132
143
  padding: 8px;
144
+
145
+ font-family: var(--md-sys-typescale-body-medium-font);
146
+ font-weight: var(--md-sys-typescale-body-medium-weight);
147
+ font-size: var(--md-sys-typescale-body-medium-size);
148
+ letter-spacing: var(--md-sys-typescale-body-medium-tracking);
149
+ line-height: var(--md-sys-typescale-body-medium-height);
150
+
151
+ h4 {
152
+ margin: 4px 0;
153
+ font-family: var(--md-sys-typescale-title-medium-font);
154
+ font-weight: var(--md-sys-typescale-title-medium-weight);
155
+ font-size: var(--md-sys-typescale-title-medium-size);
156
+ letter-spacing: var(--md-sys-typescale-title-medium-tracking);
157
+ line-height: var(--md-sys-typescale-title-medium-height);
158
+ }
159
+
160
+ p {
161
+ margin: 0;
162
+ }
163
+
164
+ .description {
165
+ font-family: var(--md-sys-typescale-body-large-font);
166
+ font-weight: var(--md-sys-typescale-body-large-weight);
167
+ font-size: var(--md-sys-typescale-body-large-size);
168
+ letter-spacing: var(--md-sys-typescale-body-large-tracking);
169
+ line-height: var(--md-sys-typescale-body-large-height);
170
+ }
171
+
172
+ ul {
173
+ margin: 0;
174
+ }
175
+
176
+ .param-name,
177
+ .param-type {
178
+ font-family: var(--md-sys-typescale-label-large-font);
179
+ font-weight: var(--md-sys-typescale-label-large-weight);
180
+ font-size: var(--md-sys-typescale-label-large-size);
181
+ letter-spacing: var(--md-sys-typescale-label-large-tracking);
182
+ line-height: var(--md-sys-typescale-label-large-height);
183
+ }
184
+
185
+ .param-description {
186
+ color: var(--md-sys-color-on-surface-variant);
187
+ }
133
188
  }
134
189
 
135
190
  /* Responsive */
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEditor.styles.js","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/CodeEditor.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuJjB,CAAA","sourcesContent":["import { css } from 'lit'\n\nexport default css`\n :host {\n display: flex;\n flex-direction: column;\n outline: none;\n min-width: 200px;\n background-color: transparent;\n color: var(--md-sys-color-on-surface);\n\n font-family: var(--md-sys-typescale-body-large-font);\n font-size: var(--md-sys-typescale-body-large-size);\n letter-spacing: var(--md-sys-typescale-body-large-tracking);\n line-height: var(--md-sys-typescale-body-large-height);\n }\n\n .surface {\n display: flex;\n flex-direction: column;\n }\n\n .content {\n display: flex;\n flex-direction: column;\n flex: 1;\n }\n\n .label {\n font-family: var(--md-sys-typescale-label-medium-font);\n font-weight: var(--md-sys-typescale-label-medium-weight);\n font-size: var(--md-sys-typescale-label-medium-size);\n letter-spacing: var(--md-sys-typescale-label-medium-tracking);\n line-height: var(--md-sys-typescale-label-medium-height);\n color: var(--md-sys-color-on-surface-variant);\n\n padding: 8px 16px 4px 16px;\n margin: 0;\n }\n\n .has-focus .label {\n color: var(--md-sys-color-primary);\n }\n\n .editor-container {\n position: relative;\n flex: 1;\n\n border-radius: var(--md-sys-shape-corner-extra-small);\n border: 1px solid var(--md-sys-color-outline);\n outline: 0px solid var(--md-sys-color-primary);\n outline-offset: -1px;\n transition:\n border-color 150ms cubic-bezier(0.4, 0, 0.2, 1),\n outline-width 150ms cubic-bezier(0.4, 0, 0.2, 1),\n outline-offset 150ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .editor-container:focus-within {\n border-color: var(--md-sys-color-primary);\n outline-width: 2px;\n outline-offset: -2px;\n }\n\n .supporting-text {\n margin-top: 4px;\n padding: 0 16px;\n color: var(--md-sys-color-on-surface-variant);\n font-family: var(--md-sys-typescale-body-small-font);\n font-weight: var(--md-sys-typescale-body-small-weight);\n font-size: var(--md-sys-typescale-body-small-size);\n letter-spacing: var(--md-sys-typescale-body-small-tracking);\n line-height: var(--md-sys-typescale-body-small-height);\n }\n\n :host([disabled]) {\n pointer-events: none;\n }\n\n :host([disabled]) .editor-container {\n border-color: var(--md-sys-color-on-surface);\n }\n\n :host([disabled]) .label,\n :host([disabled]) .editor-container {\n color: var(--md-sys-color-on-surface);\n opacity: 0.38;\n }\n\n :host([invalid]) .label,\n :host([invalid]) .supporting-text {\n color: var(--md-sys-color-error);\n }\n\n :host([invalid]) .editor-container {\n border-color: var(--md-sys-color-error);\n outline-color: var(--md-sys-color-error);\n }\n\n .mention-chip {\n display: inline-flex;\n align-items: center;\n margin: 0 2px;\n vertical-align: baseline;\n user-select: none;\n }\n\n .mention-chip ui-chip {\n margin: 0;\n font-size: inherit;\n line-height: inherit;\n }\n\n .cm-gutters {\n background: var(--md-sys-color-surface-variant);\n color: var(--md-sys-color-on-surface-variant);\n border: none;\n }\n\n .cm-focused .cm-cursor {\n border-left-color: var(--md-sys-color-primary);\n }\n\n ::selection {\n background: var(--md-sys-color-surface-variant);\n }\n\n .ͼ1.cm-focused {\n outline: none;\n }\n\n .function-info {\n padding: 8px;\n }\n\n /* Responsive */\n @media (max-width: 600px) {\n :host {\n min-width: 0;\n }\n\n .label {\n padding: 6px 6px 3px 6px;\n }\n\n .editor-container {\n padding: 6px;\n }\n\n .supporting-text {\n padding: 3px 6px 6px 6px;\n }\n }\n`\n"]}
1
+ {"version":3,"file":"CodeEditor.styles.js","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/CodeEditor.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8MjB,CAAA","sourcesContent":["import { css } from 'lit'\n\nexport default css`\n :host {\n display: flex;\n flex-direction: column;\n outline: none;\n min-width: 200px;\n background-color: transparent;\n color: var(--md-sys-color-on-surface);\n\n font-family: var(--md-sys-typescale-body-large-font);\n font-size: var(--md-sys-typescale-body-large-size);\n letter-spacing: var(--md-sys-typescale-body-large-tracking);\n line-height: var(--md-sys-typescale-body-large-height);\n }\n\n .surface {\n display: flex;\n flex-direction: column;\n }\n\n .content {\n display: flex;\n flex-direction: column;\n flex: 1;\n }\n\n .label {\n font-family: var(--md-sys-typescale-label-medium-font);\n font-weight: var(--md-sys-typescale-label-medium-weight);\n font-size: var(--md-sys-typescale-label-medium-size);\n letter-spacing: var(--md-sys-typescale-label-medium-tracking);\n line-height: var(--md-sys-typescale-label-medium-height);\n color: var(--md-sys-color-on-surface-variant);\n\n padding: 8px 16px 4px 16px;\n margin: 0;\n }\n\n .has-focus .label {\n color: var(--md-sys-color-primary);\n }\n\n .editor-container {\n position: relative;\n flex: 1;\n\n border-radius: var(--md-sys-shape-corner-extra-small);\n border: 1px solid var(--md-sys-color-outline);\n outline: 0px solid var(--md-sys-color-primary);\n outline-offset: -1px;\n transition:\n border-color 150ms cubic-bezier(0.4, 0, 0.2, 1),\n outline-width 150ms cubic-bezier(0.4, 0, 0.2, 1),\n outline-offset 150ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n .editor-container:focus-within {\n border-color: var(--md-sys-color-primary);\n outline-width: 2px;\n outline-offset: -2px;\n }\n\n .supporting-text {\n margin-top: 4px;\n padding: 0 16px;\n color: var(--md-sys-color-on-surface-variant);\n font-family: var(--md-sys-typescale-body-small-font);\n font-weight: var(--md-sys-typescale-body-small-weight);\n font-size: var(--md-sys-typescale-body-small-size);\n letter-spacing: var(--md-sys-typescale-body-small-tracking);\n line-height: var(--md-sys-typescale-body-small-height);\n }\n\n :host([disabled]) {\n pointer-events: none;\n }\n\n :host([disabled]) .editor-container {\n border-color: var(--md-sys-color-on-surface);\n }\n\n :host([disabled]) .label,\n :host([disabled]) .editor-container {\n color: var(--md-sys-color-on-surface);\n opacity: 0.38;\n }\n\n :host([invalid]) .label,\n :host([invalid]) .supporting-text {\n color: var(--md-sys-color-error);\n }\n\n :host([invalid]) .editor-container {\n border-color: var(--md-sys-color-error);\n outline-color: var(--md-sys-color-error);\n }\n\n .mention-chip {\n display: inline-flex;\n align-items: center;\n margin: 0 2px;\n vertical-align: baseline;\n user-select: none;\n }\n\n .mention-chip ui-chip {\n margin: 0;\n font-size: inherit;\n line-height: inherit;\n }\n\n .cm-gutters {\n background: var(--md-sys-color-surface-variant);\n color: var(--md-sys-color-on-surface-variant);\n border: none;\n }\n\n .cm-focused .cm-cursor {\n border-left-color: var(--md-sys-color-primary);\n }\n\n ::selection {\n background: var(--md-sys-color-surface-variant);\n }\n\n .ͼ1.cm-focused {\n outline: none;\n }\n\n .cm-tooltip-hover {\n box-shadow: var(--md-sys-elevation-3);\n }\n\n .editor-container .cm-editor .cm-tooltip,\n .cm-tooltip-lint,\n .function-info {\n background-color: var(--md-sys-color-surface-container-highest);\n color: var(--md-sys-color-on-surface);\n }\n\n .function-info {\n padding: 8px;\n\n font-family: var(--md-sys-typescale-body-medium-font);\n font-weight: var(--md-sys-typescale-body-medium-weight);\n font-size: var(--md-sys-typescale-body-medium-size);\n letter-spacing: var(--md-sys-typescale-body-medium-tracking);\n line-height: var(--md-sys-typescale-body-medium-height);\n\n h4 {\n margin: 4px 0;\n font-family: var(--md-sys-typescale-title-medium-font);\n font-weight: var(--md-sys-typescale-title-medium-weight);\n font-size: var(--md-sys-typescale-title-medium-size);\n letter-spacing: var(--md-sys-typescale-title-medium-tracking);\n line-height: var(--md-sys-typescale-title-medium-height);\n }\n\n p {\n margin: 0;\n }\n\n .description {\n font-family: var(--md-sys-typescale-body-large-font);\n font-weight: var(--md-sys-typescale-body-large-weight);\n font-size: var(--md-sys-typescale-body-large-size);\n letter-spacing: var(--md-sys-typescale-body-large-tracking);\n line-height: var(--md-sys-typescale-body-large-height);\n }\n\n ul {\n margin: 0;\n }\n\n .param-name,\n .param-type {\n font-family: var(--md-sys-typescale-label-large-font);\n font-weight: var(--md-sys-typescale-label-large-weight);\n font-size: var(--md-sys-typescale-label-large-size);\n letter-spacing: var(--md-sys-typescale-label-large-tracking);\n line-height: var(--md-sys-typescale-label-large-height);\n }\n\n .param-description {\n color: var(--md-sys-color-on-surface-variant);\n }\n }\n\n /* Responsive */\n @media (max-width: 600px) {\n :host {\n min-width: 0;\n }\n\n .label {\n padding: 6px 6px 3px 6px;\n }\n\n .editor-container {\n padding: 6px;\n }\n\n .supporting-text {\n padding: 3px 6px 6px 6px;\n }\n }\n`\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SuggestionMatchDecorator.d.ts","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/SuggestionMatchDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAc,MAAM,kBAAkB,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG5C;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,cAAc;;IASjD,WAAW,EAAE,UAAU,EAAE;IARlC;;;;;OAKG;gBAED,MAAM,EAAE,MAAM,EACP,WAAW,EAAE,UAAU,EAAE;CAmBnC"}
1
+ {"version":3,"file":"SuggestionMatchDecorator.d.ts","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/SuggestionMatchDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAc,MAAM,kBAAkB,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG5C;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,cAAc;;IASjD,WAAW,EAAE,UAAU,EAAE;IARlC;;;;;OAKG;gBAED,MAAM,EAAE,MAAM,EACP,WAAW,EAAE,UAAU,EAAE;CAkBnC"}
@@ -1,5 +1,5 @@
1
1
  import { MatchDecorator, Decoration } from '@codemirror/view';
2
- import { ChipWidget } from './PlaceholderWidget.js';
2
+ import { ChipWidget } from './ChipWidget.js';
3
3
  /**
4
4
  * A class that specializes in creating and managing decorations for suggestion matches in a code editor.
5
5
  */
@@ -19,10 +19,10 @@ export class SuggestionMatchDecorator extends MatchDecorator {
19
19
  this.suggestions = suggestions;
20
20
  }
21
21
  #decoration(match) {
22
- const label = match[1];
23
- const suggestion = this.suggestions.find((s) => s.label === label);
22
+ const id = match[1];
23
+ const suggestion = this.suggestions.find((s) => s.id === id);
24
24
  // If no suggestion is found, create a default one
25
- const suggestionData = suggestion || { id: label, label };
25
+ const suggestionData = suggestion || { id, label: id };
26
26
  return Decoration.replace({
27
27
  widget: new ChipWidget(suggestionData),
28
28
  });
@@ -1 +1 @@
1
- {"version":3,"file":"SuggestionMatchDecorator.js","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/SuggestionMatchDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAEnD;;GAEG;AACH,MAAM,OAAO,wBAAyB,SAAQ,cAAc;IASjD;IART;;;;;OAKG;IACH,YACE,MAAc,EACP,WAAyB;QAEhC,KAAK,CAAC;YACJ,MAAM;YACN,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;SAC/C,CAAC,CAAA;QALK,gBAAW,GAAX,WAAW,CAAc;IAMlC,CAAC;IAED,WAAW,CAAC,KAAsB;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACtB,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;QAElE,kDAAkD;QAClD,MAAM,cAAc,GAAe,UAAU,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;QAErE,OAAO,UAAU,CAAC,OAAO,CAAC;YACxB,MAAM,EAAE,IAAI,UAAU,CAAC,cAAc,CAAC;SACvC,CAAC,CAAA;IACJ,CAAC;CACF","sourcesContent":["import { MatchDecorator, Decoration } from '@codemirror/view'\nimport type { Suggestion } from './types.js'\nimport { ChipWidget } from './PlaceholderWidget.js'\n\n/**\n * A class that specializes in creating and managing decorations for suggestion matches in a code editor.\n */\nexport class SuggestionMatchDecorator extends MatchDecorator {\n /**\n * Creates a new instance of SuggestionMatchDecorator.\n * @param regexp - The regular expression used to match suggestions in the code.\n * @param suggestions - An array of suggestions that will be used to create decorations.\n * Each suggestion should have a unique `id` and a `label` that will be displayed in the editor.\n */\n constructor(\n regexp: RegExp,\n public suggestions: Suggestion[]\n ) {\n super({\n regexp,\n decoration: (match) => this.#decoration(match),\n })\n }\n\n #decoration(match: RegExpExecArray): Decoration {\n const label = match[1]\n const suggestion = this.suggestions.find((s) => s.label === label)\n\n // If no suggestion is found, create a default one\n const suggestionData: Suggestion = suggestion || { id: label, label }\n\n return Decoration.replace({\n widget: new ChipWidget(suggestionData),\n })\n }\n}\n"]}
1
+ {"version":3,"file":"SuggestionMatchDecorator.js","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/SuggestionMatchDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C;;GAEG;AACH,MAAM,OAAO,wBAAyB,SAAQ,cAAc;IASjD;IART;;;;;OAKG;IACH,YACE,MAAc,EACP,WAAyB;QAEhC,KAAK,CAAC;YACJ,MAAM;YACN,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;SAC/C,CAAC,CAAA;QALK,gBAAW,GAAX,WAAW,CAAc;IAMlC,CAAC;IAED,WAAW,CAAC,KAAsB;QAChC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACnB,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QAE5D,kDAAkD;QAClD,MAAM,cAAc,GAAe,UAAU,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QAClE,OAAO,UAAU,CAAC,OAAO,CAAC;YACxB,MAAM,EAAE,IAAI,UAAU,CAAC,cAAc,CAAC;SACvC,CAAC,CAAA;IACJ,CAAC;CACF","sourcesContent":["import { MatchDecorator, Decoration } from '@codemirror/view'\nimport type { Suggestion } from './types.js'\nimport { ChipWidget } from './ChipWidget.js'\n\n/**\n * A class that specializes in creating and managing decorations for suggestion matches in a code editor.\n */\nexport class SuggestionMatchDecorator extends MatchDecorator {\n /**\n * Creates a new instance of SuggestionMatchDecorator.\n * @param regexp - The regular expression used to match suggestions in the code.\n * @param suggestions - An array of suggestions that will be used to create decorations.\n * Each suggestion should have a unique `id` and a `label` that will be displayed in the editor.\n */\n constructor(\n regexp: RegExp,\n public suggestions: Suggestion[]\n ) {\n super({\n regexp,\n decoration: (match) => this.#decoration(match),\n })\n }\n\n #decoration(match: RegExpExecArray): Decoration {\n const id = match[1]\n const suggestion = this.suggestions.find((s) => s.id === id)\n\n // If no suggestion is found, create a default one\n const suggestionData: Suggestion = suggestion || { id, label: id }\n return Decoration.replace({\n widget: new ChipWidget(suggestionData),\n })\n }\n}\n"]}
@@ -8,6 +8,10 @@ import type {
8
8
  SuggestionInsertEvent,
9
9
  } from '../../../src/elements/code-editor/code-editor.js'
10
10
  import '../../../src/elements/code-editor/code-editor.js'
11
+ import { stringLibrarySchema } from '@pawel-up/jexl/schemas/string.schema.js'
12
+ import { arrayLibrarySchema } from '@pawel-up/jexl/schemas/array.schema.js'
13
+ import { dateLibrarySchema } from '@pawel-up/jexl/schemas/date.schema.js'
14
+ import { mathLibrarySchema } from '@pawel-up/jexl/schemas/math.schema.js'
11
15
 
12
16
  class CodeEditorDemo extends DemoPage {
13
17
  override accessor componentName = 'Code Editor'
@@ -18,75 +22,10 @@ class CodeEditorDemo extends DemoPage {
18
22
  @reactive()
19
23
  private accessor editorValue = [
20
24
  '// Start typing function names or {{ mentions }}',
21
- 'console.log("Hello, world!")',
22
25
  '',
23
- '// Try: getData, processData, or @John, @Jane',
24
- '// Example: Ask {{John}} about the API design',
25
- '// Example: {{Jane}} can review the implementation',
26
- '',
27
- '"Hello {{John}}! Can you help with the " + getData() + " function?"',
26
+ '"Hello {{John}}! Can you help with the " + upper() + " function?"',
28
27
  ].join('\n')
29
28
 
30
- private functionSchemas: FunctionSchema[] = [
31
- {
32
- name: 'getData',
33
- description: 'Fetches data from the server',
34
- parameters: [
35
- {
36
- name: 'url',
37
- schema: { type: 'string', description: 'The URL to fetch data from' },
38
- required: true,
39
- },
40
- {
41
- name: 'options',
42
- schema: { type: 'object', description: 'Fetch options' },
43
- required: false,
44
- },
45
- ],
46
- returns: {
47
- type: 'object',
48
- description: 'The fetched data as an object',
49
- },
50
- category: 'network',
51
- },
52
- {
53
- name: 'processData',
54
- description: 'Processes raw data into a usable format',
55
- parameters: [
56
- {
57
- name: 'data',
58
- schema: { description: 'Raw data to process' },
59
- required: true,
60
- },
61
- {
62
- name: 'transformer',
63
- schema: { description: 'Optional transformer function' },
64
- required: false,
65
- },
66
- ],
67
- returns: {},
68
- category: 'data',
69
- },
70
- {
71
- category: 'validation',
72
- name: 'validateInput',
73
- description: 'Validates user input against a schema',
74
- parameters: [
75
- {
76
- name: 'input',
77
- schema: { type: 'object', description: 'The input to validate' },
78
- required: true,
79
- },
80
- {
81
- name: 'schema',
82
- schema: { type: 'object', description: 'Validation schema' },
83
- required: true,
84
- },
85
- ],
86
- returns: { type: 'object', description: 'Validation result' },
87
- },
88
- ]
89
-
90
29
  private suggestions: Suggestion[] = [
91
30
  {
92
31
  id: 'user-john',
@@ -111,6 +50,42 @@ class CodeEditorDemo extends DemoPage {
111
50
  },
112
51
  ]
113
52
 
53
+ functions: FunctionSchema[] = []
54
+
55
+ constructor() {
56
+ super()
57
+
58
+ // Initialize function schemas
59
+ this.functions = this.createFunctionSchema()
60
+ }
61
+
62
+ /**
63
+ * Creates a schema for the code-editor functions.
64
+ * This method is responsible for defining the functions that can be used in the formula,
65
+ * given the current data type.
66
+ */
67
+ createFunctionSchema(): FunctionSchema[] {
68
+ const result: FunctionSchema[] = []
69
+
70
+ for (const func of Object.values(stringLibrarySchema.functions)) {
71
+ result.push(func)
72
+ }
73
+
74
+ for (const func of Object.values(arrayLibrarySchema.functions)) {
75
+ result.push(func)
76
+ }
77
+
78
+ for (const func of Object.values(dateLibrarySchema.functions)) {
79
+ result.push(func)
80
+ }
81
+
82
+ for (const func of Object.values(mathLibrarySchema.functions)) {
83
+ result.push(func)
84
+ }
85
+
86
+ return result
87
+ }
88
+
114
89
  private handleFunctionInsert(event: CustomEvent<FunctionInsertEvent>): void {
115
90
  const { functionSchema, position } = event.detail
116
91
  this.output = `Function inserted: ${functionSchema.name} at position ${position}`
@@ -126,6 +101,12 @@ class CodeEditorDemo extends DemoPage {
126
101
  this.editorValue = target.value
127
102
  }
128
103
 
104
+ private handleChange(event: Event): void {
105
+ const target = event.target as HTMLElement & { value: string }
106
+ this.output = `Editor content changed: ${target.value}`
107
+ console.log('Editor change:', target.value)
108
+ }
109
+
129
110
  contentTemplate() {
130
111
  return html`
131
112
  <a href="../">Back</a>
@@ -138,11 +119,12 @@ class CodeEditorDemo extends DemoPage {
138
119
  label="Code Editor"
139
120
  supporting-text="Type function names or {{fnName}} to see autocomplete"
140
121
  .value=${this.editorValue}
141
- .functionSchemas=${this.functionSchemas}
122
+ .functionSchemas=${this.functions}
142
123
  .suggestions=${this.suggestions}
143
124
  @function-insert=${this.handleFunctionInsert}
144
125
  @suggestion-insert=${this.handleSuggestionInsert}
145
126
  @input=${this.handleInput}
127
+ @change=${this.handleChange}
146
128
  ></code-editor>
147
129
 
148
130
  ${this.output ? html`<p><strong>Output:</strong> ${this.output}</p>` : ''}
@@ -156,7 +138,7 @@ class CodeEditorDemo extends DemoPage {
156
138
  label="Dark Theme Editor"
157
139
  supporting-text="Dark theme variant"
158
140
  .value=${'// Dark theme example\nconst theme = "dark"'}
159
- .functionSchemas=${this.functionSchemas}
141
+ .functionSchemas=${this.functions}
160
142
  .suggestions=${this.suggestions}
161
143
  dark-theme
162
144
  ></code-editor>
@@ -170,7 +152,7 @@ class CodeEditorDemo extends DemoPage {
170
152
  label="Disabled Editor"
171
153
  supporting-text="This editor is disabled"
172
154
  .value=${'// This editor is disabled\nconst readOnly = true'}
173
- .functionSchemas=${this.functionSchemas}
155
+ .functionSchemas=${this.functions}
174
156
  .suggestions=${this.suggestions}
175
157
  disabled
176
158
  ></code-editor>
@@ -184,23 +166,11 @@ class CodeEditorDemo extends DemoPage {
184
166
  label="Error Editor"
185
167
  supporting-text="This editor has an error"
186
168
  .value=${'// This editor has an error\nconst invalid = true'}
187
- .functionSchemas=${this.functionSchemas}
169
+ .functionSchemas=${this.functions}
188
170
  .suggestions=${this.suggestions}
189
171
  invalid
190
172
  ></code-editor>
191
173
  </section>
192
-
193
- <section class="demo-section">
194
- <h2 class="display-large">Function Schemas</h2>
195
- <p>Available function schemas for autocomplete:</p>
196
- <pre>${JSON.stringify(this.functionSchemas, null, 2)}</pre>
197
- </section>
198
-
199
- <section class="demo-section">
200
- <h2 class="display-large">Suggestions</h2>
201
- <p>Available suggestions (use @mention syntax):</p>
202
- <pre>${JSON.stringify(this.suggestions, null, 2)}</pre>
203
- </section>
204
174
  `
205
175
  }
206
176
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api-client/ui",
3
- "version": "0.5.14",
3
+ "version": "0.5.16",
4
4
  "description": "Internal UI component library for the API Client ecosystem.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "build/src/index.js",
@@ -33,7 +33,7 @@ export class ChipWidget extends WidgetType {
33
33
  const pos = view.posAtDOM(wrapper)
34
34
  if (pos === null) return
35
35
 
36
- const originalText = `{{${this.suggestion.label}}}`
36
+ const originalText = `{{${this.suggestion.id}}}`
37
37
  view.dispatch({
38
38
  changes: { from: pos, to: pos + originalText.length, insert: '' },
39
39
  })
@@ -129,8 +129,63 @@ export default css`
129
129
  outline: none;
130
130
  }
131
131
 
132
+ .cm-tooltip-hover {
133
+ box-shadow: var(--md-sys-elevation-3);
134
+ }
135
+
136
+ .editor-container .cm-editor .cm-tooltip,
137
+ .cm-tooltip-lint,
138
+ .function-info {
139
+ background-color: var(--md-sys-color-surface-container-highest);
140
+ color: var(--md-sys-color-on-surface);
141
+ }
142
+
132
143
  .function-info {
133
144
  padding: 8px;
145
+
146
+ font-family: var(--md-sys-typescale-body-medium-font);
147
+ font-weight: var(--md-sys-typescale-body-medium-weight);
148
+ font-size: var(--md-sys-typescale-body-medium-size);
149
+ letter-spacing: var(--md-sys-typescale-body-medium-tracking);
150
+ line-height: var(--md-sys-typescale-body-medium-height);
151
+
152
+ h4 {
153
+ margin: 4px 0;
154
+ font-family: var(--md-sys-typescale-title-medium-font);
155
+ font-weight: var(--md-sys-typescale-title-medium-weight);
156
+ font-size: var(--md-sys-typescale-title-medium-size);
157
+ letter-spacing: var(--md-sys-typescale-title-medium-tracking);
158
+ line-height: var(--md-sys-typescale-title-medium-height);
159
+ }
160
+
161
+ p {
162
+ margin: 0;
163
+ }
164
+
165
+ .description {
166
+ font-family: var(--md-sys-typescale-body-large-font);
167
+ font-weight: var(--md-sys-typescale-body-large-weight);
168
+ font-size: var(--md-sys-typescale-body-large-size);
169
+ letter-spacing: var(--md-sys-typescale-body-large-tracking);
170
+ line-height: var(--md-sys-typescale-body-large-height);
171
+ }
172
+
173
+ ul {
174
+ margin: 0;
175
+ }
176
+
177
+ .param-name,
178
+ .param-type {
179
+ font-family: var(--md-sys-typescale-label-large-font);
180
+ font-weight: var(--md-sys-typescale-label-large-weight);
181
+ font-size: var(--md-sys-typescale-label-large-size);
182
+ letter-spacing: var(--md-sys-typescale-label-large-tracking);
183
+ line-height: var(--md-sys-typescale-label-large-height);
184
+ }
185
+
186
+ .param-description {
187
+ color: var(--md-sys-color-on-surface-variant);
188
+ }
134
189
  }
135
190
 
136
191
  /* Responsive */
@@ -2,7 +2,7 @@ import { html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'
2
2
  import { property, query, state } from 'lit/decorators.js'
3
3
  import { classMap } from 'lit/directives/class-map.js'
4
4
  import { linter } from '@codemirror/lint'
5
- import { EditorState, Extension } from '@codemirror/state'
5
+ import { Compartment, EditorState, Extension } from '@codemirror/state'
6
6
  import {
7
7
  autocompletion,
8
8
  CompletionContext,
@@ -97,11 +97,27 @@ export default class CodeEditor extends LitElement {
97
97
  @property({ type: String })
98
98
  accessor placeholder = ''
99
99
 
100
+ /**
101
+ * This property is used internally to set value without triggering updates.
102
+ */
103
+ #value = ''
104
+
100
105
  /**
101
106
  * The editor content value
102
107
  */
108
+ get value(): string {
109
+ return this.#value
110
+ }
111
+
103
112
  @property({ type: String })
104
- accessor value = ''
113
+ set value(newValue: string) {
114
+ const oldValue = this.#value
115
+ if (newValue !== oldValue) {
116
+ this.#value = newValue
117
+ this._previousValue = newValue
118
+ this.requestUpdate('value', oldValue)
119
+ }
120
+ }
105
121
 
106
122
  /**
107
123
  * Available function schemas for autocomplete
@@ -137,6 +153,10 @@ export default class CodeEditor extends LitElement {
137
153
  private accessor isEditorFocus = false
138
154
 
139
155
  private editorView?: EditorView
156
+ /**
157
+ * A control value to track previous value of the editor.
158
+ * This is used to detect when change event should be dispatched.
159
+ */
140
160
  private _previousValue = ''
141
161
  /**
142
162
  * Matcher for suggestion placeholders in the editor.
@@ -148,12 +168,12 @@ export default class CodeEditor extends LitElement {
148
168
  */
149
169
  get activeSuggestions(): Suggestion[] {
150
170
  const suggestions: Suggestion[] = []
151
- const placeholderPattern = /\{\{(\w+)\}\}/g
171
+ const placeholderPattern = /\{\{([^}]+)\}\}/g
152
172
  let match: RegExpExecArray | null
153
173
  while ((match = placeholderPattern.exec(this.value)) !== null) {
154
174
  const placeholderText = match[1]
155
- // Find suggestion by label
156
- const suggestion = this.suggestions.find((s) => s.label.toLowerCase() === placeholderText.toLowerCase())
175
+ // Find suggestion by id
176
+ const suggestion = this.suggestions.find((s) => s.id === placeholderText)
157
177
  if (suggestion) {
158
178
  suggestions.push(suggestion)
159
179
  }
@@ -161,6 +181,8 @@ export default class CodeEditor extends LitElement {
161
181
  return suggestions
162
182
  }
163
183
 
184
+ private readonlyState = new Compartment()
185
+
164
186
  override disconnectedCallback(): void {
165
187
  super.disconnectedCallback()
166
188
  this.editorView?.destroy()
@@ -185,7 +207,9 @@ export default class CodeEditor extends LitElement {
185
207
  }
186
208
 
187
209
  if (changedProperties.has('disabled')) {
188
- this.updateEditorState()
210
+ this.editorView?.dispatch({
211
+ effects: this.readonlyState.reconfigure(EditorState.readOnly.of(this.disabled)),
212
+ })
189
213
  }
190
214
  }
191
215
 
@@ -212,6 +236,7 @@ export default class CodeEditor extends LitElement {
212
236
  this.createPlaceholderPlugin(),
213
237
  hoverTooltip(this.createHoverTooltipSource),
214
238
  linter((view) => functionLinter(view, this.functionSchemas, (e) => this.dispatchEvent(e))),
239
+ this.readonlyState.of(EditorState.readOnly.of(this.disabled)),
215
240
  ]
216
241
 
217
242
  // Add language support
@@ -249,7 +274,7 @@ export default class CodeEditor extends LitElement {
249
274
  * This is created as a method to get access to the component's `suggestions`.
250
275
  */
251
276
  private createPlaceholderPlugin(): Extension {
252
- const placeholderMatcher = new SuggestionMatchDecorator(/\{\{(\w+)\}\}/g, this.suggestions)
277
+ const placeholderMatcher = new SuggestionMatchDecorator(/\{\{([^}]+)\}\}/g, this.suggestions)
253
278
  this.placeholderMatcher = placeholderMatcher
254
279
  // This class needs to be defined here to have access to the `placeholderMatcher`
255
280
  class AtomicDecorationRange {
@@ -294,7 +319,7 @@ export default class CodeEditor extends LitElement {
294
319
  }
295
320
 
296
321
  // Check if we're typing a suggestion trigger (e.g., {{)
297
- const suggestionMatch = textBefore.match(/\{\{(\w*)$/)
322
+ const suggestionMatch = textBefore.match(/\{\{([^}]*)$/)
298
323
  if (suggestionMatch) {
299
324
  const prefix = suggestionMatch[1]
300
325
  const suggestions = this.suggestions
@@ -317,6 +342,7 @@ export default class CodeEditor extends LitElement {
317
342
  const result: Completion = {
318
343
  label: schema.name,
319
344
  detail: schema.description || '',
345
+ type: 'function',
320
346
  info: () => this.createFunctionInfoElement(schema),
321
347
  apply: (view: EditorView, completion: unknown, from: number, to: number) => {
322
348
  const functionCall = this.formatFunctionCall(schema)
@@ -336,8 +362,9 @@ export default class CodeEditor extends LitElement {
336
362
  label: suggestion.label,
337
363
  detail: suggestion.description || '',
338
364
  info: suggestion.suffix || '',
365
+ type: 'variable',
339
366
  apply: (view: EditorView, completion: unknown, from: number, to: number) => {
340
- const placeholderText = `{{${suggestion.label}}}`
367
+ const placeholderText = `{{${suggestion.id}}}`
341
368
  view.dispatch({
342
369
  changes: { from: from - 2, to, insert: placeholderText }, // -2 to include the {{
343
370
  selection: { anchor: from - 2 + placeholderText.length },
@@ -480,21 +507,6 @@ export default class CodeEditor extends LitElement {
480
507
  }
481
508
  }
482
509
 
483
- /**
484
- * Update editor state (e.g., disabled state)
485
- */
486
- private updateEditorState(): void {
487
- if (!this.editorView) return
488
-
489
- // For now, we'll handle disabled state differently
490
- // CodeMirror 6 doesn't use reconfigure for editable
491
- if (this.disabled) {
492
- this.editorView.contentDOM.setAttribute('contenteditable', 'false')
493
- } else {
494
- this.editorView.contentDOM.setAttribute('contenteditable', 'true')
495
- }
496
- }
497
-
498
510
  /**
499
511
  * Handle editor content change
500
512
  */
@@ -502,13 +514,10 @@ export default class CodeEditor extends LitElement {
502
514
  if (!this.editorView) return
503
515
 
504
516
  const newValue = this.editorView.state.doc.toString()
505
- if (newValue !== this._previousValue) {
506
- this._previousValue = newValue
507
- this.value = newValue
508
- this.hasContent = newValue.length > 0
517
+ this.#value = newValue
518
+ this.hasContent = newValue.length > 0
509
519
 
510
- this.dispatchEvent(new Event('input', { bubbles: true }))
511
- }
520
+ this.dispatchEvent(new Event('input', { bubbles: true }))
512
521
  }
513
522
 
514
523
  /**
@@ -517,8 +526,9 @@ export default class CodeEditor extends LitElement {
517
526
  private handleFocusChange(hasFocus: boolean): void {
518
527
  this.isEditorFocus = hasFocus
519
528
 
520
- if (!hasFocus && this.value !== this._previousValue) {
521
- this.dispatchEvent(new Event('change', { bubbles: true }))
529
+ if (!hasFocus && this.#value !== this._previousValue) {
530
+ this._previousValue = this.#value
531
+ this.dispatchEvent(new Event('change'))
522
532
  }
523
533
  }
524
534
 
@@ -1,6 +1,6 @@
1
1
  import { MatchDecorator, Decoration } from '@codemirror/view'
2
2
  import type { Suggestion } from './types.js'
3
- import { ChipWidget } from './PlaceholderWidget.js'
3
+ import { ChipWidget } from './ChipWidget.js'
4
4
 
5
5
  /**
6
6
  * A class that specializes in creating and managing decorations for suggestion matches in a code editor.
@@ -23,12 +23,11 @@ export class SuggestionMatchDecorator extends MatchDecorator {
23
23
  }
24
24
 
25
25
  #decoration(match: RegExpExecArray): Decoration {
26
- const label = match[1]
27
- const suggestion = this.suggestions.find((s) => s.label === label)
26
+ const id = match[1]
27
+ const suggestion = this.suggestions.find((s) => s.id === id)
28
28
 
29
29
  // If no suggestion is found, create a default one
30
- const suggestionData: Suggestion = suggestion || { id: label, label }
31
-
30
+ const suggestionData: Suggestion = suggestion || { id, label: id }
32
31
  return Decoration.replace({
33
32
  widget: new ChipWidget(suggestionData),
34
33
  })
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlaceholderWidget.d.ts","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/PlaceholderWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,6BAA6B,CAAA;AAEpC;;;;;;;;GAQG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACrB,UAAU,EAAE,UAAU;gBAAtB,UAAU,EAAE,UAAU;IAIhC,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAIvC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW;IAwB3B,WAAW,IAAI,OAAO;CAGhC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlaceholderWidget.js","sourceRoot":"","sources":["../../../../../src/elements/code-editor/internals/PlaceholderWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAEzD,OAAO,6BAA6B,CAAA;AAEpC;;;;;;;;GAQG;AACH,MAAM,OAAO,UAAW,SAAQ,UAAU;IACrB;IAAnB,YAAmB,UAAsB;QACvC,KAAK,EAAE,CAAA;QADU,eAAU,GAAV,UAAU,CAAY;IAEzC,CAAC;IAEQ,EAAE,CAAC,KAAiB;QAC3B,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,IAAK,KAAoB,CAAC,UAAU,CAAC,EAAE,CAAA;IAClE,CAAC;IAED,KAAK,CAAC,IAAgB;QACpB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;QAC9C,OAAO,CAAC,SAAS,GAAG,cAAc,CAAA;QAClC,OAAO,CAAC,YAAY,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QAE3D,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;QAC9C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAClC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAA;QACxC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;YAClC,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAM;YAExB,MAAM,YAAY,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAA;YACnD,IAAI,CAAC,QAAQ,CAAC;gBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;aAClE,CAAC,CAAA;YACF,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC,CAAC,CAAA;QAEF,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QACzB,OAAO,OAAO,CAAA;IAChB,CAAC;IAEQ,WAAW;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;CACF","sourcesContent":["import { EditorView, WidgetType } from '@codemirror/view'\nimport type { Suggestion } from './types.js'\nimport '../../../md/chip/ui-chip.js'\n\n/**\n * A widget that represents a placeholder in the code editor,\n * specifically for suggestions that are replaced with chips.\n *\n * This widget is used to create a visual representation of a suggestion\n * in the code editor, allowing users to see and interact with suggestions\n * as chips. When a chip is removed, the corresponding text in the editor\n * is also removed.\n */\nexport class ChipWidget extends WidgetType {\n constructor(public suggestion: Suggestion) {\n super()\n }\n\n override eq(other: WidgetType): boolean {\n return this.suggestion.id == (other as ChipWidget).suggestion.id\n }\n\n toDOM(view: EditorView): HTMLElement {\n const wrapper = document.createElement('span')\n wrapper.className = 'mention-chip'\n wrapper.setAttribute('data-mention-id', this.suggestion.id)\n\n const chip = document.createElement('ui-chip')\n chip.setAttribute('type', 'input')\n chip.setAttribute('removable', 'true')\n chip.textContent = this.suggestion.label\n chip.addEventListener('remove', () => {\n const pos = view.posAtDOM(wrapper)\n if (pos === null) return\n\n const originalText = `{{${this.suggestion.label}}}`\n view.dispatch({\n changes: { from: pos, to: pos + originalText.length, insert: '' },\n })\n view.focus()\n })\n\n wrapper.appendChild(chip)\n return wrapper\n }\n\n override ignoreEvent(): boolean {\n return false\n }\n}\n"]}