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.
- package/bin/cli.js +121 -72
- package/lib/components/alert.ts +143 -92
- package/lib/components/badge.ts +93 -94
- package/lib/components/base/BaseComponent.ts +397 -0
- package/lib/components/base/FormInput.ts +322 -0
- package/lib/components/button.ts +40 -131
- package/lib/components/card.ts +57 -79
- 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/{chart-types.ts → charts/lib/chart-types.ts} +1 -1
- package/lib/components/{chart-utils.ts → charts/lib/chart-utils.ts} +1 -1
- package/lib/components/{chart.ts → charts/lib/chart.ts} +3 -3
- package/lib/components/checkbox.ts +255 -204
- package/lib/components/code.ts +31 -78
- package/lib/components/container.ts +113 -130
- package/lib/components/data.ts +37 -5
- package/lib/components/datepicker.ts +180 -147
- package/lib/components/dialog.ts +218 -221
- package/lib/components/divider.ts +63 -87
- package/lib/components/docs-data.json +498 -2404
- package/lib/components/dropdown.ts +191 -236
- package/lib/components/element.ts +196 -145
- package/lib/components/fileupload.ts +253 -167
- package/lib/components/guard.ts +92 -0
- package/lib/components/heading.ts +31 -97
- package/lib/components/helpers.ts +13 -6
- package/lib/components/hero.ts +51 -114
- package/lib/components/icon.ts +33 -120
- package/lib/components/icons.ts +2 -1
- package/lib/components/include.ts +76 -3
- package/lib/components/input.ts +155 -407
- package/lib/components/kpicard.ts +16 -16
- package/lib/components/list.ts +358 -261
- package/lib/components/loading.ts +142 -211
- package/lib/components/menu.ts +63 -152
- package/lib/components/modal.ts +42 -129
- package/lib/components/nav.ts +79 -101
- package/lib/components/paragraph.ts +38 -102
- package/lib/components/progress.ts +108 -166
- package/lib/components/radio.ts +283 -234
- package/lib/components/script.ts +19 -87
- package/lib/components/select.ts +189 -199
- package/lib/components/sidebar.ts +110 -141
- package/lib/components/style.ts +19 -82
- package/lib/components/switch.ts +254 -183
- package/lib/components/table.ts +1078 -208
- package/lib/components/tabs.ts +42 -106
- package/lib/components/theme-toggle.ts +73 -165
- package/lib/components/tooltip.ts +85 -316
- package/lib/components/write.ts +108 -127
- package/lib/jux.ts +67 -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 -1
- 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 -1128
- package/lib/components/areachartsmooth.ts +0 -1380
- package/lib/components/barchart.ts +0 -1322
- package/lib/components/doughnutchart.ts +0 -1259
- 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
package/lib/components/code.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
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
7
|
export interface CodeOptions {
|
|
5
8
|
code?: string;
|
|
@@ -15,84 +18,49 @@ type CodeState = {
|
|
|
15
18
|
class: string;
|
|
16
19
|
};
|
|
17
20
|
|
|
18
|
-
export class Code {
|
|
19
|
-
state: CodeState;
|
|
20
|
-
container: HTMLElement | null = null;
|
|
21
|
-
_id: string;
|
|
22
|
-
id: string;
|
|
23
|
-
|
|
24
|
-
// CRITICAL: Store bind/sync instructions for deferred wiring
|
|
25
|
-
private _bindings: Array<{ event: string, handler: Function }> = [];
|
|
26
|
-
private _syncBindings: Array<{
|
|
27
|
-
property: string,
|
|
28
|
-
stateObj: State<any>,
|
|
29
|
-
toState?: Function,
|
|
30
|
-
toComponent?: Function
|
|
31
|
-
}> = [];
|
|
32
|
-
|
|
21
|
+
export class Code extends BaseComponent<CodeState> {
|
|
33
22
|
constructor(id: string, options: CodeOptions = {}) {
|
|
34
|
-
|
|
35
|
-
this.id = id;
|
|
36
|
-
|
|
37
|
-
this.state = {
|
|
23
|
+
super(id, {
|
|
38
24
|
code: options.code ?? '',
|
|
39
25
|
language: options.language ?? 'javascript',
|
|
40
26
|
style: options.style ?? '',
|
|
41
27
|
class: options.class ?? ''
|
|
42
|
-
};
|
|
28
|
+
});
|
|
43
29
|
}
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return this;
|
|
31
|
+
protected getTriggerEvents(): readonly string[] {
|
|
32
|
+
return TRIGGER_EVENTS;
|
|
48
33
|
}
|
|
49
34
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return this;
|
|
35
|
+
protected getCallbackEvents(): readonly string[] {
|
|
36
|
+
return CALLBACK_EVENTS;
|
|
53
37
|
}
|
|
54
38
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
39
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
40
|
+
* FLUENT API
|
|
41
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
this.state.class = value;
|
|
62
|
-
return this;
|
|
63
|
-
}
|
|
43
|
+
// ✅ Inherited from BaseComponent
|
|
64
44
|
|
|
65
|
-
|
|
66
|
-
this.
|
|
45
|
+
code(value: string): this {
|
|
46
|
+
this.state.code = value;
|
|
67
47
|
return this;
|
|
68
48
|
}
|
|
69
49
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
throw new Error(`Code.sync: Expected a State object for property "${property}"`);
|
|
73
|
-
}
|
|
74
|
-
this._syncBindings.push({ property, stateObj, toState, toComponent });
|
|
50
|
+
language(value: string): this {
|
|
51
|
+
this.state.language = value;
|
|
75
52
|
return this;
|
|
76
53
|
}
|
|
77
54
|
|
|
55
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
56
|
+
* RENDER
|
|
57
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
58
|
+
|
|
78
59
|
render(targetId?: string): this {
|
|
79
|
-
|
|
80
|
-
let container: HTMLElement;
|
|
81
|
-
if (targetId) {
|
|
82
|
-
const target = document.querySelector(targetId);
|
|
83
|
-
if (!target || !(target instanceof HTMLElement)) {
|
|
84
|
-
throw new Error(`Code: Target "${targetId}" not found`);
|
|
85
|
-
}
|
|
86
|
-
container = target;
|
|
87
|
-
} else {
|
|
88
|
-
container = getOrCreateContainer(this._id);
|
|
89
|
-
}
|
|
90
|
-
this.container = container;
|
|
60
|
+
const container = this._setupContainer(targetId);
|
|
91
61
|
|
|
92
|
-
// === 2. PREPARE: Destructure state ===
|
|
93
62
|
const { code, language, style, class: className } = this.state;
|
|
94
63
|
|
|
95
|
-
// === 3. BUILD: Create DOM elements ===
|
|
96
64
|
const wrapper = document.createElement('div');
|
|
97
65
|
wrapper.className = 'jux-code';
|
|
98
66
|
wrapper.id = this._id;
|
|
@@ -106,34 +74,28 @@ export class Code {
|
|
|
106
74
|
pre.appendChild(codeEl);
|
|
107
75
|
wrapper.appendChild(pre);
|
|
108
76
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// Wire custom bindings from .bind() calls
|
|
112
|
-
this._bindings.forEach(({ event, handler }) => {
|
|
113
|
-
wrapper.addEventListener(event, handler as EventListener);
|
|
114
|
-
});
|
|
77
|
+
this._wireStandardEvents(wrapper);
|
|
115
78
|
|
|
116
|
-
// Wire sync bindings
|
|
79
|
+
// Wire sync bindings
|
|
117
80
|
this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
|
|
118
81
|
if (property === 'code') {
|
|
119
|
-
const
|
|
82
|
+
const transform = toComponent || ((v: any) => String(v));
|
|
120
83
|
|
|
121
84
|
stateObj.subscribe((val: any) => {
|
|
122
|
-
const transformed =
|
|
85
|
+
const transformed = transform(val);
|
|
123
86
|
codeEl.textContent = transformed;
|
|
124
87
|
this.state.code = transformed;
|
|
125
88
|
|
|
126
|
-
// Re-trigger syntax highlighting if available
|
|
127
89
|
if ((window as any).Prism) {
|
|
128
90
|
(window as any).Prism.highlightElement(codeEl);
|
|
129
91
|
}
|
|
130
92
|
});
|
|
131
93
|
}
|
|
132
94
|
else if (property === 'language') {
|
|
133
|
-
const
|
|
95
|
+
const transform = toComponent || ((v: any) => String(v));
|
|
134
96
|
|
|
135
97
|
stateObj.subscribe((val: any) => {
|
|
136
|
-
const transformed =
|
|
98
|
+
const transformed = transform(val);
|
|
137
99
|
codeEl.className = `language-${transformed}`;
|
|
138
100
|
this.state.language = transformed;
|
|
139
101
|
|
|
@@ -144,10 +106,8 @@ export class Code {
|
|
|
144
106
|
}
|
|
145
107
|
});
|
|
146
108
|
|
|
147
|
-
// === 5. RENDER: Append to DOM and finalize ===
|
|
148
109
|
container.appendChild(wrapper);
|
|
149
110
|
|
|
150
|
-
// Trigger syntax highlighting
|
|
151
111
|
requestAnimationFrame(() => {
|
|
152
112
|
if ((window as any).Prism) {
|
|
153
113
|
(window as any).Prism.highlightElement(codeEl);
|
|
@@ -156,13 +116,6 @@ export class Code {
|
|
|
156
116
|
|
|
157
117
|
return this;
|
|
158
118
|
}
|
|
159
|
-
|
|
160
|
-
renderTo(juxComponent: any): this {
|
|
161
|
-
if (!juxComponent?._id) {
|
|
162
|
-
throw new Error('Code.renderTo: Invalid component');
|
|
163
|
-
}
|
|
164
|
-
return this.render(`#${juxComponent._id}`);
|
|
165
|
-
}
|
|
166
119
|
}
|
|
167
120
|
|
|
168
121
|
export function code(id: string, options: CodeOptions = {}): Code {
|
|
@@ -1,178 +1,161 @@
|
|
|
1
|
-
import {
|
|
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
|
-
* Container options
|
|
5
|
-
*/
|
|
6
7
|
export interface ContainerOptions {
|
|
7
|
-
class?: string;
|
|
8
|
-
style?: string;
|
|
9
8
|
direction?: 'row' | 'column';
|
|
10
|
-
gap?:
|
|
9
|
+
gap?: number | string;
|
|
10
|
+
wrap?: boolean;
|
|
11
11
|
align?: 'start' | 'center' | 'end' | 'stretch';
|
|
12
12
|
justify?: 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly';
|
|
13
|
+
padding?: string;
|
|
14
|
+
style?: string;
|
|
15
|
+
class?: string;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
/**
|
|
16
|
-
* Container state
|
|
17
|
-
*/
|
|
18
18
|
type ContainerState = {
|
|
19
|
-
|
|
19
|
+
direction: string;
|
|
20
|
+
gap: number | string;
|
|
21
|
+
wrap: boolean;
|
|
22
|
+
align: string;
|
|
23
|
+
justify: string;
|
|
24
|
+
padding: string;
|
|
20
25
|
style: string;
|
|
21
|
-
|
|
22
|
-
gap?: string | number;
|
|
23
|
-
align?: string;
|
|
24
|
-
justify?: string;
|
|
26
|
+
class: string;
|
|
25
27
|
};
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
* Container component - a simple div container for grouping elements
|
|
29
|
-
*
|
|
30
|
-
* Usage:
|
|
31
|
-
* // Plain container
|
|
32
|
-
* jux.container('wrapper').render('#app');
|
|
33
|
-
*
|
|
34
|
-
* // Flex container with layout
|
|
35
|
-
* jux.container('toolbar')
|
|
36
|
-
* .direction('row')
|
|
37
|
-
* .gap(16)
|
|
38
|
-
* .render('#app');
|
|
39
|
-
*/
|
|
40
|
-
export class Container {
|
|
41
|
-
state: ContainerState;
|
|
42
|
-
container: HTMLElement | null = null;
|
|
43
|
-
_id: string;
|
|
44
|
-
id: string;
|
|
45
|
-
|
|
29
|
+
export class Container extends BaseComponent<ContainerState> {
|
|
46
30
|
constructor(id: string, options: ContainerOptions = {}) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
31
|
+
super(id, {
|
|
32
|
+
direction: options.direction ?? 'column',
|
|
33
|
+
gap: options.gap ?? 0,
|
|
34
|
+
wrap: options.wrap ?? false,
|
|
35
|
+
align: options.align ?? 'stretch',
|
|
36
|
+
justify: options.justify ?? 'start',
|
|
37
|
+
padding: options.padding ?? '0',
|
|
52
38
|
style: options.style ?? '',
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
align: options.align,
|
|
56
|
-
justify: options.justify
|
|
57
|
-
};
|
|
39
|
+
class: options.class ?? ''
|
|
40
|
+
});
|
|
58
41
|
}
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
* ------------------------- */
|
|
63
|
-
|
|
64
|
-
class(value: string): this {
|
|
65
|
-
this.state.class = value;
|
|
66
|
-
return this;
|
|
43
|
+
protected getTriggerEvents(): readonly string[] {
|
|
44
|
+
return TRIGGER_EVENTS;
|
|
67
45
|
}
|
|
68
46
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return this;
|
|
47
|
+
protected getCallbackEvents(): readonly string[] {
|
|
48
|
+
return CALLBACK_EVENTS;
|
|
72
49
|
}
|
|
73
50
|
|
|
74
|
-
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
|
|
51
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
52
|
+
* FLUENT API
|
|
53
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
54
|
+
|
|
55
|
+
// ✅ Inherited from BaseComponent:
|
|
56
|
+
// - style(), class()
|
|
57
|
+
// - addClass(), removeClass(), toggleClass()
|
|
58
|
+
// - visible(), show(), hide()
|
|
59
|
+
// - attr(), attrs(), removeAttr()
|
|
60
|
+
// - disabled(), enable(), disable()
|
|
61
|
+
// - bind(), sync(), renderTo()
|
|
62
|
+
|
|
78
63
|
direction(value: 'row' | 'column'): this {
|
|
79
64
|
this.state.direction = value;
|
|
80
65
|
return this;
|
|
81
66
|
}
|
|
82
67
|
|
|
83
|
-
|
|
84
|
-
* Set gap between children
|
|
85
|
-
* Automatically enables flexbox when called
|
|
86
|
-
* @param value - Gap size (number = px, string = any CSS unit)
|
|
87
|
-
*/
|
|
88
|
-
gap(value: string | number): this {
|
|
68
|
+
gap(value: number | string): this {
|
|
89
69
|
this.state.gap = value;
|
|
90
70
|
return this;
|
|
91
71
|
}
|
|
92
72
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
73
|
+
wrap(value: boolean): this {
|
|
74
|
+
this.state.wrap = value;
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
|
|
97
78
|
align(value: 'start' | 'center' | 'end' | 'stretch'): this {
|
|
98
79
|
this.state.align = value;
|
|
99
80
|
return this;
|
|
100
81
|
}
|
|
101
82
|
|
|
102
|
-
/**
|
|
103
|
-
* Set justification of children along main axis
|
|
104
|
-
* Automatically enables flexbox when called
|
|
105
|
-
*/
|
|
106
83
|
justify(value: 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly'): this {
|
|
107
84
|
this.state.justify = value;
|
|
108
85
|
return this;
|
|
109
86
|
}
|
|
110
87
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
render(targetId?: string | HTMLElement): this {
|
|
116
|
-
let container: HTMLElement;
|
|
88
|
+
padding(value: string): this {
|
|
89
|
+
this.state.padding = value;
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
117
92
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
93
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
94
|
+
* RENDER
|
|
95
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
96
|
+
|
|
97
|
+
render(targetId?: string): this {
|
|
98
|
+
const container = this._setupContainer(targetId);
|
|
99
|
+
|
|
100
|
+
const { direction, gap, wrap, align, justify, padding, style, class: className } = this.state;
|
|
101
|
+
|
|
102
|
+
const wrapper = document.createElement('div');
|
|
103
|
+
wrapper.className = 'jux-container';
|
|
104
|
+
wrapper.id = this._id;
|
|
105
|
+
if (className) wrapper.className += ` ${className}`;
|
|
106
|
+
|
|
107
|
+
// Build inline styles
|
|
108
|
+
const gapValue = typeof gap === 'number' ? `${gap}px` : gap;
|
|
109
|
+
const computedStyle = `
|
|
110
|
+
display: flex;
|
|
111
|
+
flex-direction: ${direction};
|
|
112
|
+
gap: ${gapValue};
|
|
113
|
+
flex-wrap: ${wrap ? 'wrap' : 'nowrap'};
|
|
114
|
+
align-items: ${align};
|
|
115
|
+
justify-content: ${justify};
|
|
116
|
+
padding: ${padding};
|
|
117
|
+
${style}
|
|
118
|
+
`.trim();
|
|
119
|
+
|
|
120
|
+
wrapper.setAttribute('style', computedStyle);
|
|
121
|
+
|
|
122
|
+
this._wireStandardEvents(wrapper);
|
|
123
|
+
|
|
124
|
+
// Wire sync bindings
|
|
125
|
+
this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
|
|
126
|
+
const transform = toComponent || ((v: any) => v);
|
|
127
|
+
|
|
128
|
+
stateObj.subscribe((val: any) => {
|
|
129
|
+
const transformed = transform(val);
|
|
130
|
+
|
|
131
|
+
if (property === 'direction') {
|
|
132
|
+
this.state.direction = String(transformed);
|
|
133
|
+
wrapper.style.flexDirection = this.state.direction;
|
|
134
|
+
} else if (property === 'gap') {
|
|
135
|
+
this.state.gap = transformed;
|
|
136
|
+
const gapVal = typeof transformed === 'number' ? `${transformed}px` : transformed;
|
|
137
|
+
wrapper.style.gap = gapVal;
|
|
138
|
+
} else if (property === 'wrap') {
|
|
139
|
+
this.state.wrap = Boolean(transformed);
|
|
140
|
+
wrapper.style.flexWrap = this.state.wrap ? 'wrap' : 'nowrap';
|
|
141
|
+
} else if (property === 'align') {
|
|
142
|
+
this.state.align = String(transformed);
|
|
143
|
+
wrapper.style.alignItems = this.state.align;
|
|
144
|
+
} else if (property === 'justify') {
|
|
145
|
+
this.state.justify = String(transformed);
|
|
146
|
+
wrapper.style.justifyContent = this.state.justify;
|
|
147
|
+
} else if (property === 'padding') {
|
|
148
|
+
this.state.padding = String(transformed);
|
|
149
|
+
wrapper.style.padding = this.state.padding;
|
|
125
150
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
} else {
|
|
129
|
-
container = getOrCreateContainer(this._id);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
this.container = container;
|
|
133
|
-
const { class: className, style, direction, gap, align, justify } = this.state;
|
|
134
|
-
|
|
135
|
-
const div = document.createElement('div');
|
|
136
|
-
div.id = this._id;
|
|
137
|
-
|
|
138
|
-
// Always include jux-container class, append custom classes
|
|
139
|
-
div.className = className ? `jux-container ${className}` : 'jux-container';
|
|
140
|
-
|
|
141
|
-
// Only apply flex styles if any flex properties are set
|
|
142
|
-
const usesFlexbox = direction || gap !== undefined || align || justify;
|
|
143
|
-
|
|
144
|
-
let computedStyle = style;
|
|
145
|
-
|
|
146
|
-
if (usesFlexbox) {
|
|
147
|
-
const flexStyles: string[] = ['display: flex', 'width: auto'];
|
|
148
|
-
|
|
149
|
-
if (direction) flexStyles.push(`flex-direction: ${direction}`);
|
|
150
|
-
|
|
151
|
-
if (gap !== undefined) {
|
|
152
|
-
const gapValue = typeof gap === 'number' ? `${gap}px` : gap;
|
|
153
|
-
flexStyles.push(`gap: ${gapValue}`);
|
|
154
|
-
}
|
|
155
|
-
// Only set align-items if explicitly specified
|
|
156
|
-
if (align) flexStyles.push(`align-items: ${align}`);
|
|
157
|
-
// Only set justify-content if explicitly specified
|
|
158
|
-
if (justify) flexStyles.push(`justify-content: ${justify}`);
|
|
159
|
-
|
|
160
|
-
computedStyle = `${flexStyles.join('; ')}; ${style}`.trim();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (computedStyle) {
|
|
164
|
-
div.setAttribute('style', computedStyle);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
container.appendChild(div);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
168
153
|
|
|
154
|
+
container.appendChild(wrapper);
|
|
169
155
|
return this;
|
|
170
156
|
}
|
|
171
157
|
}
|
|
172
158
|
|
|
173
|
-
/**
|
|
174
|
-
* Factory helper
|
|
175
|
-
*/
|
|
176
159
|
export function container(id: string, options: ContainerOptions = {}): Container {
|
|
177
160
|
return new Container(id, options);
|
|
178
161
|
}
|
package/lib/components/data.ts
CHANGED
|
@@ -93,11 +93,43 @@ export class Data {
|
|
|
93
93
|
this._data = [];
|
|
94
94
|
this._loading = false;
|
|
95
95
|
}
|
|
96
|
+
|
|
97
|
+
// Remove id requirement, make it optional for caching
|
|
98
|
+
static async fetch<T = any>(url: string, options?: RequestInit): Promise<T> {
|
|
99
|
+
const response = await fetch(url, options);
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(`API error: ${response.statusText}`);
|
|
102
|
+
}
|
|
103
|
+
return response.json();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ✅ Static methods - no ID needed
|
|
107
|
+
static async post<T = any>(url: string, body: any, options?: RequestInit): Promise<T> {
|
|
108
|
+
const response = await fetch(url, options);
|
|
109
|
+
if (!response.ok) {
|
|
110
|
+
throw new Error(`API error: ${response.statusText}`);
|
|
111
|
+
}
|
|
112
|
+
return response.json();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static async put<T = any>(url: string, body: any, options?: RequestInit): Promise<T> {
|
|
116
|
+
const response = await fetch(url, options);
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
throw new Error(`API error: ${response.statusText}`);
|
|
119
|
+
}
|
|
120
|
+
return response.json();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static async delete<T = any>(url: string, options?: RequestInit): Promise<T> {
|
|
124
|
+
const response = await fetch(url, options);
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
throw new Error(`API error: ${response.statusText}`);
|
|
127
|
+
}
|
|
128
|
+
return response.json();
|
|
129
|
+
}
|
|
96
130
|
}
|
|
97
131
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
export function data(sql: string, params: any[] = [], apiUrl: string = '/api/query'): Data {
|
|
102
|
-
return new Data(sql, params, apiUrl);
|
|
132
|
+
// ✅ No ID needed - pure data fetching
|
|
133
|
+
export function data<T = any>(url: string, options?: RequestInit): Promise<T> {
|
|
134
|
+
return Data.fetch<T>(url, options);
|
|
103
135
|
}
|