juxscript 1.1.14 → 1.1.15
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 +0 -2
- package/index.d.ts.map +1 -1
- package/index.js +0 -2
- package/lib/components/alert.d.ts.map +1 -1
- package/lib/components/alert.js +14 -1
- package/lib/components/alert.ts +13 -1
- package/lib/components/badge.d.ts +2 -4
- package/lib/components/badge.d.ts.map +1 -1
- package/lib/components/badge.js +18 -1
- package/lib/components/badge.ts +17 -5
- package/lib/components/base/BaseComponent.d.ts +13 -1
- package/lib/components/base/BaseComponent.d.ts.map +1 -1
- package/lib/components/base/BaseComponent.js +20 -40
- package/lib/components/base/BaseComponent.ts +38 -41
- package/lib/components/hero.d.ts +2 -4
- package/lib/components/hero.d.ts.map +1 -1
- package/lib/components/hero.js +1 -1
- package/lib/components/hero.ts +3 -5
- package/lib/components/sidebar.d.ts +25 -15
- package/lib/components/sidebar.d.ts.map +1 -1
- package/lib/components/sidebar.js +186 -91
- package/lib/components/sidebar.ts +231 -108
- package/package.json +1 -1
- package/lib/components/guard.d.ts +0 -42
- package/lib/components/guard.d.ts.map +0 -1
- package/lib/components/guard.js +0 -59
- package/lib/components/guard.ts +0 -96
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { BaseComponent } from './base/BaseComponent.js';
|
|
1
|
+
import { BaseComponent, BaseState } from './base/BaseComponent.js';
|
|
2
2
|
import { renderIcon } from './icons.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { req } from './req.js';
|
|
5
4
|
|
|
6
5
|
// Event definitions
|
|
7
6
|
const TRIGGER_EVENTS = [] as const;
|
|
8
|
-
const CALLBACK_EVENTS = ['toggle'] as const;
|
|
7
|
+
const CALLBACK_EVENTS = ['toggle', 'itemClick'] as const;
|
|
8
|
+
|
|
9
|
+
export interface SidebarItem {
|
|
10
|
+
label: string;
|
|
11
|
+
href?: string;
|
|
12
|
+
click?: () => void;
|
|
13
|
+
icon?: string;
|
|
14
|
+
items?: SidebarItem[];
|
|
15
|
+
active?: boolean;
|
|
16
|
+
itemClass?: string;
|
|
17
|
+
}
|
|
9
18
|
|
|
10
19
|
export interface SidebarOptions {
|
|
11
20
|
position?: 'left' | 'right';
|
|
@@ -14,26 +23,27 @@ export interface SidebarOptions {
|
|
|
14
23
|
showToggle?: boolean;
|
|
15
24
|
expandOnHover?: boolean;
|
|
16
25
|
collapsed?: boolean;
|
|
17
|
-
|
|
26
|
+
items?: SidebarItem[];
|
|
27
|
+
header?: string;
|
|
28
|
+
footer?: string;
|
|
18
29
|
style?: string;
|
|
19
30
|
class?: string;
|
|
20
31
|
}
|
|
21
32
|
|
|
22
|
-
type SidebarState = {
|
|
33
|
+
type SidebarState = BaseState & {
|
|
23
34
|
position: 'left' | 'right';
|
|
24
35
|
width: string;
|
|
25
36
|
collapsible: boolean;
|
|
26
37
|
showToggle: boolean;
|
|
27
38
|
expandOnHover: boolean;
|
|
28
39
|
collapsed: boolean;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
items: SidebarItem[];
|
|
41
|
+
header: string;
|
|
42
|
+
footer: string;
|
|
32
43
|
};
|
|
33
44
|
|
|
34
45
|
export class Sidebar extends BaseComponent<SidebarState> {
|
|
35
46
|
private _sidebar: HTMLElement | null = null;
|
|
36
|
-
private _menu: Menu | null = null;
|
|
37
47
|
|
|
38
48
|
constructor(id: string, options: SidebarOptions = {}) {
|
|
39
49
|
// Restore collapsed state from localStorage if available
|
|
@@ -48,14 +58,18 @@ export class Sidebar extends BaseComponent<SidebarState> {
|
|
|
48
58
|
showToggle: options.showToggle ?? false,
|
|
49
59
|
expandOnHover: options.expandOnHover ?? false,
|
|
50
60
|
collapsed: initialCollapsed,
|
|
51
|
-
|
|
61
|
+
items: options.items ?? [],
|
|
62
|
+
header: options.header ?? '',
|
|
63
|
+
footer: options.footer ?? '',
|
|
52
64
|
style: options.style ?? '',
|
|
53
65
|
class: options.class ?? ''
|
|
54
66
|
});
|
|
55
67
|
|
|
56
|
-
|
|
68
|
+
this._setActiveStates();
|
|
69
|
+
|
|
70
|
+
// Listen for URL changes to update active states
|
|
57
71
|
if (typeof window !== 'undefined') {
|
|
58
|
-
window.addEventListener('popstate', () => this.
|
|
72
|
+
window.addEventListener('popstate', () => this.refreshActiveStates());
|
|
59
73
|
}
|
|
60
74
|
}
|
|
61
75
|
|
|
@@ -68,20 +82,160 @@ export class Sidebar extends BaseComponent<SidebarState> {
|
|
|
68
82
|
}
|
|
69
83
|
|
|
70
84
|
/* ═════════════════════════════════════════════════════════════════
|
|
71
|
-
*
|
|
85
|
+
* PRIVATE HELPERS
|
|
72
86
|
* ═════════════════════════════════════════════════════════════════ */
|
|
73
87
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
88
|
+
private _setActiveStates(): void {
|
|
89
|
+
this.state.items = this.state.items.map(item => ({
|
|
90
|
+
...item,
|
|
91
|
+
active: item.href ? req.isActiveNavItem(item.href) : false,
|
|
92
|
+
items: item.items?.map(subItem => ({
|
|
93
|
+
...subItem,
|
|
94
|
+
active: subItem.href ? req.isActiveNavItem(subItem.href) : false
|
|
95
|
+
}))
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private _renderItem(item: SidebarItem): HTMLElement {
|
|
100
|
+
const itemEl = document.createElement('div');
|
|
101
|
+
itemEl.className = 'jux-sidebar-item';
|
|
102
|
+
|
|
103
|
+
if (item.itemClass) {
|
|
104
|
+
itemEl.className += ` ${item.itemClass}`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (item.active) {
|
|
108
|
+
itemEl.classList.add('jux-sidebar-item-active');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (item.href) {
|
|
112
|
+
const link = document.createElement('a');
|
|
113
|
+
link.className = 'jux-sidebar-link';
|
|
114
|
+
link.href = item.href;
|
|
115
|
+
|
|
116
|
+
if (item.active) {
|
|
117
|
+
link.classList.add('jux-sidebar-link-active');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (item.icon) {
|
|
121
|
+
const icon = document.createElement('span');
|
|
122
|
+
icon.className = 'jux-sidebar-icon';
|
|
123
|
+
icon.appendChild(renderIcon(item.icon));
|
|
124
|
+
link.appendChild(icon);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const label = document.createElement('span');
|
|
128
|
+
label.className = 'jux-sidebar-label';
|
|
129
|
+
label.textContent = item.label;
|
|
130
|
+
link.appendChild(label);
|
|
131
|
+
|
|
132
|
+
link.addEventListener('click', (e) => {
|
|
133
|
+
this._triggerCallback('itemClick', { item, event: e });
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
itemEl.appendChild(link);
|
|
137
|
+
} else {
|
|
138
|
+
const button = document.createElement('button');
|
|
139
|
+
button.className = 'jux-sidebar-button';
|
|
140
|
+
button.type = 'button';
|
|
141
|
+
|
|
142
|
+
if (item.icon) {
|
|
143
|
+
const icon = document.createElement('span');
|
|
144
|
+
icon.className = 'jux-sidebar-icon';
|
|
145
|
+
icon.appendChild(renderIcon(item.icon));
|
|
146
|
+
button.appendChild(icon);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const label = document.createElement('span');
|
|
150
|
+
label.className = 'jux-sidebar-label';
|
|
151
|
+
label.textContent = item.label;
|
|
152
|
+
button.appendChild(label);
|
|
153
|
+
|
|
154
|
+
button.addEventListener('click', (e) => {
|
|
155
|
+
if (item.click) {
|
|
156
|
+
item.click();
|
|
157
|
+
}
|
|
158
|
+
this._triggerCallback('itemClick', { item, event: e });
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
itemEl.appendChild(button);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Handle sub-items
|
|
165
|
+
if (item.items && item.items.length > 0) {
|
|
166
|
+
itemEl.classList.add('jux-sidebar-item-has-submenu');
|
|
167
|
+
|
|
168
|
+
const submenu = document.createElement('div');
|
|
169
|
+
submenu.className = 'jux-sidebar-submenu';
|
|
170
|
+
|
|
171
|
+
item.items.forEach(subItem => {
|
|
172
|
+
submenu.appendChild(this._renderItem(subItem));
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
itemEl.appendChild(submenu);
|
|
176
|
+
|
|
177
|
+
// Toggle submenu expansion
|
|
178
|
+
const clickTarget = itemEl.querySelector('a, button');
|
|
179
|
+
if (clickTarget) {
|
|
180
|
+
clickTarget.addEventListener('click', (e) => {
|
|
181
|
+
if (!item.href) {
|
|
182
|
+
e.preventDefault();
|
|
183
|
+
}
|
|
184
|
+
itemEl.classList.toggle('jux-sidebar-item-expanded');
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return itemEl;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
193
|
+
* REACTIVE UPDATE
|
|
194
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
195
|
+
|
|
196
|
+
update(prop: string, value: any): void {
|
|
197
|
+
|
|
198
|
+
if (!this._sidebar) return;
|
|
199
|
+
|
|
200
|
+
if (prop === 'collapsed') {
|
|
201
|
+
this._sidebar.classList.toggle('jux-sidebar-collapsed', value);
|
|
202
|
+
|
|
203
|
+
// Update toggle button state
|
|
204
|
+
const toggleBtn = this._sidebar.querySelector('.jux-sidebar-toggle');
|
|
205
|
+
if (toggleBtn) {
|
|
206
|
+
toggleBtn.classList.toggle('jux-sidebar-toggle-collapsed', value);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Save to localStorage
|
|
210
|
+
const storageKey = `jux-sidebar-${this._id}-collapsed`;
|
|
211
|
+
localStorage.setItem(storageKey, String(value));
|
|
212
|
+
} else if (prop === 'items') {
|
|
213
|
+
this._setActiveStates();
|
|
214
|
+
const nav = this._sidebar.querySelector('.jux-sidebar-nav');
|
|
215
|
+
if (nav) {
|
|
216
|
+
nav.innerHTML = '';
|
|
217
|
+
this.state.items.forEach(item => {
|
|
218
|
+
nav.appendChild(this._renderItem(item));
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
} else if (prop === 'header') {
|
|
222
|
+
const header = this._sidebar.querySelector('.jux-sidebar-header');
|
|
223
|
+
if (header) header.textContent = value;
|
|
224
|
+
} else if (prop === 'footer') {
|
|
225
|
+
const footer = this._sidebar.querySelector('.jux-sidebar-footer');
|
|
226
|
+
if (footer) footer.textContent = value;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
231
|
+
* FLUENT API
|
|
232
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
82
233
|
|
|
83
234
|
width(value: string): this {
|
|
84
235
|
this.state.width = value;
|
|
236
|
+
if (this._sidebar) {
|
|
237
|
+
this._sidebar.style.width = value;
|
|
238
|
+
}
|
|
85
239
|
return this;
|
|
86
240
|
}
|
|
87
241
|
|
|
@@ -107,42 +261,38 @@ export class Sidebar extends BaseComponent<SidebarState> {
|
|
|
107
261
|
|
|
108
262
|
collapsed(value: boolean): this {
|
|
109
263
|
this.state.collapsed = value;
|
|
110
|
-
this._updateCollapsedState();
|
|
111
264
|
return this;
|
|
112
265
|
}
|
|
113
266
|
|
|
114
|
-
|
|
115
|
-
this.state.
|
|
267
|
+
items(value: SidebarItem[]): this {
|
|
268
|
+
this.state.items = value;
|
|
116
269
|
return this;
|
|
117
270
|
}
|
|
118
271
|
|
|
119
|
-
|
|
120
|
-
this.state.
|
|
121
|
-
this
|
|
122
|
-
|
|
123
|
-
// Save to localStorage
|
|
124
|
-
const storageKey = `jux-sidebar-${this._id}-collapsed`;
|
|
125
|
-
localStorage.setItem(storageKey, String(this.state.collapsed));
|
|
272
|
+
addItem(item: SidebarItem): this {
|
|
273
|
+
this.state.items = [...this.state.items, item];
|
|
274
|
+
return this;
|
|
275
|
+
}
|
|
126
276
|
|
|
127
|
-
|
|
128
|
-
this.
|
|
277
|
+
header(value: string): this {
|
|
278
|
+
this.state.header = value;
|
|
279
|
+
return this;
|
|
129
280
|
}
|
|
130
281
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
*/
|
|
134
|
-
refreshMenu(): this {
|
|
135
|
-
if (this._menu && this.state.menu) {
|
|
136
|
-
// Re-evaluate and update menu items with current active states
|
|
137
|
-
this._menu.items(this.state.menu.items || []);
|
|
138
|
-
}
|
|
282
|
+
footer(value: string): this {
|
|
283
|
+
this.state.footer = value;
|
|
139
284
|
return this;
|
|
140
285
|
}
|
|
141
286
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
287
|
+
toggle(): void {
|
|
288
|
+
this.state.collapsed = !this.state.collapsed;
|
|
289
|
+
this._triggerCallback('toggle', this.state.collapsed);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
refreshActiveStates(): this {
|
|
293
|
+
this._setActiveStates();
|
|
294
|
+
this.state.items = [...this.state.items]; // Trigger update
|
|
295
|
+
return this;
|
|
146
296
|
}
|
|
147
297
|
|
|
148
298
|
/* ═════════════════════════════════════════════════════════════════
|
|
@@ -152,30 +302,52 @@ export class Sidebar extends BaseComponent<SidebarState> {
|
|
|
152
302
|
render(targetId?: string): this {
|
|
153
303
|
const container = this._setupContainer(targetId);
|
|
154
304
|
|
|
155
|
-
const { position, collapsed, expandOnHover,
|
|
305
|
+
const { position, collapsed, expandOnHover, items, header, footer, width, style, class: className } = this.state;
|
|
156
306
|
|
|
157
|
-
// Build sidebar element
|
|
158
307
|
const sidebar = document.createElement('aside');
|
|
308
|
+
sidebar.className = `jux-sidebar jux-sidebar-${position}`;
|
|
159
309
|
sidebar.id = this._id;
|
|
160
|
-
if (className) sidebar.className = className;
|
|
161
|
-
if (style) sidebar.setAttribute('style', style);
|
|
162
310
|
|
|
163
|
-
// Apply initial collapsed state
|
|
164
311
|
if (collapsed) {
|
|
165
312
|
sidebar.classList.add('jux-sidebar-collapsed');
|
|
166
313
|
}
|
|
167
314
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
315
|
+
if (className) sidebar.className += ` ${className}`;
|
|
316
|
+
if (style) sidebar.setAttribute('style', style);
|
|
317
|
+
if (width) sidebar.style.width = width;
|
|
318
|
+
|
|
319
|
+
// Header
|
|
320
|
+
if (header) {
|
|
321
|
+
const headerEl = document.createElement('div');
|
|
322
|
+
headerEl.className = 'jux-sidebar-header';
|
|
323
|
+
headerEl.textContent = header;
|
|
324
|
+
sidebar.appendChild(headerEl);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Navigation
|
|
328
|
+
const nav = document.createElement('nav');
|
|
329
|
+
nav.className = 'jux-sidebar-nav';
|
|
330
|
+
|
|
331
|
+
items.forEach(item => {
|
|
332
|
+
nav.appendChild(this._renderItem(item));
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
sidebar.appendChild(nav);
|
|
336
|
+
|
|
337
|
+
// Footer
|
|
338
|
+
if (footer) {
|
|
339
|
+
const footerEl = document.createElement('div');
|
|
340
|
+
footerEl.className = 'jux-sidebar-footer';
|
|
341
|
+
footerEl.textContent = footer;
|
|
342
|
+
sidebar.appendChild(footerEl);
|
|
343
|
+
}
|
|
173
344
|
|
|
174
|
-
// Toggle button
|
|
345
|
+
// Toggle button
|
|
175
346
|
if (this.state.collapsible || this.state.showToggle) {
|
|
176
347
|
const toggleBtn = document.createElement('button');
|
|
177
348
|
toggleBtn.className = 'jux-sidebar-toggle';
|
|
178
349
|
toggleBtn.type = 'button';
|
|
350
|
+
toggleBtn.setAttribute('aria-label', 'Toggle sidebar');
|
|
179
351
|
|
|
180
352
|
const toggleIcon = document.createElement('span');
|
|
181
353
|
toggleIcon.className = 'jux-sidebar-toggle-icon';
|
|
@@ -189,13 +361,12 @@ export class Sidebar extends BaseComponent<SidebarState> {
|
|
|
189
361
|
|
|
190
362
|
toggleBtn.addEventListener('click', () => {
|
|
191
363
|
this.toggle();
|
|
192
|
-
toggleBtn.classList.toggle('jux-sidebar-toggle-collapsed', this.state.collapsed);
|
|
193
364
|
});
|
|
194
365
|
|
|
195
366
|
sidebar.appendChild(toggleBtn);
|
|
196
367
|
}
|
|
197
368
|
|
|
198
|
-
//
|
|
369
|
+
// Expand on hover
|
|
199
370
|
if (expandOnHover) {
|
|
200
371
|
sidebar.addEventListener('mouseenter', () => {
|
|
201
372
|
if (this.state.collapsed) {
|
|
@@ -210,56 +381,12 @@ export class Sidebar extends BaseComponent<SidebarState> {
|
|
|
210
381
|
});
|
|
211
382
|
}
|
|
212
383
|
|
|
213
|
-
// Wire events using inherited method
|
|
214
384
|
this._wireStandardEvents(sidebar);
|
|
215
|
-
|
|
216
|
-
// Wire sync bindings for 'collapsed' property
|
|
217
|
-
this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
|
|
218
|
-
if (property === 'collapsed') {
|
|
219
|
-
const transform = toComponent || ((v: any) => v);
|
|
220
|
-
|
|
221
|
-
stateObj.subscribe((val: any) => {
|
|
222
|
-
const transformed = transform(val);
|
|
223
|
-
const isCollapsed = Boolean(transformed);
|
|
224
|
-
this.state.collapsed = isCollapsed;
|
|
225
|
-
this._updateCollapsedState();
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
else if (property === 'menu') {
|
|
229
|
-
const transform = toComponent || ((v: any) => v);
|
|
230
|
-
|
|
231
|
-
stateObj.subscribe((val: any) => {
|
|
232
|
-
const transformed = transform(val);
|
|
233
|
-
this.state.menu = transformed;
|
|
234
|
-
|
|
235
|
-
// Update menu items if menu instance exists
|
|
236
|
-
if (this._menu) {
|
|
237
|
-
this._menu.items(transformed.items || []);
|
|
238
|
-
|
|
239
|
-
// Re-render the menu
|
|
240
|
-
const menuEl = menuContainer.querySelector(`#${this._id}-menu-instance`);
|
|
241
|
-
if (menuEl) {
|
|
242
|
-
menuEl.remove();
|
|
243
|
-
}
|
|
244
|
-
this._menu.render(`#${menuContainer.id}`);
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
});
|
|
385
|
+
this._wireAllSyncs();
|
|
249
386
|
|
|
250
387
|
container.appendChild(sidebar);
|
|
251
388
|
this._sidebar = sidebar;
|
|
252
389
|
|
|
253
|
-
// Create and render menu (after sidebar is in DOM)
|
|
254
|
-
if (menu) {
|
|
255
|
-
this._menu = new Menu(`${this._id}-menu-instance`, {
|
|
256
|
-
...menu,
|
|
257
|
-
orientation: 'vertical'
|
|
258
|
-
});
|
|
259
|
-
this._menu.render(`#${menuContainer.id}`);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Trigger Iconify icon rendering
|
|
263
390
|
requestAnimationFrame(() => {
|
|
264
391
|
if ((window as any).Iconify) {
|
|
265
392
|
(window as any).Iconify.scan();
|
|
@@ -268,10 +395,6 @@ export class Sidebar extends BaseComponent<SidebarState> {
|
|
|
268
395
|
|
|
269
396
|
return this;
|
|
270
397
|
}
|
|
271
|
-
|
|
272
|
-
update(prop: string, value: any): void {
|
|
273
|
-
// No reactive updates needed
|
|
274
|
-
}
|
|
275
398
|
}
|
|
276
399
|
|
|
277
400
|
export function sidebar(id: string, options: SidebarOptions = {}): Sidebar {
|
package/package.json
CHANGED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
-
import { State } from '../reactivity/state.js';
|
|
3
|
-
declare global {
|
|
4
|
-
interface Window {
|
|
5
|
-
juxBeforeNavigate?: (from: string, to: string) => boolean | string;
|
|
6
|
-
juxAfterNavigate?: (path: string) => void;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
export interface GuardOptions {
|
|
10
|
-
authState?: State<boolean>;
|
|
11
|
-
loginPath?: string;
|
|
12
|
-
protectedPaths?: string[];
|
|
13
|
-
}
|
|
14
|
-
type GuardState = {
|
|
15
|
-
authState: State<boolean> | null;
|
|
16
|
-
loginPath: string;
|
|
17
|
-
protectedPaths: string[];
|
|
18
|
-
isActive: boolean;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* ⚠️ DEPRECATED: Guard component is no longer supported after removing global middleware.
|
|
22
|
-
*
|
|
23
|
-
* Recommended alternatives:
|
|
24
|
-
* 1. Server-side authentication (Express, FastAPI, Laravel)
|
|
25
|
-
* 2. Manual route checks in each view
|
|
26
|
-
* 3. Custom wrapper components
|
|
27
|
-
*
|
|
28
|
-
* This component will be removed in a future version.
|
|
29
|
-
*/
|
|
30
|
-
export declare class Guard extends BaseComponent<GuardState> {
|
|
31
|
-
constructor(id: string, options?: GuardOptions);
|
|
32
|
-
protected getTriggerEvents(): readonly string[];
|
|
33
|
-
protected getCallbackEvents(): readonly string[];
|
|
34
|
-
requireAuth(authState: State<boolean>, loginPath?: string): this;
|
|
35
|
-
protect(...paths: string[]): this;
|
|
36
|
-
render(targetId?: string): this;
|
|
37
|
-
deactivate(): this;
|
|
38
|
-
update(prop: string, value: any): void;
|
|
39
|
-
}
|
|
40
|
-
export declare function guard(id: string, options?: GuardOptions): Guard;
|
|
41
|
-
export {};
|
|
42
|
-
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAG/C,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC;QACnE,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7C;CACJ;AAMD,MAAM,WAAW,YAAY;IACzB,SAAS,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,KAAK,UAAU,GAAG;IACd,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;;;;;;GASG;AACH,qBAAa,KAAM,SAAQ,aAAa,CAAC,UAAU,CAAC;gBACpC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB;IAclD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAQhD,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAKhE,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IASjC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAK/B,UAAU,IAAI,IAAI;IAIlB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;CAGzC;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,KAAK,CAE/D"}
|
package/lib/components/guard.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
-
// Event definitions
|
|
3
|
-
const TRIGGER_EVENTS = [];
|
|
4
|
-
const CALLBACK_EVENTS = ['blocked', 'allowed'];
|
|
5
|
-
/**
|
|
6
|
-
* ⚠️ DEPRECATED: Guard component is no longer supported after removing global middleware.
|
|
7
|
-
*
|
|
8
|
-
* Recommended alternatives:
|
|
9
|
-
* 1. Server-side authentication (Express, FastAPI, Laravel)
|
|
10
|
-
* 2. Manual route checks in each view
|
|
11
|
-
* 3. Custom wrapper components
|
|
12
|
-
*
|
|
13
|
-
* This component will be removed in a future version.
|
|
14
|
-
*/
|
|
15
|
-
export class Guard extends BaseComponent {
|
|
16
|
-
constructor(id, options = {}) {
|
|
17
|
-
super(id, {
|
|
18
|
-
authState: options.authState ?? null,
|
|
19
|
-
loginPath: options.loginPath ?? '/login',
|
|
20
|
-
protectedPaths: options.protectedPaths ?? [],
|
|
21
|
-
isActive: false
|
|
22
|
-
});
|
|
23
|
-
console.warn('[Jux Guard] DEPRECATED: Guard component no longer supported after middleware removal.\n' +
|
|
24
|
-
'Use server-side auth or manual checks instead.');
|
|
25
|
-
}
|
|
26
|
-
getTriggerEvents() {
|
|
27
|
-
return TRIGGER_EVENTS;
|
|
28
|
-
}
|
|
29
|
-
getCallbackEvents() {
|
|
30
|
-
return CALLBACK_EVENTS;
|
|
31
|
-
}
|
|
32
|
-
/* ═════════════════════════════════════════════════════════════════
|
|
33
|
-
* FLUENT API (No-ops now)
|
|
34
|
-
* ═════════════════════════════════════════════════════════════════ */
|
|
35
|
-
requireAuth(authState, loginPath) {
|
|
36
|
-
console.warn('[Jux Guard] DEPRECATED: requireAuth() has no effect');
|
|
37
|
-
return this;
|
|
38
|
-
}
|
|
39
|
-
protect(...paths) {
|
|
40
|
-
console.warn('[Jux Guard] DEPRECATED: protect() has no effect');
|
|
41
|
-
return this;
|
|
42
|
-
}
|
|
43
|
-
/* ═════════════════════════════════════════════════════════════════
|
|
44
|
-
* RENDER (No-op)
|
|
45
|
-
* ═════════════════════════════════════════════════════════════════ */
|
|
46
|
-
render(targetId) {
|
|
47
|
-
console.warn('[Jux Guard] DEPRECATED: Guard rendering has no effect');
|
|
48
|
-
return this;
|
|
49
|
-
}
|
|
50
|
-
deactivate() {
|
|
51
|
-
return this;
|
|
52
|
-
}
|
|
53
|
-
update(prop, value) {
|
|
54
|
-
// No reactive updates needed
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
export function guard(id, options) {
|
|
58
|
-
return new Guard(id, options);
|
|
59
|
-
}
|
package/lib/components/guard.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
-
import { State } from '../reactivity/state.js';
|
|
3
|
-
|
|
4
|
-
// Extend Window interface to include Jux navigation hooks
|
|
5
|
-
declare global {
|
|
6
|
-
interface Window {
|
|
7
|
-
juxBeforeNavigate?: (from: string, to: string) => boolean | string;
|
|
8
|
-
juxAfterNavigate?: (path: string) => void;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Event definitions
|
|
13
|
-
const TRIGGER_EVENTS = [] as const;
|
|
14
|
-
const CALLBACK_EVENTS = ['blocked', 'allowed'] as const;
|
|
15
|
-
|
|
16
|
-
export interface GuardOptions {
|
|
17
|
-
authState?: State<boolean>; // Check if user is authenticated
|
|
18
|
-
loginPath?: string; // Where to redirect if blocked
|
|
19
|
-
protectedPaths?: string[]; // Paths that require auth
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
type GuardState = {
|
|
23
|
-
authState: State<boolean> | null;
|
|
24
|
-
loginPath: string;
|
|
25
|
-
protectedPaths: string[];
|
|
26
|
-
isActive: boolean;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* ⚠️ DEPRECATED: Guard component is no longer supported after removing global middleware.
|
|
31
|
-
*
|
|
32
|
-
* Recommended alternatives:
|
|
33
|
-
* 1. Server-side authentication (Express, FastAPI, Laravel)
|
|
34
|
-
* 2. Manual route checks in each view
|
|
35
|
-
* 3. Custom wrapper components
|
|
36
|
-
*
|
|
37
|
-
* This component will be removed in a future version.
|
|
38
|
-
*/
|
|
39
|
-
export class Guard extends BaseComponent<GuardState> {
|
|
40
|
-
constructor(id: string, options: GuardOptions = {}) {
|
|
41
|
-
super(id, {
|
|
42
|
-
authState: options.authState ?? null,
|
|
43
|
-
loginPath: options.loginPath ?? '/login',
|
|
44
|
-
protectedPaths: options.protectedPaths ?? [],
|
|
45
|
-
isActive: false
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
console.warn(
|
|
49
|
-
'[Jux Guard] DEPRECATED: Guard component no longer supported after middleware removal.\n' +
|
|
50
|
-
'Use server-side auth or manual checks instead.'
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
protected getTriggerEvents(): readonly string[] {
|
|
55
|
-
return TRIGGER_EVENTS;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
protected getCallbackEvents(): readonly string[] {
|
|
59
|
-
return CALLBACK_EVENTS;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/* ═════════════════════════════════════════════════════════════════
|
|
63
|
-
* FLUENT API (No-ops now)
|
|
64
|
-
* ═════════════════════════════════════════════════════════════════ */
|
|
65
|
-
|
|
66
|
-
requireAuth(authState: State<boolean>, loginPath?: string): this {
|
|
67
|
-
console.warn('[Jux Guard] DEPRECATED: requireAuth() has no effect');
|
|
68
|
-
return this;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
protect(...paths: string[]): this {
|
|
72
|
-
console.warn('[Jux Guard] DEPRECATED: protect() has no effect');
|
|
73
|
-
return this;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/* ═════════════════════════════════════════════════════════════════
|
|
77
|
-
* RENDER (No-op)
|
|
78
|
-
* ═════════════════════════════════════════════════════════════════ */
|
|
79
|
-
|
|
80
|
-
render(targetId?: string): this {
|
|
81
|
-
console.warn('[Jux Guard] DEPRECATED: Guard rendering has no effect');
|
|
82
|
-
return this;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
deactivate(): this {
|
|
86
|
-
return this;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
update(prop: string, value: any): void {
|
|
90
|
-
// No reactive updates needed
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function guard(id: string, options?: GuardOptions): Guard {
|
|
95
|
-
return new Guard(id, options);
|
|
96
|
-
}
|