juxscript 1.1.111 → 1.1.113

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.
@@ -0,0 +1,204 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ import { formatIdAsLabel } from '../utils/formatId.js';
3
+ // Event definitions
4
+ const TRIGGER_EVENTS = [];
5
+ const CALLBACK_EVENTS = ['load', 'error'];
6
+ export class Image extends BaseComponent {
7
+ constructor(id, options = {}) {
8
+ super(id, {
9
+ visible: true,
10
+ disabled: false,
11
+ loading: false,
12
+ class: options.class ?? '',
13
+ style: options.style ?? '',
14
+ attributes: {},
15
+ src: options.src ?? '',
16
+ alt: options.alt ?? formatIdAsLabel(id),
17
+ objectFit: options.objectFit ?? 'cover',
18
+ loadingType: options.loading ?? 'lazy',
19
+ crossOrigin: options.crossOrigin,
20
+ isLoaded: false,
21
+ hasError: false
22
+ });
23
+ // Apply width/height if provided
24
+ if (options.width) {
25
+ this.state.style = this.state.style ? `${this.state.style}; width: ${options.width}` : `width: ${options.width}`;
26
+ }
27
+ if (options.height) {
28
+ this.state.style = this.state.style ? `${this.state.style}; height: ${options.height}` : `height: ${options.height}`;
29
+ }
30
+ }
31
+ getTriggerEvents() {
32
+ return TRIGGER_EVENTS;
33
+ }
34
+ getCallbackEvents() {
35
+ return CALLBACK_EVENTS;
36
+ }
37
+ /* ═════════════════════════════════════════════════════════════════
38
+ * FLUENT API
39
+ * ═════════════════════════════════════════════════════════════════ */
40
+ src(value) {
41
+ this.state.src = value;
42
+ if (this.container) {
43
+ const img = this.container.querySelector(`#${this._id}`);
44
+ if (img) {
45
+ img.src = value;
46
+ this.state.isLoaded = false;
47
+ this.state.hasError = false;
48
+ }
49
+ }
50
+ return this;
51
+ }
52
+ alt(value) {
53
+ this.state.alt = value;
54
+ if (this.container) {
55
+ const img = this.container.querySelector(`#${this._id}`);
56
+ if (img)
57
+ img.alt = value;
58
+ }
59
+ return this;
60
+ }
61
+ objectFit(value) {
62
+ this.state.objectFit = value;
63
+ if (this.container) {
64
+ const img = this.container.querySelector(`#${this._id}`);
65
+ if (img)
66
+ img.style.objectFit = value;
67
+ }
68
+ return this;
69
+ }
70
+ lazy() {
71
+ this.state.loadingType = 'lazy';
72
+ return this;
73
+ }
74
+ eager() {
75
+ this.state.loadingType = 'eager';
76
+ return this;
77
+ }
78
+ crossOrigin(value) {
79
+ this.state.crossOrigin = value;
80
+ return this;
81
+ }
82
+ /* ═════════════════════════════════════════════════════════════════
83
+ * STATE GETTERS
84
+ * ═════════════════════════════════════════════════════════════════ */
85
+ isLoaded() {
86
+ return this.state.isLoaded;
87
+ }
88
+ hasError() {
89
+ return this.state.hasError;
90
+ }
91
+ /* ═════════════════════════════════════════════════════════════════
92
+ * RENDER
93
+ * ═════════════════════════════════════════════════════════════════ */
94
+ render(targetId) {
95
+ const container = this._setupContainer(targetId);
96
+ const { src, alt, objectFit, loadingType, crossOrigin, style, class: className } = this.state;
97
+ const img = document.createElement('img');
98
+ img.id = this._id;
99
+ img.className = 'jux-image';
100
+ if (className)
101
+ img.className += ` ${className}`;
102
+ if (style)
103
+ img.setAttribute('style', style);
104
+ img.src = src;
105
+ img.alt = alt;
106
+ img.style.objectFit = objectFit;
107
+ img.loading = loadingType;
108
+ if (crossOrigin) {
109
+ img.crossOrigin = crossOrigin;
110
+ }
111
+ // Wire load event
112
+ img.addEventListener('load', () => {
113
+ this.state.isLoaded = true;
114
+ this.state.hasError = false;
115
+ this._triggerCallback('load', img);
116
+ });
117
+ // Wire error event
118
+ img.addEventListener('error', () => {
119
+ this.state.isLoaded = false;
120
+ this.state.hasError = true;
121
+ this._triggerCallback('error', img);
122
+ });
123
+ // Wire standard events (click, mouseover, etc.)
124
+ this._wireStandardEvents(img);
125
+ // Sync src changes
126
+ const srcSync = this._syncBindings.find(b => b.property === 'src');
127
+ if (srcSync) {
128
+ const transform = srcSync.toComponent || ((v) => String(v));
129
+ srcSync.stateObj.subscribe((val) => {
130
+ this.src(transform(val));
131
+ });
132
+ }
133
+ // Sync alt changes
134
+ const altSync = this._syncBindings.find(b => b.property === 'alt');
135
+ if (altSync) {
136
+ const transform = altSync.toComponent || ((v) => String(v));
137
+ altSync.stateObj.subscribe((val) => {
138
+ this.alt(transform(val));
139
+ });
140
+ }
141
+ container.appendChild(img);
142
+ return this;
143
+ }
144
+ update(prop, value) {
145
+ if (!this.container)
146
+ return;
147
+ const img = this.container.querySelector(`#${this._id}`);
148
+ if (!img)
149
+ return;
150
+ // Handle image-specific updates
151
+ switch (prop) {
152
+ case 'src':
153
+ img.src = value;
154
+ this.state.isLoaded = false;
155
+ this.state.hasError = false;
156
+ break;
157
+ case 'alt':
158
+ img.alt = value;
159
+ break;
160
+ case 'objectFit':
161
+ img.style.objectFit = value;
162
+ break;
163
+ case 'loadingType':
164
+ img.loading = value;
165
+ break;
166
+ case 'crossOrigin':
167
+ img.crossOrigin = value;
168
+ break;
169
+ // Base properties handled by BaseComponent.update()
170
+ default:
171
+ super.update(prop, value);
172
+ break;
173
+ }
174
+ }
175
+ }
176
+ export function image(id, options = {}) {
177
+ return new Image(id, options);
178
+ }
179
+ // Convenience helper for avatar/profile images
180
+ export function avatar(id, src, alt) {
181
+ return new Image(id, {
182
+ src,
183
+ alt: alt || 'Avatar',
184
+ objectFit: 'cover',
185
+ style: 'border-radius: 50%'
186
+ });
187
+ }
188
+ // Convenience helper for logo images
189
+ export function logo(id, src, alt) {
190
+ return new Image(id, {
191
+ src,
192
+ alt: alt || 'Logo',
193
+ objectFit: 'contain'
194
+ });
195
+ }
196
+ // Convenience helper for thumbnail images
197
+ export function thumbnail(id, src, alt) {
198
+ return new Image(id, {
199
+ src,
200
+ alt: alt || 'Thumbnail',
201
+ objectFit: 'cover',
202
+ loading: 'lazy'
203
+ });
204
+ }
@@ -0,0 +1,260 @@
1
+ import { BaseComponent, BaseState } from './base/BaseComponent.js';
2
+ import { formatIdAsLabel } from '../utils/formatId.js';
3
+
4
+ // Event definitions
5
+ const TRIGGER_EVENTS = [] as const;
6
+ const CALLBACK_EVENTS = ['load', 'error'] as const;
7
+
8
+ export interface ImageOptions {
9
+ src?: string;
10
+ alt?: string;
11
+ width?: string;
12
+ height?: string;
13
+ objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
14
+ loading?: 'lazy' | 'eager';
15
+ crossOrigin?: 'anonymous' | 'use-credentials';
16
+ style?: string;
17
+ class?: string;
18
+ }
19
+
20
+ interface ImageState extends BaseState {
21
+ src: string;
22
+ alt: string;
23
+ objectFit: string;
24
+ loadingType: string;
25
+ crossOrigin?: string;
26
+ isLoaded: boolean;
27
+ hasError: boolean;
28
+ }
29
+
30
+ export class Image extends BaseComponent<ImageState> {
31
+ constructor(id: string, options: ImageOptions = {}) {
32
+ super(id, {
33
+ visible: true,
34
+ disabled: false,
35
+ loading: false,
36
+ class: options.class ?? '',
37
+ style: options.style ?? '',
38
+ attributes: {},
39
+ src: options.src ?? '',
40
+ alt: options.alt ?? formatIdAsLabel(id),
41
+ objectFit: options.objectFit ?? 'cover',
42
+ loadingType: options.loading ?? 'lazy',
43
+ crossOrigin: options.crossOrigin,
44
+ isLoaded: false,
45
+ hasError: false
46
+ });
47
+
48
+ // Apply width/height if provided
49
+ if (options.width) {
50
+ this.state.style = this.state.style ? `${this.state.style}; width: ${options.width}` : `width: ${options.width}`;
51
+ }
52
+ if (options.height) {
53
+ this.state.style = this.state.style ? `${this.state.style}; height: ${options.height}` : `height: ${options.height}`;
54
+ }
55
+ }
56
+
57
+ protected getTriggerEvents(): readonly string[] {
58
+ return TRIGGER_EVENTS;
59
+ }
60
+
61
+ protected getCallbackEvents(): readonly string[] {
62
+ return CALLBACK_EVENTS;
63
+ }
64
+
65
+ /* ═════════════════════════════════════════════════════════════════
66
+ * FLUENT API
67
+ * ═════════════════════════════════════════════════════════════════ */
68
+
69
+ src(value: string): this {
70
+ this.state.src = value;
71
+ if (this.container) {
72
+ const img = this.container.querySelector(`#${this._id}`) as HTMLImageElement;
73
+ if (img) {
74
+ img.src = value;
75
+ this.state.isLoaded = false;
76
+ this.state.hasError = false;
77
+ }
78
+ }
79
+ return this;
80
+ }
81
+
82
+ alt(value: string): this {
83
+ this.state.alt = value;
84
+ if (this.container) {
85
+ const img = this.container.querySelector(`#${this._id}`) as HTMLImageElement;
86
+ if (img) img.alt = value;
87
+ }
88
+ return this;
89
+ }
90
+
91
+ objectFit(value: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down'): this {
92
+ this.state.objectFit = value;
93
+ if (this.container) {
94
+ const img = this.container.querySelector(`#${this._id}`) as HTMLImageElement;
95
+ if (img) img.style.objectFit = value;
96
+ }
97
+ return this;
98
+ }
99
+
100
+ lazy(): this {
101
+ this.state.loadingType = 'lazy';
102
+ return this;
103
+ }
104
+
105
+ eager(): this {
106
+ this.state.loadingType = 'eager';
107
+ return this;
108
+ }
109
+
110
+ crossOrigin(value: 'anonymous' | 'use-credentials'): this {
111
+ this.state.crossOrigin = value;
112
+ return this;
113
+ }
114
+
115
+ /* ═════════════════════════════════════════════════════════════════
116
+ * STATE GETTERS
117
+ * ═════════════════════════════════════════════════════════════════ */
118
+
119
+ isLoaded(): boolean {
120
+ return this.state.isLoaded;
121
+ }
122
+
123
+ hasError(): boolean {
124
+ return this.state.hasError;
125
+ }
126
+
127
+ /* ═════════════════════════════════════════════════════════════════
128
+ * RENDER
129
+ * ═════════════════════════════════════════════════════════════════ */
130
+
131
+ render(targetId?: string | HTMLElement | BaseComponent<any>): this {
132
+ const container = this._setupContainer(targetId);
133
+
134
+ const { src, alt, objectFit, loadingType, crossOrigin, style, class: className } = this.state;
135
+
136
+ const img = document.createElement('img');
137
+ img.id = this._id;
138
+ img.className = 'jux-image';
139
+ if (className) img.className += ` ${className}`;
140
+ if (style) img.setAttribute('style', style);
141
+
142
+ img.src = src;
143
+ img.alt = alt;
144
+ img.style.objectFit = objectFit;
145
+ img.loading = loadingType as 'lazy' | 'eager';
146
+
147
+ if (crossOrigin) {
148
+ img.crossOrigin = crossOrigin;
149
+ }
150
+
151
+ // Wire load event
152
+ img.addEventListener('load', () => {
153
+ this.state.isLoaded = true;
154
+ this.state.hasError = false;
155
+ this._triggerCallback('load', img);
156
+ });
157
+
158
+ // Wire error event
159
+ img.addEventListener('error', () => {
160
+ this.state.isLoaded = false;
161
+ this.state.hasError = true;
162
+ this._triggerCallback('error', img);
163
+ });
164
+
165
+ // Wire standard events (click, mouseover, etc.)
166
+ this._wireStandardEvents(img);
167
+
168
+ // Sync src changes
169
+ const srcSync = this._syncBindings.find(b => b.property === 'src');
170
+ if (srcSync) {
171
+ const transform = srcSync.toComponent || ((v: any) => String(v));
172
+ srcSync.stateObj.subscribe((val: any) => {
173
+ this.src(transform(val));
174
+ });
175
+ }
176
+
177
+ // Sync alt changes
178
+ const altSync = this._syncBindings.find(b => b.property === 'alt');
179
+ if (altSync) {
180
+ const transform = altSync.toComponent || ((v: any) => String(v));
181
+ altSync.stateObj.subscribe((val: any) => {
182
+ this.alt(transform(val));
183
+ });
184
+ }
185
+
186
+ container.appendChild(img);
187
+
188
+ return this;
189
+ }
190
+
191
+ update(prop: string, value: any): void {
192
+ if (!this.container) return;
193
+
194
+ const img = this.container.querySelector(`#${this._id}`) as HTMLImageElement;
195
+ if (!img) return;
196
+
197
+ // Handle image-specific updates
198
+ switch (prop) {
199
+ case 'src':
200
+ img.src = value;
201
+ this.state.isLoaded = false;
202
+ this.state.hasError = false;
203
+ break;
204
+
205
+ case 'alt':
206
+ img.alt = value;
207
+ break;
208
+
209
+ case 'objectFit':
210
+ img.style.objectFit = value;
211
+ break;
212
+
213
+ case 'loadingType':
214
+ img.loading = value as 'lazy' | 'eager';
215
+ break;
216
+
217
+ case 'crossOrigin':
218
+ img.crossOrigin = value;
219
+ break;
220
+
221
+ // Base properties handled by BaseComponent.update()
222
+ default:
223
+ super.update(prop, value);
224
+ break;
225
+ }
226
+ }
227
+ }
228
+
229
+ export function image(id: string, options: ImageOptions = {}): Image {
230
+ return new Image(id, options);
231
+ }
232
+
233
+ // Convenience helper for avatar/profile images
234
+ export function avatar(id: string, src: string, alt?: string): Image {
235
+ return new Image(id, {
236
+ src,
237
+ alt: alt || 'Avatar',
238
+ objectFit: 'cover',
239
+ style: 'border-radius: 50%'
240
+ });
241
+ }
242
+
243
+ // Convenience helper for logo images
244
+ export function logo(id: string, src: string, alt?: string): Image {
245
+ return new Image(id, {
246
+ src,
247
+ alt: alt || 'Logo',
248
+ objectFit: 'contain'
249
+ });
250
+ }
251
+
252
+ // Convenience helper for thumbnail images
253
+ export function thumbnail(id: string, src: string, alt?: string): Image {
254
+ return new Image(id, {
255
+ src,
256
+ alt: alt || 'Thumbnail',
257
+ objectFit: 'cover',
258
+ loading: 'lazy'
259
+ });
260
+ }
@@ -0,0 +1,72 @@
1
+ import { BaseComponent, BaseState } from './base/BaseComponent.js';
2
+ export interface LayerOptions {
3
+ preset?: LayerPreset;
4
+ opacity?: number;
5
+ zIndex?: number;
6
+ blur?: number;
7
+ content?: string | BaseComponent<any>;
8
+ style?: string;
9
+ class?: string;
10
+ }
11
+ interface LayerState extends BaseState {
12
+ preset?: string;
13
+ content?: string;
14
+ }
15
+ /**
16
+ * Gradient preset names from gradients.css
17
+ */
18
+ export type LayerPreset = 'ocean' | 'sunset' | 'forest' | 'fire' | 'ice' | 'candy' | 'emerald' | 'midnight' | 'peach' | 'royal' | 'coral' | 'mint' | 'grape' | 'cherry' | 'sky' | 'aurora' | 'tropical' | 'cosmic' | 'neon' | 'volcano' | 'radial-sun' | 'radial-moon' | 'radial-blue' | 'radial-purple' | 'radial-fire' | 'radial-ocean' | 'radial-emerald' | 'radial-sunset' | 'conic-rainbow' | 'conic-sunset' | 'conic-ocean' | 'conic-fire' | 'conic-neon' | 'dark-space' | 'dark-navy' | 'dark-purple' | 'dark-forest' | 'dark-crimson' | 'dark-slate' | 'overlay-dark' | 'overlay-light' | 'overlay-blue' | 'overlay-purple' | 'overlay-sunset' | 'mesh-purple' | 'mesh-ocean' | 'mesh-fire' | 'mesh-neon' | 'pastel-pink' | 'pastel-blue' | 'pastel-green' | 'pastel-purple' | 'pastel-peach' | 'pastel-lavender' | 'animated' | 'animated-fast' | 'animated-slow';
19
+ export declare class Layer extends BaseComponent<LayerState> {
20
+ constructor(id: string, options?: LayerOptions);
21
+ protected getTriggerEvents(): readonly string[];
22
+ protected getCallbackEvents(): readonly string[];
23
+ /**
24
+ * Set layer opacity
25
+ */
26
+ opacity(value: number): this;
27
+ /**
28
+ * Set layer z-index
29
+ */
30
+ zIndex(value: number): this;
31
+ /**
32
+ * Apply a gradient preset from gradients.css
33
+ */
34
+ preset(value: LayerPreset): this;
35
+ /**
36
+ * Set layer content (text or component)
37
+ */
38
+ content(value: string | BaseComponent<any>): this;
39
+ /**
40
+ * Apply backdrop blur (for overlay effects)
41
+ */
42
+ backdropBlur(value: number): this;
43
+ /**
44
+ * Make layer cover entire parent (position: absolute with inset: 0)
45
+ */
46
+ fullCover(): this;
47
+ /**
48
+ * Make layer fixed to viewport
49
+ */
50
+ fixed(): this;
51
+ render(targetId?: string | HTMLElement | BaseComponent<any>): this;
52
+ update(prop: string, value: any): void;
53
+ }
54
+ export declare function layer(id: string, options?: LayerOptions): Layer;
55
+ /**
56
+ * Create a gradient layer with preset
57
+ */
58
+ export declare function gradient(id: string, preset: LayerPreset, options?: Omit<LayerOptions, 'preset'>): Layer;
59
+ /**
60
+ * Create a dark overlay (for hero images, etc.)
61
+ */
62
+ export declare function overlay(id: string, opacity?: number): Layer;
63
+ /**
64
+ * Create a blur overlay (glassmorphism effect)
65
+ */
66
+ export declare function glassLayer(id: string, blur?: number, opacity?: number): Layer;
67
+ /**
68
+ * Create an animated gradient background
69
+ */
70
+ export declare function animatedGradient(id: string, speed?: 'fast' | 'normal' | 'slow'): Layer;
71
+ export {};
72
+ //# sourceMappingURL=layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layer.d.ts","sourceRoot":"","sources":["layer.ts"],"names":[],"mappings":"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"}