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.
- package/bin/cli.js +121 -72
- package/lib/components/alert.ts +212 -165
- package/lib/components/badge.ts +93 -103
- package/lib/components/base/BaseComponent.ts +397 -0
- package/lib/components/base/FormInput.ts +322 -0
- package/lib/components/button.ts +63 -122
- package/lib/components/card.ts +109 -155
- package/lib/components/charts/areachart.ts +315 -0
- package/lib/components/charts/barchart.ts +421 -0
- package/lib/components/charts/doughnutchart.ts +263 -0
- package/lib/components/charts/lib/BaseChart.ts +402 -0
- package/lib/components/charts/lib/chart-types.ts +159 -0
- package/lib/components/charts/lib/chart-utils.ts +160 -0
- package/lib/components/charts/lib/chart.ts +707 -0
- package/lib/components/checkbox.ts +264 -127
- package/lib/components/code.ts +75 -108
- package/lib/components/container.ts +113 -130
- package/lib/components/data.ts +37 -5
- package/lib/components/datepicker.ts +195 -147
- package/lib/components/dialog.ts +187 -157
- package/lib/components/divider.ts +85 -191
- package/lib/components/docs-data.json +544 -2027
- package/lib/components/dropdown.ts +178 -136
- package/lib/components/element.ts +227 -171
- package/lib/components/fileupload.ts +285 -228
- package/lib/components/guard.ts +92 -0
- package/lib/components/heading.ts +46 -69
- package/lib/components/helpers.ts +13 -6
- package/lib/components/hero.ts +107 -95
- package/lib/components/icon.ts +160 -0
- package/lib/components/icons.ts +175 -0
- package/lib/components/include.ts +153 -5
- package/lib/components/input.ts +174 -374
- package/lib/components/kpicard.ts +16 -16
- package/lib/components/list.ts +378 -240
- package/lib/components/loading.ts +142 -211
- package/lib/components/menu.ts +103 -97
- package/lib/components/modal.ts +138 -144
- package/lib/components/nav.ts +169 -90
- package/lib/components/paragraph.ts +49 -150
- package/lib/components/progress.ts +118 -200
- package/lib/components/radio.ts +297 -149
- package/lib/components/script.ts +19 -87
- package/lib/components/select.ts +184 -186
- package/lib/components/sidebar.ts +152 -140
- package/lib/components/style.ts +19 -82
- package/lib/components/switch.ts +258 -188
- package/lib/components/table.ts +1117 -170
- package/lib/components/tabs.ts +162 -145
- package/lib/components/theme-toggle.ts +108 -169
- package/lib/components/tooltip.ts +86 -157
- package/lib/components/write.ts +108 -127
- package/lib/jux.ts +86 -41
- package/machinery/build.js +466 -0
- package/machinery/compiler.js +354 -105
- package/machinery/server.js +23 -100
- package/machinery/watcher.js +153 -130
- package/package.json +1 -2
- package/presets/base.css +1166 -0
- package/presets/notion.css +2 -1975
- package/lib/adapters/base-adapter.js +0 -35
- package/lib/adapters/index.js +0 -33
- package/lib/adapters/mysql-adapter.js +0 -65
- package/lib/adapters/postgres-adapter.js +0 -70
- package/lib/adapters/sqlite-adapter.js +0 -56
- package/lib/components/areachart.ts +0 -1246
- package/lib/components/areachartsmooth.ts +0 -1380
- package/lib/components/barchart.ts +0 -1250
- package/lib/components/chart.ts +0 -127
- package/lib/components/doughnutchart.ts +0 -1191
- package/lib/components/footer.ts +0 -165
- package/lib/components/header.ts +0 -187
- package/lib/components/layout.ts +0 -239
- package/lib/components/main.ts +0 -137
- package/lib/layouts/default.jux +0 -8
- package/lib/layouts/figma.jux +0 -0
- /package/lib/{themes → components/charts/lib}/charts.js +0 -0
|
@@ -1,273 +1,191 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
+
|
|
3
|
+
// Event definitions
|
|
4
|
+
const TRIGGER_EVENTS = [] as const;
|
|
5
|
+
const CALLBACK_EVENTS = [] as const;
|
|
3
6
|
|
|
4
|
-
/**
|
|
5
|
-
* Progress component options
|
|
6
|
-
*/
|
|
7
7
|
export interface ProgressOptions {
|
|
8
8
|
value?: number;
|
|
9
9
|
max?: number;
|
|
10
|
-
|
|
10
|
+
variant?: 'default' | 'success' | 'warning' | 'error';
|
|
11
11
|
showPercentage?: boolean;
|
|
12
|
-
variant?: 'default' | 'success' | 'warning' | 'error' | 'info';
|
|
13
|
-
size?: 'sm' | 'md' | 'lg';
|
|
14
|
-
striped?: boolean;
|
|
15
|
-
animated?: boolean;
|
|
16
12
|
style?: string;
|
|
17
13
|
class?: string;
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
/**
|
|
21
|
-
* Progress component state
|
|
22
|
-
*/
|
|
23
16
|
type ProgressState = {
|
|
24
17
|
value: number;
|
|
25
18
|
max: number;
|
|
26
|
-
label: string;
|
|
27
|
-
showPercentage: boolean;
|
|
28
19
|
variant: string;
|
|
29
|
-
|
|
30
|
-
striped: boolean;
|
|
31
|
-
animated: boolean;
|
|
20
|
+
showPercentage: boolean;
|
|
32
21
|
style: string;
|
|
33
22
|
class: string;
|
|
34
23
|
};
|
|
35
24
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* Usage:
|
|
40
|
-
* jux.progress('upload', {
|
|
41
|
-
* value: 45,
|
|
42
|
-
* max: 100,
|
|
43
|
-
* label: 'Uploading...',
|
|
44
|
-
* showPercentage: true,
|
|
45
|
-
* animated: true
|
|
46
|
-
* }).render('#app');
|
|
47
|
-
*
|
|
48
|
-
* // Update progress
|
|
49
|
-
* const prog = jux.progress('upload').render('#app');
|
|
50
|
-
* prog.value(75);
|
|
51
|
-
*/
|
|
52
|
-
export class Progress {
|
|
53
|
-
state: ProgressState;
|
|
54
|
-
container: HTMLElement | null = null;
|
|
55
|
-
_id: string;
|
|
56
|
-
id: string;
|
|
57
|
-
private _boundState?: State<number>;
|
|
25
|
+
export class Progress extends BaseComponent<ProgressState> {
|
|
26
|
+
private _bar: HTMLElement | null = null;
|
|
27
|
+
private _label: HTMLElement | null = null;
|
|
58
28
|
|
|
59
29
|
constructor(id: string, options: ProgressOptions = {}) {
|
|
60
|
-
|
|
61
|
-
this.id = id;
|
|
62
|
-
|
|
63
|
-
this.state = {
|
|
30
|
+
super(id, {
|
|
64
31
|
value: options.value ?? 0,
|
|
65
32
|
max: options.max ?? 100,
|
|
66
|
-
label: options.label ?? '',
|
|
67
|
-
showPercentage: options.showPercentage ?? false,
|
|
68
33
|
variant: options.variant ?? 'default',
|
|
69
|
-
|
|
70
|
-
striped: options.striped ?? false,
|
|
71
|
-
animated: options.animated ?? false,
|
|
34
|
+
showPercentage: options.showPercentage ?? false,
|
|
72
35
|
style: options.style ?? '',
|
|
73
36
|
class: options.class ?? ''
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/* -------------------------
|
|
78
|
-
* Fluent API
|
|
79
|
-
* ------------------------- */
|
|
80
|
-
|
|
81
|
-
value(value: number): this {
|
|
82
|
-
this.state.value = Math.max(0, Math.min(value, this.state.max));
|
|
83
|
-
this._updateElement();
|
|
84
|
-
return this;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
max(value: number): this {
|
|
88
|
-
this.state.max = value;
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
label(value: string): this {
|
|
93
|
-
this.state.label = value;
|
|
94
|
-
this._updateElement();
|
|
95
|
-
return this;
|
|
37
|
+
});
|
|
96
38
|
}
|
|
97
39
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this._updateElement();
|
|
101
|
-
return this;
|
|
40
|
+
protected getTriggerEvents(): readonly string[] {
|
|
41
|
+
return TRIGGER_EVENTS;
|
|
102
42
|
}
|
|
103
43
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
this._updateElement();
|
|
107
|
-
return this;
|
|
44
|
+
protected getCallbackEvents(): readonly string[] {
|
|
45
|
+
return CALLBACK_EVENTS;
|
|
108
46
|
}
|
|
109
47
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
48
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
49
|
+
* FLUENT API
|
|
50
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
114
51
|
|
|
115
|
-
|
|
116
|
-
this.state.
|
|
117
|
-
this.
|
|
52
|
+
value(val: number): this {
|
|
53
|
+
this.state.value = Math.max(0, Math.min(val, this.state.max));
|
|
54
|
+
this._updateProgress();
|
|
118
55
|
return this;
|
|
119
56
|
}
|
|
120
57
|
|
|
121
|
-
|
|
122
|
-
this.state.
|
|
123
|
-
this.
|
|
58
|
+
max(val: number): this {
|
|
59
|
+
this.state.max = val;
|
|
60
|
+
this._updateProgress();
|
|
124
61
|
return this;
|
|
125
62
|
}
|
|
126
63
|
|
|
127
|
-
|
|
128
|
-
this.state.
|
|
129
|
-
return this;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
class(value: string): this {
|
|
133
|
-
this.state.class = value;
|
|
64
|
+
variant(value: 'default' | 'success' | 'warning' | 'error'): this {
|
|
65
|
+
this.state.variant = value;
|
|
134
66
|
return this;
|
|
135
67
|
}
|
|
136
68
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
*/
|
|
140
|
-
bind(stateObj: State<number>): this {
|
|
141
|
-
this._boundState = stateObj;
|
|
142
|
-
|
|
143
|
-
stateObj.subscribe((val) => {
|
|
144
|
-
this.value(val);
|
|
145
|
-
});
|
|
146
|
-
|
|
69
|
+
showPercentage(value: boolean): this {
|
|
70
|
+
this.state.showPercentage = value;
|
|
147
71
|
return this;
|
|
148
72
|
}
|
|
149
73
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
* ------------------------- */
|
|
153
|
-
|
|
154
|
-
private _updateElement(): void {
|
|
155
|
-
const wrapper = document.getElementById(this._id);
|
|
156
|
-
const bar = document.getElementById(`${this._id}-bar`);
|
|
157
|
-
const labelEl = document.getElementById(`${this._id}-label`);
|
|
158
|
-
|
|
159
|
-
// If element has a value attribute set externally (e.g., by bindValue), sync state
|
|
160
|
-
if (wrapper && wrapper.hasAttribute('data-value')) {
|
|
161
|
-
const externalValue = parseFloat(wrapper.getAttribute('data-value') || '0');
|
|
162
|
-
this.state.value = externalValue;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (bar) {
|
|
74
|
+
private _updateProgress(): void {
|
|
75
|
+
if (this._bar) {
|
|
166
76
|
const percentage = (this.state.value / this.state.max) * 100;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (this.state.striped) {
|
|
172
|
-
bar.classList.add('jux-progress-bar-striped');
|
|
173
|
-
}
|
|
174
|
-
if (this.state.animated) {
|
|
175
|
-
bar.classList.add('jux-progress-bar-animated');
|
|
77
|
+
this._bar.style.width = `${percentage}%`;
|
|
78
|
+
if (this._label) {
|
|
79
|
+
this._label.textContent = `${Math.round(percentage)}%`;
|
|
176
80
|
}
|
|
177
81
|
}
|
|
178
|
-
|
|
179
|
-
if (labelEl) {
|
|
180
|
-
const percentage = Math.round((this.state.value / this.state.max) * 100);
|
|
181
|
-
const text = this.state.showPercentage
|
|
182
|
-
? `${this.state.label} ${percentage}%`.trim()
|
|
183
|
-
: this.state.label;
|
|
184
|
-
labelEl.textContent = text;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
getPercentage(): number {
|
|
189
|
-
return Math.round((this.state.value / this.state.max) * 100);
|
|
190
82
|
}
|
|
191
83
|
|
|
192
|
-
/*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
84
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
85
|
+
* RENDER
|
|
86
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
195
87
|
|
|
196
88
|
render(targetId?: string): this {
|
|
197
|
-
|
|
89
|
+
const container = this._setupContainer(targetId);
|
|
198
90
|
|
|
199
|
-
|
|
200
|
-
const target = document.querySelector(targetId);
|
|
201
|
-
if (!target || !(target instanceof HTMLElement)) {
|
|
202
|
-
throw new Error(`Progress: Target element "${targetId}" not found`);
|
|
203
|
-
}
|
|
204
|
-
container = target;
|
|
205
|
-
} else {
|
|
206
|
-
container = getOrCreateContainer(this._id);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
this.container = container;
|
|
210
|
-
const { value, max, label, showPercentage, variant, size, striped, animated, style, class: className } = this.state;
|
|
91
|
+
const { value, max, variant, showPercentage, style, class: className } = this.state;
|
|
211
92
|
|
|
212
93
|
const wrapper = document.createElement('div');
|
|
213
|
-
wrapper.className =
|
|
94
|
+
wrapper.className = 'jux-progress';
|
|
214
95
|
wrapper.id = this._id;
|
|
96
|
+
if (className) wrapper.className += ` ${className}`;
|
|
97
|
+
if (style) wrapper.setAttribute('style', style);
|
|
215
98
|
|
|
216
|
-
if (className) {
|
|
217
|
-
wrapper.className += ` ${className}`;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (style) {
|
|
221
|
-
wrapper.setAttribute('style', style);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Label
|
|
225
|
-
if (label || showPercentage) {
|
|
226
|
-
const labelEl = document.createElement('div');
|
|
227
|
-
labelEl.className = 'jux-progress-label';
|
|
228
|
-
labelEl.id = `${this._id}-label`;
|
|
229
|
-
const percentage = Math.round((value / max) * 100);
|
|
230
|
-
const text = showPercentage
|
|
231
|
-
? `${label} ${percentage}%`.trim()
|
|
232
|
-
: label;
|
|
233
|
-
labelEl.textContent = text;
|
|
234
|
-
wrapper.appendChild(labelEl);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Progress track
|
|
238
99
|
const track = document.createElement('div');
|
|
239
100
|
track.className = 'jux-progress-track';
|
|
240
101
|
|
|
241
|
-
// Progress bar
|
|
242
102
|
const bar = document.createElement('div');
|
|
243
103
|
bar.className = `jux-progress-bar jux-progress-bar-${variant}`;
|
|
244
|
-
bar.id = `${this._id}-bar`;
|
|
245
|
-
bar.setAttribute('role', 'progressbar');
|
|
246
|
-
bar.setAttribute('aria-valuenow', value.toString());
|
|
247
|
-
bar.setAttribute('aria-valuemin', '0');
|
|
248
|
-
bar.setAttribute('aria-valuemax', max.toString());
|
|
249
|
-
|
|
250
104
|
const percentage = (value / max) * 100;
|
|
251
105
|
bar.style.width = `${percentage}%`;
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
106
|
+
this._bar = bar;
|
|
107
|
+
|
|
108
|
+
if (showPercentage) {
|
|
109
|
+
const label = document.createElement('span');
|
|
110
|
+
label.className = 'jux-progress-label';
|
|
111
|
+
label.textContent = `${Math.round(percentage)}%`;
|
|
112
|
+
bar.appendChild(label);
|
|
113
|
+
this._label = label;
|
|
258
114
|
}
|
|
259
115
|
|
|
260
116
|
track.appendChild(bar);
|
|
261
117
|
wrapper.appendChild(track);
|
|
118
|
+
|
|
119
|
+
this._wireStandardEvents(wrapper);
|
|
120
|
+
|
|
121
|
+
// Wire sync for value
|
|
122
|
+
this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
|
|
123
|
+
if (property === 'value') {
|
|
124
|
+
const transform = toComponent || ((v: any) => Number(v));
|
|
125
|
+
stateObj.subscribe((val: any) => {
|
|
126
|
+
this.value(transform(val));
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
262
131
|
container.appendChild(wrapper);
|
|
132
|
+
this._injectProgressStyles();
|
|
133
|
+
|
|
263
134
|
return this;
|
|
264
135
|
}
|
|
265
136
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
137
|
+
private _injectProgressStyles(): void {
|
|
138
|
+
const styleId = 'jux-progress-styles';
|
|
139
|
+
if (document.getElementById(styleId)) return;
|
|
140
|
+
|
|
141
|
+
const style = document.createElement('style');
|
|
142
|
+
style.id = styleId;
|
|
143
|
+
style.textContent = `
|
|
144
|
+
.jux-progress {
|
|
145
|
+
width: 100%;
|
|
146
|
+
margin-bottom: 1rem;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.jux-progress-track {
|
|
150
|
+
width: 100%;
|
|
151
|
+
height: 1.5rem;
|
|
152
|
+
background-color: #e5e7eb;
|
|
153
|
+
border-radius: 0.5rem;
|
|
154
|
+
overflow: hidden;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.jux-progress-bar {
|
|
158
|
+
height: 100%;
|
|
159
|
+
display: flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
justify-content: center;
|
|
162
|
+
color: white;
|
|
163
|
+
font-size: 0.75rem;
|
|
164
|
+
font-weight: 600;
|
|
165
|
+
transition: width 0.3s ease;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.jux-progress-bar-default {
|
|
169
|
+
background-color: #3b82f6;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.jux-progress-bar-success {
|
|
173
|
+
background-color: #10b981;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.jux-progress-bar-warning {
|
|
177
|
+
background-color: #f59e0b;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.jux-progress-bar-error {
|
|
181
|
+
background-color: #ef4444;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.jux-progress-label {
|
|
185
|
+
padding: 0 0.5rem;
|
|
186
|
+
}
|
|
187
|
+
`;
|
|
188
|
+
document.head.appendChild(style);
|
|
271
189
|
}
|
|
272
190
|
}
|
|
273
191
|
|