juxscript 1.1.3 → 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 (63) hide show
  1. package/machinery/build3.js +7 -91
  2. package/machinery/compiler3.js +3 -209
  3. package/package.json +19 -5
  4. package/lib/components/alert.ts +0 -200
  5. package/lib/components/app.ts +0 -247
  6. package/lib/components/badge.ts +0 -101
  7. package/lib/components/base/BaseComponent.ts +0 -421
  8. package/lib/components/base/FormInput.ts +0 -227
  9. package/lib/components/button.ts +0 -178
  10. package/lib/components/card.ts +0 -173
  11. package/lib/components/chart.ts +0 -231
  12. package/lib/components/checkbox.ts +0 -242
  13. package/lib/components/code.ts +0 -123
  14. package/lib/components/container.ts +0 -140
  15. package/lib/components/data.ts +0 -135
  16. package/lib/components/datepicker.ts +0 -234
  17. package/lib/components/dialog.ts +0 -172
  18. package/lib/components/divider.ts +0 -100
  19. package/lib/components/dropdown.ts +0 -186
  20. package/lib/components/element.ts +0 -267
  21. package/lib/components/fileupload.ts +0 -309
  22. package/lib/components/grid.ts +0 -291
  23. package/lib/components/guard.ts +0 -92
  24. package/lib/components/heading.ts +0 -96
  25. package/lib/components/helpers.ts +0 -41
  26. package/lib/components/hero.ts +0 -224
  27. package/lib/components/icon.ts +0 -178
  28. package/lib/components/icons.ts +0 -464
  29. package/lib/components/include.ts +0 -410
  30. package/lib/components/input.ts +0 -457
  31. package/lib/components/list.ts +0 -419
  32. package/lib/components/loading.ts +0 -100
  33. package/lib/components/menu.ts +0 -275
  34. package/lib/components/modal.ts +0 -284
  35. package/lib/components/nav.ts +0 -257
  36. package/lib/components/paragraph.ts +0 -97
  37. package/lib/components/progress.ts +0 -159
  38. package/lib/components/radio.ts +0 -278
  39. package/lib/components/req.ts +0 -303
  40. package/lib/components/script.ts +0 -41
  41. package/lib/components/select.ts +0 -252
  42. package/lib/components/sidebar.ts +0 -275
  43. package/lib/components/style.ts +0 -41
  44. package/lib/components/switch.ts +0 -246
  45. package/lib/components/table.ts +0 -1249
  46. package/lib/components/tabs.ts +0 -250
  47. package/lib/components/theme-toggle.ts +0 -293
  48. package/lib/components/tooltip.ts +0 -144
  49. package/lib/components/view.ts +0 -190
  50. package/lib/components/write.ts +0 -272
  51. package/lib/layouts/default.css +0 -260
  52. package/lib/layouts/figma.css +0 -334
  53. package/lib/reactivity/state.ts +0 -78
  54. package/lib/utils/fetch.ts +0 -553
  55. package/machinery/ast.js +0 -347
  56. package/machinery/build.js +0 -466
  57. package/machinery/bundleAssets.js +0 -0
  58. package/machinery/bundleJux.js +0 -0
  59. package/machinery/bundleVendors.js +0 -0
  60. package/machinery/doc-generator.js +0 -136
  61. package/machinery/imports.js +0 -155
  62. package/machinery/ts-shim.js +0 -46
  63. 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
- }