juxscript 1.1.71 → 1.1.73

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.
@@ -1,421 +0,0 @@
1
- import { BaseComponent, BaseState } from './base/BaseComponent.js';
2
-
3
- // Event definitions
4
- const TRIGGER_EVENTS = [] as const;
5
- const CALLBACK_EVENTS = ['select', 'expand'] as const;
6
-
7
- export interface BlueprintOptions {
8
- structureData?: any; // dom-structure-map.json
9
- classData?: any; // css-classes-inventory.json
10
- filter?: string; // Filter by component name
11
- showMethods?: boolean;
12
- expandAll?: boolean;
13
- theme?: 'light' | 'dark' | 'auto';
14
- style?: string;
15
- class?: string;
16
- }
17
-
18
- interface BlueprintState extends BaseState {
19
- structureData: any;
20
- classData: any;
21
- filter: string;
22
- showMethods: boolean;
23
- expandAll: boolean;
24
- theme: string;
25
- expandedComponents: Set<string>;
26
- }
27
-
28
- interface ComponentHierarchy {
29
- tag: string;
30
- classes: string[];
31
- id: string | null;
32
- children?: ComponentHierarchy[];
33
- }
34
-
35
- export class Blueprint extends BaseComponent<BlueprintState> {
36
- constructor(id: string, options: BlueprintOptions = {}) {
37
- super(id, {
38
- structureData: options.structureData ?? null,
39
- classData: options.classData ?? null,
40
- filter: options.filter ?? '',
41
- showMethods: options.showMethods ?? true,
42
- expandAll: options.expandAll ?? false,
43
- theme: options.theme ?? 'auto',
44
- expandedComponents: new Set<string>(),
45
- style: options.style ?? '',
46
- class: options.class ?? ''
47
- });
48
- }
49
-
50
- protected getTriggerEvents(): readonly string[] {
51
- return TRIGGER_EVENTS;
52
- }
53
-
54
- protected getCallbackEvents(): readonly string[] {
55
- return CALLBACK_EVENTS;
56
- }
57
-
58
- /* ═════════════════════════════════════════════════════════════════
59
- * FLUENT API
60
- * ═════════════════════════════════════════════════════════════════ */
61
-
62
- structureData(data: any): this {
63
- this.state.structureData = data;
64
- return this;
65
- }
66
-
67
- classData(data: any): this {
68
- this.state.classData = data;
69
- return this;
70
- }
71
-
72
- filter(value: string): this {
73
- this.state.filter = value;
74
- return this;
75
- }
76
-
77
- showMethods(value: boolean): this {
78
- this.state.showMethods = value;
79
- return this;
80
- }
81
-
82
- expandAll(value: boolean): this {
83
- this.state.expandAll = value;
84
- return this;
85
- }
86
-
87
- theme(value: 'light' | 'dark' | 'auto'): this {
88
- this.state.theme = value;
89
- return this;
90
- }
91
-
92
- toggleComponent(componentFile: string): this {
93
- if (this.state.expandedComponents.has(componentFile)) {
94
- this.state.expandedComponents.delete(componentFile);
95
- } else {
96
- this.state.expandedComponents.add(componentFile);
97
- }
98
- this._triggerCallback('expand', componentFile);
99
- return this;
100
- }
101
-
102
- /* ═════════════════════════════════════════════════════════════════
103
- * RENDER HELPERS
104
- * ═════════════════════════════════════════════════════════════════ */
105
-
106
- private _renderHierarchy(hierarchy: ComponentHierarchy[], depth: number = 0): HTMLElement {
107
- const container = document.createElement('div');
108
- container.className = 'jux-blueprint-hierarchy';
109
-
110
- hierarchy.forEach((node, index) => {
111
- const nodeEl = document.createElement('div');
112
- nodeEl.className = 'jux-blueprint-node';
113
- nodeEl.style.paddingLeft = `${depth * 20}px`;
114
-
115
- const isLast = index === hierarchy.length - 1;
116
- const connector = isLast ? '└─' : '├─';
117
-
118
- // Tree line
119
- const lineEl = document.createElement('span');
120
- lineEl.className = 'jux-blueprint-line';
121
- lineEl.textContent = connector + ' ';
122
- nodeEl.appendChild(lineEl);
123
-
124
- // Tag
125
- const tagEl = document.createElement('span');
126
- tagEl.className = 'jux-blueprint-tag';
127
- tagEl.textContent = `<${node.tag}>`;
128
- nodeEl.appendChild(tagEl);
129
-
130
- // ID
131
- if (node.id) {
132
- const idEl = document.createElement('span');
133
- idEl.className = 'jux-blueprint-id';
134
- idEl.textContent = ` #${node.id}`;
135
- nodeEl.appendChild(idEl);
136
- }
137
-
138
- // Classes
139
- if (node.classes && node.classes.length > 0) {
140
- const classesEl = document.createElement('span');
141
- classesEl.className = 'jux-blueprint-classes';
142
-
143
- node.classes.forEach(cls => {
144
- const classEl = document.createElement('span');
145
- classEl.className = 'jux-blueprint-class';
146
- classEl.textContent = `.${cls}`;
147
- classesEl.appendChild(classEl);
148
- classesEl.appendChild(document.createTextNode(' '));
149
- });
150
-
151
- nodeEl.appendChild(classesEl);
152
- }
153
-
154
- container.appendChild(nodeEl);
155
-
156
- // Render children recursively
157
- if (node.children && node.children.length > 0) {
158
- container.appendChild(this._renderHierarchy(node.children, depth + 1));
159
- }
160
- });
161
-
162
- return container;
163
- }
164
-
165
- private _renderComponentCard(component: any): HTMLElement {
166
- const { showMethods, expandAll, expandedComponents } = this.state;
167
- const isExpanded = expandAll || expandedComponents.has(component.file);
168
-
169
- const card = document.createElement('div');
170
- card.className = 'jux-blueprint-card';
171
- if (isExpanded) card.classList.add('jux-blueprint-card-expanded');
172
-
173
- // Header
174
- const header = document.createElement('div');
175
- header.className = 'jux-blueprint-card-header';
176
- header.addEventListener('click', () => {
177
- this.toggleComponent(component.file);
178
- this.update('expandedComponents', this.state.expandedComponents);
179
- });
180
-
181
- const title = document.createElement('h4');
182
- title.className = 'jux-blueprint-card-title';
183
- title.textContent = component.file;
184
- header.appendChild(title);
185
-
186
- const badge = document.createElement('span');
187
- badge.className = 'jux-blueprint-badge';
188
- badge.textContent = `${component.classCount} classes`;
189
- header.appendChild(badge);
190
-
191
- const toggle = document.createElement('span');
192
- toggle.className = 'jux-blueprint-toggle-icon';
193
- toggle.textContent = isExpanded ? '▼' : '▶';
194
- header.appendChild(toggle);
195
-
196
- card.appendChild(header);
197
-
198
- // Body (collapsed by default)
199
- if (isExpanded) {
200
- const body = document.createElement('div');
201
- body.className = 'jux-blueprint-card-body';
202
-
203
- // Class list
204
- if (component.allClasses && component.allClasses.length > 0) {
205
- const classSection = document.createElement('div');
206
- classSection.className = 'jux-blueprint-section';
207
-
208
- const classTitle = document.createElement('h5');
209
- classTitle.className = 'jux-blueprint-section-title';
210
- classTitle.textContent = 'CSS Classes';
211
- classSection.appendChild(classTitle);
212
-
213
- const classList = document.createElement('div');
214
- classList.className = 'jux-blueprint-class-list';
215
-
216
- component.allClasses.forEach((cls: string) => {
217
- const classTag = document.createElement('span');
218
- classTag.className = 'jux-blueprint-class-tag';
219
- classTag.textContent = `.${cls}`;
220
- classList.appendChild(classTag);
221
- });
222
-
223
- classSection.appendChild(classList);
224
- body.appendChild(classSection);
225
- }
226
-
227
- // DOM Structures
228
- if (component.domStructures && component.domStructures.length > 0) {
229
- component.domStructures.forEach((structure: any) => {
230
- const structSection = document.createElement('div');
231
- structSection.className = 'jux-blueprint-section';
232
-
233
- const methodTitle = document.createElement('h5');
234
- methodTitle.className = 'jux-blueprint-section-title';
235
- methodTitle.textContent = `Method: ${structure.method}()`;
236
- structSection.appendChild(methodTitle);
237
-
238
- // Render hierarchy if available
239
- if (structure.hierarchy && structure.hierarchy.length > 0) {
240
- const hierarchyEl = this._renderHierarchy(structure.hierarchy);
241
- structSection.appendChild(hierarchyEl);
242
- }
243
-
244
- body.appendChild(structSection);
245
- });
246
- }
247
-
248
- card.appendChild(body);
249
- }
250
-
251
- return card;
252
- }
253
-
254
- /* ═════════════════════════════════════════════════════════════════
255
- * REACTIVE UPDATE
256
- * ═════════════════════════════════════════════════════════════════ */
257
-
258
- update(prop: string, value: any): void {
259
- super.update(prop, value);
260
-
261
- if (!this.container) return;
262
-
263
- const blueprint = this.container.querySelector(`#${this._id}`) as HTMLElement;
264
- if (!blueprint) return;
265
-
266
- switch (prop) {
267
- case 'structureData':
268
- case 'classData':
269
- case 'filter':
270
- case 'showMethods':
271
- case 'expandAll':
272
- case 'expandedComponents':
273
- this._rebuildContent();
274
- break;
275
-
276
- case 'theme':
277
- blueprint.dataset.theme = value;
278
- break;
279
- }
280
- }
281
-
282
- private _rebuildContent(): void {
283
- if (!this.container) return;
284
-
285
- const contentContainer = this.container.querySelector('.jux-blueprint-content');
286
- if (!contentContainer) return;
287
-
288
- contentContainer.innerHTML = '';
289
-
290
- const { classData, filter } = this.state;
291
-
292
- if (!classData || !classData.components) {
293
- const emptyEl = document.createElement('div');
294
- emptyEl.className = 'jux-blueprint-empty';
295
- emptyEl.textContent = 'No component data loaded. Use .structureData() and .classData() to load JSON files.';
296
- contentContainer.appendChild(emptyEl);
297
- return;
298
- }
299
-
300
- // Filter components
301
- const filteredComponents = classData.components.filter((comp: any) => {
302
- if (!filter) return true;
303
- return comp.file.toLowerCase().includes(filter.toLowerCase());
304
- });
305
-
306
- // Render component cards
307
- filteredComponents.forEach((component: any) => {
308
- const card = this._renderComponentCard(component);
309
- contentContainer.appendChild(card);
310
- });
311
-
312
- // Show count
313
- const countEl = this.container.querySelector('.jux-blueprint-count');
314
- if (countEl) {
315
- countEl.textContent = `Showing ${filteredComponents.length} of ${classData.components.length} components`;
316
- }
317
- }
318
-
319
- /* ═════════════════════════════════════════════════════════════════
320
- * RENDER
321
- * ═════════════════════════════════════════════════════════════════ */
322
-
323
- render(targetId?: string | HTMLElement | BaseComponent<any>): this {
324
- const container = this._setupContainer(targetId);
325
- const { theme, style, class: className, classData } = this.state;
326
-
327
- // Create wrapper
328
- const wrapper = document.createElement('div');
329
- wrapper.className = 'jux-blueprint';
330
- wrapper.id = this._id;
331
- wrapper.dataset.theme = theme;
332
- if (className) wrapper.className += ` ${className}`;
333
- if (style) wrapper.setAttribute('style', style);
334
-
335
- // Header
336
- const header = document.createElement('div');
337
- header.className = 'jux-blueprint-header';
338
-
339
- const title = document.createElement('h2');
340
- title.className = 'jux-blueprint-title';
341
- title.textContent = 'Component Blueprint';
342
- header.appendChild(title);
343
-
344
- // Stats
345
- if (classData) {
346
- const stats = document.createElement('div');
347
- stats.className = 'jux-blueprint-stats';
348
- stats.innerHTML = `
349
- <span class="jux-blueprint-stat">
350
- <strong>${classData.totalFiles || 0}</strong> Components
351
- </span>
352
- <span class="jux-blueprint-stat">
353
- <strong>${classData.totalClasses || 0}</strong> Total Classes
354
- </span>
355
- `;
356
- header.appendChild(stats);
357
- }
358
-
359
- wrapper.appendChild(header);
360
-
361
- // Controls
362
- const controls = document.createElement('div');
363
- controls.className = 'jux-blueprint-controls';
364
-
365
- // Filter input
366
- const filterInput = document.createElement('input');
367
- filterInput.type = 'text';
368
- filterInput.className = 'jux-blueprint-filter';
369
- filterInput.placeholder = 'Filter components...';
370
- filterInput.value = this.state.filter;
371
- filterInput.addEventListener('input', (e) => {
372
- this.state.filter = (e.target as HTMLInputElement).value;
373
- });
374
- controls.appendChild(filterInput);
375
-
376
- // Expand All toggle
377
- const expandToggle = document.createElement('button');
378
- expandToggle.className = 'jux-blueprint-button';
379
- expandToggle.textContent = 'Expand All';
380
- expandToggle.addEventListener('click', () => {
381
- this.state.expandAll = !this.state.expandAll;
382
- expandToggle.textContent = this.state.expandAll ? 'Collapse All' : 'Expand All';
383
- });
384
- controls.appendChild(expandToggle);
385
-
386
- wrapper.appendChild(controls);
387
-
388
- // Count
389
- const count = document.createElement('div');
390
- count.className = 'jux-blueprint-count';
391
- count.textContent = classData ? `Showing ${classData.components.length} components` : 'No data loaded';
392
- wrapper.appendChild(count);
393
-
394
- // Content container
395
- const content = document.createElement('div');
396
- content.className = 'jux-blueprint-content';
397
-
398
- if (classData && classData.components) {
399
- classData.components.forEach((component: any) => {
400
- const card = this._renderComponentCard(component);
401
- content.appendChild(card);
402
- });
403
- } else {
404
- const emptyEl = document.createElement('div');
405
- emptyEl.className = 'jux-blueprint-empty';
406
- emptyEl.textContent = 'No component data loaded. Use .structureData() and .classData() to load JSON files.';
407
- content.appendChild(emptyEl);
408
- }
409
-
410
- wrapper.appendChild(content);
411
-
412
- this._wireStandardEvents(wrapper);
413
- container.appendChild(wrapper);
414
-
415
- return this;
416
- }
417
- }
418
-
419
- export function blueprint(id: string, options: BlueprintOptions = {}): Blueprint {
420
- return new Blueprint(id, options);
421
- }