juxscript 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/machinery/build3.js +7 -91
  2. package/machinery/compiler3.js +3 -209
  3. package/machinery/config.js +93 -6
  4. package/machinery/serve.js +255 -0
  5. package/machinery/watcher.js +49 -161
  6. package/package.json +19 -5
  7. package/lib/components/alert.ts +0 -200
  8. package/lib/components/app.ts +0 -247
  9. package/lib/components/badge.ts +0 -101
  10. package/lib/components/base/BaseComponent.ts +0 -421
  11. package/lib/components/base/FormInput.ts +0 -227
  12. package/lib/components/button.ts +0 -178
  13. package/lib/components/card.ts +0 -173
  14. package/lib/components/chart.ts +0 -231
  15. package/lib/components/checkbox.ts +0 -242
  16. package/lib/components/code.ts +0 -123
  17. package/lib/components/container.ts +0 -140
  18. package/lib/components/data.ts +0 -135
  19. package/lib/components/datepicker.ts +0 -234
  20. package/lib/components/dialog.ts +0 -172
  21. package/lib/components/divider.ts +0 -100
  22. package/lib/components/dropdown.ts +0 -186
  23. package/lib/components/element.ts +0 -267
  24. package/lib/components/fileupload.ts +0 -309
  25. package/lib/components/grid.ts +0 -291
  26. package/lib/components/guard.ts +0 -92
  27. package/lib/components/heading.ts +0 -96
  28. package/lib/components/helpers.ts +0 -41
  29. package/lib/components/hero.ts +0 -224
  30. package/lib/components/icon.ts +0 -178
  31. package/lib/components/icons.ts +0 -464
  32. package/lib/components/include.ts +0 -410
  33. package/lib/components/input.ts +0 -457
  34. package/lib/components/list.ts +0 -419
  35. package/lib/components/loading.ts +0 -100
  36. package/lib/components/menu.ts +0 -275
  37. package/lib/components/modal.ts +0 -284
  38. package/lib/components/nav.ts +0 -257
  39. package/lib/components/paragraph.ts +0 -97
  40. package/lib/components/progress.ts +0 -159
  41. package/lib/components/radio.ts +0 -278
  42. package/lib/components/req.ts +0 -303
  43. package/lib/components/script.ts +0 -41
  44. package/lib/components/select.ts +0 -252
  45. package/lib/components/sidebar.ts +0 -275
  46. package/lib/components/style.ts +0 -41
  47. package/lib/components/switch.ts +0 -246
  48. package/lib/components/table.ts +0 -1249
  49. package/lib/components/tabs.ts +0 -250
  50. package/lib/components/theme-toggle.ts +0 -293
  51. package/lib/components/tooltip.ts +0 -144
  52. package/lib/components/view.ts +0 -190
  53. package/lib/components/write.ts +0 -272
  54. package/lib/layouts/default.css +0 -260
  55. package/lib/layouts/figma.css +0 -334
  56. package/lib/reactivity/state.ts +0 -78
  57. package/lib/utils/fetch.ts +0 -553
  58. package/machinery/ast.js +0 -347
  59. package/machinery/build.js +0 -466
  60. package/machinery/bundleAssets.js +0 -0
  61. package/machinery/bundleJux.js +0 -0
  62. package/machinery/bundleVendors.js +0 -0
  63. package/machinery/doc-generator.js +0 -136
  64. package/machinery/imports.js +0 -155
  65. package/machinery/server.js +0 -166
  66. package/machinery/ts-shim.js +0 -46
  67. package/machinery/validators/file-validator.js +0 -123
