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,82 +1,58 @@
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 = ['confirm', 'cancel'] as const;
2
6
 
3
- /**
4
- * Dialog component options
5
- */
6
7
  export interface DialogOptions {
7
8
  title?: string;
8
9
  message?: string;
9
10
  confirmText?: string;
10
11
  cancelText?: string;
11
12
  variant?: 'default' | 'danger' | 'warning';
12
- onConfirm?: () => void;
13
- onCancel?: () => void;
14
13
  style?: string;
15
14
  class?: string;
16
15
  }
17
16
 
18
- /**
19
- * Dialog component state
20
- */
21
17
  type DialogState = {
22
18
  title: string;
23
19
  message: string;
24
20
  confirmText: string;
25
21
  cancelText: string;
26
22
  variant: string;
23
+ open: boolean;
27
24
  style: string;
28
25
  class: string;
29
- isOpen: boolean;
30
26
  };
31
27
 
32
- /**
33
- * Dialog component - Confirmation dialogs
34
- *
35
- * Usage:
36
- * jux.dialog('confirm-delete', {
37
- * title: 'Delete Item?',
38
- * message: 'This action cannot be undone.',
39
- * confirmText: 'Delete',
40
- * cancelText: 'Cancel',
41
- * variant: 'danger',
42
- * onConfirm: () => console.log('Deleted'),
43
- * onCancel: () => console.log('Cancelled')
44
- * }).render();
45
- *
46
- * // Open/close programmatically
47
- * const dialog = jux.dialog('my-dialog').render();
48
- * dialog.open();
49
- * dialog.close();
50
- */
51
- export class Dialog {
52
- state: DialogState;
53
- container: HTMLElement | null = null;
54
- _id: string;
55
- id: string;
56
- private _onConfirm?: () => void;
57
- private _onCancel?: () => void;
28
+ export class Dialog extends BaseComponent<DialogState> {
29
+ private _dialog: HTMLElement | null = null;
30
+ private _overlay: HTMLElement | null = null;
58
31
 
59
32
  constructor(id: string, options: DialogOptions = {}) {
60
- this._id = id;
61
- this.id = id;
62
- this._onConfirm = options.onConfirm;
63
- this._onCancel = options.onCancel;
64
-
65
- this.state = {
33
+ super(id, {
66
34
  title: options.title ?? 'Confirm',
67
- message: options.message ?? '',
35
+ message: options.message ?? 'Are you sure?',
68
36
  confirmText: options.confirmText ?? 'Confirm',
69
37
  cancelText: options.cancelText ?? 'Cancel',
70
38
  variant: options.variant ?? 'default',
39
+ open: false,
71
40
  style: options.style ?? '',
72
- class: options.class ?? '',
73
- isOpen: false
74
- };
41
+ class: options.class ?? ''
42
+ });
43
+ }
44
+
45
+ protected getTriggerEvents(): readonly string[] {
46
+ return TRIGGER_EVENTS;
47
+ }
48
+
49
+ protected getCallbackEvents(): readonly string[] {
50
+ return CALLBACK_EVENTS;
75
51
  }
76
52
 
77
- /* -------------------------
78
- * Fluent API
79
- * ------------------------- */
53
+ /* ═════════════════════════════════════════════════════════════════
54
+ * FLUENT API
55
+ * ═════════════════════════════════════════════════════════════════ */
80
56
 
81
57
  title(value: string): this {
82
58
  this.state.title = value;
@@ -103,153 +79,207 @@ export class Dialog {
103
79
  return this;
104
80
  }
105
81
 
106
- style(value: string): this {
107
- this.state.style = value;
108
- return this;
109
- }
110
-
111
- class(value: string): this {
112
- this.state.class = value;
113
- return this;
114
- }
115
-
116
- onConfirm(handler: () => void): this {
117
- this._onConfirm = handler;
118
- return this;
119
- }
120
-
121
- onCancel(handler: () => void): this {
122
- this._onCancel = handler;
123
- return this;
124
- }
125
-
126
- /* -------------------------
127
- * Methods
128
- * ------------------------- */
129
-
130
- open(): void {
131
- this.state.isOpen = true;
132
- const element = document.getElementById(this._id);
133
- if (element) {
134
- element.style.display = 'flex';
135
- setTimeout(() => element.classList.add('jux-dialog-open'), 10);
82
+ open(): this {
83
+ this.state.open = true;
84
+ if (this._overlay) {
85
+ this._overlay.style.display = 'flex';
136
86
  }
87
+ return this;
137
88
  }
138
89
 
139
- close(): void {
140
- this.state.isOpen = false;
141
- const element = document.getElementById(this._id);
142
- if (element) {
143
- element.classList.remove('jux-dialog-open');
144
- setTimeout(() => element.style.display = 'none', 200);
90
+ close(): this {
91
+ this.state.open = false;
92
+ if (this._overlay) {
93
+ this._overlay.style.display = 'none';
145
94
  }
95
+ return this;
146
96
  }
147
97
 
148
- /* -------------------------
149
- * Render
150
- * ------------------------- */
98
+ /* ═════════════════════════════════════════════════════════════════
99
+ * RENDER
100
+ * ═════════════════════════════════════════════════════════════════ */
151
101
 
152
102
  render(targetId?: string): this {
153
- let container: HTMLElement;
154
-
155
- if (targetId) {
156
- const target = document.querySelector(targetId);
157
- if (!target || !(target instanceof HTMLElement)) {
158
- throw new Error(`Dialog: Target element "${targetId}" not found`);
159
- }
160
- container = target;
161
- } else {
162
- container = document.body;
163
- }
164
-
165
- this.container = container;
166
103
  const { title, message, confirmText, cancelText, variant, style, class: className } = this.state;
167
104
 
168
105
  // Overlay
169
106
  const overlay = document.createElement('div');
170
- overlay.className = 'jux-dialog';
171
- overlay.id = this._id;
107
+ overlay.className = 'jux-dialog-overlay';
172
108
  overlay.style.display = 'none';
173
- overlay.setAttribute('role', 'dialog');
174
- overlay.setAttribute('aria-modal', 'true');
175
-
176
- if (className) {
177
- overlay.className += ` ${className}`;
178
- }
179
-
180
- if (style) {
181
- overlay.setAttribute('style', style);
182
- }
183
-
184
- // Click outside to close
185
- overlay.addEventListener('click', (e) => {
186
- if (e.target === overlay) {
187
- this.close();
188
- if (this._onCancel) {
189
- this._onCancel();
190
- }
191
- }
192
- });
193
-
194
- // Dialog container
195
- const dialogBox = document.createElement('div');
196
- dialogBox.className = `jux-dialog-box jux-dialog-${variant}`;
197
-
198
- // Header
199
- const header = document.createElement('div');
200
- header.className = 'jux-dialog-header';
201
-
202
- const titleEl = document.createElement('h3');
109
+ this._overlay = overlay;
110
+
111
+ // Dialog
112
+ const dialog = document.createElement('div');
113
+ dialog.className = `jux-dialog jux-dialog-${variant}`;
114
+ dialog.id = this._id;
115
+ if (className) dialog.className += ` ${className}`;
116
+ if (style) dialog.setAttribute('style', style);
117
+ this._dialog = dialog;
118
+
119
+ // Title
120
+ const titleEl = document.createElement('div');
203
121
  titleEl.className = 'jux-dialog-title';
204
122
  titleEl.textContent = title;
205
- header.appendChild(titleEl);
123
+ dialog.appendChild(titleEl);
206
124
 
207
- // Body
208
- const body = document.createElement('div');
209
- body.className = 'jux-dialog-body';
210
- body.textContent = message;
125
+ // Message
126
+ const messageEl = document.createElement('div');
127
+ messageEl.className = 'jux-dialog-message';
128
+ messageEl.textContent = message;
129
+ dialog.appendChild(messageEl);
211
130
 
212
- // Footer
213
- const footer = document.createElement('div');
214
- footer.className = 'jux-dialog-footer';
131
+ // Actions
132
+ const actions = document.createElement('div');
133
+ actions.className = 'jux-dialog-actions';
215
134
 
216
135
  const cancelBtn = document.createElement('button');
217
136
  cancelBtn.className = 'jux-dialog-button jux-dialog-button-cancel';
218
137
  cancelBtn.textContent = cancelText;
219
138
  cancelBtn.addEventListener('click', () => {
139
+ this._triggerCallback('cancel');
220
140
  this.close();
221
- if (this._onCancel) {
222
- this._onCancel();
223
- }
224
141
  });
225
142
 
226
143
  const confirmBtn = document.createElement('button');
227
144
  confirmBtn.className = `jux-dialog-button jux-dialog-button-confirm jux-dialog-button-${variant}`;
228
145
  confirmBtn.textContent = confirmText;
229
146
  confirmBtn.addEventListener('click', () => {
147
+ this._triggerCallback('confirm');
230
148
  this.close();
231
- if (this._onConfirm) {
232
- this._onConfirm();
149
+ });
150
+
151
+ actions.appendChild(cancelBtn);
152
+ actions.appendChild(confirmBtn);
153
+ dialog.appendChild(actions);
154
+
155
+ // Close on overlay click
156
+ overlay.addEventListener('click', (e) => {
157
+ if (e.target === overlay) {
158
+ this._triggerCallback('cancel');
159
+ this.close();
233
160
  }
234
161
  });
235
162
 
236
- footer.appendChild(cancelBtn);
237
- footer.appendChild(confirmBtn);
163
+ overlay.appendChild(dialog);
164
+ document.body.appendChild(overlay);
238
165
 
239
- dialogBox.appendChild(header);
240
- dialogBox.appendChild(body);
241
- dialogBox.appendChild(footer);
242
- overlay.appendChild(dialogBox);
243
- container.appendChild(overlay);
166
+ this._injectDialogStyles();
244
167
 
245
168
  return this;
246
169
  }
247
170
 
248
- renderTo(juxComponent: any): this {
249
- if (!juxComponent?._id) {
250
- throw new Error('Dialog.renderTo: Invalid component');
171
+ private _injectDialogStyles(): void {
172
+ const styleId = 'jux-dialog-styles';
173
+ if (document.getElementById(styleId)) return;
174
+
175
+ const style = document.createElement('style');
176
+ style.id = styleId;
177
+ style.textContent = `
178
+ .jux-dialog-overlay {
179
+ position: fixed;
180
+ top: 0;
181
+ left: 0;
182
+ right: 0;
183
+ bottom: 0;
184
+ background: rgba(0, 0, 0, 0.5);
185
+ display: flex;
186
+ align-items: center;
187
+ justify-content: center;
188
+ z-index: 10000;
189
+ animation: jux-dialog-fade 0.2s;
190
+ }
191
+
192
+ @keyframes jux-dialog-fade {
193
+ from { opacity: 0; }
194
+ to { opacity: 1; }
195
+ }
196
+
197
+ .jux-dialog {
198
+ background: white;
199
+ border-radius: 12px;
200
+ padding: 24px;
201
+ max-width: 400px;
202
+ width: 90%;
203
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
204
+ animation: jux-dialog-slide 0.3s;
205
+ }
206
+
207
+ @keyframes jux-dialog-slide {
208
+ from {
209
+ opacity: 0;
210
+ transform: translateY(-20px);
211
+ }
212
+ to {
213
+ opacity: 1;
214
+ transform: translateY(0);
251
215
  }
252
- return this.render(`#${juxComponent._id}`);
216
+ }
217
+
218
+ .jux-dialog-title {
219
+ font-size: 20px;
220
+ font-weight: 600;
221
+ margin-bottom: 12px;
222
+ color: #1f2937;
223
+ }
224
+
225
+ .jux-dialog-message {
226
+ font-size: 14px;
227
+ color: #6b7280;
228
+ margin-bottom: 24px;
229
+ line-height: 1.5;
230
+ }
231
+
232
+ .jux-dialog-actions {
233
+ display: flex;
234
+ gap: 12px;
235
+ justify-content: flex-end;
236
+ }
237
+
238
+ .jux-dialog-button {
239
+ padding: 8px 16px;
240
+ border-radius: 6px;
241
+ font-size: 14px;
242
+ font-weight: 500;
243
+ cursor: pointer;
244
+ transition: all 0.2s;
245
+ border: none;
246
+ }
247
+
248
+ .jux-dialog-button-cancel {
249
+ background: #f3f4f6;
250
+ color: #374151;
251
+ }
252
+
253
+ .jux-dialog-button-cancel:hover {
254
+ background: #e5e7eb;
255
+ }
256
+
257
+ .jux-dialog-button-confirm {
258
+ background: #3b82f6;
259
+ color: white;
260
+ }
261
+
262
+ .jux-dialog-button-confirm:hover {
263
+ background: #2563eb;
264
+ }
265
+
266
+ .jux-dialog-button-danger {
267
+ background: #ef4444;
268
+ }
269
+
270
+ .jux-dialog-button-danger:hover {
271
+ background: #dc2626;
272
+ }
273
+
274
+ .jux-dialog-button-warning {
275
+ background: #f59e0b;
276
+ }
277
+
278
+ .jux-dialog-button-warning:hover {
279
+ background: #d97706;
280
+ }
281
+ `;
282
+ document.head.appendChild(style);
253
283
  }
254
284
  }
255
285