snice 1.13.2 → 1.13.4
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/templates/base/README.md +1 -1
- package/dist/components/accordion/snice-accordion-item.d.ts +25 -0
- package/dist/components/accordion/snice-accordion-item.js +260 -0
- package/dist/components/accordion/snice-accordion-item.js.map +1 -0
- package/dist/components/accordion/snice-accordion.d.ts +28 -0
- package/dist/components/accordion/snice-accordion.js +221 -0
- package/dist/components/accordion/snice-accordion.js.map +1 -0
- package/dist/components/accordion/snice-accordion.types.d.ts +29 -0
- package/dist/components/accordion/snice-accordion.types.js +2 -0
- package/dist/components/accordion/snice-accordion.types.js.map +1 -0
- package/dist/components/alert/snice-alert.d.ts +26 -0
- package/dist/components/alert/snice-alert.js +191 -0
- package/dist/components/alert/snice-alert.js.map +1 -0
- package/dist/components/alert/snice-alert.types.d.ts +11 -0
- package/dist/components/alert/snice-alert.types.js +2 -0
- package/dist/components/alert/snice-alert.types.js.map +1 -0
- package/dist/components/avatar/snice-avatar.d.ts +24 -0
- package/dist/components/avatar/snice-avatar.js +177 -0
- package/dist/components/avatar/snice-avatar.js.map +1 -0
- package/dist/components/avatar/snice-avatar.types.d.ts +12 -0
- package/dist/components/avatar/snice-avatar.types.js +2 -0
- package/dist/components/avatar/snice-avatar.types.js.map +1 -0
- package/dist/components/badge/snice-badge.d.ts +25 -0
- package/dist/components/badge/snice-badge.js +157 -0
- package/dist/components/badge/snice-badge.js.map +1 -0
- package/dist/components/badge/snice-badge.types.d.ts +15 -0
- package/dist/components/badge/snice-badge.types.js +2 -0
- package/dist/components/badge/snice-badge.types.js.map +1 -0
- package/dist/components/breadcrumbs/snice-breadcrumbs.d.ts +27 -0
- package/dist/components/breadcrumbs/snice-breadcrumbs.js +212 -0
- package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +1 -0
- package/dist/components/breadcrumbs/snice-breadcrumbs.types.d.ts +23 -0
- package/dist/components/breadcrumbs/snice-breadcrumbs.types.js +2 -0
- package/dist/components/breadcrumbs/snice-breadcrumbs.types.js.map +1 -0
- package/dist/components/breadcrumbs/snice-crumb.d.ts +9 -0
- package/dist/components/breadcrumbs/snice-crumb.js +50 -0
- package/dist/components/breadcrumbs/snice-crumb.js.map +1 -0
- package/dist/components/button/snice-button.d.ts +32 -0
- package/dist/components/button/snice-button.js +212 -0
- package/dist/components/button/snice-button.js.map +1 -0
- package/dist/components/button/snice-button.types.d.ts +23 -0
- package/dist/components/button/snice-button.types.js +2 -0
- package/dist/components/button/snice-button.types.js.map +1 -0
- package/dist/components/card/snice-card.d.ts +19 -0
- package/dist/components/card/snice-card.js +132 -0
- package/dist/components/card/snice-card.js.map +1 -0
- package/dist/components/card/snice-card.types.d.ts +9 -0
- package/dist/components/card/snice-card.types.js +2 -0
- package/dist/components/card/snice-card.types.js.map +1 -0
- package/dist/components/checkbox/snice-checkbox.d.ts +34 -0
- package/dist/components/checkbox/snice-checkbox.js +289 -0
- package/dist/components/checkbox/snice-checkbox.js.map +1 -0
- package/dist/components/checkbox/snice-checkbox.types.d.ts +20 -0
- package/dist/components/checkbox/snice-checkbox.types.js +2 -0
- package/dist/components/checkbox/snice-checkbox.types.js.map +1 -0
- package/dist/components/chip/snice-chip.d.ts +28 -0
- package/dist/components/chip/snice-chip.js +203 -0
- package/dist/components/chip/snice-chip.js.map +1 -0
- package/dist/components/chip/snice-chip.types.d.ts +14 -0
- package/dist/components/chip/snice-chip.types.js +2 -0
- package/dist/components/chip/snice-chip.types.js.map +1 -0
- package/dist/components/date-picker/snice-date-picker.d.ts +82 -0
- package/dist/components/date-picker/snice-date-picker.js +880 -0
- package/dist/components/date-picker/snice-date-picker.js.map +1 -0
- package/dist/components/date-picker/snice-date-picker.types.d.ts +71 -0
- package/dist/components/date-picker/snice-date-picker.types.js +2 -0
- package/dist/components/date-picker/snice-date-picker.types.js.map +1 -0
- package/dist/components/divider/snice-divider.d.ts +17 -0
- package/dist/components/divider/snice-divider.js +111 -0
- package/dist/components/divider/snice-divider.js.map +1 -0
- package/dist/components/divider/snice-divider.types.d.ts +14 -0
- package/dist/components/divider/snice-divider.types.js +2 -0
- package/dist/components/divider/snice-divider.types.js.map +1 -0
- package/dist/components/drawer/snice-drawer.d.ts +37 -0
- package/dist/components/drawer/snice-drawer.js +335 -0
- package/dist/components/drawer/snice-drawer.js.map +1 -0
- package/dist/components/drawer/snice-drawer.types.d.ts +16 -0
- package/dist/components/drawer/snice-drawer.types.js +2 -0
- package/dist/components/drawer/snice-drawer.types.js.map +1 -0
- package/dist/components/input/snice-input.d.ts +65 -0
- package/dist/components/input/snice-input.js +603 -0
- package/dist/components/input/snice-input.js.map +1 -0
- package/dist/components/input/snice-input.types.d.ts +53 -0
- package/dist/components/input/snice-input.types.js +2 -0
- package/dist/components/input/snice-input.types.js.map +1 -0
- package/dist/components/layout/snice-layout-blog.d.ts +4 -0
- package/dist/components/layout/snice-layout-blog.js +56 -0
- package/dist/components/layout/snice-layout-blog.js.map +1 -0
- package/dist/components/layout/snice-layout-card.d.ts +6 -0
- package/dist/components/layout/snice-layout-card.js +53 -0
- package/dist/components/layout/snice-layout-card.js.map +1 -0
- package/dist/components/layout/snice-layout-centered.d.ts +5 -0
- package/dist/components/layout/snice-layout-centered.js +38 -0
- package/dist/components/layout/snice-layout-centered.js.map +1 -0
- package/dist/components/layout/snice-layout-dashboard.d.ts +4 -0
- package/dist/components/layout/snice-layout-dashboard.js +53 -0
- package/dist/components/layout/snice-layout-dashboard.js.map +1 -0
- package/dist/components/layout/snice-layout-fullscreen.d.ts +5 -0
- package/dist/components/layout/snice-layout-fullscreen.js +50 -0
- package/dist/components/layout/snice-layout-fullscreen.js.map +1 -0
- package/dist/components/layout/snice-layout-landing.d.ts +4 -0
- package/dist/components/layout/snice-layout-landing.js +55 -0
- package/dist/components/layout/snice-layout-landing.js.map +1 -0
- package/dist/components/layout/snice-layout-minimal.d.ts +4 -0
- package/dist/components/layout/snice-layout-minimal.js +27 -0
- package/dist/components/layout/snice-layout-minimal.js.map +1 -0
- package/dist/components/layout/snice-layout-sidebar.d.ts +5 -0
- package/dist/components/layout/snice-layout-sidebar.js +64 -0
- package/dist/components/layout/snice-layout-sidebar.js.map +1 -0
- package/dist/components/layout/snice-layout-split.d.ts +6 -0
- package/dist/components/layout/snice-layout-split.js +47 -0
- package/dist/components/layout/snice-layout-split.js.map +1 -0
- package/dist/components/layout/snice-layout.d.ts +4 -0
- package/dist/components/layout/snice-layout.js +43 -0
- package/dist/components/layout/snice-layout.js.map +1 -0
- package/dist/components/layout/snice-layout.types.d.ts +3 -0
- package/dist/components/layout/snice-layout.types.js +2 -0
- package/dist/components/layout/snice-layout.types.js.map +1 -0
- package/dist/components/login/snice-login.d.ts +45 -0
- package/dist/components/login/snice-login.js +385 -0
- package/dist/components/login/snice-login.js.map +1 -0
- package/dist/components/login/snice-login.types.d.ts +31 -0
- package/dist/components/login/snice-login.types.js +2 -0
- package/dist/components/login/snice-login.types.js.map +1 -0
- package/dist/components/modal/snice-modal.d.ts +32 -0
- package/dist/components/modal/snice-modal.js +288 -0
- package/dist/components/modal/snice-modal.js.map +1 -0
- package/dist/components/modal/snice-modal.types.d.ts +18 -0
- package/dist/components/modal/snice-modal.types.js +2 -0
- package/dist/components/modal/snice-modal.types.js.map +1 -0
- package/dist/components/pagination/snice-pagination.d.ts +26 -0
- package/dist/components/pagination/snice-pagination.js +373 -0
- package/dist/components/pagination/snice-pagination.js.map +1 -0
- package/dist/components/pagination/snice-pagination.types.d.ts +18 -0
- package/dist/components/pagination/snice-pagination.types.js +2 -0
- package/dist/components/pagination/snice-pagination.types.js.map +1 -0
- package/dist/components/progress/snice-progress.d.ts +35 -0
- package/dist/components/progress/snice-progress.js +295 -0
- package/dist/components/progress/snice-progress.js.map +1 -0
- package/dist/components/progress/snice-progress.types.d.ts +18 -0
- package/dist/components/progress/snice-progress.types.js +2 -0
- package/dist/components/progress/snice-progress.types.js.map +1 -0
- package/dist/components/radio/snice-radio.d.ts +33 -0
- package/dist/components/radio/snice-radio.js +286 -0
- package/dist/components/radio/snice-radio.js.map +1 -0
- package/dist/components/radio/snice-radio.types.d.ts +19 -0
- package/dist/components/radio/snice-radio.types.js +2 -0
- package/dist/components/radio/snice-radio.types.js.map +1 -0
- package/dist/components/select/snice-option.d.ts +17 -0
- package/dist/components/select/snice-option.js +77 -0
- package/dist/components/select/snice-option.js.map +1 -0
- package/dist/components/select/snice-option.types.d.ts +14 -0
- package/dist/components/select/snice-option.types.js +2 -0
- package/dist/components/select/snice-option.types.js.map +1 -0
- package/dist/components/select/snice-select.d.ts +89 -0
- package/dist/components/select/snice-select.js +900 -0
- package/dist/components/select/snice-select.js.map +1 -0
- package/dist/components/select/snice-select.types.d.ts +49 -0
- package/dist/components/select/snice-select.types.js +2 -0
- package/dist/components/select/snice-select.types.js.map +1 -0
- package/dist/components/skeleton/snice-skeleton.d.ts +16 -0
- package/dist/components/skeleton/snice-skeleton.js +159 -0
- package/dist/components/skeleton/snice-skeleton.js.map +1 -0
- package/dist/components/skeleton/snice-skeleton.types.d.ts +10 -0
- package/dist/components/skeleton/snice-skeleton.types.js +2 -0
- package/dist/components/skeleton/snice-skeleton.types.js.map +1 -0
- package/dist/components/switch/snice-switch.d.ts +38 -0
- package/dist/components/switch/snice-switch.js +309 -0
- package/dist/components/switch/snice-switch.js.map +1 -0
- package/dist/components/switch/snice-switch.types.d.ts +21 -0
- package/dist/components/switch/snice-switch.types.js +2 -0
- package/dist/components/switch/snice-switch.types.js.map +1 -0
- package/dist/components/symbols.d.ts +1 -0
- package/dist/components/symbols.js +20 -0
- package/dist/components/symbols.js.map +1 -0
- package/dist/components/table/snice-cell-boolean.d.ts +21 -0
- package/dist/components/table/snice-cell-boolean.js +152 -0
- package/dist/components/table/snice-cell-boolean.js.map +1 -0
- package/dist/components/table/snice-cell-date.d.ts +24 -0
- package/dist/components/table/snice-cell-date.js +240 -0
- package/dist/components/table/snice-cell-date.js.map +1 -0
- package/dist/components/table/snice-cell-duration.d.ts +16 -0
- package/dist/components/table/snice-cell-duration.js +123 -0
- package/dist/components/table/snice-cell-duration.js.map +1 -0
- package/dist/components/table/snice-cell-filesize.d.ts +16 -0
- package/dist/components/table/snice-cell-filesize.js +119 -0
- package/dist/components/table/snice-cell-filesize.js.map +1 -0
- package/dist/components/table/snice-cell-number.d.ts +23 -0
- package/dist/components/table/snice-cell-number.js +202 -0
- package/dist/components/table/snice-cell-number.js.map +1 -0
- package/dist/components/table/snice-cell-progress.d.ts +17 -0
- package/dist/components/table/snice-cell-progress.js +114 -0
- package/dist/components/table/snice-cell-progress.js.map +1 -0
- package/dist/components/table/snice-cell-rating.d.ts +17 -0
- package/dist/components/table/snice-cell-rating.js +113 -0
- package/dist/components/table/snice-cell-rating.js.map +1 -0
- package/dist/components/table/snice-cell-sparkline.d.ts +29 -0
- package/dist/components/table/snice-cell-sparkline.js +290 -0
- package/dist/components/table/snice-cell-sparkline.js.map +1 -0
- package/dist/components/table/snice-cell-text.d.ts +19 -0
- package/dist/components/table/snice-cell-text.js +153 -0
- package/dist/components/table/snice-cell-text.js.map +1 -0
- package/dist/components/table/snice-cell.d.ts +32 -0
- package/dist/components/table/snice-cell.js +451 -0
- package/dist/components/table/snice-cell.js.map +1 -0
- package/dist/components/table/snice-column.d.ts +62 -0
- package/dist/components/table/snice-column.js +440 -0
- package/dist/components/table/snice-column.js.map +1 -0
- package/dist/components/table/snice-header.d.ts +33 -0
- package/dist/components/table/snice-header.js +303 -0
- package/dist/components/table/snice-header.js.map +1 -0
- package/dist/components/table/snice-progress.d.ts +10 -0
- package/dist/components/table/snice-progress.js +91 -0
- package/dist/components/table/snice-progress.js.map +1 -0
- package/dist/components/table/snice-rating.d.ts +9 -0
- package/dist/components/table/snice-rating.js +68 -0
- package/dist/components/table/snice-rating.js.map +1 -0
- package/dist/components/table/snice-row.d.ts +43 -0
- package/dist/components/table/snice-row.js +365 -0
- package/dist/components/table/snice-row.js.map +1 -0
- package/dist/components/table/snice-table.d.ts +69 -0
- package/dist/components/table/snice-table.js +814 -0
- package/dist/components/table/snice-table.js.map +1 -0
- package/dist/components/table/snice-table.types.d.ts +137 -0
- package/dist/components/table/snice-table.types.js +2 -0
- package/dist/components/table/snice-table.types.js.map +1 -0
- package/dist/components/tabs/snice-tab-panel.d.ts +12 -0
- package/dist/components/tabs/snice-tab-panel.js +78 -0
- package/dist/components/tabs/snice-tab-panel.js.map +1 -0
- package/dist/components/tabs/snice-tab.d.ts +13 -0
- package/dist/components/tabs/snice-tab.js +90 -0
- package/dist/components/tabs/snice-tab.js.map +1 -0
- package/dist/components/tabs/snice-tabs.d.ts +34 -0
- package/dist/components/tabs/snice-tabs.js +367 -0
- package/dist/components/tabs/snice-tabs.js.map +1 -0
- package/dist/components/tabs/snice-tabs.types.d.ts +23 -0
- package/dist/components/tabs/snice-tabs.types.js +2 -0
- package/dist/components/tabs/snice-tabs.types.js.map +1 -0
- package/dist/components/toast/snice-toast-container.d.ts +25 -0
- package/dist/components/toast/snice-toast-container.js +251 -0
- package/dist/components/toast/snice-toast-container.js.map +1 -0
- package/dist/components/toast/snice-toast.d.ts +23 -0
- package/dist/components/toast/snice-toast.js +316 -0
- package/dist/components/toast/snice-toast.js.map +1 -0
- package/dist/components/toast/snice-toast.types.d.ts +30 -0
- package/dist/components/toast/snice-toast.types.js +2 -0
- package/dist/components/toast/snice-toast.types.js.map +1 -0
- package/dist/components/tooltip/snice-tooltip.d.ts +50 -0
- package/dist/components/tooltip/snice-tooltip.js +656 -0
- package/dist/components/tooltip/snice-tooltip.js.map +1 -0
- package/dist/components/tooltip/snice-tooltip.types.d.ts +18 -0
- package/dist/components/tooltip/snice-tooltip.types.js +2 -0
- package/dist/components/tooltip/snice-tooltip.types.js.map +1 -0
- package/dist/components/transitions.d.ts +11 -0
- package/dist/components/transitions.js +69 -0
- package/dist/components/transitions.js.map +1 -0
- package/dist/src/controller.d.ts +61 -0
- package/dist/src/controller.js +297 -0
- package/dist/src/controller.js.map +1 -0
- package/dist/src/element.d.ts +77 -0
- package/dist/src/element.js +805 -0
- package/dist/src/element.js.map +1 -0
- package/dist/src/events.d.ts +37 -0
- package/dist/src/events.js +289 -0
- package/dist/src/events.js.map +1 -0
- package/dist/src/global.d.ts +7 -0
- package/dist/src/global.js +23 -0
- package/dist/src/global.js.map +1 -0
- package/{src/index.ts → dist/src/index.d.ts} +1 -1
- package/dist/src/index.js +8 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/observe.d.ts +26 -0
- package/dist/src/observe.js +329 -0
- package/dist/src/observe.js.map +1 -0
- package/dist/src/request-response.d.ts +46 -0
- package/dist/src/request-response.js +267 -0
- package/dist/src/request-response.js.map +1 -0
- package/dist/src/router.d.ts +87 -0
- package/dist/src/router.js +375 -0
- package/dist/src/router.js.map +1 -0
- package/dist/src/symbols.d.ts +29 -0
- package/{src/symbols.ts → dist/src/symbols.js} +2 -12
- package/dist/src/symbols.js.map +1 -0
- package/dist/src/transitions.d.ts +50 -0
- package/dist/src/transitions.js +199 -0
- package/dist/src/transitions.js.map +1 -0
- package/package.json +6 -8
- package/src/controller.ts +0 -347
- package/src/element.ts +0 -897
- package/src/events.ts +0 -349
- package/src/global.ts +0 -31
- package/src/observe.ts +0 -414
- package/src/request-response.ts +0 -336
- package/src/router.ts +0 -552
- package/src/transitions.ts +0 -264
package/src/router.ts
DELETED
|
@@ -1,552 +0,0 @@
|
|
|
1
|
-
import Route from 'route-parser';
|
|
2
|
-
import { applyElementFunctionality } from './element';
|
|
3
|
-
import { ROUTER_CONTEXT, CONTEXT_REQUEST_HANDLER, PAGE_TRANSITION, CREATED_AT } from './symbols';
|
|
4
|
-
import { Transition, performTransition as performTransitionUtil } from './transitions';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Route parameters extracted from the URL
|
|
8
|
-
*/
|
|
9
|
-
export type RouteParams = Record<string, string>;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Possible outcomes from route resolution
|
|
13
|
-
*/
|
|
14
|
-
enum RouteResult {
|
|
15
|
-
SUCCESS = 'success',
|
|
16
|
-
GUARDS_FAILED = 'guards-failed',
|
|
17
|
-
NOT_FOUND = 'not-found'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Guard function that determines if navigation is allowed
|
|
22
|
-
* @param context The application context
|
|
23
|
-
* @param params The URL parameters from the route
|
|
24
|
-
*/
|
|
25
|
-
export type Guard<T = any> = (context: T, params: RouteParams) => boolean | Promise<boolean>;
|
|
26
|
-
|
|
27
|
-
export interface RouterOptions {
|
|
28
|
-
/**
|
|
29
|
-
* The target element selector where the page element will be instantiated.
|
|
30
|
-
* The router will use this selector to find the target element, clear it, and append the page element to it.
|
|
31
|
-
*/
|
|
32
|
-
target: string;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Whether to use hash routing or push state routing.
|
|
36
|
-
*/
|
|
37
|
-
type: 'hash' | 'pushstate';
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Override for the window object to use for routing, defaults to global.
|
|
41
|
-
*/
|
|
42
|
-
window?: Window;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Override for the document object to use for routing, defaults to global.
|
|
46
|
-
*/
|
|
47
|
-
document?: Document;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Global transition configuration for all pages
|
|
51
|
-
*/
|
|
52
|
-
transition?: Transition;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Optional context object passed to guard functions
|
|
56
|
-
*/
|
|
57
|
-
context?: any;
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Default layout element tag name for all pages
|
|
61
|
-
*/
|
|
62
|
-
layout?: string;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface PageOptions {
|
|
66
|
-
/**
|
|
67
|
-
* The tag name of the custom element.
|
|
68
|
-
* @example { tag: 'login-page' }
|
|
69
|
-
* // for <login-page></login-page>
|
|
70
|
-
*/
|
|
71
|
-
tag: string;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* The routes that will trigger the page element.
|
|
75
|
-
* @example { routes: ['/login', '/login/:id'] }
|
|
76
|
-
*/
|
|
77
|
-
routes: string[];
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Optional per-page transition override
|
|
81
|
-
*/
|
|
82
|
-
transition?: Transition;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Guard functions that must pass for navigation to proceed.
|
|
86
|
-
* Can be a single guard or an array of guards (all must pass).
|
|
87
|
-
*/
|
|
88
|
-
guards?: Guard<any> | Guard<any>[];
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Layout element tag name for this page.
|
|
92
|
-
* Use false to explicitly disable layout for this page.
|
|
93
|
-
*/
|
|
94
|
-
layout?: string | false;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Router return type
|
|
99
|
-
*/
|
|
100
|
-
export interface RouterInstance {
|
|
101
|
-
page: (pageOptions: PageOptions) => <C extends { new(...args: any[]): HTMLElement }>(constructor: C) => void;
|
|
102
|
-
initialize: () => void;
|
|
103
|
-
navigate: (path: string) => Promise<void>;
|
|
104
|
-
register: (route: string, tag: string, transition?: Transition, guards?: Guard<any> | Guard<any>[]) => void;
|
|
105
|
-
context: any;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Creates a new router instance.
|
|
110
|
-
* @param {RouterOptions} options - The router configuration options.
|
|
111
|
-
* @returns An object containing the router's API methods.
|
|
112
|
-
*/
|
|
113
|
-
export function Router(options: RouterOptions): RouterInstance {
|
|
114
|
-
const routes: { route: Route, tag: string, transition?: Transition, guards?: Guard<any> | Guard<any>[], layout?: string | false }[] = [];
|
|
115
|
-
let is_sorted = false;
|
|
116
|
-
|
|
117
|
-
let _404: string; // the 404 page
|
|
118
|
-
let _403: string; // the 403 forbidden page
|
|
119
|
-
let home: string; // the home page
|
|
120
|
-
let currentLayoutName: string | null = null; // Track current layout name
|
|
121
|
-
let currentLayoutTimestamp: number | null = null; // Track current layout timestamp
|
|
122
|
-
const context = options.context || {}; // Store context for guards
|
|
123
|
-
|
|
124
|
-
function getCurrentLayoutElement(target: Element): HTMLElement | null {
|
|
125
|
-
const noCurrentLayout = !currentLayoutName || !currentLayoutTimestamp;
|
|
126
|
-
if (noCurrentLayout) {
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const layoutElements = target.querySelectorAll(currentLayoutName!) as NodeListOf<HTMLElement>;
|
|
131
|
-
|
|
132
|
-
for (const element of layoutElements) {
|
|
133
|
-
const hasTimestamp = (element as any)[CREATED_AT] === currentLayoutTimestamp;
|
|
134
|
-
if (hasTimestamp) {
|
|
135
|
-
return element;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Decorator function for defining a page with associated routes.
|
|
144
|
-
* @param {PageOptions} pageOptions - The page configuration options.
|
|
145
|
-
* @returns A decorator function to apply to a custom element class.
|
|
146
|
-
*/
|
|
147
|
-
function page(pageOptions: PageOptions) {
|
|
148
|
-
return function <C extends { new(...args: any[]): HTMLElement }>(constructor: C) {
|
|
149
|
-
// Apply all element functionality (properties, queries, watchers, controllers, etc.)
|
|
150
|
-
applyElementFunctionality(constructor);
|
|
151
|
-
|
|
152
|
-
// Store transition config on constructor for later use
|
|
153
|
-
(constructor as any)[PAGE_TRANSITION] = pageOptions.transition;
|
|
154
|
-
|
|
155
|
-
// Extend the connectedCallback to add router-specific functionality
|
|
156
|
-
const elementConnectedCallback = constructor.prototype.connectedCallback;
|
|
157
|
-
constructor.prototype.connectedCallback = function() {
|
|
158
|
-
// Call the element's connectedCallback first
|
|
159
|
-
elementConnectedCallback?.call(this);
|
|
160
|
-
|
|
161
|
-
// Setup context request handler for nested elements
|
|
162
|
-
const contextRequestHandler = (event: any) => {
|
|
163
|
-
// Only respond if this element has context
|
|
164
|
-
if (this[ROUTER_CONTEXT] !== undefined) {
|
|
165
|
-
event.detail.context = this[ROUTER_CONTEXT];
|
|
166
|
-
event.stopPropagation(); // Stop bubbling once context is provided
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
this.addEventListener('@context/request', contextRequestHandler);
|
|
170
|
-
|
|
171
|
-
// Store handler for cleanup
|
|
172
|
-
(this as any)[CONTEXT_REQUEST_HANDLER] = contextRequestHandler;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// Extend the disconnectedCallback to clean up router-specific stuff
|
|
176
|
-
const elementDisconnectedCallback = constructor.prototype.disconnectedCallback;
|
|
177
|
-
constructor.prototype.disconnectedCallback = function() {
|
|
178
|
-
// Call element's disconnectedCallback first
|
|
179
|
-
elementDisconnectedCallback?.call(this);
|
|
180
|
-
|
|
181
|
-
// Clean up context request handler
|
|
182
|
-
const handler = (this as any)[CONTEXT_REQUEST_HANDLER];
|
|
183
|
-
if (handler) {
|
|
184
|
-
this.removeEventListener('@context/request', handler);
|
|
185
|
-
delete (this as any)[CONTEXT_REQUEST_HANDLER];
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Clean up context reference
|
|
189
|
-
delete (this as any)[ROUTER_CONTEXT];
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
// Define the custom element
|
|
193
|
-
customElements.define(pageOptions.tag, constructor);
|
|
194
|
-
|
|
195
|
-
// Register the routes with guards and layout
|
|
196
|
-
pageOptions.routes.forEach(route => register(route, pageOptions.tag, pageOptions.transition, pageOptions.guards, pageOptions.layout));
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Registers a new route with the router.
|
|
202
|
-
* @param {string} route - The route path.
|
|
203
|
-
* @param {string} tag - The custom element tag associated with the route.
|
|
204
|
-
* @example
|
|
205
|
-
* register('/custom-route', 'custom-element');
|
|
206
|
-
*/
|
|
207
|
-
function register(route: string, tag: string, transition?: Transition, guards?: Guard<any> | Guard<any>[], layout?: string | false): void {
|
|
208
|
-
routes.push({ route: new Route(route), tag, transition, guards, layout });
|
|
209
|
-
is_sorted = false;
|
|
210
|
-
|
|
211
|
-
if (route === '/404') {
|
|
212
|
-
_404 = tag;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (route === '/403') {
|
|
216
|
-
_403 = tag;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (route === '/') {
|
|
220
|
-
home = tag;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function setupEventListeners(): void {
|
|
225
|
-
const isHashType = options.type === 'hash';
|
|
226
|
-
const isPushStateType = options.type === 'pushstate';
|
|
227
|
-
|
|
228
|
-
if (isHashType) {
|
|
229
|
-
window.addEventListener('hashchange', () => {
|
|
230
|
-
const targetExists = !!document.querySelector(options.target);
|
|
231
|
-
if (!targetExists) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const path = getPath();
|
|
236
|
-
navigate(path);
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (isPushStateType) {
|
|
241
|
-
window.addEventListener('popstate', () => {
|
|
242
|
-
const targetExists = !!document.querySelector(options.target);
|
|
243
|
-
if (!targetExists) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const path = getPath();
|
|
248
|
-
navigate(path);
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Initializes the router and sets up navigation event listeners.
|
|
255
|
-
* @example
|
|
256
|
-
* initialize();
|
|
257
|
-
*/
|
|
258
|
-
function initialize(): void {
|
|
259
|
-
const targetExists = !!document.querySelector(options.target);
|
|
260
|
-
if (!targetExists) {
|
|
261
|
-
throw new Error(`Target element not found: ${options.target}`);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const needsSorting = !is_sorted;
|
|
265
|
-
if (needsSorting) {
|
|
266
|
-
routes.sort((a: any, b: any) => b.route.spec.length - a.route.spec.length);
|
|
267
|
-
is_sorted = true;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
setupEventListeners();
|
|
271
|
-
|
|
272
|
-
const path = getPath();
|
|
273
|
-
navigate(path);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function getPath(): string {
|
|
277
|
-
switch (options.type) {
|
|
278
|
-
case 'hash':
|
|
279
|
-
return window.location.hash.slice(1);
|
|
280
|
-
case 'pushstate':
|
|
281
|
-
return window.location.pathname;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
async function renderForbiddenPage(target: Element): Promise<void> {
|
|
286
|
-
let newPageElement: HTMLElement;
|
|
287
|
-
const has403Page = !!_403;
|
|
288
|
-
|
|
289
|
-
if (has403Page) {
|
|
290
|
-
newPageElement = document.createElement(_403);
|
|
291
|
-
(newPageElement as any)[ROUTER_CONTEXT] = context;
|
|
292
|
-
}
|
|
293
|
-
if (!has403Page) {
|
|
294
|
-
const div = document.createElement('div');
|
|
295
|
-
div.className = 'default-403';
|
|
296
|
-
div.innerHTML = /*html*/`<h1>403</h1><p>Unauthorized</p>`;
|
|
297
|
-
newPageElement = div;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
target.innerHTML = '';
|
|
301
|
-
target.appendChild(newPageElement!);
|
|
302
|
-
currentLayoutName = null;
|
|
303
|
-
currentLayoutTimestamp = null;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
async function checkGuards(guards: Guard<any> | Guard<any>[] | undefined, params: RouteParams, target: Element): Promise<boolean> {
|
|
307
|
-
const hasGuards = !!guards;
|
|
308
|
-
if (!hasGuards) {
|
|
309
|
-
return true;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const guardsArray = Array.isArray(guards) ? guards : [guards];
|
|
313
|
-
for (const guard of guardsArray) {
|
|
314
|
-
const allowed = await guard(context, params);
|
|
315
|
-
if (!allowed) {
|
|
316
|
-
await renderForbiddenPage(target);
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
return true;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
function createHomeElement(): { element: HTMLElement; transition?: Transition; layout?: string | false } {
|
|
324
|
-
const newPageElement = document.createElement(home);
|
|
325
|
-
(newPageElement as any)[ROUTER_CONTEXT] = context;
|
|
326
|
-
const constructor = customElements.get(home);
|
|
327
|
-
const transition = (constructor as any)?.[PAGE_TRANSITION];
|
|
328
|
-
|
|
329
|
-
const homeRoute = routes.find(r => r.route.match('/'));
|
|
330
|
-
return { element: newPageElement, transition, layout: homeRoute?.layout };
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
function create404Element(): { element: HTMLElement; transition?: Transition; layout?: string | false } {
|
|
334
|
-
const has404Page = !!_404;
|
|
335
|
-
|
|
336
|
-
if (has404Page) {
|
|
337
|
-
const newPageElement = document.createElement(_404);
|
|
338
|
-
(newPageElement as any)[ROUTER_CONTEXT] = context;
|
|
339
|
-
const constructor = customElements.get(_404);
|
|
340
|
-
const transition = (constructor as any)?.[PAGE_TRANSITION];
|
|
341
|
-
return { element: newPageElement, transition, layout: undefined };
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
const div = document.createElement('div');
|
|
345
|
-
div.className = 'default-404';
|
|
346
|
-
div.innerHTML = /*html*/`<h1>404</h1><p>Page not found</p>`;
|
|
347
|
-
return { element: div, transition: undefined, layout: undefined };
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
async function resolveRoute(path: string, target: Element): Promise<{ result: RouteResult; element?: HTMLElement; transition?: Transition; layout?: string | false }> {
|
|
351
|
-
for (const route of routes) {
|
|
352
|
-
const params = route.route.match(path);
|
|
353
|
-
const isMatch = params !== false;
|
|
354
|
-
if (!isMatch) {
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
const guardsAllowed = await checkGuards(route.guards, params as RouteParams, target);
|
|
359
|
-
if (!guardsAllowed) {
|
|
360
|
-
return { result: RouteResult.GUARDS_FAILED };
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const newPageElement = document.createElement(route.tag);
|
|
364
|
-
(newPageElement as any)[ROUTER_CONTEXT] = context;
|
|
365
|
-
const routeParams = params as RouteParams;
|
|
366
|
-
Object.keys(routeParams).forEach(key => newPageElement.setAttribute(key, routeParams[key]));
|
|
367
|
-
|
|
368
|
-
return { result: RouteResult.SUCCESS, element: newPageElement, transition: route.transition, layout: route.layout };
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return { result: RouteResult.NOT_FOUND };
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
function determineLayout(pageLayout: string | false | undefined): string | null {
|
|
375
|
-
const isExplicitlyNoLayout = pageLayout === false;
|
|
376
|
-
if (isExplicitlyNoLayout) {
|
|
377
|
-
return null;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
const hasPageLayout = !!pageLayout;
|
|
381
|
-
if (hasPageLayout) {
|
|
382
|
-
return pageLayout;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
const hasRouterLayout = !!options.layout;
|
|
386
|
-
if (hasRouterLayout) {
|
|
387
|
-
return options.layout!;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
return null;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function setupLayout(layoutToUse: string | null): { element: HTMLElement | null; needsNewLayout: boolean } {
|
|
394
|
-
const needsNewLayout = layoutToUse !== currentLayoutName;
|
|
395
|
-
if (!needsNewLayout) {
|
|
396
|
-
return { element: null, needsNewLayout: false };
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
currentLayoutName = layoutToUse;
|
|
400
|
-
|
|
401
|
-
const shouldCreateLayout = !!layoutToUse;
|
|
402
|
-
if (shouldCreateLayout) {
|
|
403
|
-
const timestamp = Date.now();
|
|
404
|
-
currentLayoutTimestamp = timestamp;
|
|
405
|
-
|
|
406
|
-
const layoutElement = document.createElement(layoutToUse);
|
|
407
|
-
(layoutElement as any)[ROUTER_CONTEXT] = context;
|
|
408
|
-
(layoutElement as any)[CREATED_AT] = timestamp;
|
|
409
|
-
|
|
410
|
-
return { element: layoutElement, needsNewLayout: true };
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
currentLayoutTimestamp = null;
|
|
414
|
-
return { element: null, needsNewLayout: true };
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
async function renderWithLayout(target: Element, pageElement: HTMLElement, transition: Transition | undefined, layoutElement: HTMLElement | null, needsNewLayout: boolean): Promise<void> {
|
|
418
|
-
const currentLayout = layoutElement || getCurrentLayoutElement(target);
|
|
419
|
-
if (!currentLayout) {
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
const oldPageInLayout = currentLayout.querySelector('[slot="page"]') as HTMLElement | null;
|
|
424
|
-
const shouldTransition = !!(transition && oldPageInLayout);
|
|
425
|
-
|
|
426
|
-
if (shouldTransition) {
|
|
427
|
-
pageElement.setAttribute('slot', 'page');
|
|
428
|
-
await performTransition(currentLayout, oldPageInLayout!, pageElement, transition!);
|
|
429
|
-
if (needsNewLayout) {
|
|
430
|
-
target.innerHTML = '';
|
|
431
|
-
target.appendChild(currentLayout);
|
|
432
|
-
}
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
const existingPages = currentLayout.querySelectorAll('[slot="page"]');
|
|
437
|
-
existingPages.forEach(page => page.remove());
|
|
438
|
-
pageElement.setAttribute('slot', 'page');
|
|
439
|
-
currentLayout.appendChild(pageElement);
|
|
440
|
-
|
|
441
|
-
if (needsNewLayout) {
|
|
442
|
-
target.innerHTML = '';
|
|
443
|
-
target.appendChild(currentLayout);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
async function renderDirect(target: Element, pageElement: HTMLElement, transition: Transition | undefined): Promise<void> {
|
|
448
|
-
const currentElementInTarget = target.children[0] as HTMLElement | null;
|
|
449
|
-
const shouldTransition = !!(transition && currentElementInTarget);
|
|
450
|
-
|
|
451
|
-
if (shouldTransition) {
|
|
452
|
-
await performTransition(target, currentElementInTarget!, pageElement, transition!);
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
target.innerHTML = '';
|
|
457
|
-
target.appendChild(pageElement);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* Navigates to the specified path.
|
|
462
|
-
* @param {string} path - The path to navigate to.
|
|
463
|
-
* @example
|
|
464
|
-
* navigate('/login');
|
|
465
|
-
*/
|
|
466
|
-
async function navigate(path: string): Promise<void> {
|
|
467
|
-
const target = document.querySelector(options.target);
|
|
468
|
-
if (!target) {
|
|
469
|
-
throw new Error(`Target element not found: ${options.target}`);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
window.scrollTo(0, 0);
|
|
473
|
-
|
|
474
|
-
const isHomePath = (path.trim() === '' || path === '/') && !!home;
|
|
475
|
-
|
|
476
|
-
if (isHomePath) {
|
|
477
|
-
const homeRoute = routes.find(r => r.route.match('/'));
|
|
478
|
-
const guardsAllowed = await checkGuards(homeRoute?.guards, {}, target);
|
|
479
|
-
if (!guardsAllowed) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
const { element, transition, layout } = createHomeElement();
|
|
484
|
-
const layoutToUse = determineLayout(layout);
|
|
485
|
-
const { element: layoutElement, needsNewLayout } = setupLayout(layoutToUse);
|
|
486
|
-
const finalTransition = transition || options.transition;
|
|
487
|
-
|
|
488
|
-
const hasLayout = layoutElement !== null || getCurrentLayoutElement(target) !== null;
|
|
489
|
-
if (hasLayout) {
|
|
490
|
-
await renderWithLayout(target, element, finalTransition, layoutElement, needsNewLayout);
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
await renderDirect(target, element, finalTransition);
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
const routeResult = await resolveRoute(path, target);
|
|
499
|
-
|
|
500
|
-
const isGuardsFailed = routeResult.result === RouteResult.GUARDS_FAILED;
|
|
501
|
-
if (isGuardsFailed) {
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
const isSuccess = routeResult.result === RouteResult.SUCCESS;
|
|
506
|
-
if (isSuccess) {
|
|
507
|
-
const { element, transition, layout } = routeResult;
|
|
508
|
-
const layoutToUse = determineLayout(layout);
|
|
509
|
-
const { element: layoutElement, needsNewLayout } = setupLayout(layoutToUse);
|
|
510
|
-
const finalTransition = transition || options.transition;
|
|
511
|
-
|
|
512
|
-
const hasLayout = layoutElement !== null || getCurrentLayoutElement(target) !== null;
|
|
513
|
-
if (hasLayout) {
|
|
514
|
-
await renderWithLayout(target, element!, finalTransition, layoutElement, needsNewLayout);
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
await renderDirect(target, element!, finalTransition);
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
const { element, transition, layout } = create404Element();
|
|
523
|
-
const layoutToUse = determineLayout(layout);
|
|
524
|
-
const { element: layoutElement, needsNewLayout } = setupLayout(layoutToUse);
|
|
525
|
-
const finalTransition = transition || options.transition;
|
|
526
|
-
|
|
527
|
-
const hasLayout = layoutElement !== null || getCurrentLayoutElement(target) !== null;
|
|
528
|
-
if (hasLayout) {
|
|
529
|
-
await renderWithLayout(target, element, finalTransition, layoutElement, needsNewLayout);
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
await renderDirect(target, element, finalTransition);
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
async function performTransition(
|
|
537
|
-
container: Element,
|
|
538
|
-
oldElement: HTMLElement,
|
|
539
|
-
newElement: HTMLElement,
|
|
540
|
-
transition: Transition
|
|
541
|
-
): Promise<void> {
|
|
542
|
-
return performTransitionUtil(container, oldElement, newElement, transition);
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
return {
|
|
546
|
-
page,
|
|
547
|
-
initialize,
|
|
548
|
-
navigate,
|
|
549
|
-
register,
|
|
550
|
-
context,
|
|
551
|
-
};
|
|
552
|
-
}
|