juxscript 1.0.20 → 1.0.21

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 (76) hide show
  1. package/bin/cli.js +121 -72
  2. package/lib/components/alert.ts +143 -92
  3. package/lib/components/badge.ts +93 -94
  4. package/lib/components/base/BaseComponent.ts +397 -0
  5. package/lib/components/base/FormInput.ts +322 -0
  6. package/lib/components/button.ts +40 -131
  7. package/lib/components/card.ts +57 -79
  8. package/lib/components/charts/areachart.ts +315 -0
  9. package/lib/components/charts/barchart.ts +421 -0
  10. package/lib/components/charts/doughnutchart.ts +263 -0
  11. package/lib/components/charts/lib/BaseChart.ts +402 -0
  12. package/lib/components/{chart-types.ts → charts/lib/chart-types.ts} +1 -1
  13. package/lib/components/{chart-utils.ts → charts/lib/chart-utils.ts} +1 -1
  14. package/lib/components/{chart.ts → charts/lib/chart.ts} +3 -3
  15. package/lib/components/checkbox.ts +255 -204
  16. package/lib/components/code.ts +31 -78
  17. package/lib/components/container.ts +113 -130
  18. package/lib/components/data.ts +37 -5
  19. package/lib/components/datepicker.ts +180 -147
  20. package/lib/components/dialog.ts +218 -221
  21. package/lib/components/divider.ts +63 -87
  22. package/lib/components/docs-data.json +498 -2404
  23. package/lib/components/dropdown.ts +191 -236
  24. package/lib/components/element.ts +196 -145
  25. package/lib/components/fileupload.ts +253 -167
  26. package/lib/components/guard.ts +92 -0
  27. package/lib/components/heading.ts +31 -97
  28. package/lib/components/helpers.ts +13 -6
  29. package/lib/components/hero.ts +51 -114
  30. package/lib/components/icon.ts +33 -120
  31. package/lib/components/icons.ts +2 -1
  32. package/lib/components/include.ts +76 -3
  33. package/lib/components/input.ts +155 -407
  34. package/lib/components/kpicard.ts +16 -16
  35. package/lib/components/list.ts +358 -261
  36. package/lib/components/loading.ts +142 -211
  37. package/lib/components/menu.ts +63 -152
  38. package/lib/components/modal.ts +42 -129
  39. package/lib/components/nav.ts +79 -101
  40. package/lib/components/paragraph.ts +38 -102
  41. package/lib/components/progress.ts +108 -166
  42. package/lib/components/radio.ts +283 -234
  43. package/lib/components/script.ts +19 -87
  44. package/lib/components/select.ts +189 -199
  45. package/lib/components/sidebar.ts +110 -141
  46. package/lib/components/style.ts +19 -82
  47. package/lib/components/switch.ts +254 -183
  48. package/lib/components/table.ts +1078 -208
  49. package/lib/components/tabs.ts +42 -106
  50. package/lib/components/theme-toggle.ts +73 -165
  51. package/lib/components/tooltip.ts +85 -316
  52. package/lib/components/write.ts +108 -127
  53. package/lib/jux.ts +67 -41
  54. package/machinery/build.js +466 -0
  55. package/machinery/compiler.js +354 -105
  56. package/machinery/server.js +23 -100
  57. package/machinery/watcher.js +153 -130
  58. package/package.json +1 -1
  59. package/presets/base.css +1166 -0
  60. package/presets/notion.css +2 -1975
  61. package/lib/adapters/base-adapter.js +0 -35
  62. package/lib/adapters/index.js +0 -33
  63. package/lib/adapters/mysql-adapter.js +0 -65
  64. package/lib/adapters/postgres-adapter.js +0 -70
  65. package/lib/adapters/sqlite-adapter.js +0 -56
  66. package/lib/components/areachart.ts +0 -1128
  67. package/lib/components/areachartsmooth.ts +0 -1380
  68. package/lib/components/barchart.ts +0 -1322
  69. package/lib/components/doughnutchart.ts +0 -1259
  70. package/lib/components/footer.ts +0 -165
  71. package/lib/components/header.ts +0 -187
  72. package/lib/components/layout.ts +0 -239
  73. package/lib/components/main.ts +0 -137
  74. package/lib/layouts/default.jux +0 -8
  75. package/lib/layouts/figma.jux +0 -0
  76. /package/lib/{themes → components/charts/lib}/charts.js +0 -0
