juxscript 1.1.4 → 1.1.6
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/index.d.ts +10 -10
- package/index.d.ts.map +1 -0
- package/lib/components/alert.d.ts +32 -0
- package/lib/components/alert.d.ts.map +1 -0
- package/lib/components/alert.js +153 -0
- package/lib/components/alert.ts +200 -0
- package/lib/components/app.d.ts +89 -0
- package/lib/components/app.d.ts.map +1 -0
- package/lib/components/app.js +175 -0
- package/lib/components/app.ts +247 -0
- package/lib/components/badge.d.ts +27 -0
- package/lib/components/badge.d.ts.map +1 -0
- package/lib/components/badge.js +70 -0
- package/lib/components/badge.ts +101 -0
- package/lib/components/base/BaseComponent.d.ts +142 -0
- package/lib/components/base/BaseComponent.d.ts.map +1 -0
- package/lib/components/base/BaseComponent.js +363 -0
- package/lib/components/base/BaseComponent.ts +421 -0
- package/lib/components/base/FormInput.d.ts +73 -0
- package/lib/components/base/FormInput.d.ts.map +1 -0
- package/lib/components/base/FormInput.js +163 -0
- package/lib/components/base/FormInput.ts +227 -0
- package/lib/components/button.d.ts +48 -0
- package/lib/components/button.d.ts.map +1 -0
- package/lib/components/button.js +121 -0
- package/lib/components/button.ts +178 -0
- package/lib/components/card.d.ts +34 -0
- package/lib/components/card.d.ts.map +1 -0
- package/lib/components/card.js +127 -0
- package/lib/components/card.ts +173 -0
- package/lib/components/chart.d.ts +45 -0
- package/lib/components/chart.d.ts.map +1 -0
- package/lib/components/chart.js +186 -0
- package/lib/components/chart.ts +231 -0
- package/lib/components/checkbox.d.ts +31 -0
- package/lib/components/checkbox.d.ts.map +1 -0
- package/lib/components/checkbox.js +185 -0
- package/lib/components/checkbox.ts +242 -0
- package/lib/components/code.d.ts +24 -0
- package/lib/components/code.d.ts.map +1 -0
- package/lib/components/code.js +88 -0
- package/lib/components/code.ts +123 -0
- package/lib/components/container.d.ts +42 -0
- package/lib/components/container.d.ts.map +1 -0
- package/lib/components/container.js +93 -0
- package/lib/components/container.ts +140 -0
- package/lib/components/data.d.ts +36 -0
- package/lib/components/data.d.ts.map +1 -0
- package/lib/components/data.js +110 -0
- package/lib/components/data.ts +135 -0
- package/lib/components/datepicker.d.ts +38 -0
- package/lib/components/datepicker.d.ts.map +1 -0
- package/lib/components/datepicker.js +177 -0
- package/lib/components/datepicker.ts +234 -0
- package/lib/components/dialog.d.ts +38 -0
- package/lib/components/dialog.d.ts.map +1 -0
- package/lib/components/dialog.js +126 -0
- package/lib/components/dialog.ts +172 -0
- package/lib/components/divider.d.ts +30 -0
- package/lib/components/divider.d.ts.map +1 -0
- package/lib/components/divider.js +69 -0
- package/lib/components/divider.ts +100 -0
- package/lib/components/dropdown.d.ts +39 -0
- package/lib/components/dropdown.d.ts.map +1 -0
- package/lib/components/dropdown.js +133 -0
- package/lib/components/dropdown.ts +186 -0
- package/lib/components/element.d.ts +50 -0
- package/lib/components/element.d.ts.map +1 -0
- package/lib/components/element.js +206 -0
- package/lib/components/element.ts +267 -0
- package/lib/components/fileupload.d.ts +40 -0
- package/lib/components/fileupload.d.ts.map +1 -0
- package/lib/components/fileupload.js +241 -0
- package/lib/components/fileupload.ts +309 -0
- package/lib/components/grid.d.ts +87 -0
- package/lib/components/grid.d.ts.map +1 -0
- package/lib/components/grid.js +205 -0
- package/lib/components/grid.ts +291 -0
- package/lib/components/guard.d.ts +41 -0
- package/lib/components/guard.d.ts.map +1 -0
- package/lib/components/guard.js +56 -0
- package/lib/components/guard.ts +92 -0
- package/lib/components/heading.d.ts +24 -0
- package/lib/components/heading.d.ts.map +1 -0
- package/lib/components/heading.js +67 -0
- package/lib/components/heading.ts +96 -0
- package/lib/components/helpers.d.ts +9 -0
- package/lib/components/helpers.d.ts.map +1 -0
- package/lib/components/helpers.js +30 -0
- package/lib/components/helpers.ts +41 -0
- package/lib/components/hero.d.ts +45 -0
- package/lib/components/hero.d.ts.map +1 -0
- package/lib/components/hero.js +165 -0
- package/lib/components/hero.ts +224 -0
- package/lib/components/icon.d.ts +35 -0
- package/lib/components/icon.d.ts.map +1 -0
- package/lib/components/icon.js +132 -0
- package/lib/components/icon.ts +178 -0
- package/lib/components/icons.d.ts +25 -0
- package/lib/components/icons.d.ts.map +1 -0
- package/lib/components/icons.js +440 -0
- package/lib/components/icons.ts +464 -0
- package/lib/components/include.d.ts +120 -0
- package/lib/components/include.d.ts.map +1 -0
- package/lib/components/include.js +350 -0
- package/lib/components/include.ts +410 -0
- package/lib/components/input.d.ts +83 -0
- package/lib/components/input.d.ts.map +1 -0
- package/lib/components/input.js +348 -0
- package/lib/components/input.ts +457 -0
- package/lib/components/list.d.ts +82 -0
- package/lib/components/list.d.ts.map +1 -0
- package/lib/components/list.js +311 -0
- package/lib/components/list.ts +419 -0
- package/lib/components/loading.d.ts +24 -0
- package/lib/components/loading.d.ts.map +1 -0
- package/lib/components/loading.js +73 -0
- package/lib/components/loading.ts +100 -0
- package/lib/components/menu.d.ts +37 -0
- package/lib/components/menu.d.ts.map +1 -0
- package/lib/components/menu.js +202 -0
- package/lib/components/menu.ts +275 -0
- package/lib/components/modal.d.ts +51 -0
- package/lib/components/modal.d.ts.map +1 -0
- package/lib/components/modal.js +227 -0
- package/lib/components/modal.ts +284 -0
- package/lib/components/nav.d.ts +45 -0
- package/lib/components/nav.d.ts.map +1 -0
- package/lib/components/nav.js +190 -0
- package/lib/components/nav.ts +257 -0
- package/lib/components/paragraph.d.ts +21 -0
- package/lib/components/paragraph.d.ts.map +1 -0
- package/lib/components/paragraph.js +70 -0
- package/lib/components/paragraph.ts +97 -0
- package/lib/components/progress.d.ts +39 -0
- package/lib/components/progress.d.ts.map +1 -0
- package/lib/components/progress.js +113 -0
- package/lib/components/progress.ts +159 -0
- package/lib/components/radio.d.ts +41 -0
- package/lib/components/radio.d.ts.map +1 -0
- package/lib/components/radio.js +203 -0
- package/lib/components/radio.ts +278 -0
- package/lib/components/req.d.ts +155 -0
- package/lib/components/req.d.ts.map +1 -0
- package/lib/components/req.js +253 -0
- package/lib/components/req.ts +303 -0
- package/lib/components/script.d.ts +14 -0
- package/lib/components/script.d.ts.map +1 -0
- package/lib/components/script.js +33 -0
- package/lib/components/script.ts +41 -0
- package/lib/components/select.d.ts +40 -0
- package/lib/components/select.d.ts.map +1 -0
- package/lib/components/select.js +183 -0
- package/lib/components/select.ts +252 -0
- package/lib/components/sidebar.d.ts +48 -0
- package/lib/components/sidebar.d.ts.map +1 -0
- package/lib/components/sidebar.js +207 -0
- package/lib/components/sidebar.ts +275 -0
- package/lib/components/style.d.ts +14 -0
- package/lib/components/style.d.ts.map +1 -0
- package/lib/components/style.js +33 -0
- package/lib/components/style.ts +41 -0
- package/lib/components/switch.d.ts +32 -0
- package/lib/components/switch.d.ts.map +1 -0
- package/lib/components/switch.js +186 -0
- package/lib/components/switch.ts +246 -0
- package/lib/components/table.d.ts +137 -0
- package/lib/components/table.d.ts.map +1 -0
- package/lib/components/table.js +1045 -0
- package/lib/components/table.ts +1249 -0
- package/lib/components/tabs.d.ts +36 -0
- package/lib/components/tabs.d.ts.map +1 -0
- package/lib/components/tabs.js +198 -0
- package/lib/components/tabs.ts +250 -0
- package/lib/components/theme-toggle.d.ts +44 -0
- package/lib/components/theme-toggle.d.ts.map +1 -0
- package/lib/components/theme-toggle.js +215 -0
- package/lib/components/theme-toggle.ts +293 -0
- package/lib/components/tooltip.d.ts +30 -0
- package/lib/components/tooltip.d.ts.map +1 -0
- package/lib/components/tooltip.js +109 -0
- package/lib/components/tooltip.ts +144 -0
- package/lib/components/view.d.ts +48 -0
- package/lib/components/view.d.ts.map +1 -0
- package/lib/components/view.js +149 -0
- package/lib/components/view.ts +190 -0
- package/lib/components/write.d.ts +107 -0
- package/lib/components/write.d.ts.map +1 -0
- package/lib/components/write.js +222 -0
- package/lib/components/write.ts +272 -0
- package/lib/layouts/default.css +260 -0
- package/lib/layouts/figma.css +334 -0
- package/lib/reactivity/state.d.ts +36 -0
- package/lib/reactivity/state.d.ts.map +1 -0
- package/lib/reactivity/state.js +67 -0
- package/lib/reactivity/state.ts +78 -0
- package/lib/utils/fetch.d.ts +176 -0
- package/lib/utils/fetch.d.ts.map +1 -0
- package/lib/utils/fetch.js +427 -0
- package/lib/utils/fetch.ts +553 -0
- package/machinery/compiler3.js +78 -0
- package/machinery/doc-generator.js +136 -0
- package/machinery/imports.js +155 -0
- package/machinery/ts-shim.js +46 -0
- package/package.json +9 -15
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
+
|
|
3
|
+
// Event definitions
|
|
4
|
+
const TRIGGER_EVENTS = [] as const;
|
|
5
|
+
const CALLBACK_EVENTS = [] as const;
|
|
6
|
+
|
|
7
|
+
export interface TooltipOptions {
|
|
8
|
+
text?: string;
|
|
9
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
10
|
+
style?: string;
|
|
11
|
+
class?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type TooltipState = {
|
|
15
|
+
text: string;
|
|
16
|
+
position: string;
|
|
17
|
+
style: string;
|
|
18
|
+
class: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export class Tooltip extends BaseComponent<TooltipState> {
|
|
22
|
+
private _tooltip: HTMLElement | null = null;
|
|
23
|
+
private _target: HTMLElement | null = null;
|
|
24
|
+
|
|
25
|
+
constructor(id: string, options: TooltipOptions = {}) {
|
|
26
|
+
super(id, {
|
|
27
|
+
text: options.text ?? '',
|
|
28
|
+
position: options.position ?? 'top',
|
|
29
|
+
style: options.style ?? '',
|
|
30
|
+
class: options.class ?? ''
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected getTriggerEvents(): readonly string[] {
|
|
35
|
+
return TRIGGER_EVENTS;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protected getCallbackEvents(): readonly string[] {
|
|
39
|
+
return CALLBACK_EVENTS;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
43
|
+
* FLUENT API
|
|
44
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
45
|
+
|
|
46
|
+
text(value: string): this {
|
|
47
|
+
this.state.text = value;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
position(value: 'top' | 'bottom' | 'left' | 'right'): this {
|
|
52
|
+
this.state.position = value;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
attachTo(target: HTMLElement | null): this {
|
|
57
|
+
if (!target) return this;
|
|
58
|
+
|
|
59
|
+
this._target = target;
|
|
60
|
+
this._setupTooltip();
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
65
|
+
* RENDER
|
|
66
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
67
|
+
|
|
68
|
+
private _setupTooltip(): void {
|
|
69
|
+
if (!this._target) return;
|
|
70
|
+
|
|
71
|
+
const { text, position, style, class: className } = this.state;
|
|
72
|
+
|
|
73
|
+
// Create tooltip element
|
|
74
|
+
const tooltip = document.createElement('div');
|
|
75
|
+
tooltip.className = `jux-tooltip jux-tooltip-${position}`;
|
|
76
|
+
tooltip.id = this._id;
|
|
77
|
+
if (className) tooltip.className += ` ${className}`;
|
|
78
|
+
if (style) tooltip.setAttribute('style', style);
|
|
79
|
+
tooltip.textContent = text;
|
|
80
|
+
tooltip.style.display = 'none';
|
|
81
|
+
this._tooltip = tooltip;
|
|
82
|
+
|
|
83
|
+
document.body.appendChild(tooltip);
|
|
84
|
+
|
|
85
|
+
// Show on hover
|
|
86
|
+
this._target.addEventListener('mouseenter', () => {
|
|
87
|
+
this._show();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
this._target.addEventListener('mouseleave', () => {
|
|
91
|
+
this._hide();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private _show(): void {
|
|
97
|
+
if (!this._tooltip || !this._target) return;
|
|
98
|
+
|
|
99
|
+
const targetRect = this._target.getBoundingClientRect();
|
|
100
|
+
const tooltipRect = this._tooltip.getBoundingClientRect();
|
|
101
|
+
|
|
102
|
+
let top = 0;
|
|
103
|
+
let left = 0;
|
|
104
|
+
|
|
105
|
+
switch (this.state.position) {
|
|
106
|
+
case 'top':
|
|
107
|
+
top = targetRect.top - tooltipRect.height - 8;
|
|
108
|
+
left = targetRect.left + (targetRect.width - tooltipRect.width) / 2;
|
|
109
|
+
break;
|
|
110
|
+
case 'bottom':
|
|
111
|
+
top = targetRect.bottom + 8;
|
|
112
|
+
left = targetRect.left + (targetRect.width - tooltipRect.width) / 2;
|
|
113
|
+
break;
|
|
114
|
+
case 'left':
|
|
115
|
+
top = targetRect.top + (targetRect.height - tooltipRect.height) / 2;
|
|
116
|
+
left = targetRect.left - tooltipRect.width - 8;
|
|
117
|
+
break;
|
|
118
|
+
case 'right':
|
|
119
|
+
top = targetRect.top + (targetRect.height - tooltipRect.height) / 2;
|
|
120
|
+
left = targetRect.right + 8;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
this._tooltip.style.top = `${top}px`;
|
|
125
|
+
this._tooltip.style.left = `${left}px`;
|
|
126
|
+
this._tooltip.style.display = 'block';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private _hide(): void {
|
|
130
|
+
if (this._tooltip) {
|
|
131
|
+
this._tooltip.style.display = 'none';
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
render(targetId?: string): this {
|
|
136
|
+
// Tooltips don't render to containers, they attach to targets
|
|
137
|
+
console.warn('Tooltip: Use .attachTo(element) instead of .render()');
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function tooltip(id: string, options: TooltipOptions = {}): Tooltip {
|
|
143
|
+
return new Tooltip(id, options);
|
|
144
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View component options
|
|
3
|
+
*/
|
|
4
|
+
export interface ViewOptions {
|
|
5
|
+
title?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
children?: any[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* View component state
|
|
11
|
+
*/
|
|
12
|
+
type ViewState = {
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
children: any[];
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* View component - container for organizing page content
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* const view = jux.view('myView', {
|
|
22
|
+
* title: 'Dashboard',
|
|
23
|
+
* description: 'Main dashboard view'
|
|
24
|
+
* });
|
|
25
|
+
* view.add(component1);
|
|
26
|
+
* await view.render();
|
|
27
|
+
*/
|
|
28
|
+
export declare class View {
|
|
29
|
+
state: ViewState;
|
|
30
|
+
container: HTMLElement | null;
|
|
31
|
+
_id: string;
|
|
32
|
+
id: string;
|
|
33
|
+
constructor(id: string, options?: ViewOptions);
|
|
34
|
+
title(value: string): this;
|
|
35
|
+
description(value: string): this;
|
|
36
|
+
add(component: any | any[]): this;
|
|
37
|
+
render(targetId?: string): Promise<this>;
|
|
38
|
+
/**
|
|
39
|
+
* Render to another Jux component's container
|
|
40
|
+
*/
|
|
41
|
+
renderTo(juxComponent: any): Promise<this>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Factory helper
|
|
45
|
+
*/
|
|
46
|
+
export declare function view(id: string, options?: ViewOptions): View;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["view.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,KAAK,SAAS,GAAG;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,GAAG,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,qBAAa,IAAI;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,WAAW,GAAG,IAAI,CAAQ;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;gBAEC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAejD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhC,GAAG,CAAC,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI;IAa3B,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6F9C;;OAEG;IACG,QAAQ,CAAC,YAAY,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAWjD;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI,CAEhE"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { getOrCreateContainer } from './helpers.js';
|
|
2
|
+
/**
|
|
3
|
+
* View component - container for organizing page content
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* const view = jux.view('myView', {
|
|
7
|
+
* title: 'Dashboard',
|
|
8
|
+
* description: 'Main dashboard view'
|
|
9
|
+
* });
|
|
10
|
+
* view.add(component1);
|
|
11
|
+
* await view.render();
|
|
12
|
+
*/
|
|
13
|
+
export class View {
|
|
14
|
+
constructor(id, options = {}) {
|
|
15
|
+
this.container = null;
|
|
16
|
+
this._id = id;
|
|
17
|
+
this.id = id;
|
|
18
|
+
this.state = {
|
|
19
|
+
title: options.title ?? '',
|
|
20
|
+
description: options.description ?? '',
|
|
21
|
+
children: Array.isArray(options.children) ? [...options.children] : []
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/* -------------------------
|
|
25
|
+
* Fluent API
|
|
26
|
+
* ------------------------- */
|
|
27
|
+
title(value) {
|
|
28
|
+
this.state.title = value;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
description(value) {
|
|
32
|
+
this.state.description = value;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
add(component) {
|
|
36
|
+
if (Array.isArray(component)) {
|
|
37
|
+
this.state.children.push(...component);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
this.state.children.push(component);
|
|
41
|
+
}
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
/* -------------------------
|
|
45
|
+
* Render
|
|
46
|
+
* ------------------------- */
|
|
47
|
+
async render(targetId) {
|
|
48
|
+
let container;
|
|
49
|
+
if (targetId) {
|
|
50
|
+
const target = document.querySelector(targetId);
|
|
51
|
+
if (!target || !(target instanceof HTMLElement)) {
|
|
52
|
+
throw new Error(`View: Target element "${targetId}" not found`);
|
|
53
|
+
}
|
|
54
|
+
container = target;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
container = getOrCreateContainer(this._id);
|
|
58
|
+
}
|
|
59
|
+
this.container = container;
|
|
60
|
+
const { title, description, children } = this.state;
|
|
61
|
+
const view = document.createElement('div');
|
|
62
|
+
view.className = 'jux-view';
|
|
63
|
+
view.id = this._id;
|
|
64
|
+
// View header
|
|
65
|
+
if (title || description) {
|
|
66
|
+
const header = document.createElement('div');
|
|
67
|
+
header.className = 'jux-view-header';
|
|
68
|
+
if (title) {
|
|
69
|
+
const titleEl = document.createElement('h1');
|
|
70
|
+
titleEl.className = 'jux-view-title';
|
|
71
|
+
titleEl.textContent = title;
|
|
72
|
+
header.appendChild(titleEl);
|
|
73
|
+
}
|
|
74
|
+
if (description) {
|
|
75
|
+
const descEl = document.createElement('p');
|
|
76
|
+
descEl.className = 'jux-view-description';
|
|
77
|
+
descEl.textContent = description;
|
|
78
|
+
header.appendChild(descEl);
|
|
79
|
+
}
|
|
80
|
+
view.appendChild(header);
|
|
81
|
+
}
|
|
82
|
+
// View content
|
|
83
|
+
const content = document.createElement('div');
|
|
84
|
+
content.className = 'jux-view-content';
|
|
85
|
+
// Render children
|
|
86
|
+
for (let i = 0; i < children.length; i++) {
|
|
87
|
+
const child = children[i];
|
|
88
|
+
if (!child)
|
|
89
|
+
continue;
|
|
90
|
+
// Get child ID
|
|
91
|
+
let childId = null;
|
|
92
|
+
if (child.id) {
|
|
93
|
+
childId = child.id;
|
|
94
|
+
}
|
|
95
|
+
else if (child._id) {
|
|
96
|
+
childId = child._id;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
childId = `${this._id}-child-${i}`;
|
|
100
|
+
}
|
|
101
|
+
// Create wrapper for child
|
|
102
|
+
const childWrapper = document.createElement('div');
|
|
103
|
+
childWrapper.className = 'jux-view-item';
|
|
104
|
+
childWrapper.id = `${childId}-wrapper`;
|
|
105
|
+
content.appendChild(childWrapper);
|
|
106
|
+
// Render child INTO the wrapper
|
|
107
|
+
if (typeof child.render === 'function') {
|
|
108
|
+
try {
|
|
109
|
+
// Pass the wrapper element directly
|
|
110
|
+
const result = child.render(childWrapper);
|
|
111
|
+
if (result && typeof result.then === 'function') {
|
|
112
|
+
await result;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
console.error(`View: Error rendering child ${i}:`, err);
|
|
117
|
+
childWrapper.innerHTML = `<div style="color: #ff6b6b; padding: 1rem;">Error: ${err.message}</div>`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// If no render method, try to append directly
|
|
122
|
+
if (child instanceof HTMLElement) {
|
|
123
|
+
childWrapper.appendChild(child);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
view.appendChild(content);
|
|
128
|
+
container.appendChild(view);
|
|
129
|
+
return this;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Render to another Jux component's container
|
|
133
|
+
*/
|
|
134
|
+
async renderTo(juxComponent) {
|
|
135
|
+
if (!juxComponent || typeof juxComponent !== 'object') {
|
|
136
|
+
throw new Error('View.renderTo: Invalid component - not an object');
|
|
137
|
+
}
|
|
138
|
+
if (!juxComponent._id || typeof juxComponent._id !== 'string') {
|
|
139
|
+
throw new Error('View.renderTo: Invalid component - missing _id (not a Jux component)');
|
|
140
|
+
}
|
|
141
|
+
return this.render(`#${juxComponent._id}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Factory helper
|
|
146
|
+
*/
|
|
147
|
+
export function view(id, options = {}) {
|
|
148
|
+
return new View(id, options);
|
|
149
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { getOrCreateContainer } from './helpers.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* View component options
|
|
5
|
+
*/
|
|
6
|
+
export interface ViewOptions {
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
children?: any[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* View component state
|
|
14
|
+
*/
|
|
15
|
+
type ViewState = {
|
|
16
|
+
title: string;
|
|
17
|
+
description: string;
|
|
18
|
+
children: any[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* View component - container for organizing page content
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
* const view = jux.view('myView', {
|
|
26
|
+
* title: 'Dashboard',
|
|
27
|
+
* description: 'Main dashboard view'
|
|
28
|
+
* });
|
|
29
|
+
* view.add(component1);
|
|
30
|
+
* await view.render();
|
|
31
|
+
*/
|
|
32
|
+
export class View {
|
|
33
|
+
state: ViewState;
|
|
34
|
+
container: HTMLElement | null = null;
|
|
35
|
+
_id: string;
|
|
36
|
+
id: string;
|
|
37
|
+
|
|
38
|
+
constructor(id: string, options: ViewOptions = {}) {
|
|
39
|
+
this._id = id;
|
|
40
|
+
this.id = id;
|
|
41
|
+
|
|
42
|
+
this.state = {
|
|
43
|
+
title: options.title ?? '',
|
|
44
|
+
description: options.description ?? '',
|
|
45
|
+
children: Array.isArray(options.children) ? [...options.children] : []
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* -------------------------
|
|
50
|
+
* Fluent API
|
|
51
|
+
* ------------------------- */
|
|
52
|
+
|
|
53
|
+
title(value: string): this {
|
|
54
|
+
this.state.title = value;
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
description(value: string): this {
|
|
59
|
+
this.state.description = value;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
add(component: any | any[]): this {
|
|
64
|
+
if (Array.isArray(component)) {
|
|
65
|
+
this.state.children.push(...component);
|
|
66
|
+
} else {
|
|
67
|
+
this.state.children.push(component);
|
|
68
|
+
}
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* -------------------------
|
|
73
|
+
* Render
|
|
74
|
+
* ------------------------- */
|
|
75
|
+
|
|
76
|
+
async render(targetId?: string): Promise<this> {
|
|
77
|
+
let container: HTMLElement;
|
|
78
|
+
|
|
79
|
+
if (targetId) {
|
|
80
|
+
const target = document.querySelector(targetId);
|
|
81
|
+
if (!target || !(target instanceof HTMLElement)) {
|
|
82
|
+
throw new Error(`View: Target element "${targetId}" not found`);
|
|
83
|
+
}
|
|
84
|
+
container = target;
|
|
85
|
+
} else {
|
|
86
|
+
container = getOrCreateContainer(this._id);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this.container = container;
|
|
90
|
+
const { title, description, children } = this.state;
|
|
91
|
+
|
|
92
|
+
const view = document.createElement('div');
|
|
93
|
+
view.className = 'jux-view';
|
|
94
|
+
view.id = this._id;
|
|
95
|
+
|
|
96
|
+
// View header
|
|
97
|
+
if (title || description) {
|
|
98
|
+
const header = document.createElement('div');
|
|
99
|
+
header.className = 'jux-view-header';
|
|
100
|
+
|
|
101
|
+
if (title) {
|
|
102
|
+
const titleEl = document.createElement('h1');
|
|
103
|
+
titleEl.className = 'jux-view-title';
|
|
104
|
+
titleEl.textContent = title;
|
|
105
|
+
header.appendChild(titleEl);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (description) {
|
|
109
|
+
const descEl = document.createElement('p');
|
|
110
|
+
descEl.className = 'jux-view-description';
|
|
111
|
+
descEl.textContent = description;
|
|
112
|
+
header.appendChild(descEl);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
view.appendChild(header);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// View content
|
|
119
|
+
const content = document.createElement('div');
|
|
120
|
+
content.className = 'jux-view-content';
|
|
121
|
+
|
|
122
|
+
// Render children
|
|
123
|
+
for (let i = 0; i < children.length; i++) {
|
|
124
|
+
const child = children[i];
|
|
125
|
+
if (!child) continue;
|
|
126
|
+
|
|
127
|
+
// Get child ID
|
|
128
|
+
let childId: string | null = null;
|
|
129
|
+
if ((child as any).id) {
|
|
130
|
+
childId = (child as any).id;
|
|
131
|
+
} else if ((child as any)._id) {
|
|
132
|
+
childId = (child as any)._id;
|
|
133
|
+
} else {
|
|
134
|
+
childId = `${this._id}-child-${i}`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Create wrapper for child
|
|
138
|
+
const childWrapper = document.createElement('div');
|
|
139
|
+
childWrapper.className = 'jux-view-item';
|
|
140
|
+
childWrapper.id = `${childId}-wrapper`;
|
|
141
|
+
content.appendChild(childWrapper);
|
|
142
|
+
|
|
143
|
+
// Render child INTO the wrapper
|
|
144
|
+
if (typeof (child as any).render === 'function') {
|
|
145
|
+
try {
|
|
146
|
+
// Pass the wrapper element directly
|
|
147
|
+
const result = (child as any).render(childWrapper);
|
|
148
|
+
if (result && typeof (result as any).then === 'function') {
|
|
149
|
+
await result;
|
|
150
|
+
}
|
|
151
|
+
} catch (err) {
|
|
152
|
+
console.error(`View: Error rendering child ${i}:`, err);
|
|
153
|
+
childWrapper.innerHTML = `<div style="color: #ff6b6b; padding: 1rem;">Error: ${(err as Error).message}</div>`;
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
// If no render method, try to append directly
|
|
157
|
+
if (child instanceof HTMLElement) {
|
|
158
|
+
childWrapper.appendChild(child);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
view.appendChild(content);
|
|
164
|
+
container.appendChild(view);
|
|
165
|
+
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Render to another Jux component's container
|
|
171
|
+
*/
|
|
172
|
+
async renderTo(juxComponent: any): Promise<this> {
|
|
173
|
+
if (!juxComponent || typeof juxComponent !== 'object') {
|
|
174
|
+
throw new Error('View.renderTo: Invalid component - not an object');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!juxComponent._id || typeof juxComponent._id !== 'string') {
|
|
178
|
+
throw new Error('View.renderTo: Invalid component - missing _id (not a Jux component)');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return this.render(`#${juxComponent._id}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Factory helper
|
|
187
|
+
*/
|
|
188
|
+
export function view(id: string, options: ViewOptions = {}): View {
|
|
189
|
+
return new View(id, options);
|
|
190
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write - Simple content writer with no component tracking
|
|
3
|
+
* Perfect for quick HTML output without ID management
|
|
4
|
+
*/
|
|
5
|
+
export interface WriteOptions {
|
|
6
|
+
tagType?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: string;
|
|
9
|
+
attributes?: Record<string, string>;
|
|
10
|
+
html?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Write content directly to a target element
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* // Write text (defaults to body)
|
|
17
|
+
* jux.write('Hello World!').render();
|
|
18
|
+
*
|
|
19
|
+
* // Write to specific target
|
|
20
|
+
* jux.write('Content').render('#container');
|
|
21
|
+
*
|
|
22
|
+
* // Write HTML
|
|
23
|
+
* jux.write('<strong>Bold text</strong>').html(true).render('#container');
|
|
24
|
+
*
|
|
25
|
+
* // Write with styling
|
|
26
|
+
* jux.write('Styled text').style('color: red;').render('#container');
|
|
27
|
+
*/
|
|
28
|
+
export declare class Write {
|
|
29
|
+
private content;
|
|
30
|
+
private options;
|
|
31
|
+
constructor(content: string, options?: WriteOptions);
|
|
32
|
+
/**
|
|
33
|
+
* Set HTML mode (treat content as HTML)
|
|
34
|
+
*/
|
|
35
|
+
html(enabled?: boolean): this;
|
|
36
|
+
/**
|
|
37
|
+
* Set tag type
|
|
38
|
+
*/
|
|
39
|
+
tagType(value: string): this;
|
|
40
|
+
/**
|
|
41
|
+
* Set CSS class
|
|
42
|
+
*/
|
|
43
|
+
className(value: string): this;
|
|
44
|
+
/**
|
|
45
|
+
* Set inline styles
|
|
46
|
+
*/
|
|
47
|
+
style(value: string): this;
|
|
48
|
+
/**
|
|
49
|
+
* Set custom attributes
|
|
50
|
+
*/
|
|
51
|
+
attrs(attributes: Record<string, string>): this;
|
|
52
|
+
/**
|
|
53
|
+
* Render content to target element
|
|
54
|
+
*/
|
|
55
|
+
render(targetSelector?: string): this;
|
|
56
|
+
/**
|
|
57
|
+
* Replace target content (clear first, then render)
|
|
58
|
+
*/
|
|
59
|
+
replace(targetSelector?: string): this;
|
|
60
|
+
/**
|
|
61
|
+
* Render before target element
|
|
62
|
+
*/
|
|
63
|
+
before(targetSelector: string): this;
|
|
64
|
+
/**
|
|
65
|
+
* Render after target element
|
|
66
|
+
*/
|
|
67
|
+
after(targetSelector: string): this;
|
|
68
|
+
/**
|
|
69
|
+
* Prepend to target (insert as first child)
|
|
70
|
+
*/
|
|
71
|
+
prepend(targetSelector?: string): this;
|
|
72
|
+
/**
|
|
73
|
+
* Append to target (alias for render)
|
|
74
|
+
*/
|
|
75
|
+
append(targetSelector?: string): this;
|
|
76
|
+
private _getTarget;
|
|
77
|
+
private _createElement;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Factory function - simple, no overloads
|
|
81
|
+
*/
|
|
82
|
+
export declare function write(content: string, options?: WriteOptions): Write;
|
|
83
|
+
/**
|
|
84
|
+
* Write text (explicit)
|
|
85
|
+
*/
|
|
86
|
+
export declare function writeText(content: string, options?: Omit<WriteOptions, 'html'>): Write;
|
|
87
|
+
/**
|
|
88
|
+
* Write HTML (explicit)
|
|
89
|
+
*/
|
|
90
|
+
export declare function writeHtml(content: string, options?: Omit<WriteOptions, 'html'>): Write;
|
|
91
|
+
/**
|
|
92
|
+
* Write paragraph
|
|
93
|
+
*/
|
|
94
|
+
export declare function writeParagraph(content: string, options?: Omit<WriteOptions, 'tagType'>): Write;
|
|
95
|
+
/**
|
|
96
|
+
* Write heading
|
|
97
|
+
*/
|
|
98
|
+
export declare function writeHeading(content: string, level?: 1 | 2 | 3 | 4 | 5 | 6, options?: Omit<WriteOptions, 'tagType'>): Write;
|
|
99
|
+
/**
|
|
100
|
+
* Write span
|
|
101
|
+
*/
|
|
102
|
+
export declare function writeSpan(content: string, options?: Omit<WriteOptions, 'tagType'>): Write;
|
|
103
|
+
/**
|
|
104
|
+
* Write div (explicit)
|
|
105
|
+
*/
|
|
106
|
+
export declare function writeDiv(content: string, options?: Omit<WriteOptions, 'tagType'>): Write;
|
|
107
|
+
//# sourceMappingURL=write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["write.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,KAAK;IACd,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAe;gBAElB,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB;IAgBvD;;OAEG;IACH,IAAI,CAAC,OAAO,GAAE,OAAc,GAAG,IAAI;IAKnC;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK9B;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B;;OAEG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAS/C;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI;IAUrC;;OAEG;IACH,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI;IAWtC;;OAEG;IACH,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAapC;;OAEG;IACH,KAAK,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAanC;;OAEG;IACH,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI;IAUtC;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI;IAQrC,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,cAAc;CA6BzB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,KAAK,CAExE;AAMD;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAM,GAAG,KAAK,CAE1F;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAM,GAAG,KAAK,CAE1F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAM,GAAG,KAAK,CAElG;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAK,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAM,GAAG,KAAK,CAElI;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAM,GAAG,KAAK,CAE7F;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAM,GAAG,KAAK,CAE5F"}
|