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
package/lib/components/code.ts
CHANGED
|
@@ -1,156 +1,123 @@
|
|
|
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
|
-
* Code component options
|
|
5
|
-
*/
|
|
6
7
|
export interface CodeOptions {
|
|
7
8
|
code?: string;
|
|
8
9
|
language?: string;
|
|
9
|
-
lineNumbers?: boolean;
|
|
10
|
-
highlight?: boolean;
|
|
11
10
|
style?: string;
|
|
12
11
|
class?: string;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
/**
|
|
16
|
-
* Code component state
|
|
17
|
-
*/
|
|
18
14
|
type CodeState = {
|
|
19
15
|
code: string;
|
|
20
16
|
language: string;
|
|
21
|
-
lineNumbers: boolean;
|
|
22
|
-
highlight: boolean;
|
|
23
17
|
style: string;
|
|
24
18
|
class: string;
|
|
25
19
|
};
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* code.render();
|
|
33
|
-
*/
|
|
34
|
-
export class Code {
|
|
35
|
-
state: CodeState;
|
|
36
|
-
container: HTMLElement | null = null;
|
|
37
|
-
_id: string;
|
|
38
|
-
id: string;
|
|
39
|
-
|
|
40
|
-
constructor(
|
|
41
|
-
id: string,
|
|
42
|
-
content?: string,
|
|
43
|
-
language?: string,
|
|
44
|
-
options: CodeOptions = {}
|
|
45
|
-
) {
|
|
46
|
-
this._id = id;
|
|
47
|
-
this.id = id;
|
|
48
|
-
|
|
49
|
-
this.state = {
|
|
50
|
-
code: content ?? options.code ?? '',
|
|
51
|
-
language: language ?? options.language ?? 'javascript',
|
|
52
|
-
lineNumbers: options.lineNumbers ?? false,
|
|
53
|
-
highlight: options.highlight ?? true,
|
|
21
|
+
export class Code extends BaseComponent<CodeState> {
|
|
22
|
+
constructor(id: string, options: CodeOptions = {}) {
|
|
23
|
+
super(id, {
|
|
24
|
+
code: options.code ?? '',
|
|
25
|
+
language: options.language ?? 'javascript',
|
|
54
26
|
style: options.style ?? '',
|
|
55
27
|
class: options.class ?? ''
|
|
56
|
-
};
|
|
28
|
+
});
|
|
57
29
|
}
|
|
58
30
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
* ------------------------- */
|
|
62
|
-
|
|
63
|
-
code(value: string): this {
|
|
64
|
-
this.state.code = value;
|
|
65
|
-
return this;
|
|
31
|
+
protected getTriggerEvents(): readonly string[] {
|
|
32
|
+
return TRIGGER_EVENTS;
|
|
66
33
|
}
|
|
67
34
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return this;
|
|
35
|
+
protected getCallbackEvents(): readonly string[] {
|
|
36
|
+
return CALLBACK_EVENTS;
|
|
71
37
|
}
|
|
72
38
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
39
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
40
|
+
* FLUENT API
|
|
41
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
77
42
|
|
|
78
|
-
|
|
79
|
-
this.state.highlight = value;
|
|
80
|
-
return this;
|
|
81
|
-
}
|
|
43
|
+
// ✅ Inherited from BaseComponent
|
|
82
44
|
|
|
83
|
-
|
|
84
|
-
this.state.
|
|
45
|
+
code(value: string): this {
|
|
46
|
+
this.state.code = value;
|
|
85
47
|
return this;
|
|
86
48
|
}
|
|
87
49
|
|
|
88
|
-
|
|
89
|
-
this.state.
|
|
50
|
+
language(value: string): this {
|
|
51
|
+
this.state.language = value;
|
|
90
52
|
return this;
|
|
91
53
|
}
|
|
92
54
|
|
|
93
|
-
/*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
55
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
56
|
+
* RENDER
|
|
57
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
96
58
|
|
|
97
59
|
render(targetId?: string): this {
|
|
98
|
-
|
|
60
|
+
const container = this._setupContainer(targetId);
|
|
99
61
|
|
|
100
|
-
|
|
101
|
-
const target = document.querySelector(targetId);
|
|
102
|
-
if (!target || !(target instanceof HTMLElement)) {
|
|
103
|
-
throw new Error(`Code: Target element "${targetId}" not found`);
|
|
104
|
-
}
|
|
105
|
-
container = target;
|
|
106
|
-
} else {
|
|
107
|
-
container = getOrCreateContainer(this._id);
|
|
108
|
-
}
|
|
62
|
+
const { code, language, style, class: className } = this.state;
|
|
109
63
|
|
|
110
|
-
|
|
111
|
-
|
|
64
|
+
const wrapper = document.createElement('div');
|
|
65
|
+
wrapper.className = 'jux-code';
|
|
66
|
+
wrapper.id = this._id;
|
|
67
|
+
if (className) wrapper.className += ` ${className}`;
|
|
68
|
+
if (style) wrapper.setAttribute('style', style);
|
|
112
69
|
|
|
113
70
|
const pre = document.createElement('pre');
|
|
114
|
-
pre.className = lineNumbers ? 'jux-code line-numbers' : 'jux-code';
|
|
115
|
-
pre.id = this._id;
|
|
116
|
-
|
|
117
|
-
if (className) {
|
|
118
|
-
pre.className += ` ${className}`;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (style) {
|
|
122
|
-
pre.setAttribute('style', style);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
71
|
const codeEl = document.createElement('code');
|
|
126
|
-
codeEl.className =
|
|
72
|
+
codeEl.className = `language-${language}`;
|
|
127
73
|
codeEl.textContent = code;
|
|
128
|
-
|
|
129
74
|
pre.appendChild(codeEl);
|
|
130
|
-
|
|
75
|
+
wrapper.appendChild(pre);
|
|
131
76
|
|
|
132
|
-
|
|
133
|
-
}
|
|
77
|
+
this._wireStandardEvents(wrapper);
|
|
134
78
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (!juxComponent || typeof juxComponent !== 'object') {
|
|
140
|
-
throw new Error('Code.renderTo: Invalid component - not an object');
|
|
141
|
-
}
|
|
79
|
+
// Wire sync bindings
|
|
80
|
+
this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
|
|
81
|
+
if (property === 'code') {
|
|
82
|
+
const transform = toComponent || ((v: any) => String(v));
|
|
142
83
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
84
|
+
stateObj.subscribe((val: any) => {
|
|
85
|
+
const transformed = transform(val);
|
|
86
|
+
codeEl.textContent = transformed;
|
|
87
|
+
this.state.code = transformed;
|
|
146
88
|
|
|
147
|
-
|
|
89
|
+
if ((window as any).Prism) {
|
|
90
|
+
(window as any).Prism.highlightElement(codeEl);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else if (property === 'language') {
|
|
95
|
+
const transform = toComponent || ((v: any) => String(v));
|
|
96
|
+
|
|
97
|
+
stateObj.subscribe((val: any) => {
|
|
98
|
+
const transformed = transform(val);
|
|
99
|
+
codeEl.className = `language-${transformed}`;
|
|
100
|
+
this.state.language = transformed;
|
|
101
|
+
|
|
102
|
+
if ((window as any).Prism) {
|
|
103
|
+
(window as any).Prism.highlightElement(codeEl);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
container.appendChild(wrapper);
|
|
110
|
+
|
|
111
|
+
requestAnimationFrame(() => {
|
|
112
|
+
if ((window as any).Prism) {
|
|
113
|
+
(window as any).Prism.highlightElement(codeEl);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return this;
|
|
148
118
|
}
|
|
149
119
|
}
|
|
150
120
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
*/
|
|
154
|
-
export function code(id: string, content?: string, language?: string): Code {
|
|
155
|
-
return new Code(id, content, language);
|
|
121
|
+
export function code(id: string, options: CodeOptions = {}): Code {
|
|
122
|
+
return new Code(id, options);
|
|
156
123
|
}
|
|
@@ -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: max-content'];
|
|
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
|
}
|