@@ -1,291 +0,0 @@
1
- import { BaseComponent } from './base/BaseComponent.js';
2
-
3
- // Event definitions - Grid is layout-only, no interactive events
4
- const TRIGGER_EVENTS = [] as const;
5
- const CALLBACK_EVENTS = [] as const;
6
-
7
- export interface GridRowConfig {
8
- height?: string;
9
- style?: string;
10
- class?: string;
11
- }
12
-
13
- export interface GridColumnConfig {
14
- width?: string;
15
- style?: string;
16
- class?: string;
17
- }
18
-
19
- export interface GridItemConfig {
20
- target: string; // e.g., "#Dashboard-0-1"
21
- text?: string;
22
- html?: string;
23
- component?: any; // Jux component instance
24
- }
25
-
26
- export interface GridCreateConfig {
27
- columns?: GridColumnConfig[] | number;
28
- rows?: GridRowConfig[] | number;
29
- items?: GridItemConfig[];
30
- }
31
-
32
- export interface GridOptions {
33
- columns?: GridColumnConfig[] | number;
34
- rows?: GridRowConfig[] | number;
35
- width?: string;
36
- height?: string;
37
- gap?: string;
38
- style?: string;
39
- class?: string;
40
- }
41
-
42
- type GridState = {
43
- rows: GridRowConfig[];
44
- columns: GridColumnConfig[];
45
- boundary: {
46
- width: string;
47
- height: string;
48
- };
49
- gap: string;
50
- cells: Map<string, HTMLElement>;
51
- style: string;
52
- class: string;
53
- gridder: boolean; // ✅ ADD: Enable blueprint visualization
54
- };
55
-
56
- export class Grid extends BaseComponent<GridState> {
57
- constructor(id: string, options: GridOptions = {}) {
58
- // Normalize columns/rows to config arrays
59
- const columnsConfig = normalizeTrackConfig(options.columns || 1);
60
- const rowsConfig = normalizeTrackConfig(options.rows || 1);
61
-
62
- super(id, {
63
- rows: rowsConfig,
64
- columns: columnsConfig,
65
- boundary: {
66
- width: options.width ?? '', // ✅ CHANGE: Empty = inherit parent
67
- height: options.height ?? '' // ✅ CHANGE: Empty = inherit parent
68
- },
69
- gap: options.gap ?? '0',
70
- cells: new Map(),
71
- style: options.style ?? '',
72
- class: options.class ?? '',
73
- gridder: false
74
- });
75
- }
76
-
77
- protected getTriggerEvents(): readonly string[] {
78
- return TRIGGER_EVENTS;
79
- }
80
-
81
- protected getCallbackEvents(): readonly string[] {
82
- return CALLBACK_EVENTS;
83
- }
84
-
85
- /* ═════════════════════════════════════════════════════════════════
86
- * PROPS ACCESSOR - Inherited from BaseComponent
87
- * ═════════════════════════════════════════════════════════════════ */
88
-
89
- // ✅ Already available via BaseComponent.props getter
90
- // Access: grid.props.rows, grid.props.columns, grid.props.gap, etc.
91
-
92
- /* ═════════════════════════════════════════════════════════════════
93
- * FLUENT API - The Blueprint (Setters)
94
- * ═════════════════════════════════════════════════════════════════ */
95
-
96
- width(value: string): this {
97
- this.state.boundary.width = value;
98
- return this;
99
- }
100
-
101
- height(value: string): this {
102
- this.state.boundary.height = value;
103
- return this;
104
- }
105
-
106
- gap(value: string): this {
107
- this.state.gap = value;
108
- return this;
109
- }
110
-
111
- /**
112
- * Define rows (SETTER)
113
- * @param config - Number (creates N equal rows) or Array of row configs
114
- */
115
- rows(config: GridRowConfig[] | number): this {
116
- this.state.rows = normalizeTrackConfig(config);
117
- return this;
118
- }
119
-
120
- /**
121
- * Define columns (SETTER)
122
- * @param config - Number (creates N equal columns) or Array of column configs
123
- */
124
- columns(config: GridColumnConfig[] | number): this {
125
- this.state.columns = normalizeTrackConfig(config);
126
- return this;
127
- }
128
-
129
- /**
130
- * Get the cell ID for a specific coordinate
131
- */
132
- getCellId(row: number, col: number): string {
133
- return `${this._id}-${row}-${col}`;
134
- }
135
-
136
- /**
137
- * Get the DOM element for a specific cell
138
- */
139
- getCell(row: number, col: number): HTMLElement | undefined {
140
- const cellId = this.getCellId(row, col);
141
- return this.state.cells.get(cellId);
142
- }
143
-
144
- /**
145
- * ✅ Enable blueprint/wireframe visualization
146
- * Shows grid structure, cell coordinates, and geometric borders
147
- */
148
- gridder(value: boolean = true): this {
149
- this.state.gridder = value;
150
- return this;
151
- }
152
-
153
- /* ═════════════════════════════════════════════════════════════════
154
- * ORCHESTRATION - The Execution
155
- * ═════════════════════════════════════════════════════════════════ */
156
-
157
- /**
158
- * Pattern B: The Static Orchestration
159
- * Creates the grid and populates it with items in one operation
160
- */
161
- create(config: GridCreateConfig): this {
162
- // Apply configuration
163
- if (config.columns) {
164
- this.columns(config.columns);
165
- }
166
- if (config.rows) {
167
- this.rows(config.rows);
168
- }
169
-
170
- // Render the grid structure
171
- this.render();
172
-
173
- // Populate items
174
- if (config.items) {
175
- config.items.forEach(item => {
176
- const targetId = item.target.replace(/^#/, '');
177
- const cell = document.getElementById(targetId);
178
-
179
- if (!cell) {
180
- console.warn(`[Grid] Cell not found: ${item.target}`);
181
- return;
182
- }
183
-
184
- if (item.component) {
185
- // Render Jux component
186
- item.component.render(`#${targetId}`);
187
- } else if (item.html) {
188
- cell.innerHTML = item.html;
189
- } else if (item.text) {
190
- cell.textContent = item.text;
191
- }
192
- });
193
- }
194
-
195
- return this;
196
- }
197
-
198
- /* ═════════════════════════════════════════════════════════════════
199
- * RENDER
200
- * ═════════════════════════════════════════════════════════════════ */
201
-
202
- render(targetId?: string): this {
203
- const container = this._setupContainer(targetId);
204
-
205
- const { rows, columns, boundary, gap, style, class: className, gridder } = this.state;
206
-
207
- // Build grid container
208
- const grid = document.createElement('div');
209
- grid.className = 'jux-grid';
210
- grid.id = this._id;
211
- if (gridder) grid.classList.add('jux-grid-gridder');
212
- if (className) grid.className += ` ${className}`;
213
-
214
- // Apply grid styles
215
- const gridTemplateRows = rows.map(r => r.height || '1fr').join(' ');
216
- const gridTemplateColumns = columns.map(c => c.width || '1fr').join(' ');
217
-
218
- const gridStyle = `
219
- display: grid;
220
- grid-template-rows: ${gridTemplateRows};
221
- grid-template-columns: ${gridTemplateColumns};
222
- gap: ${gap};
223
- ${boundary.width ? `width: ${boundary.width};` : ''} /* ✅ CHANGE: Only apply if set */
224
- ${boundary.height ? `height: ${boundary.height};` : ''} /* ✅ CHANGE: Only apply if set */
225
- ${style}
226
- `;
227
-
228
- grid.setAttribute('style', gridStyle.trim());
229
-
230
- // Generate cells with coordinate-based IDs
231
- this.state.cells.clear();
232
-
233
- rows.forEach((row, rowIndex) => {
234
- columns.forEach((col, colIndex) => {
235
- const cell = document.createElement('div');
236
- const cellId = this.getCellId(rowIndex, colIndex);
237
-
238
- cell.id = cellId;
239
- cell.className = 'jux-grid-cell';
240
- cell.setAttribute('data-row', String(rowIndex));
241
- cell.setAttribute('data-col', String(colIndex));
242
-
243
- // ✅ CHANGE: Use title attribute instead of DOM element
244
- if (gridder) {
245
- cell.setAttribute('title', `Cell [${rowIndex},${colIndex}] — #${cellId}`);
246
- }
247
-
248
- // Apply row-specific styles
249
- if (row.style) {
250
- cell.setAttribute('style', (cell.getAttribute('style') || '') + row.style);
251
- }
252
- if (row.class) {
253
- cell.className += ` ${row.class}`;
254
- }
255
-
256
- // Apply column-specific styles
257
- if (col.style) {
258
- cell.setAttribute('style', (cell.getAttribute('style') || '') + col.style);
259
- }
260
- if (col.class) {
261
- cell.className += ` ${col.class}`;
262
- }
263
-
264
- this.state.cells.set(cellId, cell);
265
- grid.appendChild(cell);
266
- });
267
- });
268
-
269
- this._wireStandardEvents(grid);
270
-
271
- container.appendChild(grid);
272
- return this;
273
- }
274
- }
275
-
276
- /**
277
- * Normalize track configuration to array format
278
- */
279
- function normalizeTrackConfig(config: GridRowConfig[] | GridColumnConfig[] | number): any[] {
280
- if (typeof config === 'number') {
281
- return Array(config).fill({});
282
- }
283
- return config;
284
- }
285
-
286
- /**
287
- * Factory function
288
- */
289
- export function grid(id: string, options: GridOptions = {}): Grid {
290
- return new Grid(id, options);
291
- }
@@ -1,92 +0,0 @@
1
- import { BaseComponent } from './base/BaseComponent.js';
2
- import { State } from '../reactivity/state.js';
3
-
4
- // Extend Window interface to include Jux navigation hooks
5
- declare global {
6
- interface Window {
7
- juxBeforeNavigate?: (from: string, to: string) => boolean | string;
8
- juxAfterNavigate?: (path: string) => void;
9
- }
10
- }
11
-
12
- // Event definitions
13
- const TRIGGER_EVENTS = [] as const;
14
- const CALLBACK_EVENTS = ['blocked', 'allowed'] as const;
15
-
16
- export interface GuardOptions {
17
- authState?: State<boolean>; // Check if user is authenticated
18
- loginPath?: string; // Where to redirect if blocked
19
- protectedPaths?: string[]; // Paths that require auth
20
- }
21
-
22
- type GuardState = {
23
- authState: State<boolean> | null;
24
- loginPath: string;
25
- protectedPaths: string[];
26
- isActive: boolean;
27
- };
28
-
29
- /**
30
- * ⚠️ DEPRECATED: Guard component is no longer supported after removing global middleware.
31
- *
32
- * Recommended alternatives:
33
- * 1. Server-side authentication (Express, FastAPI, Laravel)
34
- * 2. Manual route checks in each view
35
- * 3. Custom wrapper components
36
- *
37
- * This component will be removed in a future version.
38
- */
39
- export class Guard extends BaseComponent<GuardState> {
40
- constructor(id: string, options: GuardOptions = {}) {
41
- super(id, {
42
- authState: options.authState ?? null,
43
- loginPath: options.loginPath ?? '/login',
44
- protectedPaths: options.protectedPaths ?? [],
45
- isActive: false
46
- });
47
-
48
- console.warn(
49
- '[Jux Guard] DEPRECATED: Guard component no longer supported after middleware removal.\n' +
50
- 'Use server-side auth or manual checks instead.'
51
- );
52
- }
53
-
54
- protected getTriggerEvents(): readonly string[] {
55
- return TRIGGER_EVENTS;
56
- }
57
-
58
- protected getCallbackEvents(): readonly string[] {
59
- return CALLBACK_EVENTS;
60
- }
61
-
62
- /* ═════════════════════════════════════════════════════════════════
63
- * FLUENT API (No-ops now)
64
- * ═════════════════════════════════════════════════════════════════ */
65
-
66
- requireAuth(authState: State<boolean>, loginPath?: string): this {
67
- console.warn('[Jux Guard] DEPRECATED: requireAuth() has no effect');
68
- return this;
69
- }
70
-
71
- protect(...paths: string[]): this {
72
- console.warn('[Jux Guard] DEPRECATED: protect() has no effect');
73
- return this;
74
- }
75
-
76
- /* ═════════════════════════════════════════════════════════════════
77
- * RENDER (No-op)
78
- * ═════════════════════════════════════════════════════════════════ */
79
-
80
- render(targetId?: string): this {
81
- console.warn('[Jux Guard] DEPRECATED: Guard rendering has no effect');
82
- return this;
83
- }
84
-
85
- deactivate(): this {
86
- return this;
87
- }
88
- }
89
-
90
- export function guard(id: string, options?: GuardOptions): Guard {
91
- return new Guard(id, options);
92
- }
@@ -1,96 +0,0 @@
1
- import { BaseComponent } from './base/BaseComponent.js';
2
-
3
- // Event definitions
4
- const TRIGGER_EVENTS = [] as const;
5
- const CALLBACK_EVENTS = [] as const; // Headings are display-only, no events
6
-
7
- export interface HeadingOptions {
8
- level?: 1 | 2 | 3 | 4 | 5 | 6;
9
- content?: string;
10
- class?: string;
11
- style?: string;
12
- }
13
-
14
- type HeadingState = {
15
- level: 1 | 2 | 3 | 4 | 5 | 6;
16
- content: string;
17
- class: string;
18
- style: string;
19
- };
20
-
21
- export class Heading extends BaseComponent<HeadingState> {
22
- constructor(id: string, options: HeadingOptions = {}) {
23
- super(id, {
24
- level: options.level ?? 1,
25
- content: options.content ?? '',
26
- class: options.class ?? '',
27
- style: options.style ?? ''
28
- });
29
- }
30
-
31
- protected getTriggerEvents(): readonly string[] {
32
- return TRIGGER_EVENTS;
33
- }
34
-
35
- protected getCallbackEvents(): readonly string[] {
36
- return CALLBACK_EVENTS;
37
- }
38
-
39
- /* ═════════════════════════════════════════════════════════════════
40
- * FLUENT API
41
- * ═════════════════════════════════════════════════════════════════ */
42
-
43
- // ✅ Inherited from BaseComponent:
44
- // - style(), class()
45
- // - bind(), sync(), renderTo()
46
- // - All other base methods
47
-
48
- level(value: 1 | 2 | 3 | 4 | 5 | 6): this {
49
- this.state.level = value;
50
- return this;
51
- }
52
-
53
- content(value: string): this {
54
- this.state.content = value;
55
- return this;
56
- }
57
-
58
- /* ═════════════════════════════════════════════════════════════════
59
- * RENDER
60
- * ═════════════════════════════════════════════════════════════════ */
61
-
62
- render(targetId?: string): this {
63
- const container = this._setupContainer(targetId);
64
-
65
- const { content, level, style, class: className } = this.state;
66
-
67
- const heading = document.createElement(`h${level}`) as HTMLHeadingElement;
68
- heading.className = `jux-heading jux-heading-${level}`;
69
- heading.id = this._id;
70
- heading.textContent = content;
71
- if (className) heading.className += ` ${className}`;
72
- if (style) heading.setAttribute('style', style);
73
-
74
- this._wireStandardEvents(heading);
75
-
76
- // Wire sync bindings
77
- this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
78
- if (property === 'content') {
79
- const transform = toComponent || ((v: any) => String(v));
80
-
81
- stateObj.subscribe((val: any) => {
82
- const transformed = transform(val);
83
- heading.textContent = transformed;
84
- this.state.content = transformed;
85
- });
86
- }
87
- });
88
-
89
- container.appendChild(heading);
90
- return this;
91
- }
92
- }
93
-
94
- export function heading(id: string, options: HeadingOptions = {}): Heading {
95
- return new Heading(id, options);
96
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * Component helper utilities
3
- */
4
-
5
- /**
6
- * Get or create a container element for a component
7
- * Auto-creates if it doesn't exist and appends to appropriate parent
8
- */
9
- export function getOrCreateContainer(id: string): HTMLElement {
10
- if (typeof document === 'undefined') {
11
- throw new Error('Document is not available');
12
- }
13
-
14
- let container = document.getElementById(id);
15
-
16
- // Container already exists, return it
17
- if (container) {
18
- return container;
19
- }
20
-
21
- // Auto-create container if it doesn't exist
22
- container = document.createElement('div');
23
- container.id = id;
24
-
25
- // Find appropriate parent - [data-jux-page] takes precedence, then #app, then body
26
- const dataJuxPage = document.querySelector('[data-jux-page]') as HTMLElement;
27
- const app = document.getElementById('app');
28
-
29
- const parent: HTMLElement = (dataJuxPage || app || document.body) as HTMLElement;
30
-
31
- // Log warning if falling back to body
32
- if (!dataJuxPage && !app) {
33
- console.warn(
34
- `[Jux] Preferred container targets "[data-jux-page]" or "#app" not found. Creating container "#${id}" in fallback parent: body`,
35
- );
36
- }
37
-
38
- parent.appendChild(container);
39
-
40
- return container;
41
- }