symbols-app-connect 3.2.8

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.
@@ -0,0 +1,2814 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/extension.ts
31
+ var extension_exports = {};
32
+ __export(extension_exports, {
33
+ activate: () => activate,
34
+ deactivate: () => deactivate
35
+ });
36
+ module.exports = __toCommonJS(extension_exports);
37
+ var vscode5 = __toESM(require("vscode"));
38
+
39
+ // src/providers/completionProvider.ts
40
+ var vscode2 = __toESM(require("vscode"));
41
+
42
+ // src/data/domqlKeys.ts
43
+ var DOMQL_REGISTRY_KEYS = [
44
+ {
45
+ label: "extends",
46
+ detail: "extends: string | object | array",
47
+ documentation: 'Extend from one or more registered components. String references a component by name from context.components. Array allows multiple extends (first = highest priority).\n\n```js\nextends: "Button"\nextends: ["IconText", "Focusable"]\nextends: ButtonBase\n```',
48
+ snippet: "extends: '${1:ComponentName}'",
49
+ kind: "property"
50
+ },
51
+ {
52
+ label: "tag",
53
+ detail: "tag: string",
54
+ documentation: 'HTML tag name for the element node. Defaults to `div`.\n\n```js\ntag: "section"\ntag: "button"\ntag: "a"\n```',
55
+ snippet: "tag: '${1:div}'",
56
+ kind: "property"
57
+ },
58
+ {
59
+ label: "text",
60
+ detail: "text: string | function",
61
+ documentation: 'Text content of the element. Can be a static string or a function returning a string.\n\n```js\ntext: "Hello world"\ntext: ({ props }) => props.label\ntext: ({ state }) => `Count: ${state.count}`\n```',
62
+ snippet: "text: '${1:}'",
63
+ kind: "property"
64
+ },
65
+ {
66
+ label: "html",
67
+ detail: "html: string | function",
68
+ documentation: 'Raw HTML content. Sets innerHTML. Use sparingly \u2014 XSS risk with user data.\n\n```js\nhtml: ({ props }) => props.richContent\nhtml: "<strong>Bold</strong>"\n```',
69
+ snippet: "html: ${1:},",
70
+ kind: "property"
71
+ },
72
+ {
73
+ label: "attr",
74
+ detail: "attr: object",
75
+ documentation: 'HTML attributes to set on the DOM node. Values can be static or functions. Returning `null` removes the attribute.\n\n```js\nattr: {\n placeholder: ({ props }) => props.placeholder,\n disabled: ({ props }) => props.disabled || null,\n role: "button",\n "aria-label": ({ props }) => props.label\n}\n```',
76
+ snippet: "attr: {\n ${1:placeholder}: ${2:},\n},",
77
+ kind: "property"
78
+ },
79
+ {
80
+ label: "state",
81
+ detail: "state: object | string",
82
+ documentation: 'Local reactive state for the element. Use `state.update()` to update and trigger re-renders. String value inherits from ancestor state.\n\n```js\nstate: { open: false, count: 0, data: null }\nstate: "~/user" // inherit from root state key\n```',
83
+ snippet: "state: { ${1:key}: ${2:value} },",
84
+ kind: "property"
85
+ },
86
+ {
87
+ label: "if",
88
+ detail: "if: function | boolean",
89
+ documentation: "Conditional rendering. Element only renders when this returns truthy.\n\n```js\nif: ({ state }) => state.isVisible\nif: ({ props }) => Boolean(props.show)\nif: (el, state) => state.isAuthenticated\n```",
90
+ snippet: "if: ({ ${1:state} }) => ${2:condition},",
91
+ kind: "property"
92
+ },
93
+ {
94
+ label: "define",
95
+ detail: "define: object",
96
+ documentation: 'Register custom property transformers. When a matching key appears on an element, this handler runs.\n\n```js\ndefine: {\n isActive: (param, el, state) => {\n if (param) el.node.classList.add("active")\n else el.node.classList.remove("active")\n }\n}\n```',
97
+ snippet: "define: {\n ${1:propName}: (param, el, state) => {\n ${2:}\n }\n},",
98
+ kind: "property"
99
+ },
100
+ {
101
+ label: "style",
102
+ detail: "style: object",
103
+ documentation: 'Inline styles or emotion CSS-in-JS with nested selectors. Escape hatch for complex selectors.\n\n```js\nstyle: {\n "&:hover [dropdown]": {\n opacity: 1,\n transform: "translate3d(0,0,0)"\n }\n}\n```',
104
+ snippet: "style: {\n ${1:property}: ${2:value},\n},",
105
+ kind: "property"
106
+ },
107
+ {
108
+ label: "data",
109
+ detail: "data: object",
110
+ documentation: "Non-reactive data store. Store mutable references (chart instances, timers) that should NOT trigger re-renders.\n\n```js\ndata: {\n chartInstance: null,\n timer: null\n}\n```",
111
+ snippet: "data: {\n ${1:key}: ${2:null},\n},",
112
+ kind: "property"
113
+ },
114
+ {
115
+ label: "scope",
116
+ detail: "scope: string | object",
117
+ documentation: 'Assigns a scope reference. `"state"` makes `element.scope = element.state`. `"props"` makes `element.scope = element.props`.\n\n```js\nscope: "state"\nscope: "props"\nscope: { theme: "dark" }\n```',
118
+ snippet: "scope: '${1:state}',",
119
+ kind: "property"
120
+ },
121
+ {
122
+ label: "on",
123
+ detail: "on: object (v2 compat)",
124
+ documentation: "**v2 style \u2014 prefer top-level `onX` in v3.** Event handlers object.\n\n```js\n// v2\non: { click: fn, render: fn }\n\n// v3 preferred\nonClick: fn\nonRender: fn\n```",
125
+ snippet: "on: {\n ${1:event}: (event, el, state) => {\n ${2:}\n }\n},",
126
+ kind: "property"
127
+ },
128
+ {
129
+ label: "props",
130
+ detail: "props: object",
131
+ documentation: 'Explicit props object. In v3, props are flattened at element root. Use `props:` only for passing props when instantiating a component.\n\n```js\n// Passing props to an instance\nButton: {\n props: { text: "Submit", disabled: false }\n}\n```',
132
+ snippet: "props: {\n ${1:key}: ${2:value},\n},",
133
+ kind: "property"
134
+ },
135
+ {
136
+ label: "childProps",
137
+ detail: "childProps: object",
138
+ documentation: 'Props applied to all direct child elements.\n\n```js\nchildProps: { padding: "A", theme: "field" }\n```',
139
+ snippet: "childProps: {\n ${1:key}: ${2:value},\n},",
140
+ kind: "property"
141
+ },
142
+ {
143
+ label: "childrenAs",
144
+ detail: "childrenAs: string",
145
+ documentation: 'Rename the `children` key to a custom name for semantic clarity.\n\n```js\nchildrenAs: "items"\nchildrenAs: "slides"\n```',
146
+ snippet: "childrenAs: '${1:items}',",
147
+ kind: "property"
148
+ },
149
+ {
150
+ label: "children",
151
+ detail: "children: array | function",
152
+ documentation: 'Dynamic child list. Each item becomes a child element using `childExtends` as template.\n\n```js\nchildren: ({ props }) => props.items\nchildren: [{ text: "Item 1" }, { text: "Item 2" }]\n```',
153
+ snippet: "children: ${1:[]},",
154
+ kind: "property"
155
+ },
156
+ {
157
+ label: "childExtends",
158
+ detail: "childExtends: string | object | array",
159
+ documentation: 'Apply an extend to all direct child elements. Accepts string, object, or array of extends.\n\n```js\nchildExtends: "Button"\nchildExtends: ["IconText", "Focusable"]\nchildExtends: { padding: "Z2 C", round: "0" }\n```',
160
+ snippet: "childExtends: '${1:ComponentName}',",
161
+ kind: "property"
162
+ },
163
+ {
164
+ label: "childExtendsRecursive",
165
+ detail: "childExtendsRecursive: string | object | array",
166
+ documentation: 'Apply an extend to ALL descendants recursively. Accepts string, object, or array of extends.\n\n```js\nchildExtendsRecursive: "Button"\nchildExtendsRecursive: { fontSize: "A" }\n```',
167
+ snippet: "childExtendsRecursive: '${1:ComponentName}',",
168
+ kind: "property"
169
+ },
170
+ {
171
+ label: "content",
172
+ detail: "content: function | object",
173
+ documentation: "Single dynamic child element. Rendered as the element's sole child.\n\n```js\ncontent: ({ props }) => props.page\ncontent: ({ state }) => state.currentView\n```",
174
+ snippet: "content: ({ ${1:props} }) => ${2:},",
175
+ kind: "property"
176
+ },
177
+ {
178
+ label: "classlist",
179
+ detail: "classlist: object | array",
180
+ documentation: "CSS class management object. Keys are class names, values are booleans.\n\n```js\nclasslist: { active: true, hidden: false }\n```",
181
+ snippet: "classlist: { ${1:className}: ${2:true} },",
182
+ kind: "property"
183
+ },
184
+ {
185
+ label: "variables",
186
+ detail: "variables: object",
187
+ documentation: 'CSS custom properties (design tokens) scoped to this element.\n\n```js\nvariables: { color: "blue", spacing: "16px" }\n```',
188
+ snippet: "variables: { ${1:name}: ${2:value} },",
189
+ kind: "property"
190
+ },
191
+ {
192
+ label: "theme",
193
+ detail: "theme: string",
194
+ documentation: 'Apply a design system theme token to this element.\n\n```js\ntheme: "dialog"\ntheme: "field"\ntheme: "primary"\ntheme: "quaternary .child"\n```',
195
+ snippet: "theme: '${1:dialog}',",
196
+ kind: "property"
197
+ },
198
+ {
199
+ label: "deps",
200
+ detail: "deps: object",
201
+ documentation: "Dependencies injection for the element.",
202
+ snippet: "deps: { ${1:} },",
203
+ kind: "property"
204
+ },
205
+ {
206
+ label: "key",
207
+ detail: "key: string",
208
+ documentation: "Explicit element key (overrides the object property name as key).",
209
+ snippet: "key: '${1:}',",
210
+ kind: "property"
211
+ },
212
+ {
213
+ label: "query",
214
+ detail: "query: string",
215
+ documentation: "CSS query selector for targeting DOM elements.",
216
+ snippet: "query: '${1:}',",
217
+ kind: "property"
218
+ }
219
+ ];
220
+ var DOMQL_PSEUDO_SELECTORS = [
221
+ {
222
+ label: ":hover",
223
+ detail: ":hover: object",
224
+ documentation: 'Styles applied on hover.\n\n```js\n":hover": { opacity: 0.9, transform: "scale(1.015)" }\n```',
225
+ snippet: "':hover': { ${1:opacity}: ${2:0.9} },",
226
+ kind: "property"
227
+ },
228
+ {
229
+ label: ":active",
230
+ detail: ":active: object",
231
+ documentation: 'Styles applied when active/pressed.\n\n```js\n":active": { opacity: 1 }\n```',
232
+ snippet: "':active': { ${1:opacity}: ${2:1} },",
233
+ kind: "property"
234
+ },
235
+ {
236
+ label: ":focus",
237
+ detail: ":focus: object",
238
+ documentation: "Styles applied when focused.",
239
+ snippet: "':focus': { ${1:outline}: ${2:'none'} },",
240
+ kind: "property"
241
+ },
242
+ {
243
+ label: ":focus-visible",
244
+ detail: ":focus-visible: object",
245
+ documentation: "Styles applied when focused via keyboard.",
246
+ snippet: "':focus-visible': { ${1:outline}: ${2:'solid, X, blue .3'} },",
247
+ kind: "property"
248
+ },
249
+ {
250
+ label: ":disabled",
251
+ detail: ":disabled: object",
252
+ documentation: "Styles applied when disabled.",
253
+ snippet: "':disabled': { ${1:opacity}: ${2:0.5} },",
254
+ kind: "property"
255
+ },
256
+ {
257
+ label: ":not(:first-child)",
258
+ detail: ":not(:first-child): object",
259
+ documentation: "Styles for all children except the first.",
260
+ snippet: "':not(:first-child)': { ${1:borderTop}: ${2:'solid, 1px, currentColor'} },",
261
+ kind: "property"
262
+ },
263
+ {
264
+ label: ":first-child",
265
+ detail: ":first-child: object",
266
+ documentation: "Styles for the first child element.",
267
+ snippet: "':first-child': { ${1:} },",
268
+ kind: "property"
269
+ },
270
+ {
271
+ label: ":last-child",
272
+ detail: ":last-child: object",
273
+ documentation: "Styles for the last child element.",
274
+ snippet: "':last-child': { ${1:} },",
275
+ kind: "property"
276
+ },
277
+ {
278
+ label: ":before",
279
+ detail: ":before: object",
280
+ documentation: 'CSS ::before pseudo-element styles.\n\n```js\n":before": { content: "\'\'", display: "block" }\n```',
281
+ snippet: "':before': { ${1:content}: ${2:'\\'\\''} },",
282
+ kind: "property"
283
+ },
284
+ {
285
+ label: ":after",
286
+ detail: ":after: object",
287
+ documentation: "CSS ::after pseudo-element styles.",
288
+ snippet: "':after': { ${1:content}: ${2:'\\'\\''} },",
289
+ kind: "property"
290
+ }
291
+ ];
292
+ var DOMQL_MEDIA_QUERIES = [
293
+ {
294
+ label: "@dark",
295
+ detail: "@dark: object",
296
+ documentation: 'Styles applied in dark color scheme.\n\n```js\n"@dark": { background: "gray1", color: "gray12" }\n```',
297
+ snippet: "'@dark': { ${1:} },",
298
+ kind: "property"
299
+ },
300
+ {
301
+ label: "@light",
302
+ detail: "@light: object",
303
+ documentation: "Styles applied in light color scheme.",
304
+ snippet: "'@light': { ${1:} },",
305
+ kind: "property"
306
+ },
307
+ {
308
+ label: "@mobile",
309
+ detail: "@mobile: object",
310
+ documentation: "Styles applied on mobile breakpoint.",
311
+ snippet: "'@mobile': { ${1:} },",
312
+ kind: "property"
313
+ },
314
+ {
315
+ label: "@tablet",
316
+ detail: "@tablet: object",
317
+ documentation: "Styles applied on tablet breakpoint.",
318
+ snippet: "'@tablet': { ${1:} },",
319
+ kind: "property"
320
+ },
321
+ {
322
+ label: "@desktop",
323
+ detail: "@desktop: object",
324
+ documentation: "Styles applied on desktop breakpoint.",
325
+ snippet: "'@desktop': { ${1:} },",
326
+ kind: "property"
327
+ }
328
+ ];
329
+ var DOMQL_ALL_KEYS = [...DOMQL_REGISTRY_KEYS, ...DOMQL_PSEUDO_SELECTORS, ...DOMQL_MEDIA_QUERIES];
330
+
331
+ // src/data/events.ts
332
+ var DOM_EVENTS = [
333
+ {
334
+ label: "onClick",
335
+ detail: "onClick: (event, el, state) => void",
336
+ documentation: "Mouse click event handler.\n\n```js\nonClick: (event, el, state) => {\n event.preventDefault()\n state.update({ active: true })\n}\n```",
337
+ snippet: "onClick: (event, el, state) => {\n ${1:}\n},",
338
+ isDomqlLifecycle: false
339
+ },
340
+ {
341
+ label: "onDblclick",
342
+ detail: "onDblclick: (event, el, state) => void",
343
+ documentation: "Double-click event handler.",
344
+ snippet: "onDblclick: (event, el, state) => {\n ${1:}\n},",
345
+ isDomqlLifecycle: false
346
+ },
347
+ {
348
+ label: "onChange",
349
+ detail: "onChange: (event, el, state) => void",
350
+ documentation: "Input change event handler. Fires when value commits (on blur for text inputs, immediately for checkboxes/selects).\n\n```js\nonChange: (event, el, state) => {\n state.update({ value: event.target.value })\n}\n```",
351
+ snippet: "onChange: (event, el, state) => {\n state.update({ ${1:value}: event.target.value })\n},",
352
+ isDomqlLifecycle: false
353
+ },
354
+ {
355
+ label: "onInput",
356
+ detail: "onInput: (event, el, state) => void",
357
+ documentation: "Input event handler. Fires on every keystroke.\n\n```js\nonInput: (event, el, state) => {\n state.update({ value: event.target.value })\n}\n```",
358
+ snippet: "onInput: (event, el, state) => {\n state.update({ ${1:value}: event.target.value })\n},",
359
+ isDomqlLifecycle: false
360
+ },
361
+ {
362
+ label: "onSubmit",
363
+ detail: "onSubmit: (event, el, state) => void",
364
+ documentation: 'Form submit event handler.\n\n```js\nonSubmit: (event, el, state) => {\n event.preventDefault()\n el.call("submitForm", state)\n}\n```',
365
+ snippet: "onSubmit: (event, el, state) => {\n event.preventDefault()\n ${1:}\n},",
366
+ isDomqlLifecycle: false
367
+ },
368
+ {
369
+ label: "onKeydown",
370
+ detail: "onKeydown: (event, el, state) => void",
371
+ documentation: 'Keydown event handler.\n\n```js\nonKeydown: (event, el, state) => {\n if (event.key === "Enter") el.call("submit")\n if (event.key === "Escape") state.update({ open: false })\n}\n```',
372
+ snippet: 'onKeydown: (event, el, state) => {\n if (event.key === "${1:Enter}") ${2:}\n},',
373
+ isDomqlLifecycle: false
374
+ },
375
+ {
376
+ label: "onKeyup",
377
+ detail: "onKeyup: (event, el, state) => void",
378
+ documentation: "Keyup event handler.",
379
+ snippet: "onKeyup: (event, el, state) => {\n ${1:}\n},",
380
+ isDomqlLifecycle: false
381
+ },
382
+ {
383
+ label: "onKeypress",
384
+ detail: "onKeypress: (event, el, state) => void",
385
+ documentation: "Keypress event handler (deprecated, prefer onKeydown).",
386
+ snippet: "onKeypress: (event, el, state) => {\n ${1:}\n},",
387
+ isDomqlLifecycle: false
388
+ },
389
+ {
390
+ label: "onFocus",
391
+ detail: "onFocus: (event, el, state) => void",
392
+ documentation: "Focus event handler.",
393
+ snippet: "onFocus: (event, el, state) => {\n ${1:}\n},",
394
+ isDomqlLifecycle: false
395
+ },
396
+ {
397
+ label: "onBlur",
398
+ detail: "onBlur: (event, el, state) => void",
399
+ documentation: "Blur (focus lost) event handler.",
400
+ snippet: "onBlur: (event, el, state) => {\n ${1:}\n},",
401
+ isDomqlLifecycle: false
402
+ },
403
+ {
404
+ label: "onFocusin",
405
+ detail: "onFocusin: (event, el, state) => void",
406
+ documentation: "Focusin event (bubbles, unlike focus).",
407
+ snippet: "onFocusin: (event, el, state) => {\n ${1:}\n},",
408
+ isDomqlLifecycle: false
409
+ },
410
+ {
411
+ label: "onFocusout",
412
+ detail: "onFocusout: (event, el, state) => void",
413
+ documentation: "Focusout event (bubbles, unlike blur).",
414
+ snippet: "onFocusout: (event, el, state) => {\n ${1:}\n},",
415
+ isDomqlLifecycle: false
416
+ },
417
+ {
418
+ label: "onMouseover",
419
+ detail: "onMouseover: (event, el, state) => void",
420
+ documentation: "Mouseover event handler (fires on children too).",
421
+ snippet: "onMouseover: (event, el, state) => {\n ${1:}\n},",
422
+ isDomqlLifecycle: false
423
+ },
424
+ {
425
+ label: "onMouseout",
426
+ detail: "onMouseout: (event, el, state) => void",
427
+ documentation: "Mouseout event handler.",
428
+ snippet: "onMouseout: (event, el, state) => {\n ${1:}\n},",
429
+ isDomqlLifecycle: false
430
+ },
431
+ {
432
+ label: "onMouseenter",
433
+ detail: "onMouseenter: (event, el, state) => void",
434
+ documentation: "Mouseenter event (does not bubble).",
435
+ snippet: "onMouseenter: (event, el, state) => {\n ${1:}\n},",
436
+ isDomqlLifecycle: false
437
+ },
438
+ {
439
+ label: "onMouseleave",
440
+ detail: "onMouseleave: (event, el, state) => void",
441
+ documentation: "Mouseleave event (does not bubble).",
442
+ snippet: "onMouseleave: (event, el, state) => {\n ${1:}\n},",
443
+ isDomqlLifecycle: false
444
+ },
445
+ {
446
+ label: "onMousedown",
447
+ detail: "onMousedown: (event, el, state) => void",
448
+ documentation: "Mousedown event handler.",
449
+ snippet: "onMousedown: (event, el, state) => {\n ${1:}\n},",
450
+ isDomqlLifecycle: false
451
+ },
452
+ {
453
+ label: "onMouseup",
454
+ detail: "onMouseup: (event, el, state) => void",
455
+ documentation: "Mouseup event handler.",
456
+ snippet: "onMouseup: (event, el, state) => {\n ${1:}\n},",
457
+ isDomqlLifecycle: false
458
+ },
459
+ {
460
+ label: "onWheel",
461
+ detail: "onWheel: (event, el, state) => void",
462
+ documentation: "Wheel/scroll event handler.",
463
+ snippet: "onWheel: (event, el, state) => {\n ${1:}\n},",
464
+ isDomqlLifecycle: false
465
+ },
466
+ {
467
+ label: "onScroll",
468
+ detail: "onScroll: (event, el, state) => void",
469
+ documentation: "Scroll event handler.",
470
+ snippet: "onScroll: (event, el, state) => {\n ${1:}\n},",
471
+ isDomqlLifecycle: false
472
+ },
473
+ {
474
+ label: "onContextmenu",
475
+ detail: "onContextmenu: (event, el, state) => void",
476
+ documentation: "Context menu (right-click) event handler.",
477
+ snippet: "onContextmenu: (event, el, state) => {\n event.preventDefault()\n ${1:}\n},",
478
+ isDomqlLifecycle: false
479
+ },
480
+ {
481
+ label: "onDrag",
482
+ detail: "onDrag: (event, el, state) => void",
483
+ documentation: "Drag event handler.",
484
+ snippet: "onDrag: (event, el, state) => {\n ${1:}\n},",
485
+ isDomqlLifecycle: false
486
+ },
487
+ {
488
+ label: "onDragstart",
489
+ detail: "onDragstart: (event, el, state) => void",
490
+ documentation: "Dragstart event handler.",
491
+ snippet: "onDragstart: (event, el, state) => {\n ${1:}\n},",
492
+ isDomqlLifecycle: false
493
+ },
494
+ {
495
+ label: "onDragend",
496
+ detail: "onDragend: (event, el, state) => void",
497
+ documentation: "Dragend event handler.",
498
+ snippet: "onDragend: (event, el, state) => {\n ${1:}\n},",
499
+ isDomqlLifecycle: false
500
+ },
501
+ {
502
+ label: "onDragover",
503
+ detail: "onDragover: (event, el, state) => void",
504
+ documentation: "Dragover event (fires on drop target).",
505
+ snippet: "onDragover: (event, el, state) => {\n event.preventDefault()\n ${1:}\n},",
506
+ isDomqlLifecycle: false
507
+ },
508
+ {
509
+ label: "onDragenter",
510
+ detail: "onDragenter: (event, el, state) => void",
511
+ documentation: "Dragenter event (fires when dragged element enters drop target).",
512
+ snippet: "onDragenter: (event, el, state) => {\n ${1:}\n},",
513
+ isDomqlLifecycle: false
514
+ },
515
+ {
516
+ label: "onDragleave",
517
+ detail: "onDragleave: (event, el, state) => void",
518
+ documentation: "Dragleave event.",
519
+ snippet: "onDragleave: (event, el, state) => {\n ${1:}\n},",
520
+ isDomqlLifecycle: false
521
+ },
522
+ {
523
+ label: "onDrop",
524
+ detail: "onDrop: (event, el, state) => void",
525
+ documentation: "Drop event handler.",
526
+ snippet: "onDrop: (event, el, state) => {\n event.preventDefault()\n ${1:}\n},",
527
+ isDomqlLifecycle: false
528
+ },
529
+ {
530
+ label: "onTouchstart",
531
+ detail: "onTouchstart: (event, el, state) => void",
532
+ documentation: "Touch start event handler.",
533
+ snippet: "onTouchstart: (event, el, state) => {\n ${1:}\n},",
534
+ isDomqlLifecycle: false
535
+ },
536
+ {
537
+ label: "onTouchend",
538
+ detail: "onTouchend: (event, el, state) => void",
539
+ documentation: "Touch end event handler.",
540
+ snippet: "onTouchend: (event, el, state) => {\n ${1:}\n},",
541
+ isDomqlLifecycle: false
542
+ },
543
+ {
544
+ label: "onTouchmove",
545
+ detail: "onTouchmove: (event, el, state) => void",
546
+ documentation: "Touch move event handler.",
547
+ snippet: "onTouchmove: (event, el, state) => {\n ${1:}\n},",
548
+ isDomqlLifecycle: false
549
+ },
550
+ {
551
+ label: "onResize",
552
+ detail: "onResize: (event, el, state) => void",
553
+ documentation: "Resize event handler.",
554
+ snippet: "onResize: (event, el, state) => {\n ${1:}\n},",
555
+ isDomqlLifecycle: false
556
+ },
557
+ {
558
+ label: "onPointerdown",
559
+ detail: "onPointerdown: (event, el, state) => void",
560
+ documentation: "Pointer down event handler (touch + mouse unified).",
561
+ snippet: "onPointerdown: (event, el, state) => {\n ${1:}\n},",
562
+ isDomqlLifecycle: false
563
+ },
564
+ {
565
+ label: "onPointerup",
566
+ detail: "onPointerup: (event, el, state) => void",
567
+ documentation: "Pointer up event handler.",
568
+ snippet: "onPointerup: (event, el, state) => {\n ${1:}\n},",
569
+ isDomqlLifecycle: false
570
+ },
571
+ {
572
+ label: "onPointermove",
573
+ detail: "onPointermove: (event, el, state) => void",
574
+ documentation: "Pointer move event handler.",
575
+ snippet: "onPointermove: (event, el, state) => {\n ${1:}\n},",
576
+ isDomqlLifecycle: false
577
+ }
578
+ ];
579
+ var DOMQL_LIFECYCLE_EVENTS = [
580
+ {
581
+ label: "onRender",
582
+ detail: "onRender: (el, state) => void",
583
+ documentation: 'Fires after the element is rendered into the DOM. Ideal for setup, data fetching, or third-party library initialization.\n\n```js\nonRender: async (el, state) => {\n const data = await el.call("fetchData", el.props.id)\n state.update({ data, loading: false })\n}\n```',
584
+ snippet: "onRender: async (el, state) => {\n ${1:}\n},",
585
+ isDomqlLifecycle: true
586
+ },
587
+ {
588
+ label: "onInit",
589
+ detail: "onInit: (el, state) => void",
590
+ documentation: "Fires before the element renders. Used for early setup before DOM creation.",
591
+ snippet: "onInit: (el, state) => {\n ${1:}\n},",
592
+ isDomqlLifecycle: true
593
+ },
594
+ {
595
+ label: "onUpdate",
596
+ detail: "onUpdate: (el, state) => void",
597
+ documentation: "Fires after any element update (props or state). Receives the updated element.",
598
+ snippet: "onUpdate: (el, state) => {\n ${1:}\n},",
599
+ isDomqlLifecycle: true
600
+ },
601
+ {
602
+ label: "onStateUpdate",
603
+ detail: "onStateUpdate: (el, state) => void",
604
+ documentation: "Fires specifically after state updates. More focused than `onUpdate`.\n\n```js\nonStateUpdate: (el, state) => {\n if (state.active) el.node.focus()\n}\n```",
605
+ snippet: "onStateUpdate: (el, state) => {\n ${1:}\n},",
606
+ isDomqlLifecycle: true
607
+ },
608
+ {
609
+ label: "onCreate",
610
+ detail: "onCreate: (el, state) => void",
611
+ documentation: "Fires when the element is fully created (after children are created).",
612
+ snippet: "onCreate: (el, state) => {\n ${1:}\n},",
613
+ isDomqlLifecycle: true
614
+ },
615
+ {
616
+ label: "onDone",
617
+ detail: "onDone: (el, state) => void",
618
+ documentation: "Fires when the element creation cycle is complete.",
619
+ snippet: "onDone: (el, state) => {\n ${1:}\n},",
620
+ isDomqlLifecycle: true
621
+ },
622
+ {
623
+ label: "onComplete",
624
+ detail: "onComplete: (el, state) => void",
625
+ documentation: "Fires when the full element tree is complete.",
626
+ snippet: "onComplete: (el, state) => {\n ${1:}\n},",
627
+ isDomqlLifecycle: true
628
+ },
629
+ {
630
+ label: "onStateInit",
631
+ detail: "onStateInit: (el, state) => void",
632
+ documentation: "Fires when state is initialized for the first time.",
633
+ snippet: "onStateInit: (el, state) => {\n ${1:}\n},",
634
+ isDomqlLifecycle: true
635
+ },
636
+ {
637
+ label: "onStateCreated",
638
+ detail: "onStateCreated: (el, state) => void",
639
+ documentation: "Fires right after state object creation.",
640
+ snippet: "onStateCreated: (el, state) => {\n ${1:}\n},",
641
+ isDomqlLifecycle: true
642
+ },
643
+ {
644
+ label: "onBeforeStateUpdate",
645
+ detail: "onBeforeStateUpdate: (el, state) => void",
646
+ documentation: "Fires before a state update is applied.",
647
+ snippet: "onBeforeStateUpdate: (el, state) => {\n ${1:}\n},",
648
+ isDomqlLifecycle: true
649
+ },
650
+ {
651
+ label: "onBeforeUpdate",
652
+ detail: "onBeforeUpdate: (el, state) => void",
653
+ documentation: "Fires before an element update.",
654
+ snippet: "onBeforeUpdate: (el, state) => {\n ${1:}\n},",
655
+ isDomqlLifecycle: true
656
+ },
657
+ {
658
+ label: "onBeforeClassAssign",
659
+ detail: "onBeforeClassAssign: (el, state) => void",
660
+ documentation: "Fires before CSS classes are assigned to the element.",
661
+ snippet: "onBeforeClassAssign: (el, state) => {\n ${1:}\n},",
662
+ isDomqlLifecycle: true
663
+ },
664
+ {
665
+ label: "onAttachNode",
666
+ detail: "onAttachNode: (el, state) => void",
667
+ documentation: "Fires when the DOM node is attached to parent.",
668
+ snippet: "onAttachNode: (el, state) => {\n ${1:}\n},",
669
+ isDomqlLifecycle: true
670
+ },
671
+ {
672
+ label: "onFrame",
673
+ detail: "onFrame: (el, state) => void",
674
+ documentation: "Fires on every animation frame. Element must have animation frame enabled.\n\n```js\nonFrame: (el) => {\n el.setNodeStyles({ transform: `translateX(${el.data.x}px)` })\n}\n```",
675
+ snippet: "onFrame: (el, state) => {\n ${1:}\n},",
676
+ isDomqlLifecycle: true
677
+ }
678
+ ];
679
+ var ALL_EVENTS = [...DOM_EVENTS, ...DOMQL_LIFECYCLE_EVENTS];
680
+
681
+ // src/data/cssProperties.ts
682
+ var DESIGN_SYSTEM_PROPS = [
683
+ { label: "flow", detail: "Shorthand for flexDirection", documentation: 'Shorthand for `flexDirection`. Common values: `"column"`, `"row"`, `"y"`, `"x"`, `"column-reverse"`\n\n```js\nflow: "column"\nflow: "x" // alias for "row"\n```' },
684
+ { label: "align", detail: "Shorthand for alignItems and justifyContent", documentation: 'Shorthand for united `alignItems` and `justifyContent`.\n\n```js\nalign: "center center"\nalign: "flex-start space-between"\n```' },
685
+ { label: "flexAlign", detail: "Shorthand for alignItems and justifyContent", documentation: 'Shorthand for united `alignItems` and `justifyContent`.\n\n```js\nflexAlign: "flex-start center"\n```' },
686
+ { label: "round", detail: "Rounding the corners of the shape", documentation: 'Rounding the corners of the shape. Accepts spacing design tokens or CSS values.\n\n```js\nround: "C2"\nround: "100%"\n```' },
687
+ { label: "boxSize", detail: "Range of width and height", documentation: 'Range of width and height. Accepts spacing design tokens.\n\n```js\nboxSize: "C1 E" // width: C1, height: E\nboxSize: "D" // both width and height\n```' },
688
+ { label: "widthRange", detail: "Range of min-width and max-width", documentation: 'Range of min-width and max-width.\n\n```js\nwidthRange: "A1 B2" // minWidth: A1, maxWidth: B2\nwidthRange: "H2 50%"\n```' },
689
+ { label: "heightRange", detail: "Range of min-height and max-height", documentation: 'Range of min-height and max-height.\n\n```js\nheightRange: "A1 B2" // minHeight: A1, maxHeight: B2\n```' },
690
+ { label: "theme", detail: "Reference a theme from Themes configuration", documentation: 'Reference the value from the Themes configuration.\n\n```js\ntheme: "primary"\ntheme: "primary .active"\ntheme: { color: "white", "@dark": { color: "blue" } }\n```' },
691
+ { label: "columns", detail: "Shorthand for gridTemplateColumns", documentation: "Shorthand for `gridTemplateColumns`." },
692
+ { label: "rows", detail: "Shorthand for gridTemplateRows", documentation: "Shorthand for `gridTemplateRows`." },
693
+ { label: "wrap", detail: "Shorthand for flexWrap", documentation: 'Shorthand for `flexWrap`. E.g. `"wrap"`, `"nowrap"`' },
694
+ { label: "inset", detail: "CSS inset shorthand (top, right, bottom, left)", documentation: "CSS inset shorthand (top, right, bottom, left)." },
695
+ { label: "shape", detail: "Name of the shape from Shapes configuration", documentation: 'Name of the shape from Shapes configuration.\n\n```js\nshape: "tag"\nshape: "tooltip top"\n```' },
696
+ { label: "shapeModifier", detail: "Shape direction and position attributes", documentation: 'If the shape is either tooltip or tag, sets additional attributes like direction or position.\n\n```js\nshapeModifier: { position: "block center", direction: "north west" }\n```' },
697
+ { label: "shadow", detail: "Shadow depth with color and offset tokens", documentation: 'Level of the shadow that adds depth to the element.\n\n```js\nshadow: "black A A C" // color x y depth\n```' }
698
+ ];
699
+ var STANDARD_CSS_PROPS = [
700
+ // Layout
701
+ { label: "display", detail: "CSS display mode" },
702
+ { label: "position", detail: "CSS positioning method" },
703
+ { label: "top", detail: "Top offset position" },
704
+ { label: "right", detail: "Right offset position" },
705
+ { label: "bottom", detail: "Bottom offset position" },
706
+ { label: "left", detail: "Left offset position" },
707
+ { label: "zIndex", detail: "Stack order of the element" },
708
+ { label: "overflow", detail: "Content overflow behavior" },
709
+ { label: "overflowX", detail: "Horizontal overflow behavior" },
710
+ { label: "overflowY", detail: "Vertical overflow behavior" },
711
+ { label: "visibility", detail: "Element visibility" },
712
+ // Flexbox
713
+ { label: "flexDirection", detail: "CSS flexDirection property" },
714
+ { label: "flexFlow", detail: "CSS flexFlow property" },
715
+ { label: "flexWrap", detail: "CSS flexWrap property" },
716
+ { label: "flexGrow", detail: "Flex grow factor" },
717
+ { label: "flexShrink", detail: "Flex shrink factor" },
718
+ { label: "flexBasis", detail: "Initial main size of flex item" },
719
+ { label: "flex", detail: "Flex shorthand (grow shrink basis)" },
720
+ { label: "alignItems", detail: "CSS alignItems property" },
721
+ { label: "alignContent", detail: "CSS alignContent property" },
722
+ { label: "alignSelf", detail: "CSS alignSelf property" },
723
+ { label: "justifyContent", detail: "CSS justifyContent property" },
724
+ { label: "justifyItems", detail: "CSS justifyItems property" },
725
+ { label: "justifySelf", detail: "CSS justifySelf property" },
726
+ { label: "gap", detail: "gap: string", documentation: 'The space between children inside the element. Accepts spacing design tokens.\n\n```js\ngap: "A2"\ngap: "B C" // rowGap columnGap\n```' },
727
+ { label: "rowGap", detail: "Space between rows" },
728
+ { label: "columnGap", detail: "Space between columns" },
729
+ { label: "order", detail: "Flex/grid item order" },
730
+ // Grid
731
+ { label: "gridTemplateColumns", detail: "Grid column track sizes" },
732
+ { label: "gridTemplateRows", detail: "Grid row track sizes" },
733
+ { label: "gridTemplateAreas", detail: "Named grid template areas" },
734
+ { label: "gridColumn", detail: "Grid column placement" },
735
+ { label: "gridRow", detail: "Grid row placement" },
736
+ { label: "gridArea", detail: "Grid area placement" },
737
+ { label: "gridAutoFlow", detail: "Auto-placement algorithm" },
738
+ { label: "gridAutoColumns", detail: "Auto-generated column size" },
739
+ { label: "gridAutoRows", detail: "Auto-generated row size" },
740
+ // Sizing
741
+ { label: "width", detail: "Width of the element", documentation: 'Width of the element. Accepts spacing design tokens or CSS values.\n\n```js\nwidth: "F1"\nwidth: "100%"\n```' },
742
+ { label: "height", detail: "Height of the element", documentation: 'Height of the element. Accepts spacing design tokens or CSS values.\n\n```js\nheight: "F1"\n```' },
743
+ { label: "minWidth", detail: "Min width of the box", documentation: "Min width of the box. Accepts spacing design tokens or CSS values." },
744
+ { label: "maxWidth", detail: "Max width of the box", documentation: "Max width of the box. Accepts spacing design tokens or CSS values." },
745
+ { label: "minHeight", detail: "Min height of the box", documentation: "Min height of the box. Accepts spacing design tokens or CSS values." },
746
+ { label: "maxHeight", detail: "Max height of the box", documentation: "Max height of the box. Accepts spacing design tokens or CSS values." },
747
+ { label: "aspectRatio", detail: "Aspect ratio of the box (1/3, 3/7\u2026)", documentation: 'Aspect ratio of the box.\n\n```js\naspectRatio: "1 / 2"\n```' },
748
+ // Spacing
749
+ { label: "padding", detail: "Space inside the element", documentation: 'Space inside the element. Accepts spacing design tokens or CSS values.\n\n```js\npadding: "A1 C2"\npadding: "Z2 C"\n```' },
750
+ { label: "paddingTop", detail: "Top inner space" },
751
+ { label: "paddingRight", detail: "Right inner space" },
752
+ { label: "paddingBottom", detail: "Bottom inner space" },
753
+ { label: "paddingLeft", detail: "Left inner space" },
754
+ { label: "paddingInline", detail: "Inline (horizontal) inner space" },
755
+ { label: "paddingBlock", detail: "Block (vertical) inner space" },
756
+ { label: "margin", detail: "Outer space of the element", documentation: 'Outer space of the element. Accepts spacing design tokens or CSS values.\n\n```js\nmargin: "0 -B2"\n```' },
757
+ { label: "marginTop", detail: "Top outer space" },
758
+ { label: "marginRight", detail: "Right outer space" },
759
+ { label: "marginBottom", detail: "Bottom outer space" },
760
+ { label: "marginLeft", detail: "Left outer space" },
761
+ { label: "marginInline", detail: "Inline (horizontal) outer space" },
762
+ { label: "marginBlock", detail: "Block (vertical) outer space" },
763
+ // Background
764
+ { label: "background", detail: "background: string", documentation: 'Setting the specific background color matching with one from the Colors page. Accepts color tokens with modifiers.\n\n```js\nbackground: "gray"\nbackground: "blue.5" // with opacity\n```' },
765
+ { label: "backgroundColor", detail: "Background color of the element" },
766
+ { label: "backgroundImage", detail: "Background image URL or gradient" },
767
+ { label: "backgroundSize", detail: "Background image sizing" },
768
+ { label: "backgroundPosition", detail: "Background image position" },
769
+ { label: "backgroundRepeat", detail: "Background image repeat behavior" },
770
+ { label: "backgroundClip", detail: "Background painting area" },
771
+ // Border
772
+ { label: "border", detail: "border: string", documentation: 'Border with design system color tokens. Order: color, size, style.\n\n```js\nborder: "blue 1px solid"\nborderTop: "1px solid gray.5"\n```' },
773
+ { label: "borderTop", detail: "Top border with color tokens" },
774
+ { label: "borderRight", detail: "Right border with color tokens" },
775
+ { label: "borderBottom", detail: "Bottom border with color tokens" },
776
+ { label: "borderLeft", detail: "Left border with color tokens" },
777
+ { label: "borderWidth", detail: "Border width" },
778
+ { label: "borderStyle", detail: "Border line style" },
779
+ { label: "borderColor", detail: "Border color from design system" },
780
+ { label: "borderRadius", detail: "borderRadius: string", documentation: 'Rounding the corners of the shape. Accepts spacing design tokens.\n\n```js\nborderRadius: "C2"\n```' },
781
+ { label: "borderTopLeftRadius", detail: "Top-left corner radius" },
782
+ { label: "borderTopRightRadius", detail: "Top-right corner radius" },
783
+ { label: "borderBottomLeftRadius", detail: "Bottom-left corner radius" },
784
+ { label: "borderBottomRightRadius", detail: "Bottom-right corner radius" },
785
+ { label: "outline", detail: "Outline around the element" },
786
+ { label: "outlineOffset", detail: "Space between element and outline" },
787
+ // Typography
788
+ { label: "color", detail: "Text color from design system", documentation: 'Setting the specific text color matching with one from the Colors page. Accepts color tokens with modifiers.\n\n```js\ncolor: "title"\ncolor: "blue.5" // with opacity\n```' },
789
+ { label: "fontSize", detail: "Typography sequence or CSS value", documentation: 'Using typography sequence or default CSS values. Accepts typography design tokens.\n\n```js\nfontSize: "B"\nfontSize: "Z1"\n```' },
790
+ { label: "fontWeight", detail: "Font weight from configuration", documentation: 'CSS font-weight value. Finds the closest weight in configuration or sets variable font value.\n\n```js\nfontWeight: "500"\n```' },
791
+ { label: "fontFamily", detail: "Font family name" },
792
+ { label: "fontStyle", detail: "Font style (normal, italic)" },
793
+ { label: "lineHeight", detail: "Line height of text" },
794
+ { label: "letterSpacing", detail: "Space between characters" },
795
+ { label: "textAlign", detail: "Text horizontal alignment" },
796
+ { label: "textDecoration", detail: "Text decoration (underline, etc.)" },
797
+ { label: "textTransform", detail: "Text case transformation" },
798
+ { label: "textOverflow", detail: "Overflowed text behavior" },
799
+ { label: "whiteSpace", detail: "White space handling" },
800
+ { label: "wordBreak", detail: "Word breaking rules" },
801
+ { label: "wordWrap", detail: "Word wrapping behavior" },
802
+ // Effects
803
+ { label: "opacity", detail: "Element transparency (0-1)" },
804
+ { label: "boxShadow", detail: "CSS box shadow" },
805
+ { label: "filter", detail: "Visual filter effects (blur, brightness)" },
806
+ { label: "backdropFilter", detail: "Backdrop filter effects" },
807
+ { label: "transform", detail: "CSS transform (translate, rotate, scale)" },
808
+ { label: "transformOrigin", detail: "Transform origin point" },
809
+ { label: "transition", detail: "transition: string", documentation: 'Transition using timing design tokens.\n\n```js\ntransition: "A defaultBezier"\n```' },
810
+ { label: "transitionProperty", detail: "Properties to transition" },
811
+ { label: "transitionDuration", detail: "transitionDuration: string", documentation: "Duration value from Timing sequence, or CSS value." },
812
+ { label: "transitionTimingFunction", detail: "Transition easing function" },
813
+ { label: "transitionDelay", detail: "Delay before transition starts" },
814
+ { label: "animation", detail: "animation: string", documentation: 'Bundle animation properties. Accepts animation name and timing tokens.\n\n```js\nanimation: "fadeIn"\nanimation: "fadeIn C1 my-custom-bezier"\n```' },
815
+ { label: "animationName", detail: "animationName: string", documentation: "Name of the animation defined in design system." },
816
+ { label: "animationDuration", detail: "animationDuration: string", documentation: 'Duration value from Timing sequence, or CSS value.\n\n```js\nanimationDuration: "C"\n```' },
817
+ { label: "animationDelay", detail: "animationDelay: string", documentation: "Delay value from Timing sequence, or CSS value." },
818
+ { label: "animationTimingFunction", detail: "animationTimingFunction: string", documentation: "A value from Timing sequence, or CSS animation-timing-function property." },
819
+ { label: "animationFillMode", detail: "animationFillMode: string" },
820
+ { label: "animationPlayState", detail: "animationPlayState: string" },
821
+ { label: "animationIterationCount", detail: "animationIterationCount: string" },
822
+ { label: "animationDirection", detail: "animationDirection: string" },
823
+ // Cursor / pointer
824
+ { label: "cursor", detail: "Mouse cursor appearance" },
825
+ { label: "pointerEvents", detail: "Pointer event targeting" },
826
+ { label: "userSelect", detail: "Text selection behavior" },
827
+ // Misc
828
+ { label: "objectFit", detail: "Replaced element fitting" },
829
+ { label: "objectPosition", detail: "Replaced element position" },
830
+ { label: "resize", detail: "Element resize behavior" },
831
+ { label: "content", detail: "Generated content for pseudo-elements" },
832
+ { label: "listStyle", detail: "List marker style" },
833
+ { label: "tableLayout", detail: "Table layout algorithm" },
834
+ { label: "verticalAlign", detail: "Vertical alignment" },
835
+ { label: "appearance", detail: "Native UI appearance" },
836
+ { label: "boxSizing", detail: "Box model sizing method" },
837
+ { label: "isolation", detail: "Stacking context isolation" },
838
+ { label: "mixBlendMode", detail: "Color blending mode" },
839
+ { label: "willChange", detail: "Performance optimization hint" },
840
+ { label: "clipPath", detail: "Clipping region shape" },
841
+ { label: "fill", detail: "SVG fill color" },
842
+ { label: "stroke", detail: "SVG stroke color" },
843
+ { label: "strokeWidth", detail: "SVG stroke width" }
844
+ ];
845
+ var ALL_CSS_PROPS = [...DESIGN_SYSTEM_PROPS, ...STANDARD_CSS_PROPS];
846
+
847
+ // src/data/components.ts
848
+ var BUILT_IN_ATOMS = [
849
+ {
850
+ label: "Box",
851
+ detail: "Box: object \u2192 <div>",
852
+ documentation: "Generic container element. Maps to `<div>`.\n\nCommon props: `padding`, `margin`, `background`, `border`, `borderRadius`, `width`, `height`, `overflow`, `position`",
853
+ snippet: 'Box: {\n ${1:padding}: "${2:A}",\n},'
854
+ },
855
+ {
856
+ label: "Flex",
857
+ detail: "Flex: object \u2192 <div> (flexbox)",
858
+ documentation: 'Flexbox layout container.\n\nCommon props: `flow`, `align`, `gap`, `wrap`, `alignItems`, `justifyContent`\n\n```js\nFlex: {\n flow: "y",\n align: "center space-between",\n gap: "B"\n}\n```',
859
+ snippet: 'Flex: {\n flow: "${1:y}",\n gap: "${2:B}",\n},'
860
+ },
861
+ {
862
+ label: "Grid",
863
+ detail: "Grid: object \u2192 <div> (CSS grid)",
864
+ documentation: 'CSS Grid layout container.\n\nCommon props: `columns`, `rows`, `gap`\n\n```js\nGrid: {\n columns: "repeat(3, 1fr)",\n gap: "A"\n}\n```',
865
+ snippet: 'Grid: {\n columns: "${1:repeat(3, 1fr)}",\n gap: "${2:A}",\n},'
866
+ },
867
+ {
868
+ label: "Text",
869
+ detail: "Text: object \u2192 <span>",
870
+ documentation: 'Inline text element.\n\nCommon props: `text`, `color`, `fontSize`, `fontWeight`, `lineHeight`\n\n```js\nText: { text: "Hello", fontSize: "B", color: "title" }\n```',
871
+ snippet: 'Text: {\n text: "${1:}",\n},'
872
+ },
873
+ {
874
+ label: "Button",
875
+ detail: "Button: object \u2192 <button>",
876
+ documentation: 'Actionable button element.\n\nCommon props: `text`, `icon`, `type`, `disabled`, `theme`, `padding`, `round`, `onClick`\n\n```js\nButton: { text: "Save", theme: "primary", onClick: (ev, el) => {} }\n```',
877
+ snippet: 'Button: {\n text: "${1:Label}",\n onClick: (event, el, state) => {\n ${2:}\n },\n},'
878
+ },
879
+ {
880
+ label: "Link",
881
+ detail: "Link: object \u2192 <a>",
882
+ documentation: 'Anchor/link element.\n\nCommon props: `text`, `href`, `target`, `rel`, `color`, `textDecoration`\n\n```js\nLink: { text: "Read more", href: "/article" }\n```',
883
+ snippet: 'Link: {\n text: "${1:}",\n href: "${2:/}",\n},'
884
+ },
885
+ {
886
+ label: "Input",
887
+ detail: "Input: object \u2192 <input>",
888
+ documentation: 'Text input element.\n\nCommon props: `type`, `name`, `value`, `placeholder`, `required`, `disabled`, `onInput`, `onChange`\n\n```js\nInput: { type: "text", placeholder: "Enter name", onInput: (ev, el, state) => {} }\n```',
889
+ snippet: 'Input: {\n type: "${1:text}",\n placeholder: "${2:}",\n},'
890
+ },
891
+ {
892
+ label: "Icon",
893
+ detail: "Icon: object \u2192 <svg> (icon sprite)",
894
+ documentation: 'Icon from the design system sprite.\n\nCommon props: `name`, `boxSize`, `color`\n\n```js\nIcon: { name: "chevronRight", boxSize: "A" }\n```',
895
+ snippet: 'Icon: {\n name: "${1:}",\n},'
896
+ },
897
+ {
898
+ label: "IconText",
899
+ detail: "IconText: object \u2192 <div>",
900
+ documentation: 'Icon + text combination.\n\nCommon props: `icon`, `text`, `gap`, `align`\n\n```js\nIconText: { icon: "search", text: "Search", gap: "Z" }\n```',
901
+ snippet: 'IconText: {\n icon: "${1:}",\n text: "${2:}",\n},'
902
+ },
903
+ {
904
+ label: "Img",
905
+ detail: "Img: object \u2192 <img>",
906
+ documentation: 'Image element.\n\nCommon props: `src`, `alt`, `loading`, `width`, `height`, `boxSize`, `objectFit`\n\n```js\nImg: { src: "/logo.png", alt: "Logo", boxSize: "B" }\n```',
907
+ snippet: 'Img: {\n src: "${1:}",\n alt: "${2:}",\n},'
908
+ },
909
+ {
910
+ label: "Svg",
911
+ detail: "Svg: object \u2192 <svg>",
912
+ documentation: 'Raw SVG container.\n\nCommon props: `html` (inline SVG markup), `width`, `height`, `viewBox`, `fill`, `stroke`\n\n```js\nSvg: { html: "<path d=\'...\' />", viewBox: "0 0 24 24" }\n```',
913
+ snippet: 'Svg: {\n html: "${1:}",\n viewBox: "${2:0 0 24 24}",\n},'
914
+ },
915
+ {
916
+ label: "Iframe",
917
+ detail: "Iframe: object \u2192 <iframe>",
918
+ documentation: 'Embedded content frame.\n\nCommon props: `src`, `title`, `allow`, `sandbox`, `width`, `height`\n\n```js\nIframe: { src: "https://example.com", width: "100%", height: "300px" }\n```',
919
+ snippet: 'Iframe: {\n src: "${1:}",\n width: "${2:100%}",\n height: "${3:300px}",\n},'
920
+ },
921
+ {
922
+ label: "Video",
923
+ detail: "Video: object \u2192 <video>",
924
+ documentation: 'Video player element.\n\nCommon props: `src`, `poster`, `controls`, `autoplay`, `muted`, `loop`, `width`, `height`\n\n```js\nVideo: { src: "/demo.mp4", controls: true, width: "100%" }\n```',
925
+ snippet: 'Video: {\n src: "${1:}",\n controls: true,\n},'
926
+ },
927
+ {
928
+ label: "Radio",
929
+ detail: 'Radio: object \u2192 <input type="radio">',
930
+ documentation: 'Radio input element.\n\nCommon props: `name`, `value`, `checked`, `disabled`, `onChange`\n\n```js\nRadio: { name: "option", value: "a" }\n```',
931
+ snippet: 'Radio: {\n name: "${1:}",\n value: "${2:}",\n},'
932
+ },
933
+ {
934
+ label: "Checkbox",
935
+ detail: 'Checkbox: object \u2192 <input type="checkbox">',
936
+ documentation: 'Checkbox input element.\n\nCommon props: `name`, `value`, `checked`, `disabled`, `onChange`\n\n```js\nCheckbox: { name: "agree", checked: true }\n```',
937
+ snippet: 'Checkbox: {\n name: "${1:}",\n},'
938
+ }
939
+ ];
940
+ var UIKIT_COMPONENTS = [
941
+ // Typography
942
+ { label: "H1", detail: "H1: object \u2192 <h1>", documentation: "H1 heading. Common props: `text`, `color`, `fontSize`", snippet: 'H1: { text: "${1:}" },' },
943
+ { label: "H2", detail: "H2: object \u2192 <h2>", documentation: "H2 heading.", snippet: 'H2: { text: "${1:}" },' },
944
+ { label: "H3", detail: "H3: object \u2192 <h3>", documentation: "H3 heading.", snippet: 'H3: { text: "${1:}" },' },
945
+ { label: "H4", detail: "H4: object \u2192 <h4>", documentation: "H4 heading.", snippet: 'H4: { text: "${1:}" },' },
946
+ { label: "H5", detail: "H5: object \u2192 <h5>", documentation: "H5 heading.", snippet: 'H5: { text: "${1:}" },' },
947
+ { label: "H6", detail: "H6: object \u2192 <h6>", documentation: "H6 heading.", snippet: 'H6: { text: "${1:}" },' },
948
+ { label: "P", detail: "P: object \u2192 <p>", documentation: "Paragraph element.\n\nCommon props: `text`, `color`, `fontSize`, `lineHeight`, `maxWidth`", snippet: 'P: { text: "${1:}" },' },
949
+ { label: "Caption", detail: "Caption: object \u2192 <span>", documentation: "Small caption/label text.", snippet: 'Caption: { text: "${1:}" },' },
950
+ { label: "Headline", detail: "Headline: object \u2192 <span>", documentation: "Large emphasis/display text.", snippet: 'Headline: { text: "${1:}" },' },
951
+ { label: "Subhead", detail: "Subhead: object \u2192 <span>", documentation: "Subheading text.", snippet: 'Subhead: { text: "${1:}" },' },
952
+ { label: "Footnote", detail: "Footnote: object \u2192 <span>", documentation: "Footer reference text.", snippet: 'Footnote: { text: "${1:}" },' },
953
+ { label: "Strong", detail: "Strong: object \u2192 <strong>", documentation: "Bold inline text.", snippet: 'Strong: { text: "${1:}" },' },
954
+ { label: "Italic", detail: "Italic: object \u2192 <em>", documentation: "Italic inline text.", snippet: 'Italic: { text: "${1:}" },' },
955
+ { label: "U", detail: "U: object \u2192 <u>", documentation: "Underlined inline text.", snippet: 'U: { text: "${1:}" },' },
956
+ // Dividers
957
+ { label: "Hr", detail: "Hr: object \u2192 <hr>", documentation: "Horizontal rule divider.", snippet: "Hr: {}," },
958
+ { label: "HrLegend", detail: "HrLegend: object \u2192 <div>", documentation: "Divider with centered label text.\n\nCommon props: `text`", snippet: 'HrLegend: { text: "${1:Or}" },' },
959
+ // Buttons (composite)
960
+ { label: "IconButton", detail: "IconButton: object", documentation: 'Icon-only circular button.\n\nCommon props: `Icon.name`, `theme`, `fontSize`, `padding`\n\n```js\nIconButton: { Icon: { name: "plus" }, theme: "dialog" }\n```', snippet: 'IconButton: {\n Icon: { name: "${1:}" },\n},' },
961
+ { label: "SubmitButton", detail: "SubmitButton: object", documentation: 'Form submit button.\n\nCommon props: `value` (label).\n\n```js\nSubmitButton: { value: "Create account" }\n```', snippet: 'SubmitButton: {\n value: "${1:Submit}",\n},' },
962
+ // Avatar
963
+ { label: "Avatar", detail: "Avatar: object", documentation: 'User profile image.\n\nCommon props: `boxSize` (default `"C2"`), `src`, `alt`\n\n```js\nAvatar: { boxSize: "C2" }\n```', snippet: 'Avatar: {\n boxSize: "${1:C2}",\n},' },
964
+ { label: "AvatarStatus", detail: "AvatarStatus: object", documentation: 'Avatar with status dot.\n\nCommon props: `Avatar.boxSize`, `StatusDot.theme`\n\n```js\nAvatarStatus: { StatusDot: { theme: "success" } }\n```', snippet: 'AvatarStatus: {\n StatusDot: { theme: "${1:success}" },\n},' },
965
+ { label: "AvatarSet", detail: "AvatarSet: object", documentation: "Group of overlapping avatars.\n\nCommon props: `children`", snippet: "AvatarSet: {\n children: [${1:}],\n}," },
966
+ { label: "AvatarHgroup", detail: "AvatarHgroup: object", documentation: 'Avatar with name and subtitle.\n\n```js\nAvatarHgroup: { H: { text: "Name" }, P: { text: "Role" } }\n```', snippet: 'AvatarHgroup: {\n H: { text: "${1:}" },\n P: { text: "${2:}" },\n},' },
967
+ // Badge
968
+ { label: "Badge", detail: "Badge: object", documentation: 'Small colored label badge.\n\nCommon props: `text`, `theme` (default `"warning"`)\n\n```js\nBadge: { text: "New", theme: "primary" }\n```', snippet: 'Badge: {\n text: "${1:}",\n theme: "${2:primary}",\n},' },
969
+ { label: "NotificationCounter", detail: "NotificationCounter: object", documentation: 'Circular number badge.\n\nCommon props: `text` (number), `theme`\n\n```js\nNotificationCounter: { text: "5", theme: "primary" }\n```', snippet: 'NotificationCounter: {\n text: "${1:0}",\n},' },
970
+ // Form
971
+ { label: "Field", detail: "Field: object", documentation: 'Styled text input with optional icon.\n\nCommon props: `Input.placeholder`, `Input.type`, `Icon.icon`, `theme`\n\n```js\nField: { Input: { placeholder: "Enter name" }, Icon: { icon: "user" } }\n```', snippet: 'Field: {\n Input: { placeholder: "${1:}" },\n},' },
972
+ { label: "FieldCaption", detail: "FieldCaption: object", documentation: "Labeled field with caption above.\n\nCommon props: `Caption.text`, `Field` props", snippet: 'FieldCaption: {\n Caption: { text: "${1:Label}" },\n Field: { Input: { placeholder: "${2:}" } },\n},' },
973
+ { label: "Select", detail: "Select: object \u2192 <select>", documentation: "Native select element.\n\nCommon props: `children` (array of `{ text, value }` options)", snippet: 'Select: {\n children: [\n { text: "${1:Option}", value: "${2:value}" },\n ],\n},' },
974
+ { label: "SelectPicker", detail: "SelectPicker: object", documentation: "Styled select with chevron icon.\n\nCommon props: `Select.children`, `Icon.name`", snippet: 'SelectPicker: {\n Select: {\n children: [\n { text: "${1:Option}", value: "${2:value}" },\n ],\n },\n},' },
975
+ { label: "Search", detail: "Search: object", documentation: 'Search input with icon.\n\nCommon props: `Input.placeholder`, `Icon.name`\n\n```js\nSearch: { Input: { placeholder: "Search\u2026" } }\n```', snippet: 'Search: {\n Input: { placeholder: "${1:Search\u2026}" },\n},' },
976
+ // Navigation
977
+ { label: "TabSet", detail: "TabSet: object", documentation: 'Horizontal tab bar.\n\nCommon props: `children` (tab objects with `text` and optional `isActive`)\n\n```js\nTabSet: { children: [{ text: "Overview", isActive: true }, { text: "Details" }] }\n```', snippet: 'TabSet: {\n children: [\n { text: "${1:Tab 1}", isActive: true },\n { text: "${2:Tab 2}" },\n ],\n},' },
978
+ { label: "LinkSet", detail: "LinkSet: object", documentation: 'Navigation list of links.\n\nCommon props: `tag: "nav"`, `childExtend: "Link"`, `children`', snippet: 'LinkSet: {\n tag: "nav",\n children: [\n { text: "${1:Home}", href: "${2:/}" },\n ],\n},' },
979
+ { label: "Breadcrumb", detail: "Breadcrumb: object", documentation: 'Breadcrumb navigation.\n\nCommon props: `tag: "nav"`, `childExtend: "Link"`', snippet: 'Breadcrumb: {\n tag: "nav",\n},' },
980
+ { label: "Pagination", detail: "Pagination: object", documentation: "Numbered page controls.", snippet: "Pagination: {}," },
981
+ // Progress / Status
982
+ { label: "Progress", detail: "Progress: object", documentation: 'Linear progress bar.\n\nCommon props: `value` (0\u20131), `height`, `minWidth`, `round`, `theme`\n\n```js\nProgress: { value: 0.6, height: "X", round: "Y" }\n```', snippet: "Progress: {\n value: ${1:0.5},\n}," },
983
+ { label: "CircleProgress", detail: "CircleProgress: object", documentation: 'Circular progress ring.\n\nCommon props: `value` (0\u20131), `boxSize`\n\n```js\nCircleProgress: { value: 0.73, boxSize: "D" }\n```', snippet: 'CircleProgress: {\n value: ${1:0.5},\n boxSize: "${2:D}",\n},' },
984
+ { label: "StatusDot", detail: "StatusDot: object", documentation: 'Small status indicator dot.\n\nCommon props: `theme` (`"success"`, `"error"`, `"warning"`)\n\n```js\nStatusDot: { theme: "success" }\n```', snippet: 'StatusDot: {\n theme: "${1:success}",\n},' },
985
+ // Overlay
986
+ { label: "Modal", detail: "Modal: object", documentation: 'Dialog overlay container.\n\nCommon props: `Hgroup.H.text`, `Hgroup.P.text`, `IconButton.Icon.name`, `theme: "dialog"`\n\n```js\nModal: { Hgroup: { H: { text: "Confirm" } }, IconButton: { Icon: { name: "x" } } }\n```', snippet: 'Modal: {\n Hgroup: {\n H: { text: "${1:Title}" },\n P: { text: "${2:Subtitle}" },\n },\n IconButton: { Icon: { name: "x" } },\n},' },
987
+ { label: "Accordion", detail: "Accordion: object", documentation: "Expandable/collapsible section.\n\nCommon props: `ButtonParagraph.P.text`, `P.text`, `state.activeAccordion`", snippet: 'Accordion: {\n ButtonParagraph: { P: { text: "${1:Question}" } },\n P: { text: "${2:Answer}" },\n},' },
988
+ // Data display
989
+ { label: "UnitValue", detail: "UnitValue: object", documentation: 'Unit + value pair (price, stat).\n\nCommon props: `Unit.text`, `Value.text`, `flow`\n\n```js\nUnitValue: { Unit: { text: "$" }, Value: { text: "99" } }\n```', snippet: 'UnitValue: {\n Unit: { text: "${1:$}" },\n Value: { text: "${2:}" },\n},' },
990
+ { label: "Stars", detail: "Stars: object", documentation: "5-star rating display.", snippet: "Stars: {}," },
991
+ // Layout helpers
992
+ { label: "Hgroup", detail: "Hgroup: object", documentation: 'Heading group (heading + paragraph).\n\n```js\nHgroup: { H: { text: "Title" }, P: { text: "Subtitle" } }\n```', snippet: 'Hgroup: {\n H: { text: "${1:}" },\n P: { text: "${2:}" },\n},' },
993
+ // Misc
994
+ { label: "Span", detail: "Span: object \u2192 <span>", documentation: "Inline span element.", snippet: 'Span: { text: "${1:}" },' },
995
+ { label: "Div", detail: "Div: object \u2192 <div>", documentation: "Generic div container.", snippet: "Div: {}," },
996
+ { label: "Section", detail: "Section: object \u2192 <section>", documentation: "Section element.", snippet: "Section: {}," },
997
+ { label: "Header", detail: "Header: object \u2192 <header>", documentation: "Header element.", snippet: "Header: {}," },
998
+ { label: "Footer", detail: "Footer: object \u2192 <footer>", documentation: "Footer element.", snippet: "Footer: {}," },
999
+ { label: "Nav", detail: "Nav: object \u2192 <nav>", documentation: "Navigation element.", snippet: "Nav: {}," },
1000
+ { label: "Main", detail: "Main: object \u2192 <main>", documentation: "Main content element.", snippet: "Main: {}," },
1001
+ { label: "Article", detail: "Article: object \u2192 <article>", documentation: "Article element.", snippet: "Article: {}," },
1002
+ { label: "Aside", detail: "Aside: object \u2192 <aside>", documentation: "Aside/sidebar element.", snippet: "Aside: {}," },
1003
+ { label: "Form", detail: "Form: object \u2192 <form>", documentation: "Form element.", snippet: 'Form: {\n tag: "form",\n onSubmit: (event, el, state) => {\n event.preventDefault()\n ${1:}\n },\n},' },
1004
+ { label: "Table", detail: "Table: object \u2192 <table>", documentation: "Table element.", snippet: "Table: {}," },
1005
+ { label: "Tr", detail: "Tr: object \u2192 <tr>", documentation: "Table row element.", snippet: "Tr: {}," },
1006
+ { label: "Td", detail: "Td: object \u2192 <td>", documentation: "Table data cell.", snippet: "Td: {}," },
1007
+ { label: "Th", detail: "Th: object \u2192 <th>", documentation: "Table header cell.", snippet: "Th: {}," }
1008
+ ];
1009
+ var ALL_COMPONENTS = [...BUILT_IN_ATOMS, ...UIKIT_COMPONENTS];
1010
+
1011
+ // src/data/elementMethods.ts
1012
+ var ELEMENT_METHODS = [
1013
+ // Traversal
1014
+ {
1015
+ label: "lookup",
1016
+ detail: "lookup(key: string | function): element",
1017
+ documentation: 'Walk up the ancestor chain to find an element by key name or predicate.\n\n```js\nel.lookup("Modal") // find ancestor named Modal\nel.lookup(e => e.props.isRoot) // find by predicate\n```',
1018
+ snippet: 'lookup(${1:"key"})'
1019
+ },
1020
+ {
1021
+ label: "lookdown",
1022
+ detail: "lookdown(key: string | function): element",
1023
+ documentation: 'Find the first matching descendant by key or predicate.\n\n```js\nel.lookdown("Input") // find first descendant named Input\n```',
1024
+ snippet: 'lookdown(${1:"key"})'
1025
+ },
1026
+ {
1027
+ label: "lookdownAll",
1028
+ detail: "lookdownAll(key: string | function): element[]",
1029
+ documentation: 'Find all matching descendants.\n\n```js\nconst buttons = el.lookdownAll("Button")\n```',
1030
+ snippet: 'lookdownAll(${1:"key"})'
1031
+ },
1032
+ {
1033
+ label: "nextElement",
1034
+ detail: "nextElement(): element | null",
1035
+ documentation: "Returns the next sibling element in parent's children.",
1036
+ snippet: "nextElement()"
1037
+ },
1038
+ {
1039
+ label: "previousElement",
1040
+ detail: "previousElement(): element | null",
1041
+ documentation: "Returns the previous sibling element in parent's children.",
1042
+ snippet: "previousElement()"
1043
+ },
1044
+ {
1045
+ label: "getChildren",
1046
+ detail: "getChildren(): element[]",
1047
+ documentation: "Returns all direct child elements as an array.",
1048
+ snippet: "getChildren()"
1049
+ },
1050
+ {
1051
+ label: "getPath",
1052
+ detail: "getPath(): string[]",
1053
+ documentation: "Returns the path array from root to this element.",
1054
+ snippet: "getPath()"
1055
+ },
1056
+ // State navigation
1057
+ {
1058
+ label: "getRootState",
1059
+ detail: "getRootState(key?: string): state",
1060
+ documentation: 'Get the app-level root state, or a specific key from it.\n\n```js\nconst rootState = el.getRootState()\nconst user = el.getRootState("user")\n```',
1061
+ snippet: 'getRootState(${1:"key"})'
1062
+ },
1063
+ {
1064
+ label: "getRoot",
1065
+ detail: "getRoot(key?: string): element",
1066
+ documentation: "Get the root element of the tree, or a specific property from it.",
1067
+ snippet: 'getRoot(${1:"key"})'
1068
+ },
1069
+ {
1070
+ label: "getRootData",
1071
+ detail: "getRootData(key?: string): any",
1072
+ documentation: "Get data from the root element.",
1073
+ snippet: 'getRootData(${1:"key"})'
1074
+ },
1075
+ {
1076
+ label: "getRootContext",
1077
+ detail: "getRootContext(key?: string): any",
1078
+ documentation: "Get context from the root.",
1079
+ snippet: 'getRootContext(${1:"key"})'
1080
+ },
1081
+ {
1082
+ label: "getContext",
1083
+ detail: "getContext(key: string): any",
1084
+ documentation: 'Get a value from the element\'s context.\n\n```js\nconst router = el.getContext("functions.router")\n```',
1085
+ snippet: 'getContext(${1:"key"})'
1086
+ },
1087
+ // Updates
1088
+ {
1089
+ label: "update",
1090
+ detail: "update(params: object, opts?: object): element",
1091
+ documentation: 'Partially update element properties and trigger re-renders.\n\n```js\nel.update({ text: "New text", color: "primary" })\n```',
1092
+ snippet: "update({ ${1:key}: ${2:value} })"
1093
+ },
1094
+ {
1095
+ label: "set",
1096
+ detail: "set(params: object, opts?: object): element",
1097
+ documentation: 'Full replacement of element content. Removes existing children and creates new ones.\n\n```js\nel.set({ text: "Replaced content" })\n```',
1098
+ snippet: "set({ ${1:key}: ${2:value} })"
1099
+ },
1100
+ {
1101
+ label: "setProps",
1102
+ detail: "setProps(params: object, opts?: object): void",
1103
+ documentation: 'Update element props specifically and trigger re-render.\n\n```js\nel.setProps({ disabled: true, color: "error" })\n```',
1104
+ snippet: "setProps({ ${1:key}: ${2:value} })"
1105
+ },
1106
+ {
1107
+ label: "reset",
1108
+ detail: "reset(opts?: object): void",
1109
+ documentation: "Reset element to its original definition.",
1110
+ snippet: "reset()"
1111
+ },
1112
+ // DOM
1113
+ {
1114
+ label: "setNodeStyles",
1115
+ detail: "setNodeStyles(params: object): void",
1116
+ documentation: 'Apply inline styles directly to the DOM node.\n\n```js\nel.setNodeStyles({ transform: "translateX(100px)", opacity: "0.5" })\n```',
1117
+ snippet: 'setNodeStyles({ ${1:transform}: "${2:}" })'
1118
+ },
1119
+ {
1120
+ label: "remove",
1121
+ detail: "remove(opts?: object): void",
1122
+ documentation: "Remove element from DOM and clean up references.",
1123
+ snippet: "remove()"
1124
+ },
1125
+ {
1126
+ label: "append",
1127
+ detail: "append(el: object, key?: string, opts?: object): element",
1128
+ documentation: 'Append a new child element.\n\n```js\nel.append({ extends: "Button", text: "New" }, "AddButton")\n```',
1129
+ snippet: 'append({ ${1:} }, "${2:key}")'
1130
+ },
1131
+ // Content
1132
+ {
1133
+ label: "updateContent",
1134
+ detail: "updateContent(params: any, opts?: object): void",
1135
+ documentation: "Update the element's dynamic content (for elements with `content` prop).",
1136
+ snippet: "updateContent(${1:})"
1137
+ },
1138
+ {
1139
+ label: "removeContent",
1140
+ detail: "removeContent(opts?: object): void",
1141
+ documentation: "Remove the dynamic content child.",
1142
+ snippet: "removeContent()"
1143
+ },
1144
+ // Context function calls
1145
+ {
1146
+ label: "call",
1147
+ detail: "call(fnKey: string, ...args): any",
1148
+ documentation: 'Call a registered function from context (utils \u2192 functions \u2192 methods \u2192 snippets).\n\n```js\nel.call("exec", props.value, el) // execute dynamic prop\nel.call("fetchData", el.props.id) // call context function\nel.call("router", href, root, {}) // navigate\nel.call("isString", value) // call utility\n```',
1149
+ snippet: 'call("${1:fnKey}"${2:, args})'
1150
+ },
1151
+ // Debugging
1152
+ {
1153
+ label: "keys",
1154
+ detail: "keys(): string[]",
1155
+ documentation: "Returns the element's own keys (excluding internals).",
1156
+ snippet: "keys()"
1157
+ },
1158
+ {
1159
+ label: "parse",
1160
+ detail: "parse(excl?: string[]): object",
1161
+ documentation: "Serialize element to a plain object.",
1162
+ snippet: "parse()"
1163
+ },
1164
+ {
1165
+ label: "parseDeep",
1166
+ detail: "parseDeep(excl?: string[]): object",
1167
+ documentation: "Deep serialize the element tree to a plain object.",
1168
+ snippet: "parseDeep()"
1169
+ },
1170
+ {
1171
+ label: "verbose",
1172
+ detail: "verbose(...args): void",
1173
+ documentation: "Log detailed element information to the console.",
1174
+ snippet: "verbose()"
1175
+ },
1176
+ {
1177
+ label: "get",
1178
+ detail: "get(key: string): any",
1179
+ documentation: "Get an element property by key.",
1180
+ snippet: 'get("${1:key}")'
1181
+ },
1182
+ {
1183
+ label: "getRef",
1184
+ detail: "getRef(key: string): any",
1185
+ documentation: "Get a value from the `__ref` internal reference.",
1186
+ snippet: 'getRef("${1:key}")'
1187
+ },
1188
+ {
1189
+ label: "spotByPath",
1190
+ detail: "spotByPath(path: string[]): element",
1191
+ documentation: "Traverse element tree to find element at given path array.",
1192
+ snippet: "spotByPath([${1:}])"
1193
+ }
1194
+ ];
1195
+ var STATE_METHODS = [
1196
+ {
1197
+ label: "update",
1198
+ detail: "state.update(obj: object, opts?: object): void",
1199
+ documentation: "Partially update state values and trigger re-renders for all dependent elements.\n\n```js\nstate.update({ count: state.count + 1 })\nstate.update({ open: !state.open, loading: false })\n```",
1200
+ snippet: "update({ ${1:key}: ${2:value} })"
1201
+ },
1202
+ {
1203
+ label: "set",
1204
+ detail: "state.set(val: any, opts?: object): void",
1205
+ documentation: 'Replace the entire state with a new value.\n\n```js\nstate.set({ name: "New", count: 0 })\n```',
1206
+ snippet: "set(${1:value})"
1207
+ },
1208
+ {
1209
+ label: "reset",
1210
+ detail: "state.reset(opts?: object): void",
1211
+ documentation: "Reset state to its initial values.",
1212
+ snippet: "reset()"
1213
+ },
1214
+ {
1215
+ label: "toggle",
1216
+ detail: "state.toggle(key: string, opts?: object): void",
1217
+ documentation: 'Flip a boolean state property.\n\n```js\nstate.toggle("open") // open: false \u2192 true \u2192 false\nstate.toggle("active")\n```',
1218
+ snippet: 'toggle("${1:key}")'
1219
+ },
1220
+ {
1221
+ label: "remove",
1222
+ detail: "state.remove(key?: string, opts?: object): void",
1223
+ documentation: "Remove a property (or the whole state node) from state.",
1224
+ snippet: 'remove("${1:key}")'
1225
+ },
1226
+ {
1227
+ label: "add",
1228
+ detail: "state.add(value: any, opts?: object): void",
1229
+ documentation: 'Push an item to an array state.\n\n```js\nstate.add({ id: 1, text: "New item" })\n```',
1230
+ snippet: "add(${1:value})"
1231
+ },
1232
+ {
1233
+ label: "quietUpdate",
1234
+ detail: "state.quietUpdate(obj: object, opts?: object): void",
1235
+ documentation: "Update state WITHOUT triggering listeners or re-renders. Useful for internal tracking.",
1236
+ snippet: "quietUpdate({ ${1:key}: ${2:value} })"
1237
+ },
1238
+ {
1239
+ label: "quietReplace",
1240
+ detail: "state.quietReplace(obj: object, opts?: object): void",
1241
+ documentation: "Replace state values without triggering listeners.",
1242
+ snippet: "quietReplace({ ${1:key}: ${2:value} })"
1243
+ },
1244
+ {
1245
+ label: "replace",
1246
+ detail: "state.replace(obj: object, opts?: object): void",
1247
+ documentation: "Replace state values (triggers listeners).",
1248
+ snippet: "replace({ ${1:key}: ${2:value} })"
1249
+ },
1250
+ {
1251
+ label: "apply",
1252
+ detail: "state.apply(func: function, opts?: object): void",
1253
+ documentation: "Mutate state with a function (for array operations like push).\n\n```js\nstate.apply(s => { s.items.push(newItem) })\n```",
1254
+ snippet: "apply(s => { ${1:} })"
1255
+ },
1256
+ {
1257
+ label: "applyFunction",
1258
+ detail: "state.applyFunction(func: function, opts?: object): Promise<void>",
1259
+ documentation: "Async version of apply.",
1260
+ snippet: "applyFunction(async s => { ${1:} })"
1261
+ },
1262
+ {
1263
+ label: "setByPath",
1264
+ detail: "state.setByPath(path: string, value: any, opts?: object): void",
1265
+ documentation: 'Set a nested property using dot-path string.\n\n```js\nstate.setByPath("user.profile.name", "Alice")\n```',
1266
+ snippet: 'setByPath("${1:path}", ${2:value})'
1267
+ },
1268
+ {
1269
+ label: "getByPath",
1270
+ detail: "state.getByPath(path: string, opts?: object): any",
1271
+ documentation: 'Get a nested value by dot-path string.\n\n```js\nconst name = state.getByPath("user.profile.name")\n```',
1272
+ snippet: 'getByPath("${1:path}")'
1273
+ },
1274
+ {
1275
+ label: "setPathCollection",
1276
+ detail: "state.setPathCollection(changes: object, opts?: object): void",
1277
+ documentation: "Batch update multiple nested paths at once.",
1278
+ snippet: 'setPathCollection({ "${1:path}": ${2:value} })'
1279
+ },
1280
+ {
1281
+ label: "removeByPath",
1282
+ detail: "state.removeByPath(path: string, opts?: object): void",
1283
+ documentation: "Remove a nested property by dot-path string.",
1284
+ snippet: 'removeByPath("${1:path}")'
1285
+ },
1286
+ {
1287
+ label: "removePathCollection",
1288
+ detail: "state.removePathCollection(changes: object, opts?: object): void",
1289
+ documentation: "Batch remove multiple nested paths.",
1290
+ snippet: 'removePathCollection({ "${1:path}": ${2:true} })'
1291
+ },
1292
+ {
1293
+ label: "parse",
1294
+ detail: "state.parse(): object",
1295
+ documentation: "Return state as plain object (strips methods and internal keys).",
1296
+ snippet: "parse()"
1297
+ },
1298
+ {
1299
+ label: "clean",
1300
+ detail: "state.clean(opts?: object): void",
1301
+ documentation: "Clear all state properties.",
1302
+ snippet: "clean()"
1303
+ },
1304
+ {
1305
+ label: "destroy",
1306
+ detail: "state.destroy(opts?: object): void",
1307
+ documentation: "Destroy state and sever element relationship.",
1308
+ snippet: "destroy()"
1309
+ },
1310
+ {
1311
+ label: "parentUpdate",
1312
+ detail: "state.parentUpdate(obj: object, opts?: object): void",
1313
+ documentation: "Update parent element's state.",
1314
+ snippet: "parentUpdate({ ${1:key}: ${2:value} })"
1315
+ },
1316
+ {
1317
+ label: "rootUpdate",
1318
+ detail: "state.rootUpdate(obj: object, opts?: object): void",
1319
+ documentation: "Update the root application state.",
1320
+ snippet: "rootUpdate({ ${1:key}: ${2:value} })"
1321
+ },
1322
+ {
1323
+ label: "keys",
1324
+ detail: "state.keys(): string[]",
1325
+ documentation: "Returns state property keys.",
1326
+ snippet: "keys()"
1327
+ },
1328
+ {
1329
+ label: "values",
1330
+ detail: "state.values(): any[]",
1331
+ documentation: "Returns state property values.",
1332
+ snippet: "values()"
1333
+ }
1334
+ ];
1335
+ var HTML_ATTRIBUTES = [
1336
+ // Global
1337
+ "id",
1338
+ "class",
1339
+ "style",
1340
+ "title",
1341
+ "lang",
1342
+ "dir",
1343
+ "hidden",
1344
+ "tabindex",
1345
+ "contenteditable",
1346
+ "draggable",
1347
+ "spellcheck",
1348
+ "translate",
1349
+ "accesskey",
1350
+ // Data
1351
+ "data-id",
1352
+ "data-key",
1353
+ "data-value",
1354
+ "data-index",
1355
+ "data-type",
1356
+ "data-name",
1357
+ // Input
1358
+ "type",
1359
+ "name",
1360
+ "value",
1361
+ "placeholder",
1362
+ "required",
1363
+ "disabled",
1364
+ "readonly",
1365
+ "checked",
1366
+ "selected",
1367
+ "multiple",
1368
+ "min",
1369
+ "max",
1370
+ "step",
1371
+ "maxlength",
1372
+ "minlength",
1373
+ "pattern",
1374
+ "autocomplete",
1375
+ "autofocus",
1376
+ "form",
1377
+ "formaction",
1378
+ "formmethod",
1379
+ "accept",
1380
+ "capture",
1381
+ // Link/Anchor
1382
+ "href",
1383
+ "target",
1384
+ "rel",
1385
+ "download",
1386
+ "hreflang",
1387
+ "ping",
1388
+ "referrerpolicy",
1389
+ // Media
1390
+ "src",
1391
+ "alt",
1392
+ "loading",
1393
+ "decoding",
1394
+ "crossorigin",
1395
+ "usemap",
1396
+ "controls",
1397
+ "autoplay",
1398
+ "muted",
1399
+ "loop",
1400
+ "preload",
1401
+ "poster",
1402
+ "width",
1403
+ "height",
1404
+ // Forms
1405
+ "action",
1406
+ "method",
1407
+ "enctype",
1408
+ "novalidate",
1409
+ "for",
1410
+ "colspan",
1411
+ "rowspan",
1412
+ "scope",
1413
+ // ARIA
1414
+ "role",
1415
+ "aria-label",
1416
+ "aria-labelledby",
1417
+ "aria-describedby",
1418
+ "aria-hidden",
1419
+ "aria-expanded",
1420
+ "aria-selected",
1421
+ "aria-checked",
1422
+ "aria-disabled",
1423
+ "aria-controls",
1424
+ "aria-owns",
1425
+ "aria-live",
1426
+ "aria-atomic",
1427
+ "aria-relevant",
1428
+ "aria-busy",
1429
+ "aria-current",
1430
+ "aria-haspopup",
1431
+ "aria-modal",
1432
+ "aria-multiline",
1433
+ "aria-multiselectable",
1434
+ "aria-orientation",
1435
+ "aria-placeholder",
1436
+ "aria-readonly",
1437
+ "aria-required",
1438
+ "aria-sort",
1439
+ "aria-valuemax",
1440
+ "aria-valuemin",
1441
+ "aria-valuenow",
1442
+ "aria-valuetext",
1443
+ // Other
1444
+ "tabindex",
1445
+ "contenteditable",
1446
+ "autofocus",
1447
+ "sandbox",
1448
+ "allow",
1449
+ "frameborder"
1450
+ ];
1451
+
1452
+ // src/data/designSystemValues.ts
1453
+ var SEQUENCE_CONFIGS = {
1454
+ spacing: { type: "spacing", base: 16, ratio: 1.618, unit: "em", description: "Spacing (golden ratio)" },
1455
+ typography: { type: "font-size", base: 16, ratio: 1.25, unit: "em", description: "Typography (major third)" },
1456
+ timing: { type: "timing", base: 150, ratio: 1.333, unit: "ms", description: "Timing (perfect fourth)" }
1457
+ };
1458
+ function getSubValues(base, ratio, value) {
1459
+ const next = value * ratio;
1460
+ const diff = next - value;
1461
+ const subRatio = diff / 1.618;
1462
+ const first = next - subRatio;
1463
+ const second = value + subRatio;
1464
+ const middle = (first + second) / 2;
1465
+ const diffRounded = Math.floor(next) - Math.floor(value);
1466
+ return diffRounded > 16 ? [first, middle, second] : [first, second];
1467
+ }
1468
+ function formatValue(val, unit) {
1469
+ if (unit === "ms") return `~${Math.round(val)}ms`;
1470
+ if (val >= 100) return `~${Math.round(val)}px`;
1471
+ if (val >= 10) return `~${Math.round(val * 10) / 10}px`;
1472
+ return `~${Math.round(val * 100) / 100}px`;
1473
+ }
1474
+ var NUM_TO_LETTER = {
1475
+ "-6": "U",
1476
+ "-5": "V",
1477
+ "-4": "W",
1478
+ "-3": "X",
1479
+ "-2": "Y",
1480
+ "-1": "Z",
1481
+ 0: "A",
1482
+ 1: "B",
1483
+ 2: "C",
1484
+ 3: "D",
1485
+ 4: "E",
1486
+ 5: "F",
1487
+ 6: "G",
1488
+ 7: "H"
1489
+ };
1490
+ function generateTokens(config, rangeStart, rangeEnd) {
1491
+ const tokens = [];
1492
+ for (let key = rangeStart; key <= rangeEnd; key++) {
1493
+ const letter = NUM_TO_LETTER[key];
1494
+ if (!letter) continue;
1495
+ const value = config.base * Math.pow(config.ratio, key);
1496
+ const approx = key === 0 && config.unit !== "ms" ? `${config.base}px` : formatValue(value, config.unit);
1497
+ tokens.push({ label: letter, approxValue: approx, index: key });
1498
+ const subs = getSubValues(config.base, config.ratio, value);
1499
+ subs.forEach((sv, i) => {
1500
+ tokens.push({
1501
+ label: `${letter}${i + 1}`,
1502
+ approxValue: formatValue(sv, config.unit),
1503
+ index: key + (i + 1) / 10
1504
+ });
1505
+ });
1506
+ }
1507
+ return tokens;
1508
+ }
1509
+ var SPACING_TOKENS = generateTokens(SEQUENCE_CONFIGS.spacing, -4, 7);
1510
+ var TYPOGRAPHY_TOKENS = generateTokens(SEQUENCE_CONFIGS.typography, -3, 7);
1511
+ var TIMING_TOKENS = generateTokens(SEQUENCE_CONFIGS.timing, -3, 7);
1512
+ var SPACING_SCALE = SPACING_TOKENS.map((t) => t.label);
1513
+ var FONT_SIZE_SCALE = TYPOGRAPHY_TOKENS.map((t) => t.label);
1514
+ var COLOR_TOKEN_MAP = [
1515
+ { label: "blue", hex: "#213eb0" },
1516
+ { label: "green", hex: "#389d34" },
1517
+ { label: "red", hex: "#e15c55" },
1518
+ { label: "yellow", hex: "#EDCB38" },
1519
+ { label: "orange", hex: "#e97c16" },
1520
+ { label: "transparent", hex: "rgba(0,0,0,0)" },
1521
+ { label: "black", hex: "#000000" },
1522
+ { label: "gray", hex: "#4e4e50" },
1523
+ { label: "white", hex: "#ffffff" },
1524
+ { label: "title", hex: "", description: "Near-black text (light) / near-white text (dark)" },
1525
+ { label: "caption", hex: "", description: "Secondary text color, adapts to theme" },
1526
+ { label: "paragraph", hex: "", description: "Body text color, adapts to theme" },
1527
+ { label: "disabled", hex: "", description: "Muted/disabled text color" },
1528
+ { label: "line", hex: "", description: "Border/divider color, adapts to theme" },
1529
+ { label: "currentColor", hex: "", description: "Inherits current text color" },
1530
+ { label: "inherit", hex: "", description: "Inherits from parent" },
1531
+ { label: "none", hex: "", description: "No color" }
1532
+ ];
1533
+ var COLOR_TOKENS = COLOR_TOKEN_MAP.map((t) => t.label);
1534
+ var GRADIENT_TOKENS = [
1535
+ "gradient-blue-light",
1536
+ "gradient-blue-dark",
1537
+ "gradient-dark",
1538
+ "gradient-dark-active",
1539
+ "gradient-light",
1540
+ "gradient-light-active",
1541
+ "gradient-colorful"
1542
+ ];
1543
+ var THEME_TOKENS = [
1544
+ "document",
1545
+ "primary",
1546
+ "secondary",
1547
+ "tertiary",
1548
+ "quaternary",
1549
+ "quinary",
1550
+ "alert",
1551
+ "warning",
1552
+ "success",
1553
+ "field",
1554
+ "label",
1555
+ "card",
1556
+ "dialog",
1557
+ "none",
1558
+ "transparent"
1559
+ ];
1560
+ var THEME_MODIFIERS = [
1561
+ ".color-only",
1562
+ ".inactive",
1563
+ ".gradient",
1564
+ ".child",
1565
+ ".secondary",
1566
+ ".helper",
1567
+ ".light",
1568
+ ".dark",
1569
+ ".active"
1570
+ ];
1571
+ var ICON_NAMES = [
1572
+ "symbols",
1573
+ "logo",
1574
+ "arrowDownCircle",
1575
+ "arrowDownLeft",
1576
+ "arrowDownRight",
1577
+ "arrowDown",
1578
+ "arrowLeftCircle",
1579
+ "arrowLeft",
1580
+ "arrowRight",
1581
+ "arrowRightCircle",
1582
+ "arrowUpCircle",
1583
+ "arrowUpLeft",
1584
+ "arrowUpRight",
1585
+ "arrowUp",
1586
+ "checkCircle",
1587
+ "check",
1588
+ "chevronDown",
1589
+ "chevronLeft",
1590
+ "chevronRight",
1591
+ "chevronUp",
1592
+ "copy",
1593
+ "eyeOff",
1594
+ "eye",
1595
+ "info",
1596
+ "lock",
1597
+ "minus",
1598
+ "sun",
1599
+ "moon",
1600
+ "moreHorizontal",
1601
+ "moreVertical",
1602
+ "send",
1603
+ "smile",
1604
+ "search",
1605
+ "upload",
1606
+ "video",
1607
+ "x",
1608
+ "star",
1609
+ "plus"
1610
+ ];
1611
+ var HTML_TAGS = [
1612
+ "div",
1613
+ "span",
1614
+ "p",
1615
+ "a",
1616
+ "button",
1617
+ "input",
1618
+ "textarea",
1619
+ "select",
1620
+ "option",
1621
+ "form",
1622
+ "label",
1623
+ "fieldset",
1624
+ "legend",
1625
+ "h1",
1626
+ "h2",
1627
+ "h3",
1628
+ "h4",
1629
+ "h5",
1630
+ "h6",
1631
+ "ul",
1632
+ "ol",
1633
+ "li",
1634
+ "dl",
1635
+ "dt",
1636
+ "dd",
1637
+ "table",
1638
+ "thead",
1639
+ "tbody",
1640
+ "tfoot",
1641
+ "tr",
1642
+ "th",
1643
+ "td",
1644
+ "section",
1645
+ "article",
1646
+ "aside",
1647
+ "header",
1648
+ "footer",
1649
+ "nav",
1650
+ "main",
1651
+ "figure",
1652
+ "figcaption",
1653
+ "blockquote",
1654
+ "pre",
1655
+ "code",
1656
+ "img",
1657
+ "picture",
1658
+ "source",
1659
+ "video",
1660
+ "audio",
1661
+ "canvas",
1662
+ "svg",
1663
+ "path",
1664
+ "circle",
1665
+ "rect",
1666
+ "line",
1667
+ "g",
1668
+ "iframe",
1669
+ "embed",
1670
+ "object",
1671
+ "details",
1672
+ "summary",
1673
+ "dialog",
1674
+ "menu",
1675
+ "hr",
1676
+ "br",
1677
+ "wbr",
1678
+ "strong",
1679
+ "em",
1680
+ "b",
1681
+ "i",
1682
+ "u",
1683
+ "s",
1684
+ "small",
1685
+ "sub",
1686
+ "sup",
1687
+ "mark",
1688
+ "abbr",
1689
+ "time",
1690
+ "data",
1691
+ "output",
1692
+ "progress",
1693
+ "meter"
1694
+ ];
1695
+ var CSS_VALUE_ENUMS = {
1696
+ display: ["flex", "grid", "block", "inline", "inline-flex", "inline-grid", "inline-block", "none", "contents"],
1697
+ position: ["relative", "absolute", "fixed", "sticky", "static"],
1698
+ overflow: ["hidden", "auto", "scroll", "visible", "clip"],
1699
+ overflowX: ["hidden", "auto", "scroll", "visible", "clip"],
1700
+ overflowY: ["hidden", "auto", "scroll", "visible", "clip"],
1701
+ visibility: ["visible", "hidden", "collapse"],
1702
+ flexDirection: ["row", "column", "row-reverse", "column-reverse"],
1703
+ flexWrap: ["wrap", "nowrap", "wrap-reverse"],
1704
+ alignItems: ["center", "flex-start", "flex-end", "stretch", "baseline"],
1705
+ alignContent: ["center", "flex-start", "flex-end", "stretch", "space-between", "space-around", "space-evenly"],
1706
+ alignSelf: ["center", "flex-start", "flex-end", "stretch", "baseline", "auto"],
1707
+ justifyContent: ["center", "flex-start", "flex-end", "space-between", "space-around", "space-evenly", "stretch"],
1708
+ justifyItems: ["center", "start", "end", "stretch", "baseline"],
1709
+ justifySelf: ["center", "start", "end", "stretch", "baseline", "auto"],
1710
+ textAlign: ["left", "center", "right", "justify", "start", "end"],
1711
+ textDecoration: ["none", "underline", "line-through", "overline"],
1712
+ textTransform: ["none", "uppercase", "lowercase", "capitalize"],
1713
+ textOverflow: ["ellipsis", "clip"],
1714
+ whiteSpace: ["nowrap", "pre", "pre-wrap", "pre-line", "normal", "break-spaces"],
1715
+ wordBreak: ["break-word", "break-all", "keep-all", "normal"],
1716
+ fontStyle: ["normal", "italic", "oblique"],
1717
+ fontWeight: ["100", "200", "300", "400", "500", "600", "700", "800", "900", "normal", "bold", "lighter", "bolder"],
1718
+ cursor: ["pointer", "default", "move", "text", "wait", "help", "crosshair", "not-allowed", "grab", "grabbing", "zoom-in", "zoom-out", "col-resize", "row-resize", "none"],
1719
+ pointerEvents: ["auto", "none", "all"],
1720
+ userSelect: ["none", "auto", "text", "all", "contain"],
1721
+ objectFit: ["cover", "contain", "fill", "none", "scale-down"],
1722
+ objectPosition: ["center", "top", "bottom", "left", "right"],
1723
+ resize: ["none", "both", "horizontal", "vertical"],
1724
+ listStyle: ["none", "disc", "circle", "square", "decimal"],
1725
+ borderStyle: ["solid", "dashed", "dotted", "double", "none", "groove", "ridge", "inset", "outset"],
1726
+ boxSizing: ["border-box", "content-box"],
1727
+ backgroundSize: ["cover", "contain", "auto"],
1728
+ backgroundRepeat: ["no-repeat", "repeat", "repeat-x", "repeat-y", "round", "space"],
1729
+ backgroundPosition: ["center", "top", "bottom", "left", "right", "center center", "top center", "bottom center"],
1730
+ backgroundClip: ["border-box", "padding-box", "content-box", "text"],
1731
+ mixBlendMode: ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "difference", "exclusion"],
1732
+ isolation: ["auto", "isolate"],
1733
+ appearance: ["none", "auto"],
1734
+ verticalAlign: ["top", "middle", "bottom", "baseline", "text-top", "text-bottom"],
1735
+ tableLayout: ["auto", "fixed"],
1736
+ willChange: ["auto", "transform", "opacity", "scroll-position"],
1737
+ // DOMQL shorthand values
1738
+ flow: ["column", "row", "x", "y", "column-reverse", "row-reverse"],
1739
+ wrap: ["wrap", "nowrap", "wrap-reverse"],
1740
+ scope: ["state", "props"]
1741
+ };
1742
+ var COLOR_PROPERTIES = /* @__PURE__ */ new Set([
1743
+ "color",
1744
+ "background",
1745
+ "backgroundColor",
1746
+ "borderColor",
1747
+ "borderTopColor",
1748
+ "borderRightColor",
1749
+ "borderBottomColor",
1750
+ "borderLeftColor",
1751
+ "outlineColor",
1752
+ "fill",
1753
+ "stroke",
1754
+ "caretColor",
1755
+ "accentColor",
1756
+ "textDecorationColor",
1757
+ "columnRuleColor"
1758
+ ]);
1759
+ var SPACING_PROPERTIES = /* @__PURE__ */ new Set([
1760
+ "padding",
1761
+ "paddingTop",
1762
+ "paddingRight",
1763
+ "paddingBottom",
1764
+ "paddingLeft",
1765
+ "paddingInline",
1766
+ "paddingBlock",
1767
+ "margin",
1768
+ "marginTop",
1769
+ "marginRight",
1770
+ "marginBottom",
1771
+ "marginLeft",
1772
+ "marginInline",
1773
+ "marginBlock",
1774
+ "gap",
1775
+ "rowGap",
1776
+ "columnGap",
1777
+ "top",
1778
+ "right",
1779
+ "bottom",
1780
+ "left",
1781
+ "inset",
1782
+ "width",
1783
+ "height",
1784
+ "minWidth",
1785
+ "maxWidth",
1786
+ "minHeight",
1787
+ "maxHeight",
1788
+ "flexBasis",
1789
+ "borderRadius",
1790
+ "borderTopLeftRadius",
1791
+ "borderTopRightRadius",
1792
+ "borderBottomLeftRadius",
1793
+ "borderBottomRightRadius",
1794
+ "round",
1795
+ "boxSize",
1796
+ "widthRange",
1797
+ "heightRange",
1798
+ "borderWidth",
1799
+ "outlineOffset",
1800
+ "outlineWidth"
1801
+ ]);
1802
+ var FONT_SIZE_PROPERTIES = /* @__PURE__ */ new Set([
1803
+ "fontSize",
1804
+ "lineHeight",
1805
+ "letterSpacing"
1806
+ ]);
1807
+ var INPUT_TYPES = [
1808
+ "text",
1809
+ "password",
1810
+ "email",
1811
+ "number",
1812
+ "tel",
1813
+ "url",
1814
+ "search",
1815
+ "date",
1816
+ "time",
1817
+ "datetime-local",
1818
+ "month",
1819
+ "week",
1820
+ "color",
1821
+ "range",
1822
+ "file",
1823
+ "hidden",
1824
+ "checkbox",
1825
+ "radio",
1826
+ "submit",
1827
+ "reset",
1828
+ "button",
1829
+ "image"
1830
+ ];
1831
+ var TARGET_VALUES = ["_self", "_blank", "_parent", "_top"];
1832
+ var REL_VALUES = [
1833
+ "noopener",
1834
+ "noreferrer",
1835
+ "nofollow",
1836
+ "external",
1837
+ "noopener noreferrer",
1838
+ "stylesheet",
1839
+ "icon",
1840
+ "preload",
1841
+ "prefetch"
1842
+ ];
1843
+ var AUTOCOMPLETE_VALUES = [
1844
+ "off",
1845
+ "on",
1846
+ "name",
1847
+ "email",
1848
+ "username",
1849
+ "new-password",
1850
+ "current-password",
1851
+ "tel",
1852
+ "address-line1",
1853
+ "address-line2",
1854
+ "country",
1855
+ "postal-code"
1856
+ ];
1857
+ var BOOLEAN_VALUES = ["true", "false"];
1858
+ var LOADING_VALUES = ["lazy", "eager"];
1859
+
1860
+ // src/providers/workspaceScanner.ts
1861
+ var vscode = __toESM(require("vscode"));
1862
+ var SCAN_INTERVAL = 3e4;
1863
+ var PASCAL_CASE_RE = /^[A-Z][a-zA-Z0-9]+$/;
1864
+ var cache = { components: /* @__PURE__ */ new Map(), lastScan: 0 };
1865
+ var EXPORT_RE = /export\s+(?:const|let|var|function)\s+([A-Z][a-zA-Z0-9]+)/g;
1866
+ var OBJECT_KEY_RE = /^\s+([A-Z][a-zA-Z0-9]+)\s*[:{]/gm;
1867
+ function extractComponentsWithLines(text) {
1868
+ const results = [];
1869
+ const seen = /* @__PURE__ */ new Set();
1870
+ EXPORT_RE.lastIndex = 0;
1871
+ let m;
1872
+ while (m = EXPORT_RE.exec(text)) {
1873
+ if (PASCAL_CASE_RE.test(m[1]) && !seen.has(m[1])) {
1874
+ seen.add(m[1]);
1875
+ const line = text.substring(0, m.index).split("\n").length - 1;
1876
+ results.push({ name: m[1], line });
1877
+ }
1878
+ }
1879
+ OBJECT_KEY_RE.lastIndex = 0;
1880
+ while (m = OBJECT_KEY_RE.exec(text)) {
1881
+ if (PASCAL_CASE_RE.test(m[1]) && !seen.has(m[1])) {
1882
+ seen.add(m[1]);
1883
+ const line = text.substring(0, m.index).split("\n").length - 1;
1884
+ results.push({ name: m[1], line });
1885
+ }
1886
+ }
1887
+ return results;
1888
+ }
1889
+ async function scanWorkspaceComponents() {
1890
+ await ensureScan();
1891
+ return [...cache.components.keys()].sort();
1892
+ }
1893
+ async function ensureScan() {
1894
+ const now = Date.now();
1895
+ if (now - cache.lastScan < SCAN_INTERVAL && cache.components.size > 0) return;
1896
+ const components = /* @__PURE__ */ new Map();
1897
+ try {
1898
+ const files = await vscode.workspace.findFiles(
1899
+ "**/*.{js,ts,jsx,tsx}",
1900
+ "{**/node_modules/**,**/dist/**,**/out/**,**/build/**,.next/**}",
1901
+ 500
1902
+ );
1903
+ for (const file of files) {
1904
+ try {
1905
+ const doc = await vscode.workspace.openTextDocument(file);
1906
+ const text = doc.getText();
1907
+ if (/extends\s*:|childExtends|from\s+['"](@domql|@symbo\.ls|smbls)/.test(text)) {
1908
+ for (const { name, line } of extractComponentsWithLines(text)) {
1909
+ if (!components.has(name)) {
1910
+ components.set(name, { uri: file, line });
1911
+ }
1912
+ }
1913
+ }
1914
+ } catch {
1915
+ }
1916
+ }
1917
+ } catch {
1918
+ }
1919
+ cache = { components, lastScan: now };
1920
+ }
1921
+ function invalidateCache() {
1922
+ cache.lastScan = 0;
1923
+ }
1924
+
1925
+ // src/providers/completionProvider.ts
1926
+ var DOMQL_IMPORT_RE = /from\s+['"](@domql\/|domql|@symbo\.ls\/|smbls)/;
1927
+ var DOMQL_SIGNATURE_RE = /\b(extends|childExtends|childExtendsRecursive|onRender|onStateUpdate|onInit)\s*:/;
1928
+ var DESIGN_SYSTEM_RE = /\b(flow|theme|round|boxSize|childExtend|widthRange|heightRange)\s*:\s*['"`]/;
1929
+ var COMPONENT_EXPORT_RE = /export\s+(?:const|let|var)\s+[A-Z][a-zA-Z0-9]+\s*=\s*\{/;
1930
+ function isDomqlFile(text, detectByImports) {
1931
+ if (DOMQL_IMPORT_RE.test(text)) return true;
1932
+ if (!detectByImports) return true;
1933
+ if (DOMQL_SIGNATURE_RE.test(text)) return true;
1934
+ if (DESIGN_SYSTEM_RE.test(text)) return true;
1935
+ if (COMPONENT_EXPORT_RE.test(text)) return true;
1936
+ return false;
1937
+ }
1938
+ function findEnclosingKey(text, offset) {
1939
+ let depth = 0;
1940
+ for (let i = offset - 1; i >= 0; i--) {
1941
+ const ch = text[i];
1942
+ if (ch === "}" || ch === "]") {
1943
+ depth++;
1944
+ } else if (ch === "{" || ch === "[") {
1945
+ if (depth === 0) {
1946
+ const before = text.substring(0, i).trimEnd();
1947
+ const m = before.match(/(\w+)\s*:\s*$/);
1948
+ return m ? m[1] : null;
1949
+ }
1950
+ depth--;
1951
+ }
1952
+ }
1953
+ return null;
1954
+ }
1955
+ function isAtKeyPosition(linePrefix) {
1956
+ const afterDelim = linePrefix.split(/[,{]/).pop() ?? "";
1957
+ return !/:/.test(afterDelim);
1958
+ }
1959
+ function getPropertyNameBeforeColon(linePrefix) {
1960
+ const m = linePrefix.match(/(\w+)\s*:\s*['"]?[^,{}]*$/);
1961
+ return m ? m[1] : null;
1962
+ }
1963
+ function findTagInScope(text, offset) {
1964
+ let depth = 0;
1965
+ let braceStart = -1;
1966
+ for (let i = offset - 1; i >= 0; i--) {
1967
+ const ch = text[i];
1968
+ if (ch === "}") depth++;
1969
+ else if (ch === "{") {
1970
+ if (depth === 0) {
1971
+ braceStart = i;
1972
+ break;
1973
+ }
1974
+ depth--;
1975
+ }
1976
+ }
1977
+ if (braceStart === -1) return null;
1978
+ const scope = text.substring(braceStart, Math.min(offset + 500, text.length));
1979
+ const tagMatch = scope.match(/tag\s*:\s*['"](\w+)['"]/);
1980
+ return tagMatch ? tagMatch[1] : null;
1981
+ }
1982
+ function isInsideCallArgs(linePrefix) {
1983
+ return /\.call\(\s*['"][^'"]*$/.test(linePrefix);
1984
+ }
1985
+ function isInsideStringValue(linePrefix) {
1986
+ const singleQuotes = (linePrefix.match(/(?<![\\])'/g) || []).length;
1987
+ const doubleQuotes = (linePrefix.match(/(?<![\\])"/g) || []).length;
1988
+ return singleQuotes % 2 === 1 || doubleQuotes % 2 === 1;
1989
+ }
1990
+ function getPropertyForStringValue(linePrefix) {
1991
+ const m = linePrefix.match(/(\w+)\s*:\s*['"][^'"]*$/);
1992
+ return m ? m[1] : null;
1993
+ }
1994
+ function detectContext(document, position) {
1995
+ const linePrefix = document.lineAt(position).text.substring(0, position.character);
1996
+ if (isInsideCallArgs(linePrefix)) return { type: "call-arg" };
1997
+ if (/\bel\.\s*$/.test(linePrefix)) return { type: "el-method" };
1998
+ if (/\bstate\.\s*$/.test(linePrefix)) return { type: "state-method" };
1999
+ const fullText = document.getText();
2000
+ const config = vscode2.workspace.getConfiguration("symbolsApp");
2001
+ if (!isDomqlFile(fullText, config.get("detectByImports", true))) return { type: "none" };
2002
+ const offset = document.offsetAt(position);
2003
+ const enclosingKey = findEnclosingKey(fullText, offset);
2004
+ const tag = findTagInScope(fullText, offset) ?? void 0;
2005
+ if (isInsideStringValue(linePrefix)) {
2006
+ const prop = getPropertyForStringValue(linePrefix);
2007
+ if (prop) {
2008
+ if (enclosingKey === "attr") {
2009
+ return { type: "attr-value", propertyName: prop, enclosingTag: tag, inString: true };
2010
+ }
2011
+ return { type: "element-value", propertyName: prop, enclosingKey: enclosingKey ?? void 0, enclosingTag: tag, inString: true };
2012
+ }
2013
+ }
2014
+ const atKeyPos = isAtKeyPosition(linePrefix);
2015
+ const propertyName = !atKeyPos ? getPropertyNameBeforeColon(linePrefix) : null;
2016
+ if (enclosingKey === "attr") {
2017
+ if (atKeyPos) return { type: "attr-key", enclosingTag: tag };
2018
+ return { type: "attr-value", propertyName: propertyName ?? void 0, enclosingTag: tag };
2019
+ }
2020
+ if (enclosingKey === "state") return { type: "state-key" };
2021
+ if (enclosingKey === "on") return { type: "on-key" };
2022
+ if (enclosingKey === "define") return { type: "define-key" };
2023
+ if (!atKeyPos && propertyName) {
2024
+ return { type: "element-value", propertyName, enclosingKey: enclosingKey ?? void 0, enclosingTag: tag };
2025
+ }
2026
+ if (atKeyPos) return { type: "element-key" };
2027
+ return { type: "none" };
2028
+ }
2029
+ function mkItem(label, kind, detail, docs, snippet, sort = "5") {
2030
+ const item = new vscode2.CompletionItem(label, kind);
2031
+ item.detail = detail;
2032
+ const md = new vscode2.MarkdownString(docs);
2033
+ md.isTrusted = true;
2034
+ item.documentation = md;
2035
+ if (snippet) item.insertText = new vscode2.SnippetString(snippet);
2036
+ item.sortText = sort + label;
2037
+ return item;
2038
+ }
2039
+ function mkValueItem(label, detail, docs, sort = "1", inString = false) {
2040
+ const item = new vscode2.CompletionItem(label, vscode2.CompletionItemKind.Value);
2041
+ item.detail = detail;
2042
+ if (docs) {
2043
+ const md = new vscode2.MarkdownString(docs);
2044
+ md.isTrusted = true;
2045
+ item.documentation = md;
2046
+ }
2047
+ item.sortText = sort + label;
2048
+ item.filterText = label;
2049
+ item.range = void 0;
2050
+ if (!inString) {
2051
+ item.insertText = new vscode2.SnippetString(`'${label}'`);
2052
+ }
2053
+ return item;
2054
+ }
2055
+ function getElementKeyCompletions() {
2056
+ const config = vscode2.workspace.getConfiguration("symbolsApp");
2057
+ const items = [];
2058
+ for (const k of DOMQL_ALL_KEYS) {
2059
+ items.push(mkItem(k.label, vscode2.CompletionItemKind.Property, k.detail, k.documentation, k.snippet, "1"));
2060
+ }
2061
+ for (const ev of DOMQL_LIFECYCLE_EVENTS) {
2062
+ items.push(mkItem(ev.label, vscode2.CompletionItemKind.Event, ev.detail, ev.documentation, ev.snippet, "2"));
2063
+ }
2064
+ for (const ev of DOM_EVENTS) {
2065
+ items.push(mkItem(ev.label, vscode2.CompletionItemKind.Event, ev.detail, ev.documentation, ev.snippet, "3"));
2066
+ }
2067
+ for (const c of ALL_COMPONENTS) {
2068
+ items.push(mkItem(c.label, vscode2.CompletionItemKind.Class, c.detail, c.documentation, c.snippet, "4"));
2069
+ }
2070
+ if (config.get("completeCssProps", true)) {
2071
+ for (const p of ALL_CSS_PROPS) {
2072
+ items.push(mkItem(p.label, vscode2.CompletionItemKind.Property, p.detail, p.documentation ?? "", void 0, "5"));
2073
+ }
2074
+ }
2075
+ return items;
2076
+ }
2077
+ function getAttrKeyCompletions(tag) {
2078
+ return HTML_ATTRIBUTES.map((attr) => {
2079
+ const item = new vscode2.CompletionItem(attr, vscode2.CompletionItemKind.Property);
2080
+ item.detail = `HTML attribute: ${attr}`;
2081
+ const needsQuotes = attr.includes("-");
2082
+ item.insertText = new vscode2.SnippetString(
2083
+ needsQuotes ? `"${attr}": \${1:},` : `${attr}: \${1:},`
2084
+ );
2085
+ return item;
2086
+ });
2087
+ }
2088
+ function getOnKeyCompletions() {
2089
+ return [...DOM_EVENTS, ...DOMQL_LIFECYCLE_EVENTS].map((ev) => {
2090
+ const raw = ev.label.charAt(2).toLowerCase() + ev.label.slice(3);
2091
+ const item = new vscode2.CompletionItem(raw, vscode2.CompletionItemKind.Event);
2092
+ item.detail = `on.${raw} (v2 \u2014 prefer top-level ${ev.label})`;
2093
+ const md = new vscode2.MarkdownString(`**v2 style** \u2014 prefer \`${ev.label}\` in v3.
2094
+
2095
+ ${ev.documentation}`);
2096
+ md.isTrusted = true;
2097
+ item.documentation = md;
2098
+ const sig = ev.isDomqlLifecycle ? `${raw}: (el, state) => {
2099
+ \${1:}
2100
+ },` : `${raw}: (event, el, state) => {
2101
+ \${1:}
2102
+ },`;
2103
+ item.insertText = new vscode2.SnippetString(sig);
2104
+ return item;
2105
+ });
2106
+ }
2107
+ function getElementMethodCompletions() {
2108
+ return ELEMENT_METHODS.map((m) => {
2109
+ const item = new vscode2.CompletionItem(m.label, vscode2.CompletionItemKind.Method);
2110
+ item.detail = m.detail;
2111
+ const md = new vscode2.MarkdownString(m.documentation);
2112
+ md.isTrusted = true;
2113
+ item.documentation = md;
2114
+ item.insertText = new vscode2.SnippetString(m.snippet);
2115
+ return item;
2116
+ });
2117
+ }
2118
+ function getStateMethodCompletions() {
2119
+ return STATE_METHODS.map((m) => {
2120
+ const item = new vscode2.CompletionItem(m.label, vscode2.CompletionItemKind.Method);
2121
+ item.detail = m.detail;
2122
+ const md = new vscode2.MarkdownString(m.documentation);
2123
+ md.isTrusted = true;
2124
+ item.documentation = md;
2125
+ item.insertText = new vscode2.SnippetString(m.snippet);
2126
+ return item;
2127
+ });
2128
+ }
2129
+ function getStateKeyCompletions() {
2130
+ const common = [
2131
+ ["loading", "false", "Loading flag"],
2132
+ ["error", "null", "Error message or null"],
2133
+ ["data", "null", "Fetched data"],
2134
+ ["open", "false", "Open/closed toggle"],
2135
+ ["active", "null", "Currently active item key"],
2136
+ ["selected", "null", "Currently selected value"],
2137
+ ["count", "0", "Numeric counter"],
2138
+ ["items", "[]", "Array of items"],
2139
+ ["value", "''", "Input value"]
2140
+ ];
2141
+ return common.map(([key, def, desc]) => {
2142
+ const item = new vscode2.CompletionItem(key, vscode2.CompletionItemKind.Property);
2143
+ item.detail = `${key}: ${def}`;
2144
+ item.documentation = new vscode2.MarkdownString(desc);
2145
+ item.insertText = new vscode2.SnippetString(`${key}: \${1:${def}},`);
2146
+ return item;
2147
+ });
2148
+ }
2149
+ function getColorCompletions(inString = false) {
2150
+ const items = [];
2151
+ for (const c of COLOR_TOKEN_MAP) {
2152
+ const desc = c.description || "";
2153
+ const detail = c.hex ? `${c.hex}` : c.description || "Color token";
2154
+ const docs = c.hex ? `\`${c.label}\` \u2192 \`${c.hex}\`
2155
+
2156
+ Modifiers: \`${c.label}.5\` (opacity), \`${c.label}+16\` (lighten), \`${c.label}-16\` (darken), \`${c.label}=50\` (set lightness)` : `${desc}
2157
+
2158
+ Modifiers: \`${c.label}.5\` (opacity)`;
2159
+ items.push(mkValueItem(c.label, detail, docs, "1", inString));
2160
+ }
2161
+ for (const g of GRADIENT_TOKENS) {
2162
+ items.push(mkValueItem(g, `Gradient: ${g}`, "Design system gradient token", "2", inString));
2163
+ }
2164
+ return items;
2165
+ }
2166
+ function getSpacingCompletions(inString = false) {
2167
+ const cfg = SEQUENCE_CONFIGS.spacing;
2168
+ return SPACING_TOKENS.map((token, i) => {
2169
+ const sort = String(i).padStart(2, "0");
2170
+ return mkValueItem(token.label, `${token.label} \u2192 ${token.approxValue}`, `**Spacing** \`${token.label}\` \u2248 **${token.approxValue}**
2171
+
2172
+ Base: A = ${cfg.base}px, ratio: ${cfg.ratio} (golden ratio)
2173
+
2174
+ Scale: W X Y Z **A** B C D E F G H
2175
+
2176
+ Sub-steps: A1, A2 interpolate between A and B
2177
+
2178
+ Operations: \`A+B\`, \`A-Z\`, \`A*2\`, \`-A\` (negative)`, sort, inString);
2179
+ });
2180
+ }
2181
+ function getFontSizeCompletions(inString = false) {
2182
+ const cfg = SEQUENCE_CONFIGS.typography;
2183
+ return TYPOGRAPHY_TOKENS.map((token, i) => {
2184
+ const sort = String(i).padStart(2, "0");
2185
+ return mkValueItem(token.label, `${token.label} \u2192 ${token.approxValue}`, `**Typography** \`${token.label}\` \u2248 **${token.approxValue}**
2186
+
2187
+ Base: A = ${cfg.base}px, ratio: ${cfg.ratio} (major third)
2188
+
2189
+ Scale: X Y Z **A** B C D E F G H`, sort, inString);
2190
+ });
2191
+ }
2192
+ function getThemeCompletions(inString = false) {
2193
+ const items = [];
2194
+ for (const t of THEME_TOKENS) {
2195
+ items.push(mkValueItem(t, `Theme: ${t}`, `Apply design system theme.
2196
+
2197
+ Modifiers: \`"${t} .child"\`, \`"${t} .color-only"\``, "1", inString));
2198
+ }
2199
+ for (const t of ["primary", "secondary", "card", "dialog", "label"]) {
2200
+ for (const mod of THEME_MODIFIERS) {
2201
+ items.push(mkValueItem(`${t} ${mod}`, `Theme modifier: ${t} ${mod}`, `Theme \`${t}\` with modifier \`${mod}\``, "3", inString));
2202
+ }
2203
+ }
2204
+ return items;
2205
+ }
2206
+ function getIconCompletions(inString = false) {
2207
+ return ICON_NAMES.map(
2208
+ (name) => mkValueItem(name, `Icon: ${name}`, `Default icon from design system`, "1", inString)
2209
+ );
2210
+ }
2211
+ function getExtendsCompletions(workspaceComponents, inString = false) {
2212
+ const items = [];
2213
+ for (const c of ALL_COMPONENTS) {
2214
+ items.push(mkValueItem(c.label, c.detail, c.documentation, "1", inString));
2215
+ }
2216
+ for (const name of workspaceComponents) {
2217
+ if (ALL_COMPONENTS.some((c) => c.label === name)) continue;
2218
+ items.push(mkValueItem(name, `Project component: ${name}`, "Detected from workspace", "2", inString));
2219
+ }
2220
+ return items;
2221
+ }
2222
+ function getTagCompletions(inString = false) {
2223
+ return HTML_TAGS.map(
2224
+ (tag) => mkValueItem(tag, `HTML tag: <${tag}>`, void 0, "1", inString)
2225
+ );
2226
+ }
2227
+ function getCssEnumCompletions(property, inString = false) {
2228
+ const values = CSS_VALUE_ENUMS[property];
2229
+ if (!values) return [];
2230
+ return values.map((v) => mkValueItem(v, `${property}: ${v}`, void 0, "1", inString));
2231
+ }
2232
+ function getAttrValueCompletions(attrName) {
2233
+ switch (attrName) {
2234
+ case "type":
2235
+ return INPUT_TYPES.map((t) => mkValueItem(t, `type="${t}"`, void 0, "1"));
2236
+ case "target":
2237
+ return TARGET_VALUES.map((t) => mkValueItem(t, `target="${t}"`, void 0, "1"));
2238
+ case "rel":
2239
+ return REL_VALUES.map((r) => mkValueItem(r, `rel="${r}"`, void 0, "1"));
2240
+ case "autocomplete":
2241
+ return AUTOCOMPLETE_VALUES.map((a) => mkValueItem(a, `autocomplete="${a}"`, void 0, "1"));
2242
+ case "loading":
2243
+ return LOADING_VALUES.map((l) => mkValueItem(l, `loading="${l}"`, void 0, "1"));
2244
+ case "disabled":
2245
+ case "checked":
2246
+ case "required":
2247
+ case "readonly":
2248
+ case "multiple":
2249
+ case "hidden":
2250
+ case "draggable":
2251
+ case "contenteditable":
2252
+ case "spellcheck":
2253
+ case "novalidate":
2254
+ case "autofocus":
2255
+ return BOOLEAN_VALUES.map((b) => mkValueItem(b, `${attrName}="${b}"`, void 0, "1"));
2256
+ case "role":
2257
+ return [
2258
+ "button",
2259
+ "link",
2260
+ "dialog",
2261
+ "alert",
2262
+ "navigation",
2263
+ "menu",
2264
+ "menuitem",
2265
+ "tab",
2266
+ "tablist",
2267
+ "tabpanel",
2268
+ "checkbox",
2269
+ "radio",
2270
+ "listbox",
2271
+ "option",
2272
+ "textbox",
2273
+ "search",
2274
+ "progressbar",
2275
+ "slider",
2276
+ "switch",
2277
+ "tooltip",
2278
+ "img",
2279
+ "heading",
2280
+ "list",
2281
+ "listitem",
2282
+ "group",
2283
+ "region",
2284
+ "banner",
2285
+ "main",
2286
+ "complementary",
2287
+ "contentinfo",
2288
+ "form",
2289
+ "presentation",
2290
+ "none"
2291
+ ].map((r) => mkValueItem(r, `role="${r}"`, void 0, "1"));
2292
+ case "dir":
2293
+ return ["ltr", "rtl", "auto"].map((d) => mkValueItem(d, `dir="${d}"`, void 0, "1"));
2294
+ case "method":
2295
+ return ["get", "post", "put", "delete", "patch"].map((m) => mkValueItem(m, `method="${m}"`, void 0, "1"));
2296
+ case "enctype":
2297
+ return ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"].map((e) => mkValueItem(e, `enctype="${e}"`, void 0, "1"));
2298
+ default:
2299
+ return [];
2300
+ }
2301
+ }
2302
+ function getCallArgCompletions() {
2303
+ const fns = [
2304
+ ["exec", "Execute a dynamic prop value"],
2305
+ ["fetchData", "Fetch data from API"],
2306
+ ["router", "Navigate to a route"],
2307
+ ["isString", "Check if value is string"],
2308
+ ["isObject", "Check if value is object"],
2309
+ ["isArray", "Check if value is array"],
2310
+ ["isNumber", "Check if value is number"],
2311
+ ["isFunction", "Check if value is function"],
2312
+ ["isBoolean", "Check if value is boolean"],
2313
+ ["isDefined", "Check if value is defined"],
2314
+ ["isUndefined", "Check if value is undefined"],
2315
+ ["isNull", "Check if value is null"],
2316
+ ["isEmpty", "Check if value is empty"],
2317
+ ["deepMerge", "Deep merge objects"],
2318
+ ["deepClone", "Deep clone an object"],
2319
+ ["getSystemTheme", "Get current system color scheme"],
2320
+ ["setTheme", "Set application theme"]
2321
+ ];
2322
+ return fns.map(
2323
+ ([name, desc]) => mkValueItem(name, desc, `Context function: \`el.call("${name}", ...args)\`
2324
+
2325
+ Resolution: utils \u2192 functions \u2192 methods \u2192 snippets`, "1")
2326
+ );
2327
+ }
2328
+ async function getValueCompletions(ctx) {
2329
+ const prop = ctx.propertyName;
2330
+ if (!prop) return [];
2331
+ const inStr = ctx.inString ?? false;
2332
+ if (prop === "extends" || prop === "childExtends" || prop === "childExtendsRecursive" || prop === "childExtend") {
2333
+ const wsComponents = await scanWorkspaceComponents();
2334
+ return getExtendsCompletions(wsComponents, inStr);
2335
+ }
2336
+ if (prop === "tag") return getTagCompletions(inStr);
2337
+ if (prop === "theme") return getThemeCompletions(inStr);
2338
+ if (prop === "icon" || prop === "name") return getIconCompletions(inStr);
2339
+ if (COLOR_PROPERTIES.has(prop)) return getColorCompletions(inStr);
2340
+ if (SPACING_PROPERTIES.has(prop)) return getSpacingCompletions(inStr);
2341
+ if (FONT_SIZE_PROPERTIES.has(prop)) return getFontSizeCompletions(inStr);
2342
+ const enumItems = getCssEnumCompletions(prop, inStr);
2343
+ if (enumItems.length > 0) return enumItems;
2344
+ if (prop === "transition" || prop === "transitionDuration" || prop === "animationDuration") {
2345
+ const cfg = SEQUENCE_CONFIGS.timing;
2346
+ const items = TIMING_TOKENS.map((t, i) => {
2347
+ const sort = String(i).padStart(2, "0");
2348
+ return mkValueItem(t.label, `${t.label} \u2192 ${t.approxValue}`, `**Timing** \`${t.label}\` \u2248 **${t.approxValue}**
2349
+
2350
+ Base: A = ${cfg.base}ms, ratio: ${cfg.ratio} (perfect fourth)`, sort, inStr);
2351
+ });
2352
+ if (prop === "transition") {
2353
+ items.push(mkValueItem("A defaultBezier", "transition: A defaultBezier", "Common transition with default easing", "99", inStr));
2354
+ }
2355
+ return items;
2356
+ }
2357
+ return [];
2358
+ }
2359
+ var DomqlCompletionProvider = class {
2360
+ async provideCompletionItems(document, position) {
2361
+ if (!vscode2.workspace.getConfiguration("symbolsApp").get("enable", true)) return [];
2362
+ const ctx = detectContext(document, position);
2363
+ let items;
2364
+ switch (ctx.type) {
2365
+ case "el-method":
2366
+ items = getElementMethodCompletions();
2367
+ break;
2368
+ case "state-method":
2369
+ items = getStateMethodCompletions();
2370
+ break;
2371
+ case "call-arg":
2372
+ items = getCallArgCompletions();
2373
+ break;
2374
+ case "attr-key":
2375
+ items = getAttrKeyCompletions(ctx.enclosingTag);
2376
+ break;
2377
+ case "attr-value":
2378
+ items = ctx.propertyName ? getAttrValueCompletions(ctx.propertyName) : [];
2379
+ break;
2380
+ case "on-key":
2381
+ items = getOnKeyCompletions();
2382
+ break;
2383
+ case "state-key":
2384
+ items = getStateKeyCompletions();
2385
+ break;
2386
+ case "define-key":
2387
+ items = [mkItem(
2388
+ "propName",
2389
+ vscode2.CompletionItemKind.Property,
2390
+ "(param, el, state, context) => void",
2391
+ "Custom property transformer \u2014 runs when this key appears on any element.",
2392
+ "propName: (param, el, state) => {\n ${1:}\n},",
2393
+ "1"
2394
+ )];
2395
+ break;
2396
+ case "element-value":
2397
+ items = await getValueCompletions(ctx);
2398
+ break;
2399
+ case "element-key": {
2400
+ items = getElementKeyCompletions();
2401
+ const wsComponents = await scanWorkspaceComponents();
2402
+ for (const name of wsComponents) {
2403
+ if (ALL_COMPONENTS.some((c) => c.label === name)) continue;
2404
+ items.push(mkItem(
2405
+ name,
2406
+ vscode2.CompletionItemKind.Class,
2407
+ `Project component: ${name}`,
2408
+ "Detected from workspace files",
2409
+ `${name}: {
2410
+ \${1:}
2411
+ },`,
2412
+ "4"
2413
+ ));
2414
+ }
2415
+ break;
2416
+ }
2417
+ default:
2418
+ return [];
2419
+ }
2420
+ if (items.length === 0) return [];
2421
+ return new vscode2.CompletionList(items, true);
2422
+ }
2423
+ };
2424
+
2425
+ // src/providers/hoverProvider.ts
2426
+ var vscode3 = __toESM(require("vscode"));
2427
+ var keyMap = /* @__PURE__ */ new Map();
2428
+ for (const k of DOMQL_ALL_KEYS) {
2429
+ keyMap.set(k.label, `**${k.detail}**
2430
+
2431
+ ${k.documentation}`);
2432
+ }
2433
+ for (const ev of ALL_EVENTS) {
2434
+ keyMap.set(ev.label, `**${ev.detail}**
2435
+
2436
+ ${ev.documentation}`);
2437
+ }
2438
+ for (const m of ELEMENT_METHODS) {
2439
+ keyMap.set(m.label, `**${m.detail}**
2440
+
2441
+ ${m.documentation}`);
2442
+ }
2443
+ for (const m of STATE_METHODS) {
2444
+ keyMap.set(`state.${m.label}`, `**${m.detail}**
2445
+
2446
+ ${m.documentation}`);
2447
+ }
2448
+ for (const c of ALL_COMPONENTS) {
2449
+ keyMap.set(c.label, `**${c.detail}**
2450
+
2451
+ ${c.documentation}`);
2452
+ }
2453
+ for (const p of ALL_CSS_PROPS) {
2454
+ if (p.documentation) keyMap.set(p.label, `**${p.detail}**
2455
+
2456
+ ${p.documentation}`);
2457
+ }
2458
+ var valueHints = /* @__PURE__ */ new Map();
2459
+ for (const c of COLOR_TOKEN_MAP) {
2460
+ if (c.label !== "inherit" && c.label !== "none" && c.label !== "currentColor") {
2461
+ const hexInfo = c.hex ? ` \u2192 \`${c.hex}\`` : "";
2462
+ const desc = c.description ? `
2463
+
2464
+ ${c.description}` : "";
2465
+ valueHints.set(c.label, `**Color token:** \`${c.label}\`${hexInfo}${desc}
2466
+
2467
+ Modifiers: \`${c.label}.5\` (opacity), \`${c.label}+16\` (lighten), \`${c.label}-16\` (darken), \`${c.label}=50\` (set lightness)`);
2468
+ }
2469
+ }
2470
+ for (const g of GRADIENT_TOKENS) {
2471
+ valueHints.set(g, `**Gradient token:** \`${g}\``);
2472
+ }
2473
+ for (const t of THEME_TOKENS) {
2474
+ valueHints.set(t, `**Theme:** \`${t}\`
2475
+
2476
+ Usage: \`theme: "${t}"\`
2477
+
2478
+ Modifiers: \`"${t} .child"\`, \`"${t} .color-only"\``);
2479
+ }
2480
+ function getPropertyContext(document, position) {
2481
+ const line = document.lineAt(position).text;
2482
+ const colonIdx = line.indexOf(":");
2483
+ if (colonIdx === -1 || position.character <= colonIdx) return null;
2484
+ const beforeColon = line.substring(0, colonIdx).trim();
2485
+ const m = beforeColon.match(/(\w+)$/);
2486
+ return m ? m[1] : null;
2487
+ }
2488
+ var DomqlHoverProvider = class {
2489
+ provideHover(document, position) {
2490
+ if (!vscode3.workspace.getConfiguration("symbolsApp").get("enable", true)) return null;
2491
+ const fullText = document.getText();
2492
+ const config = vscode3.workspace.getConfiguration("symbolsApp");
2493
+ if (!isDomqlFile(fullText, config.get("detectByImports", true))) return null;
2494
+ const wordRange = document.getWordRangeAtPosition(position, /[\w.@:-]+/);
2495
+ if (!wordRange) return null;
2496
+ const word = document.getText(wordRange);
2497
+ const docs = keyMap.get(word);
2498
+ if (docs) {
2499
+ const md = new vscode3.MarkdownString(docs);
2500
+ md.isTrusted = true;
2501
+ return new vscode3.Hover(md, wordRange);
2502
+ }
2503
+ const prop = getPropertyContext(document, position);
2504
+ if (prop) {
2505
+ if (SPACING_PROPERTIES.has(prop)) {
2506
+ const token = SPACING_TOKENS.find((t) => t.label === word);
2507
+ if (token) {
2508
+ const cfg = SEQUENCE_CONFIGS.spacing;
2509
+ const md = new vscode3.MarkdownString(`**Spacing token:** \`${word}\` \u2248 **${token.approxValue}**
2510
+
2511
+ Base: A = ${cfg.base}px, ratio: ${cfg.ratio} (golden ratio)
2512
+
2513
+ Scale: W X Y Z **A** B C D E F G H
2514
+
2515
+ Operations: \`A+B\`, \`A-Z\`, \`A*2\`, \`-A\` (negative)`);
2516
+ md.isTrusted = true;
2517
+ return new vscode3.Hover(md, wordRange);
2518
+ }
2519
+ }
2520
+ if (FONT_SIZE_PROPERTIES.has(prop)) {
2521
+ const token = TYPOGRAPHY_TOKENS.find((t) => t.label === word);
2522
+ if (token) {
2523
+ const cfg = SEQUENCE_CONFIGS.typography;
2524
+ const md = new vscode3.MarkdownString(`**Typography token:** \`${word}\` \u2248 **${token.approxValue}**
2525
+
2526
+ Base: A = ${cfg.base}px, ratio: ${cfg.ratio} (major third)
2527
+
2528
+ Scale: X Y Z **A** B C D E F G H`);
2529
+ md.isTrusted = true;
2530
+ return new vscode3.Hover(md, wordRange);
2531
+ }
2532
+ }
2533
+ if (prop === "transition" || prop === "transitionDuration" || prop === "animationDuration") {
2534
+ const token = TIMING_TOKENS.find((t) => t.label === word);
2535
+ if (token) {
2536
+ const cfg = SEQUENCE_CONFIGS.timing;
2537
+ const md = new vscode3.MarkdownString(`**Timing token:** \`${word}\` \u2248 **${token.approxValue}**
2538
+
2539
+ Base: A = ${cfg.base}ms, ratio: ${cfg.ratio} (perfect fourth)`);
2540
+ md.isTrusted = true;
2541
+ return new vscode3.Hover(md, wordRange);
2542
+ }
2543
+ }
2544
+ if (COLOR_PROPERTIES.has(prop) || prop === "background") {
2545
+ const hint = valueHints.get(word);
2546
+ if (hint) {
2547
+ const md = new vscode3.MarkdownString(hint);
2548
+ md.isTrusted = true;
2549
+ return new vscode3.Hover(md, wordRange);
2550
+ }
2551
+ }
2552
+ if (prop === "theme") {
2553
+ const hint = valueHints.get(word);
2554
+ if (hint) {
2555
+ const md = new vscode3.MarkdownString(hint);
2556
+ md.isTrusted = true;
2557
+ return new vscode3.Hover(md, wordRange);
2558
+ }
2559
+ }
2560
+ if ((prop === "icon" || prop === "name") && ICON_NAMES.includes(word)) {
2561
+ const md = new vscode3.MarkdownString(`**Icon:** \`${word}\`
2562
+
2563
+ Default icon from design system sprite`);
2564
+ md.isTrusted = true;
2565
+ return new vscode3.Hover(md, wordRange);
2566
+ }
2567
+ }
2568
+ const generalHint = valueHints.get(word);
2569
+ if (generalHint) {
2570
+ const md = new vscode3.MarkdownString(generalHint);
2571
+ md.isTrusted = true;
2572
+ return new vscode3.Hover(md, wordRange);
2573
+ }
2574
+ return null;
2575
+ }
2576
+ };
2577
+
2578
+ // src/providers/definitionProvider.ts
2579
+ var vscode4 = __toESM(require("vscode"));
2580
+ var fs = __toESM(require("fs"));
2581
+ var path = __toESM(require("path"));
2582
+ var PASCAL_CASE_RE2 = /^[A-Z][a-zA-Z0-9]+$/;
2583
+ function findSymbolsConfig(fromPath) {
2584
+ let current = path.dirname(fromPath);
2585
+ while (true) {
2586
+ const configPath = path.join(current, "symbols.json");
2587
+ if (fs.existsSync(configPath)) {
2588
+ try {
2589
+ const json = JSON.parse(fs.readFileSync(configPath, "utf-8"));
2590
+ return { root: current, dir: json.dir || "./symbols" };
2591
+ } catch {
2592
+ return { root: current, dir: "./symbols" };
2593
+ }
2594
+ }
2595
+ const parent = path.dirname(current);
2596
+ if (parent === current) break;
2597
+ current = parent;
2598
+ }
2599
+ return null;
2600
+ }
2601
+ var DomqlDefinitionProvider = class {
2602
+ async provideDefinition(document, position) {
2603
+ if (!vscode4.workspace.getConfiguration("symbolsApp").get("enable", true)) return null;
2604
+ const fullText = document.getText();
2605
+ const config = vscode4.workspace.getConfiguration("symbolsApp");
2606
+ if (!isDomqlFile(fullText, config.get("detectByImports", true))) return null;
2607
+ const wordRange = document.getWordRangeAtPosition(position, /[A-Z][a-zA-Z0-9]+/) || document.getWordRangeAtPosition(position, /[a-zA-Z][a-zA-Z0-9]+/);
2608
+ if (!wordRange) return null;
2609
+ const word = document.getText(wordRange);
2610
+ if (!PASCAL_CASE_RE2.test(word)) return null;
2611
+ const line = document.lineAt(position).text;
2612
+ const insideString = isInsideQuotes(line, wordRange.start.character);
2613
+ const isObjKey = line.substring(wordRange.end.character).trimStart().startsWith(":");
2614
+ const textBefore = line.substring(0, wordRange.start.character);
2615
+ const isDirectRef = /(?:extends|childExtends|childExtendsRecursive|childExtend)\s*:\s*$/.test(textBefore.trimEnd());
2616
+ const isArrayRef = /(?:extends|childExtends)\s*:\s*\[/.test(textBefore);
2617
+ if (!insideString && !isObjKey && !isDirectRef && !isArrayRef) return null;
2618
+ const conventionResult = this.findByConvention(word, document.uri.fsPath);
2619
+ if (conventionResult) return conventionResult;
2620
+ return this.findByWorkspaceSearch(word, document.uri);
2621
+ }
2622
+ findByConvention(name, filePath) {
2623
+ const symConfig = findSymbolsConfig(filePath);
2624
+ const searchDirs = [];
2625
+ if (symConfig) {
2626
+ const symbolsBase = path.resolve(symConfig.root, symConfig.dir);
2627
+ searchDirs.push(
2628
+ path.join(symbolsBase, "components"),
2629
+ symbolsBase,
2630
+ path.join(symConfig.root, "components")
2631
+ );
2632
+ }
2633
+ const fileDir = path.dirname(filePath);
2634
+ searchDirs.push(
2635
+ path.join(fileDir, "..", "components"),
2636
+ // sibling components dir
2637
+ path.join(fileDir, "components"),
2638
+ fileDir
2639
+ );
2640
+ const folders = vscode4.workspace.workspaceFolders;
2641
+ if (folders) {
2642
+ for (const f of folders) {
2643
+ searchDirs.push(
2644
+ path.join(f.uri.fsPath, "components"),
2645
+ path.join(f.uri.fsPath, "symbols", "components")
2646
+ );
2647
+ }
2648
+ }
2649
+ const extensions = [".js", ".ts", ".jsx", ".tsx"];
2650
+ for (const dir of searchDirs) {
2651
+ for (const ext of extensions) {
2652
+ const candidate = path.join(dir, `${name}${ext}`);
2653
+ const loc = this.resolveFile(candidate, name);
2654
+ if (loc) return loc;
2655
+ }
2656
+ for (const ext of extensions) {
2657
+ const candidate = path.join(dir, name, `index${ext}`);
2658
+ const loc = this.resolveFile(candidate, name);
2659
+ if (loc) return loc;
2660
+ }
2661
+ }
2662
+ return null;
2663
+ }
2664
+ resolveFile(filePath, name) {
2665
+ if (!fs.existsSync(filePath)) return null;
2666
+ try {
2667
+ const text = fs.readFileSync(filePath, "utf-8");
2668
+ const lines = text.split("\n");
2669
+ const pattern = new RegExp(`(?:export\\s+)?(?:const|let|var|function)\\s+${name}\\b`);
2670
+ for (let i = 0; i < lines.length; i++) {
2671
+ if (pattern.test(lines[i])) {
2672
+ return new vscode4.Location(vscode4.Uri.file(filePath), new vscode4.Position(i, 0));
2673
+ }
2674
+ }
2675
+ return new vscode4.Location(vscode4.Uri.file(filePath), new vscode4.Position(0, 0));
2676
+ } catch {
2677
+ return new vscode4.Location(vscode4.Uri.file(filePath), new vscode4.Position(0, 0));
2678
+ }
2679
+ }
2680
+ async findByWorkspaceSearch(name, currentUri) {
2681
+ try {
2682
+ const nameFiles = await vscode4.workspace.findFiles(
2683
+ `**/${name}.{js,ts,jsx,tsx}`,
2684
+ "{**/node_modules/**,**/dist/**,**/out/**,**/build/**}",
2685
+ 10
2686
+ );
2687
+ for (const file of nameFiles) {
2688
+ try {
2689
+ const doc = await vscode4.workspace.openTextDocument(file);
2690
+ const text = doc.getText();
2691
+ if (!text.includes(name)) continue;
2692
+ const lines = text.split("\n");
2693
+ for (let i = 0; i < lines.length; i++) {
2694
+ if (new RegExp(`(?:export\\s+)?(?:const|let|var|function)\\s+${name}\\s*[=({]`).test(lines[i])) {
2695
+ return new vscode4.Location(file, new vscode4.Position(i, 0));
2696
+ }
2697
+ }
2698
+ return new vscode4.Location(file, new vscode4.Position(0, 0));
2699
+ } catch {
2700
+ }
2701
+ }
2702
+ const files = await vscode4.workspace.findFiles(
2703
+ "**/*.{js,ts,jsx,tsx}",
2704
+ "{**/node_modules/**,**/dist/**,**/out/**,**/build/**,.next/**}",
2705
+ 300
2706
+ );
2707
+ for (const file of files) {
2708
+ try {
2709
+ const doc = await vscode4.workspace.openTextDocument(file);
2710
+ const text = doc.getText();
2711
+ if (!text.includes(name)) continue;
2712
+ const lines = text.split("\n");
2713
+ for (let i = 0; i < lines.length; i++) {
2714
+ if (new RegExp(`^export\\s+(?:const|let|var)\\s+${name}\\s*=`).test(lines[i])) {
2715
+ return new vscode4.Location(file, new vscode4.Position(i, 0));
2716
+ }
2717
+ }
2718
+ } catch {
2719
+ }
2720
+ }
2721
+ } catch {
2722
+ }
2723
+ return null;
2724
+ }
2725
+ };
2726
+ function isInsideQuotes(line, charIndex) {
2727
+ let inSingle = false;
2728
+ let inDouble = false;
2729
+ for (let i = 0; i < charIndex; i++) {
2730
+ const ch = line[i];
2731
+ const prev = i > 0 ? line[i - 1] : "";
2732
+ if (prev === "\\") continue;
2733
+ if (ch === "'" && !inDouble) inSingle = !inSingle;
2734
+ if (ch === '"' && !inSingle) inDouble = !inDouble;
2735
+ }
2736
+ return inSingle || inDouble;
2737
+ }
2738
+
2739
+ // src/extension.ts
2740
+ var LANGUAGES = ["javascript", "typescript", "javascriptreact", "typescriptreact"];
2741
+ var output;
2742
+ function activate(context) {
2743
+ output = vscode5.window.createOutputChannel("Symbols.app");
2744
+ output.appendLine("Symbols.app extension activating...");
2745
+ const completionProvider = new DomqlCompletionProvider();
2746
+ const hoverProvider = new DomqlHoverProvider();
2747
+ const definitionProvider = new DomqlDefinitionProvider();
2748
+ for (const lang of LANGUAGES) {
2749
+ const selector = { language: lang, scheme: "file" };
2750
+ context.subscriptions.push(
2751
+ vscode5.languages.registerCompletionItemProvider(
2752
+ selector,
2753
+ completionProvider,
2754
+ ".",
2755
+ " ",
2756
+ "\n",
2757
+ ",",
2758
+ ":",
2759
+ "'",
2760
+ '"'
2761
+ )
2762
+ );
2763
+ context.subscriptions.push(
2764
+ vscode5.languages.registerHoverProvider(selector, hoverProvider)
2765
+ );
2766
+ context.subscriptions.push(
2767
+ vscode5.languages.registerDefinitionProvider(selector, definitionProvider)
2768
+ );
2769
+ }
2770
+ const watcher = vscode5.workspace.createFileSystemWatcher("**/*.{js,ts,jsx,tsx}");
2771
+ watcher.onDidChange(() => invalidateCache());
2772
+ watcher.onDidCreate(() => invalidateCache());
2773
+ watcher.onDidDelete(() => invalidateCache());
2774
+ context.subscriptions.push(watcher);
2775
+ context.subscriptions.push(
2776
+ vscode5.commands.registerCommand("symbolsApp.toggle", () => {
2777
+ const config = vscode5.workspace.getConfiguration("symbolsApp");
2778
+ const current = config.get("enable", true);
2779
+ config.update("enable", !current, vscode5.ConfigurationTarget.Global);
2780
+ vscode5.window.showInformationMessage(
2781
+ `Symbols.app ${!current ? "enabled" : "disabled"}`
2782
+ );
2783
+ })
2784
+ );
2785
+ context.subscriptions.push(
2786
+ vscode5.commands.registerCommand("symbolsApp.diagnose", () => {
2787
+ output.show();
2788
+ output.appendLine("--- Diagnostics ---");
2789
+ output.appendLine(`Workspace folders: ${vscode5.workspace.workspaceFolders?.map((f) => f.uri.fsPath).join(", ")}`);
2790
+ const editor = vscode5.window.activeTextEditor;
2791
+ if (editor) {
2792
+ output.appendLine(`Active file: ${editor.document.uri.fsPath}`);
2793
+ output.appendLine(`Language: ${editor.document.languageId}`);
2794
+ const text = editor.document.getText();
2795
+ output.appendLine(`File length: ${text.length}`);
2796
+ output.appendLine(`Has DOMQL import: ${/from\s+['"](@domql\/|domql|@symbo\.ls\/|smbls)/.test(text)}`);
2797
+ output.appendLine(`Has extends/childExtends: ${/\b(extends|childExtends|childExtendsRecursive|onRender|onStateUpdate|onInit)\s*:/.test(text)}`);
2798
+ output.appendLine(`Has design system props: ${/\b(flow|theme|round|boxSize|childExtend|widthRange|heightRange)\s*:\s*['"\`]/.test(text)}`);
2799
+ output.appendLine(`Has component export: ${/export\s+(?:const|let|var)\s+[A-Z][a-zA-Z0-9]+\s*=\s*\{/.test(text)}`);
2800
+ }
2801
+ output.appendLine("--- End ---");
2802
+ vscode5.window.showInformationMessage("Symbols.app: Check Output panel (Symbols.app channel)");
2803
+ })
2804
+ );
2805
+ output.appendLine("Symbols.app extension activated successfully");
2806
+ vscode5.window.showInformationMessage("Symbols.app Connect active");
2807
+ }
2808
+ function deactivate() {
2809
+ }
2810
+ // Annotate the CommonJS export names for ESM import in node:
2811
+ 0 && (module.exports = {
2812
+ activate,
2813
+ deactivate
2814
+ });