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
@@ -0,0 +1,402 @@
1
+ import { BaseComponent } from '../../base/BaseComponent.js';
2
+
3
+
4
+ // Event definitions
5
+ const TRIGGER_EVENTS = [] as const;
6
+ const CALLBACK_EVENTS = [] as const;
7
+
8
+ /**
9
+ * Base chart data point
10
+ */
11
+ export interface ChartDataPoint {
12
+ label: string;
13
+ value: number;
14
+ color?: string;
15
+ }
16
+
17
+ /**
18
+ * Base chart state shared by all chart types
19
+ */
20
+ export interface BaseChartState {
21
+ data: ChartDataPoint[];
22
+ title: string;
23
+ subtitle: string;
24
+ xAxisLabel: string;
25
+ yAxisLabel: string;
26
+ showTicksX: boolean;
27
+ showTicksY: boolean;
28
+ showScaleX: boolean;
29
+ showScaleY: boolean;
30
+ scaleXUnit: string;
31
+ scaleYUnit: string;
32
+ showLegend: boolean;
33
+ legendOrientation: 'horizontal' | 'vertical';
34
+ showDataTable: boolean;
35
+ showDataLabels: boolean;
36
+ animate: boolean;
37
+ animationDuration: number;
38
+ width: number;
39
+ height: number;
40
+ colors: string[];
41
+ class: string;
42
+ style: string;
43
+ theme?: 'google' | 'seriesa' | 'hr' | 'figma' | 'notion' | 'chalk' | 'mint';
44
+ styleMode: 'default' | 'gradient' | 'outline' | 'dashed' | 'glow' | 'glass';
45
+ borderRadius: number;
46
+ }
47
+
48
+ /**
49
+ * Abstract base class for all chart components
50
+ */
51
+ export abstract class BaseChart<TState extends BaseChartState> extends BaseComponent<TState> {
52
+ protected getTriggerEvents(): readonly string[] {
53
+ return TRIGGER_EVENTS;
54
+ }
55
+
56
+ protected getCallbackEvents(): readonly string[] {
57
+ return CALLBACK_EVENTS;
58
+ }
59
+
60
+ /* ═════════════════════════════════════════════════════════════════
61
+ * SHARED FLUENT API (All charts inherit these)
62
+ * ═════════════════════════════════════════════════════════════════ */
63
+
64
+ data(value: ChartDataPoint[]): this {
65
+ this.state.data = value;
66
+ if (this.container) this._updateChart();
67
+ return this;
68
+ }
69
+
70
+ title(value: string): this {
71
+ this.state.title = value;
72
+ if (this.container) this._updateChart();
73
+ return this;
74
+ }
75
+
76
+ subtitle(value: string): this {
77
+ this.state.subtitle = value;
78
+ if (this.container) this._updateChart();
79
+ return this;
80
+ }
81
+
82
+ xAxisLabel(value: string): this {
83
+ this.state.xAxisLabel = value;
84
+ if (this.container) this._updateChart();
85
+ return this;
86
+ }
87
+
88
+ yAxisLabel(value: string): this {
89
+ this.state.yAxisLabel = value;
90
+ if (this.container) this._updateChart();
91
+ return this;
92
+ }
93
+
94
+ showTicksX(value: boolean): this {
95
+ this.state.showTicksX = value;
96
+ if (this.container) this._updateChart();
97
+ return this;
98
+ }
99
+
100
+ showTicksY(value: boolean): this {
101
+ this.state.showTicksY = value;
102
+ if (this.container) this._updateChart();
103
+ return this;
104
+ }
105
+
106
+ showScaleX(value: boolean): this {
107
+ this.state.showScaleX = value;
108
+ if (this.container) this._updateChart();
109
+ return this;
110
+ }
111
+
112
+ showScaleY(value: boolean): this {
113
+ this.state.showScaleY = value;
114
+ if (this.container) this._updateChart();
115
+ return this;
116
+ }
117
+
118
+ scaleXUnit(value: string): this {
119
+ this.state.scaleXUnit = value;
120
+ if (this.container) this._updateChart();
121
+ return this;
122
+ }
123
+
124
+ scaleYUnit(value: string): this {
125
+ this.state.scaleYUnit = value;
126
+ if (this.container) this._updateChart();
127
+ return this;
128
+ }
129
+
130
+ showLegend(value: boolean): this {
131
+ this.state.showLegend = value;
132
+ if (this.container) this._updateChart();
133
+ return this;
134
+ }
135
+
136
+ legendOrientation(value: 'horizontal' | 'vertical'): this {
137
+ this.state.legendOrientation = value;
138
+ if (this.container) this._updateChart();
139
+ return this;
140
+ }
141
+
142
+ showDataTable(value: boolean): this {
143
+ this.state.showDataTable = value;
144
+ if (this.container) this._updateChart();
145
+ return this;
146
+ }
147
+
148
+ showDataLabels(value: boolean): this {
149
+ this.state.showDataLabels = value;
150
+ if (this.container) this._updateChart();
151
+ return this;
152
+ }
153
+
154
+ animate(value: boolean): this {
155
+ this.state.animate = value;
156
+ if (this.container) this._updateChart();
157
+ return this;
158
+ }
159
+
160
+ animationDuration(value: number): this {
161
+ this.state.animationDuration = value;
162
+ if (this.container) this._updateChart();
163
+ return this;
164
+ }
165
+
166
+ width(value: number): this {
167
+ this.state.width = value;
168
+ if (this.container) this._updateChart();
169
+ return this;
170
+ }
171
+
172
+ height(value: number): this {
173
+ this.state.height = value;
174
+ if (this.container) this._updateChart();
175
+ return this;
176
+ }
177
+
178
+ colors(value: string[]): this {
179
+ this.state.colors = value;
180
+ if (this.container) this._updateChart();
181
+ return this;
182
+ }
183
+
184
+ theme(value: 'google' | 'seriesa' | 'hr' | 'figma' | 'notion' | 'chalk' | 'mint'): this {
185
+ this.state.theme = value;
186
+ this._applyTheme(value);
187
+ if (this.container) this._updateChart();
188
+ return this;
189
+ }
190
+
191
+ styleMode(value: 'default' | 'gradient' | 'outline' | 'dashed' | 'glow' | 'glass'): this {
192
+ this.state.styleMode = value;
193
+ if (this.container) this._updateChart();
194
+ return this;
195
+ }
196
+
197
+ borderRadius(value: number): this {
198
+ this.state.borderRadius = value;
199
+ if (this.container) this._updateChart();
200
+ return this;
201
+ }
202
+
203
+ /* ═════════════════════════════════════════════════════════════════
204
+ * SHARED INTERNAL METHODS
205
+ * ═════════════════════════════════════════════════════════════════ */
206
+
207
+ protected _updateChart(): void {
208
+ if (!this.container) return;
209
+
210
+ const wrapper = this.container.querySelector(`#${this._id}`) as HTMLElement;
211
+ if (!wrapper) return;
212
+
213
+ wrapper.innerHTML = '';
214
+ this._buildChart(wrapper);
215
+
216
+ if (this.state.theme) {
217
+ this._applyThemeToWrapper(wrapper);
218
+ }
219
+ }
220
+
221
+ protected _buildChart(wrapper: HTMLElement): void {
222
+ const { title, subtitle, showLegend, showDataTable } = this.state;
223
+
224
+ if (title) {
225
+ const titleEl = document.createElement('h3');
226
+ titleEl.className = `${this._getChartClassName()}-title`;
227
+ titleEl.textContent = title;
228
+ wrapper.appendChild(titleEl);
229
+ }
230
+
231
+ if (subtitle) {
232
+ const subtitleEl = document.createElement('p');
233
+ subtitleEl.className = `${this._getChartClassName()}-subtitle`;
234
+ subtitleEl.textContent = subtitle;
235
+ wrapper.appendChild(subtitleEl);
236
+ }
237
+
238
+ const svg = this._createSVG();
239
+ wrapper.appendChild(svg);
240
+
241
+ if (showLegend) {
242
+ const legend = this._createLegend();
243
+ wrapper.appendChild(legend);
244
+ }
245
+
246
+ if (showDataTable) {
247
+ const table = this._createDataTable();
248
+ wrapper.appendChild(table);
249
+ }
250
+ }
251
+
252
+ protected _createLegend(): HTMLElement {
253
+ const { data, colors } = this.state;
254
+ const className = this._getChartClassName();
255
+
256
+ const legend = document.createElement('div');
257
+ legend.className = `${className}-legend`;
258
+
259
+ data.forEach((point, index) => {
260
+ const color = point.color || colors[index % colors.length];
261
+
262
+ const item = document.createElement('div');
263
+ item.className = `${className}-legend-item`;
264
+
265
+ const swatch = document.createElement('div');
266
+ swatch.className = `${className}-legend-swatch`;
267
+ swatch.style.background = color;
268
+
269
+ const label = document.createElement('span');
270
+ label.className = `${className}-legend-label`;
271
+ label.textContent = point.label;
272
+
273
+ item.appendChild(swatch);
274
+ item.appendChild(label);
275
+ legend.appendChild(item);
276
+ });
277
+
278
+ return legend;
279
+ }
280
+
281
+ protected _createDataTable(): HTMLElement {
282
+ const { data, xAxisLabel, yAxisLabel } = this.state;
283
+ const className = this._getChartClassName();
284
+
285
+ const table = document.createElement('table');
286
+ table.className = `${className}-table`;
287
+
288
+ const thead = document.createElement('thead');
289
+ const headerRow = document.createElement('tr');
290
+
291
+ [xAxisLabel || 'Label', yAxisLabel || 'Value'].forEach(text => {
292
+ const th = document.createElement('th');
293
+ th.textContent = text;
294
+ headerRow.appendChild(th);
295
+ });
296
+ thead.appendChild(headerRow);
297
+ table.appendChild(thead);
298
+
299
+ const tbody = document.createElement('tbody');
300
+ data.forEach(point => {
301
+ const row = document.createElement('tr');
302
+
303
+ const labelCell = document.createElement('td');
304
+ labelCell.textContent = point.label;
305
+
306
+ const valueCell = document.createElement('td');
307
+ valueCell.textContent = point.value.toString();
308
+
309
+ row.appendChild(labelCell);
310
+ row.appendChild(valueCell);
311
+ tbody.appendChild(row);
312
+ });
313
+ table.appendChild(tbody);
314
+
315
+ return table;
316
+ }
317
+
318
+ protected _lightenColor(color: string, percent: number): string {
319
+ const num = parseInt(color.replace('#', ''), 16);
320
+ const r = Math.min(255, Math.floor((num >> 16) + ((255 - (num >> 16)) * percent / 100)));
321
+ const g = Math.min(255, Math.floor(((num >> 8) & 0x00FF) + ((255 - ((num >> 8) & 0x00FF)) * percent / 100)));
322
+ const b = Math.min(255, Math.floor((num & 0x0000FF) + ((255 - (num & 0x0000FF)) * percent / 100)));
323
+ return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, '0')}`;
324
+ }
325
+
326
+ protected _applyTheme(themeName: string): void {
327
+ // Simple theme color sets
328
+ const themes: Record<string, string[]> = {
329
+ google: ['#4285F4', '#EA4335', '#FBBC04', '#34A853', '#FF6D01', '#46BDC6'],
330
+ seriesa: ['#667eea', '#764ba2', '#f093fb', '#4facfe', '#00f2fe', '#43e97b'],
331
+ hr: ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F'],
332
+ figma: ['#0ACF83', '#FF7262', '#1ABCFE', '#A259FF', '#F24E1E', '#FFC700'],
333
+ notion: ['#2EAADC', '#9B59B6', '#E67E22', '#E74C3C', '#F39C12', '#16A085'],
334
+ chalk: ['#96CEB4', '#FFEAA7', '#DFE6E9', '#74B9FF', '#FD79A8', '#A29BFE'],
335
+ mint: ['#26de81', '#20bf6b', '#0fb9b1', '#2bcbba', '#45aaf2', '#4b7bec']
336
+ };
337
+
338
+ this.state.colors = themes[themeName] || themes.google;
339
+ }
340
+
341
+ protected _applyThemeToWrapper(wrapper: HTMLElement): void {
342
+ if (!this.state.theme) return;
343
+
344
+ wrapper.classList.remove('theme-google', 'theme-seriesa', 'theme-hr', 'theme-figma', 'theme-notion', 'theme-chalk', 'theme-mint');
345
+ wrapper.classList.add(`theme-${this.state.theme}`);
346
+ }
347
+
348
+ /* ═════════════════════════════════════════════════════════════════
349
+ * ABSTRACT METHODS (Child must implement)
350
+ * ═════════════════════════════════════════════════════════════════ */
351
+
352
+ protected abstract _createSVG(): SVGSVGElement;
353
+ protected abstract _getChartClassName(): string;
354
+ protected abstract _getBaseStyles(): string;
355
+
356
+ /* ═════════════════════════════════════════════════════════════════
357
+ * RENDER (Shared implementation)
358
+ * ═════════════════════════════════════════════════════════════════ */
359
+
360
+ render(targetId?: string): this {
361
+ if (this.state.theme) {
362
+ this._applyTheme(this.state.theme);
363
+ }
364
+
365
+ const container = this._setupContainer(targetId);
366
+ const { class: className, style } = this.state;
367
+
368
+ const wrapper = document.createElement('div');
369
+ wrapper.id = this._id;
370
+ wrapper.className = this._getChartClassName();
371
+
372
+ if (this.state.theme) {
373
+ wrapper.classList.add(`theme-${this.state.theme}`);
374
+ }
375
+
376
+ if (className) {
377
+ wrapper.classList.add(...className.split(' '));
378
+ }
379
+
380
+ if (style) {
381
+ wrapper.setAttribute('style', style);
382
+ }
383
+
384
+ // Inject styles
385
+ this._injectStyles();
386
+
387
+ container.appendChild(wrapper);
388
+ this._buildChart(wrapper);
389
+
390
+ return this;
391
+ }
392
+
393
+ private _injectStyles(): void {
394
+ const styleId = `${this._getChartClassName()}-styles`;
395
+ if (document.getElementById(styleId)) return;
396
+
397
+ const style = document.createElement('style');
398
+ style.id = styleId;
399
+ style.textContent = this._getBaseStyles();
400
+ document.head.appendChild(style);
401
+ }
402
+ }
@@ -1,4 +1,4 @@
1
- import { State } from '../reactivity/state.js';
1
+ import { State } from '../../../reactivity/state.js';
2
2
 
3
3
  /**
4
4
  * Shared chart data point
@@ -7,7 +7,7 @@ import {
7
7
  notionTheme,
8
8
  chalkTheme,
9
9
  mintTheme
10
- } from '../themes/charts.js';
10
+ } from './charts.js';
11
11
 
12
12
  /**
13
13
  * Lighten a hex color by a percentage
@@ -1,5 +1,5 @@
1
- import { getOrCreateContainer } from './helpers.js';
2
- import { State } from '../reactivity/state.js';
1
+ import { getOrCreateContainer } from '../../helpers.js';
2
+ import { State } from '../../../reactivity/state.js';
3
3
 
4
4
  /**
5
5
  * Chart component using Chart.js library
@@ -240,7 +240,7 @@ export class Chart {
240
240
  // Chart.js options configuration methods
241
241
  theme(value: string): this {
242
242
  // Import theme colors and apply to chart
243
- import('../themes/charts.js').then(themes => {
243
+ import('./charts.js').then(themes => {
244
244
  const themeConfig = themes.chartThemes[value as keyof typeof themes.chartThemes];
245
245
 
246
246
  if (!themeConfig) return;