@mhmo91/schmancy 0.4.79 → 0.4.80
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/ai/area.md +223 -11
- package/dist/ai/area.md +223 -11
- package/dist/area.cjs +1 -1
- package/dist/area.js +13 -12
- package/dist/{avatar-Cxu7EOku.cjs → avatar-Bws6p1iq.cjs} +2 -2
- package/dist/{avatar-Cxu7EOku.cjs.map → avatar-Bws6p1iq.cjs.map} +1 -1
- package/dist/{avatar-CokwBO2O.js → avatar-kpFZmTl5.js} +2 -2
- package/dist/{avatar-CokwBO2O.js.map → avatar-kpFZmTl5.js.map} +1 -1
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/content-drawer.cjs +1 -1
- package/dist/content-drawer.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +192 -191
- package/dist/{utils-C9nzOWpR.cjs → lazy-DObpkuL6.cjs} +2 -2
- package/dist/lazy-DObpkuL6.cjs.map +1 -0
- package/dist/{utils-03Coa8AW.js → lazy-E2LCDm7n.js} +37 -23
- package/dist/lazy-E2LCDm7n.js.map +1 -0
- package/dist/nav-drawer.cjs +1 -1
- package/dist/nav-drawer.js +1 -1
- package/dist/route.component-5LuJ2r6W.js +311 -0
- package/dist/route.component-5LuJ2r6W.js.map +1 -0
- package/dist/route.component-DR82kcmu.cjs +12 -0
- package/dist/route.component-DR82kcmu.cjs.map +1 -0
- package/dist/teleport.cjs +1 -1
- package/dist/teleport.js +1 -1
- package/package.json +1 -1
- package/types/src/area/area.component.d.ts +6 -36
- package/types/src/area/index.d.ts +1 -0
- package/types/src/area/lazy.d.ts +44 -0
- package/types/src/area/router.types.d.ts +3 -1
- package/dist/route.component-BMRfUQ9O.cjs +0 -12
- package/dist/route.component-BMRfUQ9O.cjs.map +0 -1
- package/dist/route.component-D2BflZS9.js +0 -341
- package/dist/route.component-D2BflZS9.js.map +0 -1
- package/dist/utils-03Coa8AW.js.map +0 -1
- package/dist/utils-C9nzOWpR.cjs.map +0 -1
package/ai/area.md
CHANGED
|
@@ -429,10 +429,206 @@ class AppLayout extends LitElement {
|
|
|
429
429
|
}
|
|
430
430
|
```
|
|
431
431
|
|
|
432
|
-
### 4. Dynamic Route Loading
|
|
432
|
+
### 4. Dynamic Route Loading & Lazy Components
|
|
433
|
+
|
|
434
|
+
#### Using the `lazy()` helper function
|
|
435
|
+
|
|
436
|
+
Schmancy Area provides a powerful `lazy()` function similar to React.lazy() for optimal code splitting:
|
|
433
437
|
|
|
434
438
|
```typescript
|
|
435
|
-
|
|
439
|
+
import { lazy } from '@schmancy/area';
|
|
440
|
+
|
|
441
|
+
// Create lazy-loaded components
|
|
442
|
+
const LazyDashboard = lazy(() => import('./components/dashboard'));
|
|
443
|
+
const LazyAnalytics = lazy(() => import('./components/analytics'));
|
|
444
|
+
const LazyReports = lazy(() => import('./components/reports'));
|
|
445
|
+
|
|
446
|
+
// Use with area.push()
|
|
447
|
+
area.push({
|
|
448
|
+
component: LazyDashboard,
|
|
449
|
+
area: 'main'
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// Use with declarative routes
|
|
453
|
+
<schmancy-route
|
|
454
|
+
when="/analytics"
|
|
455
|
+
.component=${LazyAnalytics}
|
|
456
|
+
.guard=${() => hasFeature('analytics') || '/upgrade'}>
|
|
457
|
+
</schmancy-route>
|
|
458
|
+
|
|
459
|
+
// Set as default for an area
|
|
460
|
+
<schmancy-area name="main" .default=${LazyDashboard}></schmancy-area>
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
#### Preloading Components
|
|
464
|
+
|
|
465
|
+
Lazy components support preloading for better perceived performance:
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
const LazyProfile = lazy(() => import('./profile'));
|
|
469
|
+
|
|
470
|
+
// Preload on hover for instant navigation
|
|
471
|
+
button.addEventListener('mouseenter', () => {
|
|
472
|
+
LazyProfile.preload();
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
// Preload after initial page load
|
|
476
|
+
window.addEventListener('load', () => {
|
|
477
|
+
setTimeout(() => {
|
|
478
|
+
LazyProfile.preload();
|
|
479
|
+
LazySettings.preload();
|
|
480
|
+
}, 2000);
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### Complete Example: Lazy-Loaded Navigation
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
import { $LitElement } from '@mixins/index';
|
|
488
|
+
import { area, lazy } from '@schmancy/area';
|
|
489
|
+
import { html } from 'lit';
|
|
490
|
+
import { customElement, state } from 'lit/decorators.js';
|
|
491
|
+
|
|
492
|
+
// Define lazy components with default exports
|
|
493
|
+
const routes = {
|
|
494
|
+
dashboard: lazy(() => import('./lazy-components/dashboard')),
|
|
495
|
+
users: lazy(() => import('./lazy-components/users')),
|
|
496
|
+
products: lazy(() => import('./lazy-components/products')),
|
|
497
|
+
reports: lazy(() => import('./lazy-components/reports')),
|
|
498
|
+
settings: lazy(() => import('./lazy-components/settings'))
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
@customElement('app-shell')
|
|
502
|
+
export class AppShell extends $LitElement() {
|
|
503
|
+
@state() private currentRoute = 'dashboard';
|
|
504
|
+
|
|
505
|
+
private navigate(route: string, component: any) {
|
|
506
|
+
this.currentRoute = route;
|
|
507
|
+
area.push({
|
|
508
|
+
area: 'main',
|
|
509
|
+
component: component
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
render() {
|
|
514
|
+
return html`
|
|
515
|
+
<div class="grid grid-cols-[auto_1fr]">
|
|
516
|
+
<!-- Sidebar Navigation -->
|
|
517
|
+
<schmancy-list>
|
|
518
|
+
<schmancy-list-item
|
|
519
|
+
?selected=${this.currentRoute === 'dashboard'}
|
|
520
|
+
@click=${() => this.navigate('dashboard', routes.dashboard)}
|
|
521
|
+
@mouseenter=${() => routes.dashboard.preload()}>
|
|
522
|
+
<schmancy-icon slot="start">dashboard</schmancy-icon>
|
|
523
|
+
Dashboard
|
|
524
|
+
</schmancy-list-item>
|
|
525
|
+
|
|
526
|
+
<schmancy-list-item
|
|
527
|
+
?selected=${this.currentRoute === 'users'}
|
|
528
|
+
@click=${() => this.navigate('users', routes.users)}
|
|
529
|
+
@mouseenter=${() => routes.users.preload()}>
|
|
530
|
+
<schmancy-icon slot="start">group</schmancy-icon>
|
|
531
|
+
Users
|
|
532
|
+
</schmancy-list-item>
|
|
533
|
+
|
|
534
|
+
<schmancy-list-item
|
|
535
|
+
?selected=${this.currentRoute === 'products'}
|
|
536
|
+
@click=${() => this.navigate('products', routes.products)}
|
|
537
|
+
@mouseenter=${() => routes.products.preload()}>
|
|
538
|
+
<schmancy-icon slot="start">inventory_2</schmancy-icon>
|
|
539
|
+
Products
|
|
540
|
+
</schmancy-list-item>
|
|
541
|
+
</schmancy-list>
|
|
542
|
+
|
|
543
|
+
<!-- Main Content Area -->
|
|
544
|
+
<schmancy-area
|
|
545
|
+
name="main"
|
|
546
|
+
.default=${routes.dashboard}>
|
|
547
|
+
</schmancy-area>
|
|
548
|
+
</div>
|
|
549
|
+
`;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
#### Lazy Component Structure
|
|
555
|
+
|
|
556
|
+
Each lazy-loaded component should use default export:
|
|
557
|
+
|
|
558
|
+
```typescript
|
|
559
|
+
// lazy-components/dashboard.ts
|
|
560
|
+
import { html, css } from 'lit';
|
|
561
|
+
import { customElement } from 'lit/decorators.js';
|
|
562
|
+
import { $LitElement } from '@mixins/index';
|
|
563
|
+
|
|
564
|
+
@customElement('lazy-dashboard')
|
|
565
|
+
export default class LazyDashboard extends $LitElement(css`
|
|
566
|
+
:host {
|
|
567
|
+
display: block;
|
|
568
|
+
padding: 24px;
|
|
569
|
+
}
|
|
570
|
+
`) {
|
|
571
|
+
render() {
|
|
572
|
+
return html`
|
|
573
|
+
<schmancy-surface type="container" rounded="all">
|
|
574
|
+
<schmancy-typography type="headline">Dashboard</schmancy-typography>
|
|
575
|
+
<!-- Dashboard content -->
|
|
576
|
+
</schmancy-surface>
|
|
577
|
+
`;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
#### Benefits of Lazy Loading
|
|
583
|
+
|
|
584
|
+
1. **Reduced Initial Bundle Size**: Components are loaded only when needed
|
|
585
|
+
2. **Faster Initial Page Load**: Critical path includes only essential code
|
|
586
|
+
3. **Automatic Code Splitting**: Each lazy import creates a separate chunk
|
|
587
|
+
4. **Memory Efficiency**: Components not in use aren't loaded in memory
|
|
588
|
+
5. **Better Perceived Performance**: Preloading on hover makes navigation feel instant
|
|
589
|
+
|
|
590
|
+
#### Performance Best Practices
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
// 1. Group related components in the same chunk
|
|
594
|
+
const LazyAdminComponents = lazy(() => import('./admin/index'));
|
|
595
|
+
|
|
596
|
+
// 2. Preload critical routes after initial render
|
|
597
|
+
connectedCallback() {
|
|
598
|
+
super.connectedCallback();
|
|
599
|
+
|
|
600
|
+
// Preload common routes after a delay
|
|
601
|
+
setTimeout(() => {
|
|
602
|
+
routes.dashboard.preload();
|
|
603
|
+
routes.users.preload();
|
|
604
|
+
}, 3000);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// 3. Use intersection observer for preloading visible links
|
|
608
|
+
const observer = new IntersectionObserver((entries) => {
|
|
609
|
+
entries.forEach(entry => {
|
|
610
|
+
if (entry.isIntersecting) {
|
|
611
|
+
const route = entry.target.dataset.route;
|
|
612
|
+
routes[route]?.preload();
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
// 4. Handle loading errors gracefully
|
|
618
|
+
const LazyFeature = lazy(() =>
|
|
619
|
+
import('./feature').catch(() =>
|
|
620
|
+
// Fallback to simpler version on error
|
|
621
|
+
import('./feature-lite')
|
|
622
|
+
)
|
|
623
|
+
);
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
#### Legacy Method (Still Supported)
|
|
627
|
+
|
|
628
|
+
The traditional dynamic import method is still supported:
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
// Direct dynamic import (without lazy helper)
|
|
436
632
|
<schmancy-route
|
|
437
633
|
when="/analytics"
|
|
438
634
|
.component=${() => import('./analytics-dashboard.js').then(m => m.AnalyticsDashboard)}
|
|
@@ -613,7 +809,7 @@ area.on('protected-area').pipe(
|
|
|
613
809
|
```typescript
|
|
614
810
|
// Route Action - used for navigation
|
|
615
811
|
interface RouteAction {
|
|
616
|
-
component: CustomElementConstructor | string | HTMLElement | Promise<NodeModule
|
|
812
|
+
component: CustomElementConstructor | string | HTMLElement | Promise<NodeModule> | LazyComponent;
|
|
617
813
|
area: string;
|
|
618
814
|
state?: Record<string, unknown>;
|
|
619
815
|
params?: Record<string, unknown>; // Query parameters
|
|
@@ -638,10 +834,22 @@ type GuardFunction = () => GuardResult | Promise<GuardResult>;
|
|
|
638
834
|
// Route component props
|
|
639
835
|
interface RouteProps {
|
|
640
836
|
when: string; // URL segment pattern
|
|
641
|
-
component?: string | CustomElementConstructor | HTMLElement;
|
|
642
|
-
default?: string | CustomElementConstructor | HTMLElement;
|
|
837
|
+
component?: string | CustomElementConstructor | HTMLElement | LazyComponent;
|
|
838
|
+
default?: string | CustomElementConstructor | HTMLElement | LazyComponent;
|
|
643
839
|
guard?: GuardFunction;
|
|
644
840
|
}
|
|
841
|
+
|
|
842
|
+
// Lazy Loading Types (from lazy.ts)
|
|
843
|
+
type CustomElementConstructor = typeof HTMLElement;
|
|
844
|
+
|
|
845
|
+
// LazyComponent interface with preload capability
|
|
846
|
+
interface LazyComponent<T extends CustomElementConstructor = CustomElementConstructor> {
|
|
847
|
+
(): Promise<{ default: T }>;
|
|
848
|
+
preload(): Promise<void>;
|
|
849
|
+
_promise?: Promise<{ default: T }>;
|
|
850
|
+
_module?: { default: T };
|
|
851
|
+
}
|
|
852
|
+
|
|
645
853
|
```
|
|
646
854
|
|
|
647
855
|
## Related Components
|
|
@@ -653,12 +861,16 @@ interface RouteProps {
|
|
|
653
861
|
|
|
654
862
|
## Performance Tips
|
|
655
863
|
|
|
656
|
-
1. **Use lazy
|
|
657
|
-
2. **Implement
|
|
658
|
-
3. **
|
|
659
|
-
4. **
|
|
660
|
-
5. **
|
|
661
|
-
6. **
|
|
864
|
+
1. **Use the `lazy()` function** for automatic code splitting and optimal loading
|
|
865
|
+
2. **Implement preloading on hover** for instant perceived navigation
|
|
866
|
+
3. **Handle loading errors** with catch blocks in import statements
|
|
867
|
+
4. **Group related components** in the same lazy chunk when appropriate
|
|
868
|
+
5. **Cache guard results** when checking expensive operations
|
|
869
|
+
6. **Use `historyStrategy: 'silent'`** for non-navigational updates
|
|
870
|
+
7. **Debounce rapid navigation** in user-triggered events
|
|
871
|
+
8. **Preload critical routes** after initial render using `component.preload()`
|
|
872
|
+
9. **Leverage default exports** in lazy-loaded components for cleaner imports
|
|
873
|
+
10. **Monitor bundle sizes** to ensure effective code splitting
|
|
662
874
|
|
|
663
875
|
## Summary
|
|
664
876
|
|
package/dist/ai/area.md
CHANGED
|
@@ -429,10 +429,206 @@ class AppLayout extends LitElement {
|
|
|
429
429
|
}
|
|
430
430
|
```
|
|
431
431
|
|
|
432
|
-
### 4. Dynamic Route Loading
|
|
432
|
+
### 4. Dynamic Route Loading & Lazy Components
|
|
433
|
+
|
|
434
|
+
#### Using the `lazy()` helper function
|
|
435
|
+
|
|
436
|
+
Schmancy Area provides a powerful `lazy()` function similar to React.lazy() for optimal code splitting:
|
|
433
437
|
|
|
434
438
|
```typescript
|
|
435
|
-
|
|
439
|
+
import { lazy } from '@schmancy/area';
|
|
440
|
+
|
|
441
|
+
// Create lazy-loaded components
|
|
442
|
+
const LazyDashboard = lazy(() => import('./components/dashboard'));
|
|
443
|
+
const LazyAnalytics = lazy(() => import('./components/analytics'));
|
|
444
|
+
const LazyReports = lazy(() => import('./components/reports'));
|
|
445
|
+
|
|
446
|
+
// Use with area.push()
|
|
447
|
+
area.push({
|
|
448
|
+
component: LazyDashboard,
|
|
449
|
+
area: 'main'
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// Use with declarative routes
|
|
453
|
+
<schmancy-route
|
|
454
|
+
when="/analytics"
|
|
455
|
+
.component=${LazyAnalytics}
|
|
456
|
+
.guard=${() => hasFeature('analytics') || '/upgrade'}>
|
|
457
|
+
</schmancy-route>
|
|
458
|
+
|
|
459
|
+
// Set as default for an area
|
|
460
|
+
<schmancy-area name="main" .default=${LazyDashboard}></schmancy-area>
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
#### Preloading Components
|
|
464
|
+
|
|
465
|
+
Lazy components support preloading for better perceived performance:
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
const LazyProfile = lazy(() => import('./profile'));
|
|
469
|
+
|
|
470
|
+
// Preload on hover for instant navigation
|
|
471
|
+
button.addEventListener('mouseenter', () => {
|
|
472
|
+
LazyProfile.preload();
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
// Preload after initial page load
|
|
476
|
+
window.addEventListener('load', () => {
|
|
477
|
+
setTimeout(() => {
|
|
478
|
+
LazyProfile.preload();
|
|
479
|
+
LazySettings.preload();
|
|
480
|
+
}, 2000);
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### Complete Example: Lazy-Loaded Navigation
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
import { $LitElement } from '@mixins/index';
|
|
488
|
+
import { area, lazy } from '@schmancy/area';
|
|
489
|
+
import { html } from 'lit';
|
|
490
|
+
import { customElement, state } from 'lit/decorators.js';
|
|
491
|
+
|
|
492
|
+
// Define lazy components with default exports
|
|
493
|
+
const routes = {
|
|
494
|
+
dashboard: lazy(() => import('./lazy-components/dashboard')),
|
|
495
|
+
users: lazy(() => import('./lazy-components/users')),
|
|
496
|
+
products: lazy(() => import('./lazy-components/products')),
|
|
497
|
+
reports: lazy(() => import('./lazy-components/reports')),
|
|
498
|
+
settings: lazy(() => import('./lazy-components/settings'))
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
@customElement('app-shell')
|
|
502
|
+
export class AppShell extends $LitElement() {
|
|
503
|
+
@state() private currentRoute = 'dashboard';
|
|
504
|
+
|
|
505
|
+
private navigate(route: string, component: any) {
|
|
506
|
+
this.currentRoute = route;
|
|
507
|
+
area.push({
|
|
508
|
+
area: 'main',
|
|
509
|
+
component: component
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
render() {
|
|
514
|
+
return html`
|
|
515
|
+
<div class="grid grid-cols-[auto_1fr]">
|
|
516
|
+
<!-- Sidebar Navigation -->
|
|
517
|
+
<schmancy-list>
|
|
518
|
+
<schmancy-list-item
|
|
519
|
+
?selected=${this.currentRoute === 'dashboard'}
|
|
520
|
+
@click=${() => this.navigate('dashboard', routes.dashboard)}
|
|
521
|
+
@mouseenter=${() => routes.dashboard.preload()}>
|
|
522
|
+
<schmancy-icon slot="start">dashboard</schmancy-icon>
|
|
523
|
+
Dashboard
|
|
524
|
+
</schmancy-list-item>
|
|
525
|
+
|
|
526
|
+
<schmancy-list-item
|
|
527
|
+
?selected=${this.currentRoute === 'users'}
|
|
528
|
+
@click=${() => this.navigate('users', routes.users)}
|
|
529
|
+
@mouseenter=${() => routes.users.preload()}>
|
|
530
|
+
<schmancy-icon slot="start">group</schmancy-icon>
|
|
531
|
+
Users
|
|
532
|
+
</schmancy-list-item>
|
|
533
|
+
|
|
534
|
+
<schmancy-list-item
|
|
535
|
+
?selected=${this.currentRoute === 'products'}
|
|
536
|
+
@click=${() => this.navigate('products', routes.products)}
|
|
537
|
+
@mouseenter=${() => routes.products.preload()}>
|
|
538
|
+
<schmancy-icon slot="start">inventory_2</schmancy-icon>
|
|
539
|
+
Products
|
|
540
|
+
</schmancy-list-item>
|
|
541
|
+
</schmancy-list>
|
|
542
|
+
|
|
543
|
+
<!-- Main Content Area -->
|
|
544
|
+
<schmancy-area
|
|
545
|
+
name="main"
|
|
546
|
+
.default=${routes.dashboard}>
|
|
547
|
+
</schmancy-area>
|
|
548
|
+
</div>
|
|
549
|
+
`;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
#### Lazy Component Structure
|
|
555
|
+
|
|
556
|
+
Each lazy-loaded component should use default export:
|
|
557
|
+
|
|
558
|
+
```typescript
|
|
559
|
+
// lazy-components/dashboard.ts
|
|
560
|
+
import { html, css } from 'lit';
|
|
561
|
+
import { customElement } from 'lit/decorators.js';
|
|
562
|
+
import { $LitElement } from '@mixins/index';
|
|
563
|
+
|
|
564
|
+
@customElement('lazy-dashboard')
|
|
565
|
+
export default class LazyDashboard extends $LitElement(css`
|
|
566
|
+
:host {
|
|
567
|
+
display: block;
|
|
568
|
+
padding: 24px;
|
|
569
|
+
}
|
|
570
|
+
`) {
|
|
571
|
+
render() {
|
|
572
|
+
return html`
|
|
573
|
+
<schmancy-surface type="container" rounded="all">
|
|
574
|
+
<schmancy-typography type="headline">Dashboard</schmancy-typography>
|
|
575
|
+
<!-- Dashboard content -->
|
|
576
|
+
</schmancy-surface>
|
|
577
|
+
`;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
#### Benefits of Lazy Loading
|
|
583
|
+
|
|
584
|
+
1. **Reduced Initial Bundle Size**: Components are loaded only when needed
|
|
585
|
+
2. **Faster Initial Page Load**: Critical path includes only essential code
|
|
586
|
+
3. **Automatic Code Splitting**: Each lazy import creates a separate chunk
|
|
587
|
+
4. **Memory Efficiency**: Components not in use aren't loaded in memory
|
|
588
|
+
5. **Better Perceived Performance**: Preloading on hover makes navigation feel instant
|
|
589
|
+
|
|
590
|
+
#### Performance Best Practices
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
// 1. Group related components in the same chunk
|
|
594
|
+
const LazyAdminComponents = lazy(() => import('./admin/index'));
|
|
595
|
+
|
|
596
|
+
// 2. Preload critical routes after initial render
|
|
597
|
+
connectedCallback() {
|
|
598
|
+
super.connectedCallback();
|
|
599
|
+
|
|
600
|
+
// Preload common routes after a delay
|
|
601
|
+
setTimeout(() => {
|
|
602
|
+
routes.dashboard.preload();
|
|
603
|
+
routes.users.preload();
|
|
604
|
+
}, 3000);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// 3. Use intersection observer for preloading visible links
|
|
608
|
+
const observer = new IntersectionObserver((entries) => {
|
|
609
|
+
entries.forEach(entry => {
|
|
610
|
+
if (entry.isIntersecting) {
|
|
611
|
+
const route = entry.target.dataset.route;
|
|
612
|
+
routes[route]?.preload();
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
// 4. Handle loading errors gracefully
|
|
618
|
+
const LazyFeature = lazy(() =>
|
|
619
|
+
import('./feature').catch(() =>
|
|
620
|
+
// Fallback to simpler version on error
|
|
621
|
+
import('./feature-lite')
|
|
622
|
+
)
|
|
623
|
+
);
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
#### Legacy Method (Still Supported)
|
|
627
|
+
|
|
628
|
+
The traditional dynamic import method is still supported:
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
// Direct dynamic import (without lazy helper)
|
|
436
632
|
<schmancy-route
|
|
437
633
|
when="/analytics"
|
|
438
634
|
.component=${() => import('./analytics-dashboard.js').then(m => m.AnalyticsDashboard)}
|
|
@@ -613,7 +809,7 @@ area.on('protected-area').pipe(
|
|
|
613
809
|
```typescript
|
|
614
810
|
// Route Action - used for navigation
|
|
615
811
|
interface RouteAction {
|
|
616
|
-
component: CustomElementConstructor | string | HTMLElement | Promise<NodeModule
|
|
812
|
+
component: CustomElementConstructor | string | HTMLElement | Promise<NodeModule> | LazyComponent;
|
|
617
813
|
area: string;
|
|
618
814
|
state?: Record<string, unknown>;
|
|
619
815
|
params?: Record<string, unknown>; // Query parameters
|
|
@@ -638,10 +834,22 @@ type GuardFunction = () => GuardResult | Promise<GuardResult>;
|
|
|
638
834
|
// Route component props
|
|
639
835
|
interface RouteProps {
|
|
640
836
|
when: string; // URL segment pattern
|
|
641
|
-
component?: string | CustomElementConstructor | HTMLElement;
|
|
642
|
-
default?: string | CustomElementConstructor | HTMLElement;
|
|
837
|
+
component?: string | CustomElementConstructor | HTMLElement | LazyComponent;
|
|
838
|
+
default?: string | CustomElementConstructor | HTMLElement | LazyComponent;
|
|
643
839
|
guard?: GuardFunction;
|
|
644
840
|
}
|
|
841
|
+
|
|
842
|
+
// Lazy Loading Types (from lazy.ts)
|
|
843
|
+
type CustomElementConstructor = typeof HTMLElement;
|
|
844
|
+
|
|
845
|
+
// LazyComponent interface with preload capability
|
|
846
|
+
interface LazyComponent<T extends CustomElementConstructor = CustomElementConstructor> {
|
|
847
|
+
(): Promise<{ default: T }>;
|
|
848
|
+
preload(): Promise<void>;
|
|
849
|
+
_promise?: Promise<{ default: T }>;
|
|
850
|
+
_module?: { default: T };
|
|
851
|
+
}
|
|
852
|
+
|
|
645
853
|
```
|
|
646
854
|
|
|
647
855
|
## Related Components
|
|
@@ -653,12 +861,16 @@ interface RouteProps {
|
|
|
653
861
|
|
|
654
862
|
## Performance Tips
|
|
655
863
|
|
|
656
|
-
1. **Use lazy
|
|
657
|
-
2. **Implement
|
|
658
|
-
3. **
|
|
659
|
-
4. **
|
|
660
|
-
5. **
|
|
661
|
-
6. **
|
|
864
|
+
1. **Use the `lazy()` function** for automatic code splitting and optimal loading
|
|
865
|
+
2. **Implement preloading on hover** for instant perceived navigation
|
|
866
|
+
3. **Handle loading errors** with catch blocks in import statements
|
|
867
|
+
4. **Group related components** in the same lazy chunk when appropriate
|
|
868
|
+
5. **Cache guard results** when checking expensive operations
|
|
869
|
+
6. **Use `historyStrategy: 'silent'`** for non-navigational updates
|
|
870
|
+
7. **Debounce rapid navigation** in user-triggered events
|
|
871
|
+
8. **Preload critical routes** after initial render using `component.preload()`
|
|
872
|
+
9. **Leverage default exports** in lazy-loaded components for cleaner imports
|
|
873
|
+
10. **Monitor bundle sizes** to ensure effective code splitting
|
|
662
874
|
|
|
663
875
|
## Summary
|
|
664
876
|
|
package/dist/area.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./route.component-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./route.component-DR82kcmu.cjs"),e=require("./lazy-DObpkuL6.cjs");exports.FINDING_MORTIES=t.FINDING_MORTIES,exports.HERE_RICKY=t.HERE_RICKY,exports.HISTORY_STRATEGY=t.HISTORY_STRATEGY,Object.defineProperty(exports,"SchmancyArea",{enumerable:!0,get:()=>t.SchmancyArea}),Object.defineProperty(exports,"SchmancyRoute",{enumerable:!0,get:()=>t.SchmancyRoute}),exports.area=t.area,exports.routerHistory=t.routerHistory,exports.buildQueryString=e.buildQueryString,exports.compareActiveRoutes=e.compareActiveRoutes,exports.compareCustomElementConstructors=e.compareCustomElementConstructors,exports.compareRouteActions=e.compareRouteActions,exports.createRouteCacheKey=e.createRouteCacheKey,exports.debounce=e.debounce,exports.decodeRouteState=e.decodeRouteState,exports.deepMerge=e.deepMerge,exports.encodeRouteState=e.encodeRouteState,exports.extractQueryParams=e.extractQueryParams,exports.getTagName=e.getTagName,exports.isObject=e.isObject,exports.lazy=e.lazy,exports.normalizeTagName=e.normalizeTagName,exports.sanitizeRouteState=e.sanitizeRouteState;
|
|
2
2
|
//# sourceMappingURL=area.cjs.map
|
package/dist/area.js
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import { F as s, H as t, c as o, S as r, a as c, b as
|
|
2
|
-
import { l as n, h as i, c as S, f as d, j as
|
|
1
|
+
import { F as s, H as t, c as o, S as r, a as c, b as m, r as u } from "./route.component-5LuJ2r6W.js";
|
|
2
|
+
import { l as n, h as i, c as S, f as d, j as y, a as g, b as p, d as T, e as b, k as l, g as E, i as I, m as h, n as A, s as C } from "./lazy-E2LCDm7n.js";
|
|
3
3
|
export {
|
|
4
4
|
s as FINDING_MORTIES,
|
|
5
5
|
t as HERE_RICKY,
|
|
6
6
|
o as HISTORY_STRATEGY,
|
|
7
7
|
r as SchmancyArea,
|
|
8
8
|
c as SchmancyRoute,
|
|
9
|
-
|
|
9
|
+
m as area,
|
|
10
10
|
n as buildQueryString,
|
|
11
11
|
i as compareActiveRoutes,
|
|
12
12
|
S as compareCustomElementConstructors,
|
|
13
13
|
d as compareRouteActions,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
y as createRouteCacheKey,
|
|
15
|
+
g as debounce,
|
|
16
|
+
p as decodeRouteState,
|
|
17
17
|
T as deepMerge,
|
|
18
18
|
b as encodeRouteState,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
l as extractQueryParams,
|
|
20
|
+
E as getTagName,
|
|
21
|
+
I as isObject,
|
|
22
|
+
h as lazy,
|
|
23
|
+
A as normalizeTagName,
|
|
24
|
+
u as routerHistory,
|
|
25
|
+
C as sanitizeRouteState
|
|
25
26
|
};
|
|
26
27
|
//# sourceMappingURL=area.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";const l=require("lit"),a=require("lit/decorators.js"),s=require("rxjs");require("./animated-text-Ra7G35tz.cjs");const $=require("./route.component-
|
|
1
|
+
"use strict";const l=require("lit"),a=require("lit/decorators.js"),s=require("rxjs");require("./animated-text-Ra7G35tz.cjs");const $=require("./route.component-DR82kcmu.cjs");require("./autocomplete-0qgkJELR.cjs"),require("lit/directives/class-map.js"),require("lit/directives/style-map.js");const _=require("./tailwind.mixin-BPLAZH0W.cjs"),C=require("./ripple-C2BHbhcS.cjs");require("./boat-CsmB4RXa.cjs"),require("./spinner-uKeW1jVr.cjs"),require("./icon-button-D41ID2Fc.cjs"),require("./media-DMXDyK_t.cjs"),require("./checkbox-D6bUTeG8.cjs"),require("./chips-CtbapOaS.cjs"),require("./code-preview-DGkqHYdn.cjs"),require("./payment-card-form-CIo6Jvh4.cjs");const p=require("./types.cjs"),d=require("./provide-BxZ2kn_p.cjs"),b=require("./litElement.mixin-DiSo_YRo.cjs"),m=require("./consume-edta5ng5.cjs");require("./date-range-Dfw7LxKv.cjs"),require("./date-range-inline-CBOrdNiP.cjs"),require("./delay-DFB3_NEH.cjs"),require("./details-Cv8AMues.cjs"),require("./dialog-content-CURTuo8R.cjs"),require("./dialog-service-juvsgc5X.cjs"),require("./divider-CVomKpEr.cjs"),require("./dropdown-content-lZcMgCym.cjs"),require("./timezone-C8PYHpA5.cjs"),require("./form-Cid9N-2B.cjs"),require("./icon-7uflQBUI.cjs"),require("./input-CcwnttG1.cjs"),require("./flex-CbGwzfNX.cjs"),require("./list-BAjh6Ucg.cjs"),require("./email-recipients-D2bcyJAi.cjs"),require("./map-wFoHnuTE.cjs"),require("./menu-D6djF8D7.cjs");const W=require("lit/directives/when.js");require("./notification-service-CnVFGj74.cjs"),require("./option-D22bslGV.cjs"),require("./progress-Cz6acdfO.cjs"),require("./radio-button-XTjTthrJ.cjs"),require("./index-CCi1otmh.cjs"),require("./select-BZuUqcqv.cjs"),require("./sheet-CSp5quAX.cjs");const j=require("./sheet.service-BxvWBGsJ.cjs");require("./slider-CPJ-4yg4.cjs"),require("./schmancy-steps-container-CDj0iFPm.cjs"),require("./context-object-bNADqf9U.cjs");const N=require("rxjs/operators");require("./surface-DCAyIw6O.cjs"),require("./table-N5w5txc8.cjs"),require("./tabs-compatibility-B_0MOHRx.cjs"),require("./textarea-CfO-1Q7I.cjs"),require("./theme.component--fI9PP4Y.cjs"),require("./theme-button-QgQtIkNO.cjs"),require("./tooltip-DxkXzv_5.cjs"),require("./tree-DD_zsKhj.cjs"),require("./typewriter-BZQFLCSO.cjs"),require("./typography-C6a_0J8h.cjs");const o=require("./theme.interface-Xg5Zi46a.cjs");var R=Object.defineProperty,X=Object.getOwnPropertyDescriptor,g=(e,t,n,i)=>{for(var c,r=i>1?void 0:i?X(t,n):t,h=e.length-1;h>=0;h--)(c=e[h])&&(r=(i?c(t,n,r):c(r))||r);return i&&r&&R(t,n,r),r};exports.SchmancyBadgeV2=class extends _.TailwindElement(l.css`
|
|
2
2
|
:host {
|
|
3
3
|
display: inline-flex;
|
|
4
4
|
}
|
|
@@ -202,4 +202,4 @@
|
|
|
202
202
|
`}getColorAttributes(){const e={primary:{bgColor:o.SchmancyTheme.sys.color.primary.container,color:o.SchmancyTheme.sys.color.primary.onContainer},secondary:{bgColor:o.SchmancyTheme.sys.color.secondary.container,color:o.SchmancyTheme.sys.color.secondary.onContainer},tertiary:{bgColor:o.SchmancyTheme.sys.color.tertiary.container,color:o.SchmancyTheme.sys.color.tertiary.onContainer},success:{bgColor:o.SchmancyTheme.sys.color.success.container,color:o.SchmancyTheme.sys.color.success.onContainer},error:{bgColor:o.SchmancyTheme.sys.color.error.container,color:o.SchmancyTheme.sys.color.error.onContainer},neutral:{bgColor:o.SchmancyTheme.sys.color.surface.container,color:o.SchmancyTheme.sys.color.surface.on}};return C.color(e[this.color])}renderStatusIndicator(){const e={online:o.SchmancyTheme.sys.color.success.default,offline:o.SchmancyTheme.sys.color.surface.onVariant,busy:o.SchmancyTheme.sys.color.error.default,away:o.SchmancyTheme.sys.color.tertiary.default},t={"absolute bottom-0 right-0 rounded-full border-2 border-surface-default":!0,[{xs:"w-1.5 h-1.5",sm:"w-2 h-2",md:"w-2.5 h-2.5",lg:"w-3 h-3",xl:"w-4 h-4"}[this.size]]:!0};return l.html`
|
|
203
203
|
<div class="${this.classMap(t)}" style="background-color: ${e[this.status]};"></div>
|
|
204
204
|
`}},u([a.property({type:String})],exports.SchmancyAvatar.prototype,"initials",2),u([a.property({type:String})],exports.SchmancyAvatar.prototype,"src",2),u([a.property({type:String})],exports.SchmancyAvatar.prototype,"icon",2),u([a.property({type:String})],exports.SchmancyAvatar.prototype,"size",2),u([a.property({type:String})],exports.SchmancyAvatar.prototype,"color",2),u([a.property({type:String})],exports.SchmancyAvatar.prototype,"shape",2),u([a.property({type:Boolean})],exports.SchmancyAvatar.prototype,"bordered",2),u([a.property({type:String})],exports.SchmancyAvatar.prototype,"status",2),exports.SchmancyAvatar=u([a.customElement("schmancy-avatar")],exports.SchmancyAvatar),exports.$drawer=Q,exports.HereMorty=B,exports.SchmancyContentDrawerID=P,exports.SchmancyContentDrawerMaxHeight=M,exports.SchmancyContentDrawerMinWidth=k,exports.SchmancyContentDrawerSheetMode=q,exports.SchmancyContentDrawerSheetState=A,exports.SchmancyDrawerNavbarMode=O,exports.SchmancyDrawerNavbarState=z,exports.WhereAreYouRicky=I,exports.schmancyContentDrawer=V,exports.schmancyNavDrawer=H,exports.teleport=x;
|
|
205
|
-
//# sourceMappingURL=avatar-
|
|
205
|
+
//# sourceMappingURL=avatar-Bws6p1iq.cjs.map
|