juxscript 1.1.65 → 1.1.67
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.
- package/lib/components/blueprint.d.ts +17 -24
- package/lib/components/blueprint.d.ts.map +1 -1
- package/lib/components/blueprint.js +217 -220
- package/lib/components/blueprint.ts +375 -386
- package/package.json +1 -1
|
@@ -1,45 +1,38 @@
|
|
|
1
1
|
import { BaseComponent, BaseState } from './base/BaseComponent.js';
|
|
2
2
|
export interface BlueprintOptions {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
structureData?: any;
|
|
4
|
+
classData?: any;
|
|
5
|
+
filter?: string;
|
|
6
|
+
showMethods?: boolean;
|
|
7
7
|
expandAll?: boolean;
|
|
8
8
|
theme?: 'light' | 'dark' | 'auto';
|
|
9
|
-
interactive?: boolean;
|
|
10
9
|
style?: string;
|
|
11
10
|
class?: string;
|
|
12
11
|
}
|
|
13
12
|
interface BlueprintState extends BaseState {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
structureData: any;
|
|
14
|
+
classData: any;
|
|
15
|
+
filter: string;
|
|
16
|
+
showMethods: boolean;
|
|
18
17
|
expandAll: boolean;
|
|
19
18
|
theme: string;
|
|
20
|
-
|
|
21
|
-
selectedNode: string | null;
|
|
22
|
-
hoveredNode: string | null;
|
|
19
|
+
expandedComponents: Set<string>;
|
|
23
20
|
}
|
|
24
21
|
export declare class Blueprint extends BaseComponent<BlueprintState> {
|
|
25
|
-
private _domStructure;
|
|
26
22
|
constructor(id: string, options?: BlueprintOptions);
|
|
27
23
|
protected getTriggerEvents(): readonly string[];
|
|
28
24
|
protected getCallbackEvents(): readonly string[];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
structureData(data: any): this;
|
|
26
|
+
classData(data: any): this;
|
|
27
|
+
filter(value: string): this;
|
|
28
|
+
showMethods(value: boolean): this;
|
|
33
29
|
expandAll(value: boolean): this;
|
|
34
30
|
theme(value: 'light' | 'dark' | 'auto'): this;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
private
|
|
38
|
-
private _renderNode;
|
|
39
|
-
private _renderTree;
|
|
31
|
+
toggleComponent(componentFile: string): this;
|
|
32
|
+
private _renderHierarchy;
|
|
33
|
+
private _renderComponentCard;
|
|
40
34
|
update(prop: string, value: any): void;
|
|
41
|
-
private
|
|
42
|
-
private _updateNodeStates;
|
|
35
|
+
private _rebuildContent;
|
|
43
36
|
render(targetId?: string | HTMLElement | BaseComponent<any>): this;
|
|
44
37
|
}
|
|
45
38
|
export declare function blueprint(id: string, options?: BlueprintOptions): Blueprint;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blueprint.d.ts","sourceRoot":"","sources":["blueprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"blueprint.d.ts","sourceRoot":"","sources":["blueprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAMnE,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,cAAe,SAAQ,SAAS;IACxC,aAAa,EAAE,GAAG,CAAC;IACnB,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACjC;AASD,qBAAa,SAAU,SAAQ,aAAa,CAAC,cAAc,CAAC;gBAC9C,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IActD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAQhD,aAAa,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAK9B,SAAS,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAK1B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK3B,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKjC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK/B,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;IAK7C,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAc5C,OAAO,CAAC,gBAAgB;IA2DxB,OAAO,CAAC,oBAAoB;IA6F5B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAwBtC,OAAO,CAAC,eAAe;IAyCvB,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI;CA8FnE;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS,CAE/E"}
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
-
import { registry } from './registry.js';
|
|
3
2
|
// Event definitions
|
|
4
3
|
const TRIGGER_EVENTS = [];
|
|
5
|
-
const CALLBACK_EVENTS = ['select', '
|
|
4
|
+
const CALLBACK_EVENTS = ['select', 'expand'];
|
|
6
5
|
export class Blueprint extends BaseComponent {
|
|
7
6
|
constructor(id, options = {}) {
|
|
8
7
|
super(id, {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
expandAll: options.expandAll ??
|
|
8
|
+
structureData: options.structureData ?? null,
|
|
9
|
+
classData: options.classData ?? null,
|
|
10
|
+
filter: options.filter ?? '',
|
|
11
|
+
showMethods: options.showMethods ?? true,
|
|
12
|
+
expandAll: options.expandAll ?? false,
|
|
14
13
|
theme: options.theme ?? 'auto',
|
|
15
|
-
|
|
16
|
-
selectedNode: null,
|
|
17
|
-
hoveredNode: null,
|
|
14
|
+
expandedComponents: new Set(),
|
|
18
15
|
style: options.style ?? '',
|
|
19
16
|
class: options.class ?? ''
|
|
20
17
|
});
|
|
21
|
-
this._domStructure = [];
|
|
22
18
|
}
|
|
23
19
|
getTriggerEvents() {
|
|
24
20
|
return TRIGGER_EVENTS;
|
|
@@ -29,20 +25,20 @@ export class Blueprint extends BaseComponent {
|
|
|
29
25
|
/* ═════════════════════════════════════════════════════════════════
|
|
30
26
|
* FLUENT API
|
|
31
27
|
* ═════════════════════════════════════════════════════════════════ */
|
|
32
|
-
|
|
33
|
-
this.state.
|
|
28
|
+
structureData(data) {
|
|
29
|
+
this.state.structureData = data;
|
|
34
30
|
return this;
|
|
35
31
|
}
|
|
36
|
-
|
|
37
|
-
this.state.
|
|
32
|
+
classData(data) {
|
|
33
|
+
this.state.classData = data;
|
|
38
34
|
return this;
|
|
39
35
|
}
|
|
40
|
-
|
|
41
|
-
this.state.
|
|
36
|
+
filter(value) {
|
|
37
|
+
this.state.filter = value;
|
|
42
38
|
return this;
|
|
43
39
|
}
|
|
44
|
-
|
|
45
|
-
this.state.
|
|
40
|
+
showMethods(value) {
|
|
41
|
+
this.state.showMethods = value;
|
|
46
42
|
return this;
|
|
47
43
|
}
|
|
48
44
|
expandAll(value) {
|
|
@@ -53,132 +49,136 @@ export class Blueprint extends BaseComponent {
|
|
|
53
49
|
this.state.theme = value;
|
|
54
50
|
return this;
|
|
55
51
|
}
|
|
56
|
-
|
|
57
|
-
this.state.
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
selectNode(path) {
|
|
61
|
-
this.state.selectedNode = path;
|
|
62
|
-
this._triggerCallback('select', path);
|
|
63
|
-
return this;
|
|
64
|
-
}
|
|
65
|
-
/* ═════════════════════════════════════════════════════════════════
|
|
66
|
-
* DOM ANALYSIS
|
|
67
|
-
* ═════════════════════════════════════════════════════════════════ */
|
|
68
|
-
_analyzeDOMStructure(componentId) {
|
|
69
|
-
const component = registry.get(componentId);
|
|
70
|
-
if (!component || !component.container) {
|
|
71
|
-
return [];
|
|
52
|
+
toggleComponent(componentFile) {
|
|
53
|
+
if (this.state.expandedComponents.has(componentFile)) {
|
|
54
|
+
this.state.expandedComponents.delete(componentFile);
|
|
72
55
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return [];
|
|
56
|
+
else {
|
|
57
|
+
this.state.expandedComponents.add(componentFile);
|
|
76
58
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
tag: element.tagName.toLowerCase(),
|
|
80
|
-
classes: Array.from(element.classList),
|
|
81
|
-
id: element.id || null,
|
|
82
|
-
depth,
|
|
83
|
-
path,
|
|
84
|
-
children: []
|
|
85
|
-
};
|
|
86
|
-
Array.from(element.children).forEach((child, index) => {
|
|
87
|
-
node.children.push(extractNode(child, depth + 1, `${path}.${index}`));
|
|
88
|
-
});
|
|
89
|
-
return node;
|
|
90
|
-
};
|
|
91
|
-
return [extractNode(rootElement)];
|
|
59
|
+
this._triggerCallback('expand', componentFile);
|
|
60
|
+
return this;
|
|
92
61
|
}
|
|
93
62
|
/* ═════════════════════════════════════════════════════════════════
|
|
94
|
-
* RENDER
|
|
63
|
+
* RENDER HELPERS
|
|
95
64
|
* ═════════════════════════════════════════════════════════════════ */
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
nodeEl.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const indent = prefix + connector;
|
|
112
|
-
lineEl.textContent = indent;
|
|
113
|
-
nodeEl.appendChild(lineEl);
|
|
114
|
-
// Node content
|
|
115
|
-
const contentEl = document.createElement('span');
|
|
116
|
-
contentEl.className = 'jux-blueprint-content';
|
|
117
|
-
// Tag
|
|
118
|
-
if (showTags) {
|
|
65
|
+
_renderHierarchy(hierarchy, depth = 0) {
|
|
66
|
+
const container = document.createElement('div');
|
|
67
|
+
container.className = 'jux-blueprint-hierarchy';
|
|
68
|
+
hierarchy.forEach((node, index) => {
|
|
69
|
+
const nodeEl = document.createElement('div');
|
|
70
|
+
nodeEl.className = 'jux-blueprint-node';
|
|
71
|
+
nodeEl.style.paddingLeft = `${depth * 20}px`;
|
|
72
|
+
const isLast = index === hierarchy.length - 1;
|
|
73
|
+
const connector = isLast ? '└─' : '├─';
|
|
74
|
+
// Tree line
|
|
75
|
+
const lineEl = document.createElement('span');
|
|
76
|
+
lineEl.className = 'jux-blueprint-line';
|
|
77
|
+
lineEl.textContent = connector + ' ';
|
|
78
|
+
nodeEl.appendChild(lineEl);
|
|
79
|
+
// Tag
|
|
119
80
|
const tagEl = document.createElement('span');
|
|
120
81
|
tagEl.className = 'jux-blueprint-tag';
|
|
121
82
|
tagEl.textContent = `<${node.tag}>`;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
classesEl.appendChild(classEl);
|
|
140
|
-
if (index < node.classes.length - 1) {
|
|
83
|
+
nodeEl.appendChild(tagEl);
|
|
84
|
+
// ID
|
|
85
|
+
if (node.id) {
|
|
86
|
+
const idEl = document.createElement('span');
|
|
87
|
+
idEl.className = 'jux-blueprint-id';
|
|
88
|
+
idEl.textContent = ` #${node.id}`;
|
|
89
|
+
nodeEl.appendChild(idEl);
|
|
90
|
+
}
|
|
91
|
+
// Classes
|
|
92
|
+
if (node.classes && node.classes.length > 0) {
|
|
93
|
+
const classesEl = document.createElement('span');
|
|
94
|
+
classesEl.className = 'jux-blueprint-classes';
|
|
95
|
+
node.classes.forEach(cls => {
|
|
96
|
+
const classEl = document.createElement('span');
|
|
97
|
+
classEl.className = 'jux-blueprint-class';
|
|
98
|
+
classEl.textContent = `.${cls}`;
|
|
99
|
+
classesEl.appendChild(classEl);
|
|
141
100
|
classesEl.appendChild(document.createTextNode(' '));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
nodeEl.style.cursor = 'pointer';
|
|
150
|
-
nodeEl.addEventListener('click', (e) => {
|
|
151
|
-
e.stopPropagation();
|
|
152
|
-
this.state.selectedNode = node.path;
|
|
153
|
-
this._triggerCallback('select', node);
|
|
154
|
-
});
|
|
155
|
-
nodeEl.addEventListener('mouseenter', () => {
|
|
156
|
-
this.state.hoveredNode = node.path;
|
|
157
|
-
this._triggerCallback('hover', node);
|
|
158
|
-
});
|
|
159
|
-
nodeEl.addEventListener('mouseleave', () => {
|
|
160
|
-
if (this.state.hoveredNode === node.path) {
|
|
161
|
-
this.state.hoveredNode = null;
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
return nodeEl;
|
|
166
|
-
}
|
|
167
|
-
_renderTree(nodes, prefix = '') {
|
|
168
|
-
const treeEl = document.createElement('div');
|
|
169
|
-
treeEl.className = 'jux-blueprint-tree';
|
|
170
|
-
nodes.forEach((node, index) => {
|
|
171
|
-
const isLast = index === nodes.length - 1;
|
|
172
|
-
const nodeEl = this._renderNode(node, isLast, prefix);
|
|
173
|
-
treeEl.appendChild(nodeEl);
|
|
174
|
-
// Render children
|
|
175
|
-
if (node.children.length > 0) {
|
|
176
|
-
const childPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
177
|
-
const childrenEl = this._renderTree(node.children, childPrefix);
|
|
178
|
-
treeEl.appendChild(childrenEl);
|
|
101
|
+
});
|
|
102
|
+
nodeEl.appendChild(classesEl);
|
|
103
|
+
}
|
|
104
|
+
container.appendChild(nodeEl);
|
|
105
|
+
// Render children recursively
|
|
106
|
+
if (node.children && node.children.length > 0) {
|
|
107
|
+
container.appendChild(this._renderHierarchy(node.children, depth + 1));
|
|
179
108
|
}
|
|
180
109
|
});
|
|
181
|
-
return
|
|
110
|
+
return container;
|
|
111
|
+
}
|
|
112
|
+
_renderComponentCard(component) {
|
|
113
|
+
const { showMethods, expandAll, expandedComponents } = this.state;
|
|
114
|
+
const isExpanded = expandAll || expandedComponents.has(component.file);
|
|
115
|
+
const card = document.createElement('div');
|
|
116
|
+
card.className = 'jux-blueprint-card';
|
|
117
|
+
if (isExpanded)
|
|
118
|
+
card.classList.add('jux-blueprint-card-expanded');
|
|
119
|
+
// Header
|
|
120
|
+
const header = document.createElement('div');
|
|
121
|
+
header.className = 'jux-blueprint-card-header';
|
|
122
|
+
header.addEventListener('click', () => {
|
|
123
|
+
this.toggleComponent(component.file);
|
|
124
|
+
this.update('expandedComponents', this.state.expandedComponents);
|
|
125
|
+
});
|
|
126
|
+
const title = document.createElement('h4');
|
|
127
|
+
title.className = 'jux-blueprint-card-title';
|
|
128
|
+
title.textContent = component.file;
|
|
129
|
+
header.appendChild(title);
|
|
130
|
+
const badge = document.createElement('span');
|
|
131
|
+
badge.className = 'jux-blueprint-badge';
|
|
132
|
+
badge.textContent = `${component.classCount} classes`;
|
|
133
|
+
header.appendChild(badge);
|
|
134
|
+
const toggle = document.createElement('span');
|
|
135
|
+
toggle.className = 'jux-blueprint-toggle-icon';
|
|
136
|
+
toggle.textContent = isExpanded ? '▼' : '▶';
|
|
137
|
+
header.appendChild(toggle);
|
|
138
|
+
card.appendChild(header);
|
|
139
|
+
// Body (collapsed by default)
|
|
140
|
+
if (isExpanded) {
|
|
141
|
+
const body = document.createElement('div');
|
|
142
|
+
body.className = 'jux-blueprint-card-body';
|
|
143
|
+
// Class list
|
|
144
|
+
if (component.allClasses && component.allClasses.length > 0) {
|
|
145
|
+
const classSection = document.createElement('div');
|
|
146
|
+
classSection.className = 'jux-blueprint-section';
|
|
147
|
+
const classTitle = document.createElement('h5');
|
|
148
|
+
classTitle.className = 'jux-blueprint-section-title';
|
|
149
|
+
classTitle.textContent = 'CSS Classes';
|
|
150
|
+
classSection.appendChild(classTitle);
|
|
151
|
+
const classList = document.createElement('div');
|
|
152
|
+
classList.className = 'jux-blueprint-class-list';
|
|
153
|
+
component.allClasses.forEach((cls) => {
|
|
154
|
+
const classTag = document.createElement('span');
|
|
155
|
+
classTag.className = 'jux-blueprint-class-tag';
|
|
156
|
+
classTag.textContent = `.${cls}`;
|
|
157
|
+
classList.appendChild(classTag);
|
|
158
|
+
});
|
|
159
|
+
classSection.appendChild(classList);
|
|
160
|
+
body.appendChild(classSection);
|
|
161
|
+
}
|
|
162
|
+
// DOM Structures
|
|
163
|
+
if (component.domStructures && component.domStructures.length > 0) {
|
|
164
|
+
component.domStructures.forEach((structure) => {
|
|
165
|
+
const structSection = document.createElement('div');
|
|
166
|
+
structSection.className = 'jux-blueprint-section';
|
|
167
|
+
const methodTitle = document.createElement('h5');
|
|
168
|
+
methodTitle.className = 'jux-blueprint-section-title';
|
|
169
|
+
methodTitle.textContent = `Method: ${structure.method}()`;
|
|
170
|
+
structSection.appendChild(methodTitle);
|
|
171
|
+
// Render hierarchy if available
|
|
172
|
+
if (structure.hierarchy && structure.hierarchy.length > 0) {
|
|
173
|
+
const hierarchyEl = this._renderHierarchy(structure.hierarchy);
|
|
174
|
+
structSection.appendChild(hierarchyEl);
|
|
175
|
+
}
|
|
176
|
+
body.appendChild(structSection);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
card.appendChild(body);
|
|
180
|
+
}
|
|
181
|
+
return card;
|
|
182
182
|
}
|
|
183
183
|
/* ═════════════════════════════════════════════════════════════════
|
|
184
184
|
* REACTIVE UPDATE
|
|
@@ -191,65 +191,57 @@ export class Blueprint extends BaseComponent {
|
|
|
191
191
|
if (!blueprint)
|
|
192
192
|
return;
|
|
193
193
|
switch (prop) {
|
|
194
|
-
case '
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
case 'showClasses':
|
|
199
|
-
case 'showIds':
|
|
200
|
-
case 'showTags':
|
|
194
|
+
case 'structureData':
|
|
195
|
+
case 'classData':
|
|
196
|
+
case 'filter':
|
|
197
|
+
case 'showMethods':
|
|
201
198
|
case 'expandAll':
|
|
202
|
-
case '
|
|
203
|
-
this.
|
|
199
|
+
case 'expandedComponents':
|
|
200
|
+
this._rebuildContent();
|
|
204
201
|
break;
|
|
205
202
|
case 'theme':
|
|
206
203
|
blueprint.dataset.theme = value;
|
|
207
204
|
break;
|
|
208
|
-
case 'selectedNode':
|
|
209
|
-
case 'hoveredNode':
|
|
210
|
-
this._updateNodeStates();
|
|
211
|
-
break;
|
|
212
205
|
}
|
|
213
206
|
}
|
|
214
|
-
|
|
207
|
+
_rebuildContent() {
|
|
215
208
|
if (!this.container)
|
|
216
209
|
return;
|
|
217
|
-
const
|
|
218
|
-
if (!
|
|
210
|
+
const contentContainer = this.container.querySelector('.jux-blueprint-content');
|
|
211
|
+
if (!contentContainer)
|
|
219
212
|
return;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
treeContainer.appendChild(treeEl);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
213
|
+
contentContainer.innerHTML = '';
|
|
214
|
+
const { classData, filter } = this.state;
|
|
215
|
+
if (!classData || !classData.components) {
|
|
226
216
|
const emptyEl = document.createElement('div');
|
|
227
217
|
emptyEl.className = 'jux-blueprint-empty';
|
|
228
|
-
emptyEl.textContent = 'No component
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
_updateNodeStates() {
|
|
233
|
-
if (!this.container)
|
|
218
|
+
emptyEl.textContent = 'No component data loaded. Use .structureData() and .classData() to load JSON files.';
|
|
219
|
+
contentContainer.appendChild(emptyEl);
|
|
234
220
|
return;
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
221
|
+
}
|
|
222
|
+
// Filter components
|
|
223
|
+
const filteredComponents = classData.components.filter((comp) => {
|
|
224
|
+
if (!filter)
|
|
225
|
+
return true;
|
|
226
|
+
return comp.file.toLowerCase().includes(filter.toLowerCase());
|
|
227
|
+
});
|
|
228
|
+
// Render component cards
|
|
229
|
+
filteredComponents.forEach((component) => {
|
|
230
|
+
const card = this._renderComponentCard(component);
|
|
231
|
+
contentContainer.appendChild(card);
|
|
241
232
|
});
|
|
233
|
+
// Show count
|
|
234
|
+
const countEl = this.container.querySelector('.jux-blueprint-count');
|
|
235
|
+
if (countEl) {
|
|
236
|
+
countEl.textContent = `Showing ${filteredComponents.length} of ${classData.components.length} components`;
|
|
237
|
+
}
|
|
242
238
|
}
|
|
243
239
|
/* ═════════════════════════════════════════════════════════════════
|
|
244
240
|
* RENDER
|
|
245
241
|
* ═════════════════════════════════════════════════════════════════ */
|
|
246
242
|
render(targetId) {
|
|
247
243
|
const container = this._setupContainer(targetId);
|
|
248
|
-
const {
|
|
249
|
-
// Analyze structure if componentId is provided
|
|
250
|
-
if (componentId) {
|
|
251
|
-
this._domStructure = this._analyzeDOMStructure(componentId);
|
|
252
|
-
}
|
|
244
|
+
const { theme, style, class: className, classData } = this.state;
|
|
253
245
|
// Create wrapper
|
|
254
246
|
const wrapper = document.createElement('div');
|
|
255
247
|
wrapper.className = 'jux-blueprint';
|
|
@@ -262,64 +254,69 @@ export class Blueprint extends BaseComponent {
|
|
|
262
254
|
// Header
|
|
263
255
|
const header = document.createElement('div');
|
|
264
256
|
header.className = 'jux-blueprint-header';
|
|
265
|
-
const title = document.createElement('
|
|
257
|
+
const title = document.createElement('h2');
|
|
266
258
|
title.className = 'jux-blueprint-title';
|
|
267
|
-
title.textContent =
|
|
259
|
+
title.textContent = 'Component Blueprint';
|
|
268
260
|
header.appendChild(title);
|
|
261
|
+
// Stats
|
|
262
|
+
if (classData) {
|
|
263
|
+
const stats = document.createElement('div');
|
|
264
|
+
stats.className = 'jux-blueprint-stats';
|
|
265
|
+
stats.innerHTML = `
|
|
266
|
+
<span class="jux-blueprint-stat">
|
|
267
|
+
<strong>${classData.totalFiles || 0}</strong> Components
|
|
268
|
+
</span>
|
|
269
|
+
<span class="jux-blueprint-stat">
|
|
270
|
+
<strong>${classData.totalClasses || 0}</strong> Total Classes
|
|
271
|
+
</span>
|
|
272
|
+
`;
|
|
273
|
+
header.appendChild(stats);
|
|
274
|
+
}
|
|
275
|
+
wrapper.appendChild(header);
|
|
269
276
|
// Controls
|
|
270
277
|
const controls = document.createElement('div');
|
|
271
278
|
controls.className = 'jux-blueprint-controls';
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const checkbox = document.createElement('input');
|
|
281
|
-
checkbox.type = 'checkbox';
|
|
282
|
-
checkbox.checked = this.state[prop];
|
|
283
|
-
checkbox.addEventListener('change', () => {
|
|
284
|
-
this.state[prop] = checkbox.checked;
|
|
285
|
-
});
|
|
286
|
-
toggleEl.appendChild(checkbox);
|
|
287
|
-
toggleEl.appendChild(document.createTextNode(` ${label}`));
|
|
288
|
-
controls.appendChild(toggleEl);
|
|
279
|
+
// Filter input
|
|
280
|
+
const filterInput = document.createElement('input');
|
|
281
|
+
filterInput.type = 'text';
|
|
282
|
+
filterInput.className = 'jux-blueprint-filter';
|
|
283
|
+
filterInput.placeholder = 'Filter components...';
|
|
284
|
+
filterInput.value = this.state.filter;
|
|
285
|
+
filterInput.addEventListener('input', (e) => {
|
|
286
|
+
this.state.filter = e.target.value;
|
|
289
287
|
});
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
288
|
+
controls.appendChild(filterInput);
|
|
289
|
+
// Expand All toggle
|
|
290
|
+
const expandToggle = document.createElement('button');
|
|
291
|
+
expandToggle.className = 'jux-blueprint-button';
|
|
292
|
+
expandToggle.textContent = 'Expand All';
|
|
293
|
+
expandToggle.addEventListener('click', () => {
|
|
294
|
+
this.state.expandAll = !this.state.expandAll;
|
|
295
|
+
expandToggle.textContent = this.state.expandAll ? 'Collapse All' : 'Expand All';
|
|
296
|
+
});
|
|
297
|
+
controls.appendChild(expandToggle);
|
|
298
|
+
wrapper.appendChild(controls);
|
|
299
|
+
// Count
|
|
300
|
+
const count = document.createElement('div');
|
|
301
|
+
count.className = 'jux-blueprint-count';
|
|
302
|
+
count.textContent = classData ? `Showing ${classData.components.length} components` : 'No data loaded';
|
|
303
|
+
wrapper.appendChild(count);
|
|
304
|
+
// Content container
|
|
305
|
+
const content = document.createElement('div');
|
|
306
|
+
content.className = 'jux-blueprint-content';
|
|
307
|
+
if (classData && classData.components) {
|
|
308
|
+
classData.components.forEach((component) => {
|
|
309
|
+
const card = this._renderComponentCard(component);
|
|
310
|
+
content.appendChild(card);
|
|
311
|
+
});
|
|
298
312
|
}
|
|
299
313
|
else {
|
|
300
314
|
const emptyEl = document.createElement('div');
|
|
301
315
|
emptyEl.className = 'jux-blueprint-empty';
|
|
302
|
-
emptyEl.textContent =
|
|
303
|
-
|
|
304
|
-
: 'Set componentId to analyze a component';
|
|
305
|
-
treeContainer.appendChild(emptyEl);
|
|
316
|
+
emptyEl.textContent = 'No component data loaded. Use .structureData() and .classData() to load JSON files.';
|
|
317
|
+
content.appendChild(emptyEl);
|
|
306
318
|
}
|
|
307
|
-
wrapper.appendChild(
|
|
308
|
-
// Legend
|
|
309
|
-
const legend = document.createElement('div');
|
|
310
|
-
legend.className = 'jux-blueprint-legend';
|
|
311
|
-
legend.innerHTML = `
|
|
312
|
-
<span class="jux-blueprint-legend-item">
|
|
313
|
-
<span class="jux-blueprint-tag"><tag></span> HTML Element
|
|
314
|
-
</span>
|
|
315
|
-
<span class="jux-blueprint-legend-item">
|
|
316
|
-
<span class="jux-blueprint-id">#id</span> Element ID
|
|
317
|
-
</span>
|
|
318
|
-
<span class="jux-blueprint-legend-item">
|
|
319
|
-
<span class="jux-blueprint-class">.class</span> CSS Class
|
|
320
|
-
</span>
|
|
321
|
-
`;
|
|
322
|
-
wrapper.appendChild(legend);
|
|
319
|
+
wrapper.appendChild(content);
|
|
323
320
|
this._wireStandardEvents(wrapper);
|
|
324
321
|
container.appendChild(wrapper);
|
|
325
322
|
return this;
|