@sondor-technology/sondor-components 1.0.2 → 1.0.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/dist/components/checkbox/checkbox.d.ts +3 -0
- package/dist/components/checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox/checkbox.js +38 -20
- package/dist/components/form/form-step.d.ts +1 -0
- package/dist/components/form/form-step.d.ts.map +1 -1
- package/dist/components/form/form-step.js +3 -0
- package/dist/components/form/form.d.ts +7 -2
- package/dist/components/form/form.d.ts.map +1 -1
- package/dist/components/form/form.js +157 -59
- package/dist/components/icon/icon-paths.d.ts +16 -0
- package/dist/components/icon/icon-paths.d.ts.map +1 -1
- package/dist/components/icon/icon-paths.js +16 -0
- package/dist/components/icon/icon.d.ts +2 -1
- package/dist/components/icon/icon.d.ts.map +1 -1
- package/dist/components/modal/modal.d.ts +11 -0
- package/dist/components/modal/modal.d.ts.map +1 -1
- package/dist/components/modal/modal.js +103 -15
- package/dist/components/router/router.d.ts +27 -3
- package/dist/components/router/router.d.ts.map +1 -1
- package/dist/components/router/router.js +72 -12
- package/dist/components/skeleton/skeleton.d.ts +2 -3
- package/dist/components/skeleton/skeleton.d.ts.map +1 -1
- package/dist/components/skeleton/skeleton.js +89 -18
- package/dist/components/vertical-nav/vertical-nav-group.d.ts +6 -0
- package/dist/components/vertical-nav/vertical-nav-group.d.ts.map +1 -1
- package/dist/components/vertical-nav/vertical-nav-group.js +37 -21
- package/dist/components/vertical-nav/vertical-nav-item.d.ts +6 -0
- package/dist/components/vertical-nav/vertical-nav-item.d.ts.map +1 -1
- package/dist/components/vertical-nav/vertical-nav-item.js +27 -7
- package/package.json +5 -1
- package/src/components/checkbox/checkbox.ts +54 -26
- package/src/components/form/form-step.ts +5 -1
- package/src/components/form/form.ts +182 -66
- package/src/components/icon/icon-paths.ts +16 -0
- package/src/components/icon/icon.ts +3 -1
- package/src/components/modal/modal.ts +103 -15
- package/src/components/router/router.ts +99 -12
- package/src/components/skeleton/skeleton.ts +87 -20
- package/src/components/vertical-nav/vertical-nav-group.ts +40 -21
- package/src/components/vertical-nav/vertical-nav-item.ts +30 -7
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import { IconName } from './icon-paths.js';
|
|
3
|
+
export type IconVariant = 'outline' | 'solid';
|
|
3
4
|
export declare class StIcon extends LitElement {
|
|
4
5
|
name: IconName | string;
|
|
5
|
-
variant:
|
|
6
|
+
variant: IconVariant;
|
|
6
7
|
color: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info';
|
|
7
8
|
size: 'sm' | 'md' | 'lg' | 'xl';
|
|
8
9
|
static styles: import("lit").CSSResult[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../src/components/icon/icon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,EAAa,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGtD,qBACa,MAAO,SAAQ,UAAU;IACR,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAM;IAC7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../src/components/icon/icon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,EAAa,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGtD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;AAE9C,qBACa,MAAO,SAAQ,UAAU;IACR,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAM;IAC7B,OAAO,EAAE,WAAW,CAAa;IAGlB,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAa;IAGlG,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAElF,MAAM,CAAC,MAAM,4BAsCX;IAEF,MAAM,yCAmBL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
|
|
@@ -8,10 +8,21 @@ export declare class StModal extends LitElement {
|
|
|
8
8
|
* Title text displayed in the modal header.
|
|
9
9
|
*/
|
|
10
10
|
heading: string;
|
|
11
|
+
/**
|
|
12
|
+
* Size of the modal (sm, md, lg, xl, xxl).
|
|
13
|
+
*/
|
|
14
|
+
size: 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
|
|
15
|
+
/**
|
|
16
|
+
* If true, the modal cannot be closed by clicking the backdrop or pressing Esc.
|
|
17
|
+
*/
|
|
18
|
+
static: boolean;
|
|
11
19
|
private dialogEl;
|
|
20
|
+
private isClosing;
|
|
12
21
|
static styles: import("lit").CSSResult[];
|
|
13
22
|
updated(changedProperties: PropertyValues): void;
|
|
23
|
+
private closeWithAnimation;
|
|
14
24
|
private handleClose;
|
|
25
|
+
private handleCancel;
|
|
15
26
|
private onDialogClose;
|
|
16
27
|
private handleBackdropClick;
|
|
17
28
|
render(): import("lit-html").TemplateResult<1>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../../src/components/modal/modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,cAAc,
|
|
1
|
+
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../../src/components/modal/modal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,cAAc,EAAW,MAAM,KAAK,CAAC;AAIrE,qBACa,OAAQ,SAAQ,UAAU;IACrC;;OAEG;IACyC,IAAI,UAAS;IAEzD;;OAEG;IACyB,OAAO,SAAM;IAEzC;;OAEG;IACyB,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAQ;IAE3E;;OAEG;IAC0B,MAAM,UAAS;IAE3B,OAAO,CAAC,QAAQ,CAAqB;IAEtD,OAAO,CAAC,SAAS,CAAS;IAE1B,MAAM,CAAC,MAAM,4BAkHX;IAEF,OAAO,CAAC,iBAAiB,EAAE,cAAc,QAYxC;IAED,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,mBAAmB;IAe3B,MAAM,yCA4BL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAC;KACrB;CACF"}
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { LitElement, html, css } from 'lit';
|
|
7
|
+
import { LitElement, html, css, nothing } from 'lit';
|
|
8
8
|
import { customElement, property, query } from 'lit/decorators.js';
|
|
9
9
|
import { resetStyles } from '../../styles/reset.js';
|
|
10
10
|
let StModal = class StModal extends LitElement {
|
|
@@ -18,23 +18,55 @@ let StModal = class StModal extends LitElement {
|
|
|
18
18
|
* Title text displayed in the modal header.
|
|
19
19
|
*/
|
|
20
20
|
this.heading = '';
|
|
21
|
+
/**
|
|
22
|
+
* Size of the modal (sm, md, lg, xl, xxl).
|
|
23
|
+
*/
|
|
24
|
+
this.size = 'md';
|
|
25
|
+
/**
|
|
26
|
+
* If true, the modal cannot be closed by clicking the backdrop or pressing Esc.
|
|
27
|
+
*/
|
|
28
|
+
this.static = false;
|
|
29
|
+
this.isClosing = false;
|
|
21
30
|
}
|
|
22
31
|
updated(changedProperties) {
|
|
23
32
|
if (changedProperties.has('open')) {
|
|
24
|
-
if (this.
|
|
25
|
-
|
|
33
|
+
if (this.open) {
|
|
34
|
+
this.dialogEl.classList.remove('closing');
|
|
35
|
+
this.isClosing = false;
|
|
36
|
+
if (!this.dialogEl.open) {
|
|
26
37
|
this.dialogEl.showModal();
|
|
27
38
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
}
|
|
40
|
+
else if (this.dialogEl.open && !this.isClosing) {
|
|
41
|
+
this.closeWithAnimation();
|
|
31
42
|
}
|
|
32
43
|
}
|
|
33
44
|
}
|
|
45
|
+
closeWithAnimation() {
|
|
46
|
+
if (this.isClosing)
|
|
47
|
+
return;
|
|
48
|
+
this.isClosing = true;
|
|
49
|
+
this.dialogEl.classList.add('closing');
|
|
50
|
+
const onAnimationEnd = () => {
|
|
51
|
+
this.dialogEl.removeEventListener('animationend', onAnimationEnd);
|
|
52
|
+
this.dialogEl.classList.remove('closing');
|
|
53
|
+
this.isClosing = false;
|
|
54
|
+
if (!this.open) {
|
|
55
|
+
this.dialogEl.close();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
this.dialogEl.addEventListener('animationend', onAnimationEnd);
|
|
59
|
+
}
|
|
34
60
|
handleClose() {
|
|
35
61
|
this.open = false;
|
|
36
62
|
this.dispatchEvent(new CustomEvent('st-close', { bubbles: true, composed: true }));
|
|
37
63
|
}
|
|
64
|
+
handleCancel(e) {
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
if (!this.static) {
|
|
67
|
+
this.handleClose();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
38
70
|
onDialogClose() {
|
|
39
71
|
if (this.open) {
|
|
40
72
|
this.open = false;
|
|
@@ -42,28 +74,36 @@ let StModal = class StModal extends LitElement {
|
|
|
42
74
|
}
|
|
43
75
|
}
|
|
44
76
|
handleBackdropClick(e) {
|
|
77
|
+
if (this.static)
|
|
78
|
+
return;
|
|
45
79
|
const rect = this.dialogEl.getBoundingClientRect();
|
|
46
|
-
|
|
80
|
+
const clickedOutside = e.clientX < rect.left ||
|
|
47
81
|
e.clientX > rect.right ||
|
|
48
82
|
e.clientY < rect.top ||
|
|
49
|
-
e.clientY > rect.bottom
|
|
83
|
+
e.clientY > rect.bottom;
|
|
84
|
+
if (clickedOutside) {
|
|
50
85
|
this.handleClose();
|
|
51
86
|
}
|
|
52
87
|
}
|
|
53
88
|
render() {
|
|
54
89
|
return html `
|
|
55
90
|
<dialog
|
|
56
|
-
|
|
91
|
+
class="size-${this.size}"
|
|
92
|
+
aria-labelledby=${this.heading ? 'modal-heading' : nothing}
|
|
93
|
+
@cancel=${this.handleCancel}
|
|
57
94
|
@click=${this.handleBackdropClick}
|
|
58
95
|
@close=${this.onDialogClose}
|
|
59
96
|
>
|
|
60
97
|
<div class="modal-header" @click=${(e) => e.stopPropagation()}>
|
|
61
98
|
<slot name="header">
|
|
62
|
-
<h3 class="modal-title">${this.heading}</h3>
|
|
99
|
+
<h3 class="modal-title" id="modal-heading">${this.heading}</h3>
|
|
63
100
|
</slot>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
101
|
+
|
|
102
|
+
${!this.static ? html `
|
|
103
|
+
<button class="close-btn" @click=${this.handleClose} aria-label="Close modal">
|
|
104
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
|
105
|
+
</button>
|
|
106
|
+
` : nothing}
|
|
67
107
|
</div>
|
|
68
108
|
<div class="modal-body" @click=${(e) => e.stopPropagation()}>
|
|
69
109
|
<slot></slot>
|
|
@@ -88,17 +128,59 @@ StModal.styles = [
|
|
|
88
128
|
border-radius: var(--st-radius-lg, 0.5rem);
|
|
89
129
|
background-color: var(--st-color-surface);
|
|
90
130
|
color: var(--st-color-text);
|
|
91
|
-
|
|
92
|
-
|
|
131
|
+
|
|
132
|
+
/* Responsive width calculation */
|
|
133
|
+
width: calc(100% - 2rem);
|
|
134
|
+
margin: auto;
|
|
135
|
+
|
|
93
136
|
box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
|
94
137
|
font-family: var(--st-font-family, inherit);
|
|
95
138
|
}
|
|
96
139
|
|
|
140
|
+
/* Sizes */
|
|
141
|
+
dialog.size-sm { max-width: 400px; }
|
|
142
|
+
dialog.size-md { max-width: 500px; }
|
|
143
|
+
dialog.size-lg { max-width: 800px; }
|
|
144
|
+
dialog.size-xl { max-width: 1024px; }
|
|
145
|
+
dialog.size-xxl { max-width: 1280px; }
|
|
146
|
+
|
|
97
147
|
dialog::backdrop {
|
|
98
148
|
background-color: rgba(0, 0, 0, 0.5);
|
|
99
149
|
backdrop-filter: blur(2px);
|
|
100
150
|
}
|
|
101
151
|
|
|
152
|
+
/* Animations */
|
|
153
|
+
@keyframes fade-in {
|
|
154
|
+
from { opacity: 0; }
|
|
155
|
+
to { opacity: 1; }
|
|
156
|
+
}
|
|
157
|
+
@keyframes fade-out {
|
|
158
|
+
from { opacity: 1; }
|
|
159
|
+
to { opacity: 0; }
|
|
160
|
+
}
|
|
161
|
+
@keyframes slide-up {
|
|
162
|
+
from { opacity: 0; transform: translateY(20px) scale(0.95); }
|
|
163
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
164
|
+
}
|
|
165
|
+
@keyframes slide-down {
|
|
166
|
+
from { opacity: 1; transform: translateY(0) scale(1); }
|
|
167
|
+
to { opacity: 0; transform: translateY(20px) scale(0.95); }
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
dialog[open] {
|
|
171
|
+
animation: slide-up 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
172
|
+
}
|
|
173
|
+
dialog[open]::backdrop {
|
|
174
|
+
animation: fade-in 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
dialog.closing {
|
|
178
|
+
animation: slide-down 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
179
|
+
}
|
|
180
|
+
dialog.closing::backdrop {
|
|
181
|
+
animation: fade-out 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
182
|
+
}
|
|
183
|
+
|
|
102
184
|
.modal-header {
|
|
103
185
|
display: flex;
|
|
104
186
|
align-items: center;
|
|
@@ -154,6 +236,12 @@ __decorate([
|
|
|
154
236
|
__decorate([
|
|
155
237
|
property({ type: String })
|
|
156
238
|
], StModal.prototype, "heading", void 0);
|
|
239
|
+
__decorate([
|
|
240
|
+
property({ type: String })
|
|
241
|
+
], StModal.prototype, "size", void 0);
|
|
242
|
+
__decorate([
|
|
243
|
+
property({ type: Boolean })
|
|
244
|
+
], StModal.prototype, "static", void 0);
|
|
157
245
|
__decorate([
|
|
158
246
|
query('dialog')
|
|
159
247
|
], StModal.prototype, "dialogEl", void 0);
|
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export interface RouteDefinition {
|
|
2
|
+
component: string;
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
export type RouteConfig = Record<string, RouteDefinition>;
|
|
6
|
+
export interface RouteMatch {
|
|
7
|
+
path: string;
|
|
8
|
+
component: string;
|
|
9
|
+
params: Record<string, string>;
|
|
10
|
+
definition: RouteDefinition;
|
|
11
|
+
}
|
|
12
|
+
export declare class AppRouter {
|
|
13
|
+
private _routes;
|
|
14
|
+
private _initialized;
|
|
15
|
+
constructor(routes?: RouteConfig);
|
|
16
|
+
/**
|
|
17
|
+
* Register or update the route configuration for this application.
|
|
18
|
+
*/
|
|
19
|
+
setRoutes(routes: RouteConfig): void;
|
|
20
|
+
/**
|
|
21
|
+
* Programmatically navigate to an internal path.
|
|
22
|
+
*/
|
|
23
|
+
navigate(path: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Matches a URL path against the registered routes.
|
|
26
|
+
*/
|
|
27
|
+
matchRoute(currentPath: string): RouteMatch | null;
|
|
3
28
|
private _notify;
|
|
4
29
|
}
|
|
5
30
|
export declare const router: AppRouter;
|
|
6
|
-
export {};
|
|
7
31
|
//# sourceMappingURL=router.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/components/router/router.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/components/router/router.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAE1D,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,eAAe,CAAC;CAC7B;AASD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,YAAY,CAAS;IAE7B,YAAY,MAAM,CAAC,EAAE,WAAW,EA+B/B;IAED;;OAEG;IACI,SAAS,CAAC,MAAM,EAAE,WAAW,QAUnC;IAED;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,MAAM,QAG3B;IAED;;OAEG;IACI,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA+BxD;IAED,OAAO,CAAC,OAAO;CAahB;AAGD,eAAO,MAAM,MAAM,WAAkB,CAAC"}
|
|
@@ -1,37 +1,97 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
function getRouteWeight(pattern) {
|
|
2
|
+
const segments = pattern.split('/').filter(Boolean);
|
|
3
|
+
return segments.reduce((weight, seg) => {
|
|
4
|
+
return weight + (seg.startsWith(':') ? 1 : 10);
|
|
5
|
+
}, 0);
|
|
6
|
+
}
|
|
7
|
+
export class AppRouter {
|
|
8
|
+
constructor(routes) {
|
|
9
|
+
this._routes = {};
|
|
10
|
+
this._initialized = false;
|
|
11
|
+
if (routes) {
|
|
12
|
+
this.setRoutes(routes);
|
|
13
|
+
}
|
|
3
14
|
window.addEventListener('popstate', () => this._notify());
|
|
4
15
|
document.addEventListener('click', (e) => {
|
|
5
|
-
// 1. Ignore modified clicks (Ctrl+Click, etc)
|
|
6
16
|
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
|
|
7
17
|
return;
|
|
8
18
|
}
|
|
9
|
-
// 2. Safely traverse the path
|
|
10
19
|
const path = e.composedPath();
|
|
11
20
|
const link = path.find((el) => el && typeof el.hasAttribute === 'function' && el.hasAttribute('href'));
|
|
12
21
|
if (!link)
|
|
13
22
|
return;
|
|
14
23
|
const href = link.getAttribute('href');
|
|
15
24
|
const target = link.getAttribute('target');
|
|
16
|
-
// 3. Ignore external links
|
|
17
25
|
if (!href || href.startsWith('http') || href.startsWith('mailto:') || target === '_blank') {
|
|
18
26
|
return;
|
|
19
27
|
}
|
|
20
|
-
// 4. Intercept internal links
|
|
21
28
|
if (href.startsWith('/')) {
|
|
22
29
|
e.preventDefault();
|
|
23
|
-
|
|
24
|
-
this._notify();
|
|
30
|
+
this.navigate(href);
|
|
25
31
|
}
|
|
26
32
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Register or update the route configuration for this application.
|
|
36
|
+
*/
|
|
37
|
+
setRoutes(routes) {
|
|
38
|
+
this._routes = routes;
|
|
39
|
+
// Trigger initial route resolution once routes are registered
|
|
40
|
+
if (!this._initialized) {
|
|
41
|
+
this._initialized = true;
|
|
42
|
+
setTimeout(() => this._notify(), 0);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this._notify();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Programmatically navigate to an internal path.
|
|
50
|
+
*/
|
|
51
|
+
navigate(path) {
|
|
52
|
+
window.history.pushState(null, '', path);
|
|
53
|
+
this._notify();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Matches a URL path against the registered routes.
|
|
57
|
+
*/
|
|
58
|
+
matchRoute(currentPath) {
|
|
59
|
+
const sortedRoutes = Object.entries(this._routes).sort(([patternA], [patternB]) => getRouteWeight(patternB) - getRouteWeight(patternA));
|
|
60
|
+
for (const [pattern, routeDef] of sortedRoutes) {
|
|
61
|
+
const paramNames = [];
|
|
62
|
+
const regexPath = pattern.replace(/:([a-zA-Z0-9_]+)/g, (_, paramName) => {
|
|
63
|
+
paramNames.push(paramName);
|
|
64
|
+
return '([^/]+)';
|
|
65
|
+
});
|
|
66
|
+
const regex = new RegExp(`^${regexPath}$`);
|
|
67
|
+
const match = currentPath.match(regex);
|
|
68
|
+
if (match) {
|
|
69
|
+
const params = {};
|
|
70
|
+
paramNames.forEach((name, index) => {
|
|
71
|
+
params[name] = decodeURIComponent(match[index + 1]);
|
|
72
|
+
});
|
|
73
|
+
return {
|
|
74
|
+
path: currentPath,
|
|
75
|
+
component: routeDef.component,
|
|
76
|
+
params,
|
|
77
|
+
definition: routeDef
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
30
82
|
}
|
|
31
83
|
_notify() {
|
|
84
|
+
const currentPath = window.location.pathname;
|
|
85
|
+
const match = this.matchRoute(currentPath);
|
|
32
86
|
window.dispatchEvent(new CustomEvent('route-changed', {
|
|
33
|
-
detail:
|
|
87
|
+
detail: {
|
|
88
|
+
path: currentPath,
|
|
89
|
+
component: match ? match.component : 'not-found-page',
|
|
90
|
+
params: match ? match.params : {},
|
|
91
|
+
definition: match ? match.definition : null
|
|
92
|
+
}
|
|
34
93
|
}));
|
|
35
94
|
}
|
|
36
95
|
}
|
|
96
|
+
// Export a singleton instance for standard app-wide use
|
|
37
97
|
export const router = new AppRouter();
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
export declare class StSkeleton extends LitElement {
|
|
3
|
-
/** Variant shape: 'text' | 'circular' | 'rectangular' */
|
|
4
3
|
variant: 'text' | 'circular' | 'rectangular';
|
|
5
|
-
|
|
4
|
+
animation: 'shimmer' | 'pulse' | 'none';
|
|
6
5
|
width: string;
|
|
7
|
-
/** Custom height override (e.g., '40px', '1rem') */
|
|
8
6
|
height: string;
|
|
7
|
+
updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
9
8
|
static styles: import("lit").CSSResult[];
|
|
10
9
|
render(): import("lit-html").TemplateResult<1>;
|
|
11
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/skeleton/skeleton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C,qBACa,UAAW,SAAQ,UAAU;
|
|
1
|
+
{"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/skeleton/skeleton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C,qBACa,UAAW,SAAQ,UAAU;IACG,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,CAAU;IACtD,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAa;IACnE,KAAK,SAAM;IACX,MAAM,SAAM;IAGxC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,QAkBhE;IAED,MAAM,CAAC,MAAM,4BAyFX;IAEF,MAAM,yCAIL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
|
|
@@ -10,19 +10,35 @@ import { resetStyles } from '../../styles/reset.js';
|
|
|
10
10
|
let StSkeleton = class StSkeleton extends LitElement {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
|
-
/** Variant shape: 'text' | 'circular' | 'rectangular' */
|
|
14
13
|
this.variant = 'text';
|
|
15
|
-
|
|
14
|
+
this.animation = 'shimmer';
|
|
16
15
|
this.width = '';
|
|
17
|
-
/** Custom height override (e.g., '40px', '1rem') */
|
|
18
16
|
this.height = '';
|
|
19
17
|
}
|
|
18
|
+
// Apply properties directly to the :host as CSS variables when they change
|
|
19
|
+
updated(changedProperties) {
|
|
20
|
+
super.updated(changedProperties);
|
|
21
|
+
if (changedProperties.has('width')) {
|
|
22
|
+
if (this.width) {
|
|
23
|
+
this.style.setProperty('--st-skeleton-width', this.width);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this.style.removeProperty('--st-skeleton-width');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (changedProperties.has('height')) {
|
|
30
|
+
if (this.height) {
|
|
31
|
+
this.style.setProperty('--st-skeleton-height', this.height);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.style.removeProperty('--st-skeleton-height');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
20
38
|
render() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
${this.height ? `--st-skeleton-height: ${this.height};` : ''}
|
|
39
|
+
return html `
|
|
40
|
+
<div class="skeleton" aria-hidden="true" part="base"></div>
|
|
24
41
|
`;
|
|
25
|
-
return html `<div class="skeleton" style=${style}></div>`;
|
|
26
42
|
}
|
|
27
43
|
};
|
|
28
44
|
StSkeleton.styles = [
|
|
@@ -30,12 +46,38 @@ StSkeleton.styles = [
|
|
|
30
46
|
css `
|
|
31
47
|
:host {
|
|
32
48
|
display: block;
|
|
33
|
-
|
|
49
|
+
|
|
50
|
+
/* Define base sizing variables that can be overridden by props */
|
|
51
|
+
--_width: var(--st-skeleton-width, 100%);
|
|
52
|
+
--_height: var(--st-skeleton-height, 1em);
|
|
53
|
+
|
|
54
|
+
/*
|
|
55
|
+
CRITICAL FIX: Apply sizing directly to the host.
|
|
56
|
+
This allows external classes and styles (like margin: auto) to work perfectly.
|
|
57
|
+
*/
|
|
58
|
+
width: var(--_width);
|
|
59
|
+
height: var(--_height);
|
|
60
|
+
|
|
61
|
+
/* Expose radius as a token for external theme overrides */
|
|
62
|
+
--st-skeleton-radius: var(--st-radius-sm, 0.25rem);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Shape Variants adjust the host's sizing variables */
|
|
66
|
+
:host([variant="circular"]) {
|
|
67
|
+
--_width: var(--st-skeleton-width, 2.5rem);
|
|
68
|
+
--_height: var(--st-skeleton-height, 2.5rem);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:host([variant="rectangular"]) {
|
|
72
|
+
--_height: var(--st-skeleton-height, 8rem);
|
|
34
73
|
}
|
|
35
74
|
|
|
36
75
|
.skeleton {
|
|
37
|
-
|
|
38
|
-
|
|
76
|
+
/* The inner element simply fills the host */
|
|
77
|
+
display: block;
|
|
78
|
+
width: 100%;
|
|
79
|
+
height: 100%;
|
|
80
|
+
|
|
39
81
|
background: linear-gradient(
|
|
40
82
|
90deg,
|
|
41
83
|
var(--st-color-surface-muted, #f1f5f9) 25%,
|
|
@@ -43,29 +85,58 @@ StSkeleton.styles = [
|
|
|
43
85
|
var(--st-color-surface-muted, #f1f5f9) 63%
|
|
44
86
|
);
|
|
45
87
|
background-size: 400% 100%;
|
|
46
|
-
|
|
47
|
-
|
|
88
|
+
border-radius: var(--st-skeleton-radius);
|
|
89
|
+
|
|
90
|
+
/* Prevent accidental selection */
|
|
91
|
+
user-select: none;
|
|
92
|
+
pointer-events: none;
|
|
48
93
|
}
|
|
49
94
|
|
|
50
95
|
:host([variant="circular"]) .skeleton {
|
|
51
96
|
border-radius: 50%;
|
|
52
|
-
height: var(--st-skeleton-height, 2.5rem);
|
|
53
|
-
width: var(--st-skeleton-width, 2.5rem);
|
|
54
97
|
}
|
|
55
98
|
|
|
56
|
-
|
|
57
|
-
|
|
99
|
+
/* Animations */
|
|
100
|
+
:host([animation="shimmer"]) .skeleton {
|
|
101
|
+
animation: st-shimmer 1.4s ease infinite;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
:host([animation="pulse"]) .skeleton {
|
|
105
|
+
background: var(--st-color-surface-muted, #f1f5f9);
|
|
106
|
+
animation: st-pulse 1.5s ease-in-out infinite;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
:host([animation="none"]) .skeleton {
|
|
110
|
+
background: var(--st-color-surface-muted, #f1f5f9);
|
|
111
|
+
animation: none;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Accessibility: Respect OS reduced motion settings */
|
|
115
|
+
@media (prefers-reduced-motion: reduce) {
|
|
116
|
+
.skeleton {
|
|
117
|
+
animation: none !important;
|
|
118
|
+
background: var(--st-color-surface-muted, #f1f5f9) !important;
|
|
119
|
+
}
|
|
58
120
|
}
|
|
59
121
|
|
|
60
122
|
@keyframes st-shimmer {
|
|
61
123
|
0% { background-position: 100% 0; }
|
|
62
|
-
100% { background-position:
|
|
124
|
+
100% { background-position: -100% 0; }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@keyframes st-pulse {
|
|
128
|
+
0% { opacity: 1; }
|
|
129
|
+
50% { opacity: 0.4; }
|
|
130
|
+
100% { opacity: 1; }
|
|
63
131
|
}
|
|
64
132
|
`
|
|
65
133
|
];
|
|
66
134
|
__decorate([
|
|
67
|
-
property({ type: String })
|
|
135
|
+
property({ type: String, reflect: true })
|
|
68
136
|
], StSkeleton.prototype, "variant", void 0);
|
|
137
|
+
__decorate([
|
|
138
|
+
property({ type: String, reflect: true })
|
|
139
|
+
], StSkeleton.prototype, "animation", void 0);
|
|
69
140
|
__decorate([
|
|
70
141
|
property({ type: String })
|
|
71
142
|
], StSkeleton.prototype, "width", void 0);
|
|
@@ -2,8 +2,14 @@ import { LitElement } from 'lit';
|
|
|
2
2
|
export declare class StNavGroup extends LitElement {
|
|
3
3
|
label: string;
|
|
4
4
|
open: boolean;
|
|
5
|
+
depth: number;
|
|
5
6
|
static styles: import("lit").CSSResult[];
|
|
6
7
|
private _toggle;
|
|
7
8
|
render(): import("lit-html").TemplateResult<1>;
|
|
8
9
|
}
|
|
10
|
+
declare global {
|
|
11
|
+
interface HTMLElementTagNameMap {
|
|
12
|
+
'st-vertical-nav-group': StNavGroup;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
9
15
|
//# sourceMappingURL=vertical-nav-group.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vertical-nav-group.d.ts","sourceRoot":"","sources":["../../../src/components/vertical-nav/vertical-nav-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C,qBACa,UAAW,SAAQ,UAAU;IACZ,KAAK,SAAM;IACK,IAAI,UAAS;
|
|
1
|
+
{"version":3,"file":"vertical-nav-group.d.ts","sourceRoot":"","sources":["../../../src/components/vertical-nav/vertical-nav-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C,qBACa,UAAW,SAAQ,UAAU;IACZ,KAAK,SAAM;IACK,IAAI,UAAS;IAC7B,KAAK,SAAK;IAEtC,MAAM,CAAC,MAAM,4BA8EX;IAEF,OAAO,CAAC,OAAO;IAIf,MAAM,yCAcL;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,uBAAuB,EAAE,UAAU,CAAC;KACrC;CACF"}
|