juxscript 1.0.19 → 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 (77) hide show
  1. package/bin/cli.js +121 -72
  2. package/lib/components/alert.ts +212 -165
  3. package/lib/components/badge.ts +93 -103
  4. package/lib/components/base/BaseComponent.ts +397 -0
  5. package/lib/components/base/FormInput.ts +322 -0
  6. package/lib/components/button.ts +63 -122
  7. package/lib/components/card.ts +109 -155
  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/charts/lib/chart-types.ts +159 -0
  13. package/lib/components/charts/lib/chart-utils.ts +160 -0
  14. package/lib/components/charts/lib/chart.ts +707 -0
  15. package/lib/components/checkbox.ts +264 -127
  16. package/lib/components/code.ts +75 -108
  17. package/lib/components/container.ts +113 -130
  18. package/lib/components/data.ts +37 -5
  19. package/lib/components/datepicker.ts +195 -147
  20. package/lib/components/dialog.ts +187 -157
  21. package/lib/components/divider.ts +85 -191
  22. package/lib/components/docs-data.json +544 -2027
  23. package/lib/components/dropdown.ts +178 -136
  24. package/lib/components/element.ts +227 -171
  25. package/lib/components/fileupload.ts +285 -228
  26. package/lib/components/guard.ts +92 -0
  27. package/lib/components/heading.ts +46 -69
  28. package/lib/components/helpers.ts +13 -6
  29. package/lib/components/hero.ts +107 -95
  30. package/lib/components/icon.ts +160 -0
  31. package/lib/components/icons.ts +175 -0
  32. package/lib/components/include.ts +153 -5
  33. package/lib/components/input.ts +174 -374
  34. package/lib/components/kpicard.ts +16 -16
  35. package/lib/components/list.ts +378 -240
  36. package/lib/components/loading.ts +142 -211
  37. package/lib/components/menu.ts +103 -97
  38. package/lib/components/modal.ts +138 -144
  39. package/lib/components/nav.ts +169 -90
  40. package/lib/components/paragraph.ts +49 -150
  41. package/lib/components/progress.ts +118 -200
  42. package/lib/components/radio.ts +297 -149
  43. package/lib/components/script.ts +19 -87
  44. package/lib/components/select.ts +184 -186
  45. package/lib/components/sidebar.ts +152 -140
  46. package/lib/components/style.ts +19 -82
  47. package/lib/components/switch.ts +258 -188
  48. package/lib/components/table.ts +1117 -170
  49. package/lib/components/tabs.ts +162 -145
  50. package/lib/components/theme-toggle.ts +108 -169
  51. package/lib/components/tooltip.ts +86 -157
  52. package/lib/components/write.ts +108 -127
  53. package/lib/jux.ts +86 -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 -2
  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 -1246
  67. package/lib/components/areachartsmooth.ts +0 -1380
  68. package/lib/components/barchart.ts +0 -1250
  69. package/lib/components/chart.ts +0 -127
  70. package/lib/components/doughnutchart.ts +0 -1191
  71. package/lib/components/footer.ts +0 -165
  72. package/lib/components/header.ts +0 -187
  73. package/lib/components/layout.ts +0 -239
  74. package/lib/components/main.ts +0 -137
  75. package/lib/layouts/default.jux +0 -8
  76. package/lib/layouts/figma.jux +0 -0
  77. /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
  }