@@ -1,263 +1,194 @@
1
- import { getOrCreateContainer } from './helpers.js';
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+
3
+ // Event definitions
4
+ const TRIGGER_EVENTS = [] as const;
5
+ const CALLBACK_EVENTS = [] as const;
2
6
 
3
- /**
4
- * Loading component options
5
- */
6
7
  export interface LoadingOptions {
7
- variant?: 'spinner' | 'dots' | 'pulse' | 'skeleton';
8
+ variant?: 'spinner' | 'dots' | 'pulse';
8
9
  size?: 'sm' | 'md' | 'lg';
9
- text?: string;
10
- fullscreen?: boolean;
11
10
  style?: string;
12
11
  class?: string;
13
12
  }
14
13
 
15
- /**
16
- * Loading component state
17
- */
18
14
  type LoadingState = {
19
15
  variant: string;
20
16
  size: string;
21
- text: string;
22
- fullscreen: boolean;
23
17
  style: string;
24
18
  class: string;
25
19
  };
26
20
 
27
- /**
28
- * Loading component - Spinners, skeletons, loading indicators
29
- *
30
- * Usage:
31
- * jux.loading('my-spinner', {
32
- * variant: 'spinner',
33
- * size: 'lg',
34
- * text: 'Loading...'
35
- * }).render('#app');
36
- *
37
- * // Fullscreen overlay
38
- * jux.loading('loading-overlay', {
39
- * variant: 'spinner',
40
- * fullscreen: true,
41
- * text: 'Please wait...'
42
- * }).render();
43
- *
44
- * Variants: spinner, dots, pulse, skeleton
45
- */
46
- export class Loading {
47
- state: LoadingState;
48
- container: HTMLElement | null = null;
49
- _id: string;
50
- id: string;
51
-
21
+ export class Loading extends BaseComponent<LoadingState> {
52
22
  constructor(id: string, options: LoadingOptions = {}) {
53
- this._id = id;
54
- this.id = id;
55
-
56
- this.state = {
23
+ super(id, {
57
24
  variant: options.variant ?? 'spinner',
58
25
  size: options.size ?? 'md',
59
- text: options.text ?? '',
60
- fullscreen: options.fullscreen ?? false,
61
26
  style: options.style ?? '',
62
27
  class: options.class ?? ''
63
- };
28
+ });
64
29
  }
65
30
 
66
- /* -------------------------
67
- * Fluent API
68
- * ------------------------- */
69
-
70
- variant(value: 'spinner' | 'dots' | 'pulse' | 'skeleton'): this {
71
- this.state.variant = value;
72
- return this;
31
+ protected getTriggerEvents(): readonly string[] {
32
+ return TRIGGER_EVENTS;
73
33
  }
74
34
 
75
- size(value: 'sm' | 'md' | 'lg'): this {
76
- this.state.size = value;
77
- return this;
35
+ protected getCallbackEvents(): readonly string[] {
36
+ return CALLBACK_EVENTS;
78
37
  }
79
38
 
80
- text(value: string): this {
81
- this.state.text = value;
82
- return this;
83
- }
39
+ /* ═════════════════════════════════════════════════════════════════
40
+ * FLUENT API
41
+ * ═════════════════════════════════════════════════════════════════ */
84
42
 
85
- fullscreen(value: boolean): this {
86
- this.state.fullscreen = value;
87
- return this;
88
- }
43
+ // Inherited from BaseComponent:
44
+ // - style(), class()
45
+ // - bind(), sync(), renderTo()
46
+ // - visible(), show(), hide()
89
47
 
90
- style(value: string): this {
91
- this.state.style = value;
48
+ variant(value: 'spinner' | 'dots' | 'pulse'): this {
49
+ this.state.variant = value;
92
50
  return this;
93
51
  }
94
52
 
95
- class(value: string): this {
96
- this.state.class = value;
53
+ size(value: 'sm' | 'md' | 'lg'): this {
54
+ this.state.size = value;
97
55
  return this;
98
56
  }
99
57
 
100
- /* -------------------------
101
- * Methods
102
- * ------------------------- */
103
-
104
- /**
105
- * Show the loading indicator
106
- */
107
- show(): void {
108
- const element = document.getElementById(this._id);
109
- if (element) {
110
- element.style.display = 'flex';
111
- }
112
- }
113
-
114
- /**
115
- * Hide the loading indicator
116
- */
117
- hide(): void {
118
- const element = document.getElementById(this._id);
119
- if (element) {
120
- element.style.display = 'none';
121
- }
122
- }
123
-
124
- /**
125
- * Remove the loading indicator
126
- */
127
- remove(): void {
128
- const element = document.getElementById(this._id);
129
- if (element) {
130
- element.remove();
131
- }
132
- }
133
-
134
- /* -------------------------
135
- * Helpers
136
- * ------------------------- */
137
-
138
- private _renderSpinner(): HTMLElement {
139
- const spinner = document.createElement('div');
140
- spinner.className = 'jux-loading-spinner';
141
- return spinner;
142
- }
143
-
144
- private _renderDots(): HTMLElement {
145
- const dots = document.createElement('div');
146
- dots.className = 'jux-loading-dots';
147
- for (let i = 0; i < 3; i++) {
148
- const dot = document.createElement('div');
149
- dot.className = 'jux-loading-dot';
150
- dots.appendChild(dot);
151
- }
152
- return dots;
153
- }
154
-
155
- private _renderPulse(): HTMLElement {
156
- const pulse = document.createElement('div');
157
- pulse.className = 'jux-loading-pulse';
158
- return pulse;
159
- }
160
-
161
- private _renderSkeleton(): HTMLElement {
162
- const skeleton = document.createElement('div');
163
- skeleton.className = 'jux-loading-skeleton';
164
-
165
- // Create 3 skeleton lines
166
- for (let i = 0; i < 3; i++) {
167
- const line = document.createElement('div');
168
- line.className = 'jux-loading-skeleton-line';
169
- if (i === 2) line.style.width = '60%'; // Last line shorter
170
- skeleton.appendChild(line);
171
- }
172
- return skeleton;
173
- }
174
-
175
- /* -------------------------
176
- * Render
177
- * ------------------------- */
58
+ /* ═════════════════════════════════════════════════════════════════
59
+ * RENDER
60
+ * ═════════════════════════════════════════════════════════════════ */
178
61
 
179
62
  render(targetId?: string): this {
180
- let container: HTMLElement;
63
+ const container = this._setupContainer(targetId);
181
64
 
182
- if (targetId) {
183
- const target = document.querySelector(targetId);
184
- if (!target || !(target instanceof HTMLElement)) {
185
- throw new Error(`Loading: Target element "${targetId}" not found`);
186
- }
187
- container = target;
188
- } else {
189
- container = getOrCreateContainer(this._id);
190
- }
191
-
192
- this.container = container;
193
- const { variant, size, text, fullscreen, style, class: className } = this.state;
65
+ const { variant, size, style, class: className } = this.state;
194
66
 
195
67
  const loading = document.createElement('div');
196
- loading.className = `jux-loading jux-loading-${size}`;
68
+ loading.className = `jux-loading jux-loading-${variant} jux-loading-${size}`;
197
69
  loading.id = this._id;
198
-
199
- if (fullscreen) {
200
- loading.className += ' jux-loading-fullscreen';
201
- }
202
-
203
- if (className) {
204
- loading.className += ` ${className}`;
205
- }
206
-
207
- if (style) {
208
- loading.setAttribute('style', style);
209
- }
210
-
211
- // Render appropriate variant
212
- let indicator: HTMLElement;
213
- switch (variant) {
214
- case 'dots':
215
- indicator = this._renderDots();
216
- break;
217
- case 'pulse':
218
- indicator = this._renderPulse();
219
- break;
220
- case 'skeleton':
221
- indicator = this._renderSkeleton();
222
- break;
223
- case 'spinner':
224
- default:
225
- indicator = this._renderSpinner();
70
+ if (className) loading.className += ` ${className}`;
71
+ if (style) loading.setAttribute('style', style);
72
+
73
+ // Build variant-specific content
74
+ if (variant === 'spinner') {
75
+ const spinner = document.createElement('div');
76
+ spinner.className = 'jux-loading-spinner';
77
+ loading.appendChild(spinner);
78
+ } else if (variant === 'dots') {
79
+ for (let i = 0; i < 3; i++) {
80
+ const dot = document.createElement('div');
81
+ dot.className = 'jux-loading-dot';
82
+ loading.appendChild(dot);
83
+ }
84
+ } else if (variant === 'pulse') {
85
+ const pulse = document.createElement('div');
86
+ pulse.className = 'jux-loading-pulse';
87
+ loading.appendChild(pulse);
226
88
  }
227
89
 
228
- loading.appendChild(indicator);
229
-
230
- // Optional text
231
- if (text) {
232
- const textEl = document.createElement('div');
233
- textEl.className = 'jux-loading-text';
234
- textEl.textContent = text;
235
- loading.appendChild(textEl);
236
- }
90
+ this._wireStandardEvents(loading);
237
91
 
238
92
  container.appendChild(loading);
93
+ this._injectLoadingStyles();
94
+
239
95
  return this;
240
96
  }
241
97
 
242
- /**
243
- * Render to another Jux component's container
244
- */
245
- renderTo(juxComponent: any): this {
246
- if (!juxComponent || typeof juxComponent !== 'object') {
247
- throw new Error('Loading.renderTo: Invalid component - not an object');
248
- }
249
-
250
- if (!juxComponent._id || typeof juxComponent._id !== 'string') {
251
- throw new Error('Loading.renderTo: Invalid component - missing _id (not a Jux component)');
252
- }
253
-
254
- return this.render(`#${juxComponent._id}`);
98
+ private _injectLoadingStyles(): void {
99
+ const styleId = 'jux-loading-styles';
100
+ if (document.getElementById(styleId)) return;
101
+
102
+ const style = document.createElement('style');
103
+ style.id = styleId;
104
+ style.textContent = `
105
+ .jux-loading {
106
+ display: inline-flex;
107
+ align-items: center;
108
+ justify-content: center;
109
+ gap: 4px;
110
+ }
111
+
112
+ .jux-loading-sm { width: 20px; height: 20px; }
113
+ .jux-loading-md { width: 40px; height: 40px; }
114
+ .jux-loading-lg { width: 60px; height: 60px; }
115
+
116
+ /* Spinner */
117
+ .jux-loading-spinner {
118
+ width: 30px;
119
+ height: 30px;
120
+ border: 2px solid #e5e7eb;
121
+ border-top-color: #3b82f6;
122
+ border-radius: 50%;
123
+ animation: jux-spin 0.8s linear infinite;
124
+ }
125
+
126
+ .jux-loading-sm .jux-loading-spinner {
127
+ border-width: 2px;
128
+ }
129
+
130
+ .jux-loading-md .jux-loading-spinner {
131
+ border-width: 3px;
132
+ }
133
+
134
+ .jux-loading-lg .jux-loading-spinner {
135
+ border-width: 4px;
136
+ }
137
+
138
+ @keyframes jux-spin {
139
+ to { transform: rotate(360deg); }
140
+ }
141
+
142
+ /* Dots */
143
+ .jux-loading-dot {
144
+ width: 8px;
145
+ height: 8px;
146
+ background: #3b82f6;
147
+ border-radius: 50%;
148
+ animation: jux-bounce 1.4s infinite ease-in-out both;
149
+ }
150
+
151
+ .jux-loading-sm .jux-loading-dot {
152
+ width: 5px;
153
+ height: 5px;
154
+ }
155
+
156
+ .jux-loading-md .jux-loading-dot {
157
+ width: 8px;
158
+ height: 8px;
159
+ }
160
+
161
+ .jux-loading-lg .jux-loading-dot {
162
+ width: 12px;
163
+ height: 12px;
164
+ }
165
+
166
+ .jux-loading-dot:nth-child(1) { animation-delay: -0.32s; }
167
+ .jux-loading-dot:nth-child(2) { animation-delay: -0.16s; }
168
+
169
+ @keyframes jux-bounce {
170
+ 0%, 80%, 100% { transform: scale(0); }
171
+ 40% { transform: scale(1); }
172
+ }
173
+
174
+ /* Pulse */
175
+ .jux-loading-pulse {
176
+ width: 100%;
177
+ height: 100%;
178
+ background: #3b82f6;
179
+ border-radius: 50%;
180
+ animation: jux-pulse 1.5s ease-in-out infinite;
181
+ }
182
+
183
+ @keyframes jux-pulse {
184
+ 0%, 100% { opacity: 1; transform: scale(0.8); }
185
+ 50% { opacity: 0.5; transform: scale(1.2); }
186
+ }
187
+ `;
188
+ document.head.appendChild(style);
255
189
  }
256
190
  }
257
191
 
258
- /**
259
- * Factory helper
260
- */
261
192
  export function loading(id: string, options: LoadingOptions = {}): Loading {
262
193
  return new Loading(id, options);
263
194
  }