juxscript 1.1.295 → 1.1.297

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,3 @@
1
+ export declare function devtools(show?: boolean): void;
2
+ export default devtools;
3
+ //# sourceMappingURL=devtools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../../../lib/devtools/devtools.ts"],"names":[],"mappings":"AAoJA,wBAAgB,QAAQ,CAAC,IAAI,GAAE,OAAc,GAAG,IAAI,CA0CnD;AAED,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,181 @@
1
+ import { pageState } from '../state/pageState.js';
2
+ let panel = null;
3
+ let interval = null;
4
+ const STYLES = `
5
+ position: fixed;
6
+ bottom: 0;
7
+ right: 0;
8
+ width: 420px;
9
+ max-height: 60vh;
10
+ overflow-y: auto;
11
+ background: #1e1e2e;
12
+ color: #cdd6f4;
13
+ font-family: 'SF Mono', 'Fira Code', monospace;
14
+ font-size: 11px;
15
+ line-height: 1.4;
16
+ padding: 0;
17
+ border-top-left-radius: 8px;
18
+ box-shadow: -2px -2px 12px rgba(0,0,0,0.4);
19
+ z-index: 99999;
20
+ border: 1px solid #45475a;
21
+ `;
22
+ const HEADER_STYLES = `
23
+ position: sticky;
24
+ top: 0;
25
+ background: #313244;
26
+ padding: 6px 10px;
27
+ display: flex;
28
+ justify-content: space-between;
29
+ align-items: center;
30
+ border-bottom: 1px solid #45475a;
31
+ cursor: move;
32
+ `;
33
+ function escapeHtml(str) {
34
+ return String(str)
35
+ .replace(/&/g, '&')
36
+ .replace(/</g, '&lt;')
37
+ .replace(/>/g, '&gt;')
38
+ .replace(/"/g, '&quot;');
39
+ }
40
+ function formatValue(val) {
41
+ if (val === undefined)
42
+ return '<span style="color:#6c7086">undefined</span>';
43
+ if (val === null)
44
+ return '<span style="color:#6c7086">null</span>';
45
+ if (typeof val === 'boolean')
46
+ return `<span style="color:#fab387">${val}</span>`;
47
+ if (typeof val === 'number')
48
+ return `<span style="color:#fab387">${val}</span>`;
49
+ if (typeof val === 'string') {
50
+ const truncated = val.length > 40 ? escapeHtml(val.slice(0, 40)) + '…' : escapeHtml(val);
51
+ return `<span style="color:#a6e3a1">"${truncated}"</span>`;
52
+ }
53
+ if (Array.isArray(val))
54
+ return `<span style="color:#89b4fa">Array[${val.length}]</span>`;
55
+ if (typeof val === 'object') {
56
+ try {
57
+ const keys = Object.keys(val);
58
+ return `<span style="color:#89b4fa">{${keys.slice(0, 3).join(', ')}${keys.length > 3 ? '…' : ''}}</span>`;
59
+ }
60
+ catch {
61
+ return '<span style="color:#89b4fa">{…}</span>';
62
+ }
63
+ }
64
+ if (typeof val === 'function')
65
+ return '<span style="color:#cba6f7">ƒ()</span>';
66
+ return escapeHtml(String(val));
67
+ }
68
+ function buildContent() {
69
+ const keys = pageState.__keys?.() ?? [];
70
+ if (keys.length === 0) {
71
+ return '<div style="padding:10px;color:#6c7086">No components registered</div>';
72
+ }
73
+ let html = '';
74
+ for (const key of keys) {
75
+ const proxy = pageState[key];
76
+ if (!proxy)
77
+ continue;
78
+ // Read known props
79
+ const value = proxy.value;
80
+ const content = proxy.content;
81
+ const checked = proxy.checked;
82
+ // Read event flags
83
+ const events = [];
84
+ for (const evt of ['blur', 'focus', 'click', 'change', 'input', 'hover', 'active', 'focused']) {
85
+ try {
86
+ if (proxy[evt] === true)
87
+ events.push(evt);
88
+ }
89
+ catch { /* skip */ }
90
+ }
91
+ // Component type detection
92
+ const el = proxy.getElement?.();
93
+ let typeLabel = 'unknown';
94
+ let typeColor = '#6c7086';
95
+ if (el instanceof HTMLElement) {
96
+ const tag = el.tagName.toLowerCase();
97
+ const isStore = el.getAttribute('data-jux-store');
98
+ if (isStore) {
99
+ typeLabel = `store:${isStore}`;
100
+ typeColor = '#f38ba8';
101
+ }
102
+ else if (el instanceof HTMLInputElement) {
103
+ typeLabel = `input[${el.type}]`;
104
+ typeColor = '#89dceb';
105
+ }
106
+ else if (el instanceof HTMLSelectElement) {
107
+ typeLabel = 'select';
108
+ typeColor = '#89dceb';
109
+ }
110
+ else {
111
+ typeLabel = tag;
112
+ typeColor = '#94e2d5';
113
+ }
114
+ }
115
+ html += `
116
+ <div style="border-bottom:1px solid #313244;padding:6px 10px;">
117
+ <div style="display:flex;justify-content:space-between;margin-bottom:2px;">
118
+ <span style="color:#cba6f7;font-weight:bold;">${escapeHtml(key)}</span>
119
+ <span style="color:${typeColor};font-size:10px;">${escapeHtml(typeLabel)}</span>
120
+ </div>
121
+ <div style="padding-left:8px;">`;
122
+ if (value !== undefined) {
123
+ html += `<div><span style="color:#74c7ec">value:</span> ${formatValue(value)}</div>`;
124
+ }
125
+ if (content !== undefined && content !== value) {
126
+ html += `<div><span style="color:#74c7ec">content:</span> ${formatValue(content)}</div>`;
127
+ }
128
+ if (checked !== undefined) {
129
+ html += `<div><span style="color:#74c7ec">checked:</span> ${formatValue(checked)}</div>`;
130
+ }
131
+ if (events.length > 0) {
132
+ html += `<div><span style="color:#f9e2af">events:</span> <span style="color:#fab387">${events.join(', ')}</span></div>`;
133
+ }
134
+ html += `</div></div>`;
135
+ }
136
+ return html;
137
+ }
138
+ function refresh() {
139
+ if (!panel)
140
+ return;
141
+ const body = panel.querySelector('[data-devtools-body]');
142
+ if (body)
143
+ body.innerHTML = buildContent();
144
+ }
145
+ export function devtools(show = true) {
146
+ if (!show) {
147
+ if (panel) {
148
+ panel.remove();
149
+ panel = null;
150
+ }
151
+ if (interval) {
152
+ clearInterval(interval);
153
+ interval = null;
154
+ }
155
+ return;
156
+ }
157
+ if (panel) {
158
+ refresh();
159
+ return;
160
+ }
161
+ panel = document.createElement('div');
162
+ panel.id = '__jux-devtools';
163
+ panel.setAttribute('style', STYLES);
164
+ panel.innerHTML = `
165
+ <div style="${HEADER_STYLES}">
166
+ <span style="color:#f9e2af;font-weight:bold;">🔧 JUX DevTools</span>
167
+ <div>
168
+ <button data-devtools-refresh style="background:none;border:1px solid #45475a;color:#cdd6f4;cursor:pointer;padding:2px 6px;border-radius:3px;margin-right:4px;font-size:10px;">↻</button>
169
+ <button data-devtools-close style="background:none;border:1px solid #45475a;color:#cdd6f4;cursor:pointer;padding:2px 6px;border-radius:3px;font-size:10px;">✕</button>
170
+ </div>
171
+ </div>
172
+ <div data-devtools-body></div>
173
+ `;
174
+ document.body.appendChild(panel);
175
+ panel.querySelector('[data-devtools-close]')?.addEventListener('click', () => devtools(false));
176
+ panel.querySelector('[data-devtools-refresh]')?.addEventListener('click', () => refresh());
177
+ refresh();
178
+ // Auto-refresh every 500ms to catch async changes
179
+ interval = setInterval(refresh, 500);
180
+ }
181
+ export default devtools;
@@ -7,6 +7,7 @@ import { checkbox, checkboxGroup } from "./components/checkbox.js";
7
7
  import { pageState } from "./state/pageState.js";
8
8
  import { data } from "./components/data.js";
9
9
  import { store } from "./components/store.js";
10
+ import { devtools } from "./devtools/devtools.js";
10
11
  export declare const jux: {
11
12
  tag: typeof tag;
12
13
  div: typeof div;
@@ -27,6 +28,7 @@ export declare const jux: {
27
28
  checkboxGroup: typeof checkboxGroup;
28
29
  data: typeof data;
29
30
  store: typeof store;
31
+ devtools: typeof devtools;
30
32
  };
31
33
  export { pageState };
32
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE9C,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;CAef,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;CAgBf,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
package/dist/lib/index.js CHANGED
@@ -7,6 +7,7 @@ import { checkbox, checkboxGroup } from "./components/checkbox.js";
7
7
  import { pageState } from "./state/pageState.js";
8
8
  import { data } from "./components/data.js";
9
9
  import { store } from "./components/store.js";
10
+ import { devtools } from "./devtools/devtools.js";
10
11
  export const jux = {
11
12
  tag,
12
13
  div,
@@ -21,7 +22,8 @@ export const jux = {
21
22
  checkbox,
22
23
  checkboxGroup,
23
24
  data,
24
- store
25
+ store,
26
+ devtools
25
27
  };
26
28
  export { pageState };
27
29
  jux.watch = pageState.__watch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.295",
3
+ "version": "1.1.297",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "./dist/lib/index.js",