@capgo/capacitor-transitions 8.0.3 → 8.1.0
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/README.md +50 -3
- package/dist/{chunk-LABKGL2K.mjs → chunk-B6BVMPJ3.mjs} +58 -7
- package/dist/chunk-B6BVMPJ3.mjs.map +1 -0
- package/dist/{components-M5B63NYZ.mjs → components-HRZG74NZ.mjs} +2 -2
- package/dist/index.d.mts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +63 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +13 -1
- package/dist/react/index.d.ts +13 -1
- package/dist/react/index.js +68 -7
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +67 -7
- package/dist/react/index.mjs.map +1 -1
- package/dist/solid/index.d.mts +10 -1
- package/dist/solid/index.d.ts +10 -1
- package/dist/solid/index.js +68 -7
- package/dist/solid/index.js.map +1 -1
- package/dist/solid/index.mjs +67 -7
- package/dist/solid/index.mjs.map +1 -1
- package/dist/svelte/index.d.mts +10 -1
- package/dist/svelte/index.d.ts +10 -1
- package/dist/svelte/index.js +70 -9
- package/dist/svelte/index.js.map +1 -1
- package/dist/svelte/index.mjs +68 -8
- package/dist/svelte/index.mjs.map +1 -1
- package/dist/vue/index.d.mts +10 -1
- package/dist/vue/index.d.ts +10 -1
- package/dist/vue/index.js +68 -7
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/index.mjs +67 -7
- package/dist/vue/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-LABKGL2K.mjs.map +0 -1
- /package/dist/{components-M5B63NYZ.mjs.map → components-HRZG74NZ.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
Framework-agnostic page transitions for Capacitor apps. iOS-style navigation without opinions.
|
|
11
11
|
|
|
12
|
+
## Demo
|
|
13
|
+
|
|
14
|
+
<img src="./docs/demo.webp" alt="Demo of capacitor-transitions in action" width="300" />
|
|
15
|
+
|
|
12
16
|
## Features
|
|
13
17
|
|
|
14
18
|
- **Framework Agnostic** - Works with React, Vue, Angular, Svelte, Solid, and any other framework
|
|
@@ -66,6 +70,11 @@ const outlet = document.querySelector('cap-router-outlet');
|
|
|
66
70
|
outlet.push(newPageElement);
|
|
67
71
|
outlet.pop();
|
|
68
72
|
outlet.setRoot(newRootElement);
|
|
73
|
+
outlet.setRoot(onboardingDoneElement, { direction: 'forward' });
|
|
74
|
+
|
|
75
|
+
// For router-driven replace/reset flows, reset the stack but keep a forward slide.
|
|
76
|
+
outlet.setNavigation('root', 'forward');
|
|
77
|
+
yourRouter.replace('/home');
|
|
69
78
|
```
|
|
70
79
|
|
|
71
80
|
### React
|
|
@@ -73,7 +82,13 @@ outlet.setRoot(newRootElement);
|
|
|
73
82
|
```tsx
|
|
74
83
|
import { useRef, useEffect } from 'react';
|
|
75
84
|
import { useNavigate } from 'react-router-dom';
|
|
76
|
-
import {
|
|
85
|
+
import {
|
|
86
|
+
initTransitions,
|
|
87
|
+
setDirection,
|
|
88
|
+
setNavigation,
|
|
89
|
+
setupPage,
|
|
90
|
+
setupRouterOutlet,
|
|
91
|
+
} from '@capgo/capacitor-transitions/react';
|
|
77
92
|
import '@capgo/capacitor-transitions';
|
|
78
93
|
|
|
79
94
|
// Initialize once at app startup
|
|
@@ -115,6 +130,11 @@ function HomePage() {
|
|
|
115
130
|
navigate(`/details/${id}`);
|
|
116
131
|
};
|
|
117
132
|
|
|
133
|
+
const finishOnboarding = () => {
|
|
134
|
+
setNavigation('root', 'forward');
|
|
135
|
+
navigate('/home', { replace: true });
|
|
136
|
+
};
|
|
137
|
+
|
|
118
138
|
return (
|
|
119
139
|
<cap-page ref={pageRef}>
|
|
120
140
|
<cap-header slot="header">
|
|
@@ -364,7 +384,7 @@ Drive both packages from the same router actions:
|
|
|
364
384
|
|
|
365
385
|
```typescript
|
|
366
386
|
import { NativeNavigation } from '@capgo/native-navigation';
|
|
367
|
-
import { setDirection } from '@capgo/capacitor-transitions/react';
|
|
387
|
+
import { setDirection, setNavigation } from '@capgo/capacitor-transitions/react';
|
|
368
388
|
import { router } from './router';
|
|
369
389
|
|
|
370
390
|
await NativeNavigation.addListener('navbarBack', () => {
|
|
@@ -381,6 +401,16 @@ async function openMessage(id: string) {
|
|
|
381
401
|
backButton: { visible: true, title: 'Inbox' },
|
|
382
402
|
});
|
|
383
403
|
}
|
|
404
|
+
|
|
405
|
+
async function finishOnboarding() {
|
|
406
|
+
setNavigation('root', 'forward');
|
|
407
|
+
router.replace('/inbox');
|
|
408
|
+
|
|
409
|
+
await NativeNavigation.setNavbar({
|
|
410
|
+
title: 'Inbox',
|
|
411
|
+
backButton: { visible: false },
|
|
412
|
+
});
|
|
413
|
+
}
|
|
384
414
|
```
|
|
385
415
|
|
|
386
416
|
Do not render the native top bar again as a moving `<cap-header>`. Native Navigation keeps the bar native; this package animates the web page body.
|
|
@@ -405,7 +435,8 @@ Methods:
|
|
|
405
435
|
|
|
406
436
|
- `push(element, config?)` - Navigate forward to new page
|
|
407
437
|
- `pop(config?)` - Navigate back
|
|
408
|
-
- `setRoot(element, config?)` - Replace navigation stack
|
|
438
|
+
- `setRoot(element, config?)` - Replace navigation stack. Pass `{ direction: 'forward' }` to reset the stack with a forward slide.
|
|
439
|
+
- `setNavigation(action, direction?)` - Set the stack action and animation direction for the next router-driven navigation
|
|
409
440
|
- `setSwipeGesture(true | false | 'auto')` - Enable, disable, or auto-detect edge swipe-back gesture
|
|
410
441
|
|
|
411
442
|
`swipe-gesture="auto"` uses Capacitor's runtime helpers (`Capacitor.isNativePlatform()` and `Capacitor.getPlatform()`) and enables the gesture only for native iOS apps. Use `swipe-gesture="true"` to force it on any platform or `swipe-gesture="false"` to disable it.
|
|
@@ -448,6 +479,17 @@ Footer container. Use with `slot="footer"`.
|
|
|
448
479
|
| `'root'` | Replace animation (fade) |
|
|
449
480
|
| `'none'` | No animation |
|
|
450
481
|
|
|
482
|
+
### Navigation Actions
|
|
483
|
+
|
|
484
|
+
Navigation actions control the recorded stack independently from the visual animation. This is useful when a router `replace` or native navigation reset should feel like a forward page push but must not leave a swipe-back entry behind.
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
setNavigation('root', 'forward');
|
|
488
|
+
router.replace('/home');
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
`setNavigation('root', 'forward')` clears the transition stack after the navigation and plays the forward animation. Swipe-back stays disabled because there is no previous page.
|
|
492
|
+
|
|
451
493
|
### Helper Functions
|
|
452
494
|
|
|
453
495
|
All framework bindings export these helper functions:
|
|
@@ -459,6 +501,10 @@ initTransitions({ platform: 'auto' });
|
|
|
459
501
|
// Set the direction for the next navigation
|
|
460
502
|
setDirection('forward' | 'back' | 'root' | 'none');
|
|
461
503
|
|
|
504
|
+
// Set the stack action and animation direction for the next navigation
|
|
505
|
+
setNavigation('root', 'forward');
|
|
506
|
+
setNavigation('root'); // direction is optional and defaults to the same value as the stack action.
|
|
507
|
+
|
|
462
508
|
// Set up a router outlet element
|
|
463
509
|
setupRouterOutlet(element, options);
|
|
464
510
|
|
|
@@ -494,6 +540,7 @@ const controller = createTransitionController({
|
|
|
494
540
|
await controller.push(element, { direction: 'forward' });
|
|
495
541
|
await controller.pop({ direction: 'back' });
|
|
496
542
|
await controller.setRoot(element, { direction: 'root' });
|
|
543
|
+
await controller.setRoot(element, { direction: 'forward' });
|
|
497
544
|
|
|
498
545
|
// Lifecycle hooks
|
|
499
546
|
controller.registerLifecycle('page-id', {
|
|
@@ -22,6 +22,21 @@ function isNativeSwipeGesturePlatform() {
|
|
|
22
22
|
return isNative && platform === "ios";
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
// src/core/navigation.ts
|
|
26
|
+
function getDefaultNavigationDirection(action) {
|
|
27
|
+
return action;
|
|
28
|
+
}
|
|
29
|
+
function setOutletDirectionIntent(outlet, direction) {
|
|
30
|
+
const element = outlet;
|
|
31
|
+
element.dataset.direction = direction;
|
|
32
|
+
delete element.dataset.navigationAction;
|
|
33
|
+
}
|
|
34
|
+
function setOutletNavigationIntent(outlet, action, direction = getDefaultNavigationDirection(action)) {
|
|
35
|
+
const element = outlet;
|
|
36
|
+
element.dataset.navigationAction = action;
|
|
37
|
+
element.dataset.direction = direction;
|
|
38
|
+
}
|
|
39
|
+
|
|
25
40
|
// src/core/animations.ts
|
|
26
41
|
var IOS_EASING = "cubic-bezier(0.32, 0.72, 0, 1)";
|
|
27
42
|
var ANDROID_EASING = "cubic-bezier(0.36, 0.66, 0.04, 1)";
|
|
@@ -963,19 +978,24 @@ var TransitionController = class {
|
|
|
963
978
|
* Replace all pages with a new root
|
|
964
979
|
*/
|
|
965
980
|
async setRoot(enteringEl, config = {}) {
|
|
966
|
-
return this.navigate(enteringEl, {
|
|
981
|
+
return this.navigate(enteringEl, {
|
|
982
|
+
...config,
|
|
983
|
+
direction: config.direction ?? "root",
|
|
984
|
+
navigationAction: "root"
|
|
985
|
+
});
|
|
967
986
|
}
|
|
968
987
|
/**
|
|
969
988
|
* Main navigation method
|
|
970
989
|
*/
|
|
971
990
|
async navigate(enteringEl, config = {}) {
|
|
972
991
|
const direction = config.direction || "forward";
|
|
992
|
+
const navigationAction = this.resolveNavigationAction(direction, config.navigationAction);
|
|
973
993
|
const enteringState = this.createPageState(enteringEl);
|
|
974
994
|
const leavingState = this.currentPage;
|
|
975
995
|
return this.navigateWithStates(enteringState, leavingState, config, () => {
|
|
976
|
-
if (
|
|
996
|
+
if (navigationAction === "root") {
|
|
977
997
|
this.pageStack = [enteringState];
|
|
978
|
-
} else if (
|
|
998
|
+
} else if (navigationAction === "back" && this.pageStack.length > 0) {
|
|
979
999
|
this.pageStack.pop();
|
|
980
1000
|
const staleEnteringState = this.pageStack.pop();
|
|
981
1001
|
if (staleEnteringState && staleEnteringState.element !== enteringState.element) {
|
|
@@ -983,11 +1003,27 @@ var TransitionController = class {
|
|
|
983
1003
|
this.lifecycleCallbacks.delete(staleEnteringState.id);
|
|
984
1004
|
}
|
|
985
1005
|
this.pageStack.push(enteringState);
|
|
1006
|
+
} else if (navigationAction === "none" && this.pageStack.length > 0) {
|
|
1007
|
+
const staleState = this.pageStack.pop();
|
|
1008
|
+
if (staleState && staleState.element !== enteringState.element) {
|
|
1009
|
+
staleState.element.remove();
|
|
1010
|
+
this.lifecycleCallbacks.delete(staleState.id);
|
|
1011
|
+
}
|
|
1012
|
+
this.pageStack.push(enteringState);
|
|
986
1013
|
} else {
|
|
987
1014
|
this.pageStack.push(enteringState);
|
|
988
1015
|
}
|
|
989
1016
|
});
|
|
990
1017
|
}
|
|
1018
|
+
resolveNavigationAction(direction, navigationAction) {
|
|
1019
|
+
if (navigationAction) {
|
|
1020
|
+
return navigationAction;
|
|
1021
|
+
}
|
|
1022
|
+
if (direction === "root" || direction === "back") {
|
|
1023
|
+
return direction;
|
|
1024
|
+
}
|
|
1025
|
+
return "forward";
|
|
1026
|
+
}
|
|
991
1027
|
/**
|
|
992
1028
|
* Navigate between two known page states
|
|
993
1029
|
*/
|
|
@@ -1448,20 +1484,29 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1448
1484
|
*/
|
|
1449
1485
|
async handleNewPage(page) {
|
|
1450
1486
|
const outletDirection = this.dataset.direction;
|
|
1487
|
+
const outletNavigationAction = this.dataset.navigationAction;
|
|
1451
1488
|
const explicitDirection = page.dataset.direction || outletDirection;
|
|
1489
|
+
const explicitNavigationAction = page.dataset.navigationAction || outletNavigationAction;
|
|
1452
1490
|
const direction = this.resolveNavigationDirection(explicitDirection);
|
|
1453
1491
|
if (outletDirection) {
|
|
1454
1492
|
delete this.dataset.direction;
|
|
1455
1493
|
}
|
|
1494
|
+
if (outletNavigationAction) {
|
|
1495
|
+
delete this.dataset.navigationAction;
|
|
1496
|
+
}
|
|
1456
1497
|
const skipTransition = this.skipNextHistoryBackTransition && direction === "back";
|
|
1457
1498
|
this.skipNextHistoryBackTransition = false;
|
|
1458
1499
|
const hadPageBefore = this.controller.stack.length > 0;
|
|
1459
1500
|
this.stylePageForTransition(page);
|
|
1460
1501
|
this.pendingPage = page;
|
|
1461
1502
|
try {
|
|
1462
|
-
const result = await this.controller.navigate(page, {
|
|
1503
|
+
const result = await this.controller.navigate(page, {
|
|
1504
|
+
direction,
|
|
1505
|
+
navigationAction: explicitNavigationAction,
|
|
1506
|
+
duration: skipTransition ? 0 : void 0
|
|
1507
|
+
});
|
|
1463
1508
|
if (result.success) {
|
|
1464
|
-
this.recordCompletedNavigation(direction, { hadPageBefore });
|
|
1509
|
+
this.recordCompletedNavigation(explicitNavigationAction ?? direction, { hadPageBefore });
|
|
1465
1510
|
}
|
|
1466
1511
|
} finally {
|
|
1467
1512
|
this.pendingPage = null;
|
|
@@ -1590,6 +1635,12 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1590
1635
|
this.updateSwipeGestureListeners();
|
|
1591
1636
|
}
|
|
1592
1637
|
}
|
|
1638
|
+
/**
|
|
1639
|
+
* Set the navigation stack action and animation direction for the next router-driven navigation.
|
|
1640
|
+
*/
|
|
1641
|
+
setNavigation(action, direction = getDefaultNavigationDirection(action)) {
|
|
1642
|
+
setOutletNavigationIntent(this, action, direction);
|
|
1643
|
+
}
|
|
1593
1644
|
/**
|
|
1594
1645
|
* Get the transition controller for advanced usage
|
|
1595
1646
|
*/
|
|
@@ -1988,7 +2039,7 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1988
2039
|
}
|
|
1989
2040
|
if (shouldUseHistory) {
|
|
1990
2041
|
this.skipNextHistoryBackTransition = true;
|
|
1991
|
-
this
|
|
2042
|
+
setOutletDirectionIntent(this, "back");
|
|
1992
2043
|
window.history.back();
|
|
1993
2044
|
return;
|
|
1994
2045
|
}
|
|
@@ -2438,4 +2489,4 @@ export {
|
|
|
2438
2489
|
CapContent,
|
|
2439
2490
|
CapFooter
|
|
2440
2491
|
};
|
|
2441
|
-
//# sourceMappingURL=chunk-
|
|
2492
|
+
//# sourceMappingURL=chunk-B6BVMPJ3.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/native-platform.ts","../src/core/navigation.ts","../src/core/animations.ts","../src/core/view-transitions.ts","../src/core/transition-controller.ts","../src/components/cap-router-outlet.ts","../src/components/cap-page.ts","../src/components/cap-header.ts","../src/components/cap-content.ts","../src/components/cap-footer.ts"],"sourcesContent":["import type { NativePlatform, NativePlatformInfo } from './types';\n\ninterface CapacitorRuntime {\n getPlatform?: () => string;\n isNativePlatform?: () => boolean;\n}\n\nfunction getCapacitorRuntime(): CapacitorRuntime | undefined {\n return (globalThis as { Capacitor?: CapacitorRuntime }).Capacitor;\n}\n\nfunction normalizePlatform(platform: string | undefined): NativePlatform {\n if (platform === 'ios' || platform === 'android' || platform === 'web') {\n return platform;\n }\n\n return 'unknown';\n}\n\nexport function detectNativePlatform(): NativePlatformInfo {\n const capacitor = getCapacitorRuntime();\n const platform = normalizePlatform(capacitor?.getPlatform?.());\n const isNative = capacitor?.isNativePlatform?.() ?? (platform === 'ios' || platform === 'android');\n\n return {\n platform,\n isNative,\n };\n}\n\nexport function isNativeSwipeGesturePlatform(): boolean {\n const { platform, isNative } = detectNativePlatform();\n\n return isNative && platform === 'ios';\n}\n","import type { NavigationAction, TransitionDirection } from './types';\n\nexport function getDefaultNavigationDirection(action: NavigationAction): TransitionDirection {\n return action;\n}\n\nexport function setOutletDirectionIntent(outlet: Element, direction: TransitionDirection): void {\n const element = outlet as HTMLElement;\n element.dataset.direction = direction;\n delete element.dataset.navigationAction;\n}\n\nexport function setOutletNavigationIntent(\n outlet: Element,\n action: NavigationAction,\n direction: TransitionDirection = getDefaultNavigationDirection(action),\n): void {\n const element = outlet as HTMLElement;\n element.dataset.navigationAction = action;\n element.dataset.direction = direction;\n}\n","/**\n * Core animation system using Web Animations API\n * Provides iOS and Android style page transitions\n */\n\nimport type { TransitionAnimationOptions, TransitionEasing, TransitionPlatform, ResolvedPlatform } from './types';\n\n/** iOS easing curve - matches UIKit spring animation feel */\nexport const IOS_EASING = 'cubic-bezier(0.32, 0.72, 0, 1)';\n\n/** Android Material Design forward easing */\nexport const ANDROID_EASING = 'cubic-bezier(0.36, 0.66, 0.04, 1)';\n\n/** Android Material Design back easing */\nexport const ANDROID_BACK_EASING = 'cubic-bezier(0.47, 0, 0.745, 0.715)';\n\n/** Default iOS transition duration */\nexport const IOS_DURATION = 540;\n\n/** Default Android forward transition duration */\nexport const ANDROID_DURATION = 280;\n\n/** Default Android back transition duration */\nexport const ANDROID_BACK_DURATION = 200;\n\nconst IOS_OFF_OPACITY = 0.8;\nconst IOS_CENTER = '0%';\nconst IOS_OFF_RIGHT = '99.5%';\nconst IOS_OFF_LEFT = '-33%';\nconst IOS_OFF_RIGHT_RTL = '-99.5%';\nconst IOS_OFF_LEFT_RTL = '33%';\nconst MD_OFF_BOTTOM = '40px';\nconst MD_CENTER = '0px';\n\n/**\n * Resolve easing string to CSS value\n */\nexport function resolveEasing(easing: TransitionEasing): string {\n switch (easing) {\n case 'ios':\n return IOS_EASING;\n case 'android':\n return ANDROID_EASING;\n case 'linear':\n return 'linear';\n case 'ease':\n return 'ease';\n case 'ease-in':\n return 'ease-in';\n case 'ease-out':\n return 'ease-out';\n case 'ease-in-out':\n return 'ease-in-out';\n default:\n return easing; // Custom cubic-bezier\n }\n}\n\n/**\n * Detect platform from user agent\n */\nexport function detectPlatform(): ResolvedPlatform {\n if (typeof navigator === 'undefined') return 'ios';\n\n const ua = navigator.userAgent.toLowerCase();\n\n if (/iphone|ipad|ipod/.test(ua)) return 'ios';\n if (/android/.test(ua)) return 'android';\n\n // Default to iOS for web/desktop - it's the more polished animation\n return 'ios';\n}\n\n/**\n * Get default duration for platform\n */\nexport function getDefaultDuration(\n platform: TransitionPlatform,\n direction: 'forward' | 'back' | 'root' | 'none' = 'forward',\n): number {\n const resolved = platform === 'auto' ? detectPlatform() : platform;\n if (resolved === 'ios') {\n return IOS_DURATION;\n }\n return direction === 'back' ? ANDROID_BACK_DURATION : ANDROID_DURATION;\n}\n\n/**\n * Get default easing for platform\n */\nexport function getDefaultEasing(\n platform: TransitionPlatform,\n direction: 'forward' | 'back' | 'root' | 'none' = 'forward',\n): string {\n const resolved = platform === 'auto' ? detectPlatform() : platform;\n if (resolved === 'ios') {\n return IOS_EASING;\n }\n return direction === 'back' ? ANDROID_BACK_EASING : ANDROID_EASING;\n}\n\nfunction getDocumentDirection(element: HTMLElement): 'ltr' | 'rtl' {\n const doc = element.ownerDocument;\n return doc.dir === 'rtl' || doc.documentElement.dir === 'rtl' ? 'rtl' : 'ltr';\n}\n\nfunction preparePageLayer(element: HTMLElement, zIndex: string): void {\n element.classList.add('cap-transition-active');\n element.style.display = '';\n element.style.visibility = 'visible';\n element.style.position = 'absolute';\n element.style.top = '0';\n element.style.left = '0';\n element.style.width = '100%';\n element.style.height = '100%';\n element.style.zIndex = zIndex;\n element.style.pointerEvents = 'none';\n element.style.willChange = 'transform, opacity';\n element.style.backfaceVisibility = 'hidden';\n element.style.transformStyle = 'preserve-3d';\n}\n\nfunction createAnimation(element: HTMLElement, keyframes: Keyframe[], duration: number, easing: string): Animation {\n return element.animate(keyframes, {\n duration,\n easing,\n fill: 'both',\n });\n}\n\nfunction resolvePageContents(element: HTMLElement): HTMLElement[] {\n return Array.from(\n element.querySelectorAll<HTMLElement>(\n ':scope > [data-cap-content], :scope > .cap-content, :scope > cap-content, :scope > [slot=\"content\"]',\n ),\n );\n}\n\nfunction resolvePageChrome(element: HTMLElement): HTMLElement[] {\n return Array.from(\n element.querySelectorAll<HTMLElement>(\n ':scope > [data-cap-header], :scope > .cap-header, :scope > cap-header, :scope > [slot=\"header\"], :scope > [data-cap-footer], :scope > .cap-footer, :scope > cap-footer, :scope > [slot=\"footer\"]',\n ),\n );\n}\n\nfunction resolvePageHeaders(element: HTMLElement): HTMLElement[] {\n return Array.from(\n element.querySelectorAll<HTMLElement>(\n ':scope > [data-cap-header], :scope > .cap-header, :scope > cap-header, :scope > [slot=\"header\"]',\n ),\n );\n}\n\nfunction invertTranslateOffset(offset: string): string {\n if (offset === IOS_CENTER) {\n return IOS_CENTER;\n }\n\n return offset.startsWith('-') ? offset.slice(1) : `-${offset}`;\n}\n\nfunction createPinnedChromeAnimations(\n elements: HTMLElement[],\n fromTransform: string,\n toTransform: string,\n duration: number,\n easing: string,\n): Animation[] {\n return elements.map((element) => {\n element.style.willChange = 'transform';\n element.style.backfaceVisibility = 'hidden';\n\n return createAnimation(element, [{ transform: fromTransform }, { transform: toTransform }], duration, easing);\n });\n}\n\nfunction uniqueElements(elements: HTMLElement[]): HTMLElement[] {\n return Array.from(new Set(elements));\n}\n\nfunction resolveToolbarItems(header: HTMLElement): HTMLElement[] {\n const toolbarItems = Array.from(\n header.querySelectorAll<HTMLElement>(\n ':scope > [data-cap-toolbar] > *, :scope > .toolbar > *, :scope > [role=\"toolbar\"] > *, :scope > ion-toolbar > *',\n ),\n );\n const directItems = Array.from(\n header.querySelectorAll<HTMLElement>(\n ':scope > [data-cap-toolbar-item], :scope > .cap-toolbar-item, :scope > h1, :scope > h2, :scope > h3, :scope > button, :scope > a',\n ),\n );\n\n return uniqueElements(\n [...toolbarItems, ...directItems].filter(\n (element) =>\n !element.matches('[data-cap-toolbar-background], .toolbar-background, [aria-hidden=\"true\"]') &&\n element.tagName !== 'STYLE' &&\n element.tagName !== 'SCRIPT',\n ),\n );\n}\n\nfunction createOpacityAnimations(\n elements: HTMLElement[],\n fromOpacity: number,\n toOpacity: number,\n duration: number,\n easing: string,\n): Animation[] {\n return elements.map((element) => {\n element.style.willChange = 'opacity';\n element.style.backfaceVisibility = 'hidden';\n\n return createAnimation(element, [{ opacity: fromOpacity }, { opacity: toOpacity }], duration, easing);\n });\n}\n\nfunction createToolbarItemAnimations(\n headers: HTMLElement[],\n fromTransform: string,\n toTransform: string,\n fromOpacity: number,\n toOpacity: number,\n duration: number,\n easing: string,\n): Animation[] {\n return headers.flatMap((header) =>\n resolveToolbarItems(header).map((element) => {\n element.style.willChange = 'transform, opacity';\n element.style.backfaceVisibility = 'hidden';\n\n return createAnimation(\n element,\n [\n { transform: fromTransform, opacity: fromOpacity },\n { transform: toTransform, opacity: toOpacity },\n ],\n duration,\n easing,\n );\n }),\n );\n}\n\n/**\n * iOS-style horizontal slide transition\n * Forward: new page slides in from right\n * Back: old page slides out to right\n */\nexport function createIOSTransition(options: TransitionAnimationOptions): Animation[] {\n const { enteringEl, leavingEl, direction, duration, easing } = options;\n const animations: Animation[] = [];\n\n const isBack = direction === 'back';\n const isRoot = direction === 'root';\n const isRTL = getDocumentDirection(enteringEl) === 'rtl';\n const offRight = isRTL ? IOS_OFF_RIGHT_RTL : IOS_OFF_RIGHT;\n const offLeft = isRTL ? IOS_OFF_LEFT_RTL : IOS_OFF_LEFT;\n const chromeOffRight = invertTranslateOffset(offRight);\n const chromeOffLeft = invertTranslateOffset(offLeft);\n const leadingEdgeShadow = isRTL ? '8px 0 24px rgba(0, 0, 0, 0.18)' : '-8px 0 24px rgba(0, 0, 0, 0.18)';\n const enteringContent = resolvePageContents(enteringEl);\n const enteringHeaders = resolvePageHeaders(enteringEl);\n const leavingContent = leavingEl ? resolvePageContents(leavingEl) : [];\n const leavingHeaders = leavingEl ? resolvePageHeaders(leavingEl) : [];\n\n preparePageLayer(enteringEl, isBack ? '99' : '101');\n if (leavingEl) {\n preparePageLayer(leavingEl, '100');\n }\n\n if (isRoot) {\n animations.push(\n createAnimation(\n enteringEl,\n [\n { opacity: 0.01, transform: 'translate3d(0, 0, 0)' },\n { opacity: 1, transform: 'translate3d(0, 0, 0)' },\n ],\n duration,\n easing,\n ),\n );\n\n if (leavingEl) {\n animations.push(\n createAnimation(\n leavingEl,\n [\n { opacity: 1, transform: 'translate3d(0, 0, 0)' },\n { opacity: 0, transform: 'translate3d(0, 0, 0)' },\n ],\n Math.min(duration, 240),\n easing,\n ),\n );\n }\n } else if (isBack) {\n // Matches Ionic iOS: previous page sits behind at one-third offset and brightens as the top page exits.\n animations.push(\n ...createPinnedChromeAnimations(\n resolvePageChrome(enteringEl),\n `translate3d(${chromeOffLeft}, 0, 0)`,\n `translate3d(${IOS_CENTER}, 0, 0)`,\n duration,\n easing,\n ),\n );\n animations.push(\n createAnimation(\n enteringEl,\n [{ transform: `translate3d(${offLeft}, 0, 0)` }, { transform: `translate3d(${IOS_CENTER}, 0, 0)` }],\n duration,\n easing,\n ),\n );\n animations.push(...createOpacityAnimations(enteringContent, IOS_OFF_OPACITY, 1, duration, easing));\n animations.push(\n ...createToolbarItemAnimations(\n enteringHeaders,\n `translate3d(${offLeft}, 0, 0)`,\n `translate3d(${IOS_CENTER}, 0, 0)`,\n 0.01,\n 1,\n duration,\n easing,\n ),\n );\n\n if (leavingEl) {\n leavingEl.style.boxShadow = leadingEdgeShadow;\n animations.push(\n ...createPinnedChromeAnimations(\n resolvePageChrome(leavingEl),\n `translate3d(${IOS_CENTER}, 0, 0)`,\n `translate3d(${chromeOffRight}, 0, 0)`,\n duration,\n easing,\n ),\n );\n animations.push(\n createAnimation(\n leavingEl,\n [{ transform: `translate3d(${IOS_CENTER}, 0, 0)` }, { transform: `translate3d(${offRight}, 0, 0)` }],\n duration,\n easing,\n ),\n );\n animations.push(\n ...createToolbarItemAnimations(\n leavingHeaders,\n `translate3d(${IOS_CENTER}, 0, 0)`,\n `translate3d(${offRight}, 0, 0)`,\n 0.99,\n 0,\n duration,\n easing,\n ),\n );\n }\n } else {\n enteringEl.style.boxShadow = leadingEdgeShadow;\n animations.push(\n ...createPinnedChromeAnimations(\n resolvePageChrome(enteringEl),\n `translate3d(${chromeOffRight}, 0, 0)`,\n `translate3d(${IOS_CENTER}, 0, 0)`,\n duration,\n easing,\n ),\n );\n animations.push(\n createAnimation(\n enteringEl,\n [{ transform: `translate3d(${offRight}, 0, 0)` }, { transform: `translate3d(${IOS_CENTER}, 0, 0)` }],\n duration,\n easing,\n ),\n );\n animations.push(\n ...createToolbarItemAnimations(\n enteringHeaders,\n `translate3d(${offRight}, 0, 0)`,\n `translate3d(${IOS_CENTER}, 0, 0)`,\n 0.01,\n 1,\n duration,\n easing,\n ),\n );\n\n if (leavingEl) {\n animations.push(\n ...createPinnedChromeAnimations(\n resolvePageChrome(leavingEl),\n `translate3d(${IOS_CENTER}, 0, 0)`,\n `translate3d(${chromeOffLeft}, 0, 0)`,\n duration,\n easing,\n ),\n );\n animations.push(\n createAnimation(\n leavingEl,\n [{ transform: `translate3d(${IOS_CENTER}, 0, 0)` }, { transform: `translate3d(${offLeft}, 0, 0)` }],\n duration,\n easing,\n ),\n );\n animations.push(...createOpacityAnimations(leavingContent, 1, IOS_OFF_OPACITY, duration, easing));\n animations.push(\n ...createToolbarItemAnimations(\n leavingHeaders,\n `translate3d(${IOS_CENTER}, 0, 0)`,\n `translate3d(${offLeft}, 0, 0)`,\n 0.99,\n 0,\n duration,\n easing,\n ),\n );\n }\n }\n\n return animations;\n}\n\n/**\n * Android-style vertical slide transition\n * Forward: new page slides up from bottom\n * Back: old page slides down to bottom\n */\nexport function createAndroidTransition(options: TransitionAnimationOptions): Animation[] {\n const { enteringEl, leavingEl, direction, duration, easing } = options;\n const animations: Animation[] = [];\n\n const isBack = direction === 'back';\n const isRoot = direction === 'root';\n\n preparePageLayer(enteringEl, isBack ? '99' : '101');\n if (leavingEl) {\n preparePageLayer(leavingEl, '100');\n }\n\n if (isRoot) {\n animations.push(\n createAnimation(\n enteringEl,\n [\n { opacity: 0.01, transform: `translate3d(0, ${MD_OFF_BOTTOM}, 0)` },\n { opacity: 1, transform: `translate3d(0, ${MD_CENTER}, 0)` },\n ],\n duration,\n easing,\n ),\n );\n\n if (leavingEl) {\n animations.push(\n createAnimation(\n leavingEl,\n [\n { opacity: 1, transform: `translate3d(0, ${MD_CENTER}, 0)` },\n { opacity: 0, transform: `translate3d(0, ${MD_CENTER}, 0)` },\n ],\n Math.min(duration, ANDROID_BACK_DURATION),\n ANDROID_BACK_EASING,\n ),\n );\n }\n } else if (isBack) {\n enteringEl.style.opacity = '1';\n enteringEl.style.transform = `translate3d(0, ${MD_CENTER}, 0)`;\n\n if (leavingEl) {\n animations.push(\n createAnimation(\n leavingEl,\n [\n { opacity: 1, transform: `translate3d(0, ${MD_CENTER}, 0)` },\n { opacity: 0, transform: `translate3d(0, ${MD_OFF_BOTTOM}, 0)` },\n ],\n duration,\n easing,\n ),\n );\n }\n } else {\n animations.push(\n createAnimation(\n enteringEl,\n [\n { opacity: 0.01, transform: `translate3d(0, ${MD_OFF_BOTTOM}, 0)` },\n { opacity: 1, transform: `translate3d(0, ${MD_CENTER}, 0)` },\n ],\n duration,\n easing,\n ),\n );\n\n if (leavingEl) {\n leavingEl.style.opacity = '1';\n leavingEl.style.transform = `translate3d(0, ${MD_CENTER}, 0)`;\n }\n }\n\n return animations;\n}\n\n/**\n * No animation - instant transition\n */\nexport function createNoneTransition(options: TransitionAnimationOptions): Animation[] {\n const { enteringEl, leavingEl } = options;\n\n enteringEl.style.opacity = '1';\n enteringEl.style.transform = 'none';\n\n if (leavingEl) {\n leavingEl.style.opacity = '0';\n leavingEl.style.transform = 'none';\n }\n\n return [];\n}\n\n/**\n * Create platform-appropriate transition\n */\nexport function createTransition(\n options: TransitionAnimationOptions,\n platform: TransitionPlatform = 'auto',\n): Animation[] {\n if (options.direction === 'none') {\n return createNoneTransition(options);\n }\n\n const resolved = platform === 'auto' ? detectPlatform() : platform;\n\n if (resolved === 'android') {\n return createAndroidTransition(options);\n }\n\n return createIOSTransition(options);\n}\n\n/**\n * Wait for all animations to complete\n */\nexport async function waitForAnimations(animations: Animation[]): Promise<void> {\n if (animations.length === 0) return;\n\n await Promise.all(animations.map((anim) => anim.finished.catch(() => undefined)));\n}\n\n/**\n * Cancel all animations\n */\nexport function cancelAnimations(animations: Animation[]): void {\n animations.forEach((anim) => anim.cancel());\n}\n\n/**\n * Create header-specific animation\n * Headers can have different animations (e.g., title changes, back button appears)\n */\nexport function createHeaderTransition(\n options: TransitionAnimationOptions & {\n enteringHeader?: HTMLElement;\n leavingHeader?: HTMLElement;\n },\n): Animation[] {\n const { enteringHeader, leavingHeader, direction, duration, easing } = options;\n const animations: Animation[] = [];\n\n const isBack = direction === 'back';\n\n if (enteringHeader) {\n if (isBack) {\n // Header fades in from left\n const enterAnim = enteringHeader.animate(\n [\n { opacity: 0, transform: 'translateX(-20px)' },\n { opacity: 1, transform: 'translateX(0)' },\n ],\n { duration: duration * 0.7, easing, fill: 'forwards' },\n );\n animations.push(enterAnim);\n } else {\n // Header fades in from right\n const enterAnim = enteringHeader.animate(\n [\n { opacity: 0, transform: 'translateX(20px)' },\n { opacity: 1, transform: 'translateX(0)' },\n ],\n { duration: duration * 0.7, easing, fill: 'forwards' },\n );\n animations.push(enterAnim);\n }\n }\n\n if (leavingHeader) {\n if (isBack) {\n // Header fades out to right\n const leaveAnim = leavingHeader.animate(\n [\n { opacity: 1, transform: 'translateX(0)' },\n { opacity: 0, transform: 'translateX(20px)' },\n ],\n { duration: duration * 0.7, easing, fill: 'forwards' },\n );\n animations.push(leaveAnim);\n } else {\n // Header fades out to left\n const leaveAnim = leavingHeader.animate(\n [\n { opacity: 1, transform: 'translateX(0)' },\n { opacity: 0, transform: 'translateX(-20px)' },\n ],\n { duration: duration * 0.7, easing, fill: 'forwards' },\n );\n animations.push(leaveAnim);\n }\n }\n\n return animations;\n}\n\n/**\n * Create footer-specific animation\n * Footers typically stay in place or fade\n */\nexport function createFooterTransition(\n options: TransitionAnimationOptions & {\n enteringFooter?: HTMLElement;\n leavingFooter?: HTMLElement;\n },\n): Animation[] {\n const { enteringFooter, leavingFooter, duration, easing } = options;\n const animations: Animation[] = [];\n\n // Footers typically just fade in/out if they change\n if (enteringFooter && leavingFooter && enteringFooter !== leavingFooter) {\n const enterAnim = enteringFooter.animate([{ opacity: 0 }, { opacity: 1 }], {\n duration: duration * 0.5,\n easing,\n fill: 'forwards',\n });\n animations.push(enterAnim);\n\n const leaveAnim = leavingFooter.animate([{ opacity: 1 }, { opacity: 0 }], {\n duration: duration * 0.5,\n easing,\n fill: 'forwards',\n });\n animations.push(leaveAnim);\n }\n\n return animations;\n}\n","/**\n * View Transitions API support\n * Progressive enhancement for browsers that support it\n */\n\nimport type { TransitionDirection } from './types';\n\n/** Check if View Transitions API is supported */\nexport function supportsViewTransitions(): boolean {\n return typeof document !== 'undefined' && 'startViewTransition' in document;\n}\n\n/** View transition options */\nexport interface ViewTransitionOptions {\n /** Callback to update the DOM */\n update: () => void | Promise<void>;\n /** Direction for animation classes */\n direction?: TransitionDirection;\n /** Custom view transition names to apply */\n names?: {\n header?: string;\n content?: string;\n footer?: string;\n };\n /** Skip animation */\n skipAnimation?: boolean;\n}\n\n/**\n * Run a transition with View Transitions API if available\n * Falls back to immediate update if not supported\n */\nexport async function runViewTransition(options: ViewTransitionOptions): Promise<void> {\n const { update, direction = 'forward', skipAnimation = false } = options;\n\n if (skipAnimation || !supportsViewTransitions()) {\n await update();\n return;\n }\n\n // Add direction class for CSS targeting\n const root = document.documentElement;\n root.dataset.transitionDirection = direction;\n\n try {\n const transition = (\n document as Document & { startViewTransition: (cb: () => Promise<void>) => { finished: Promise<void> } }\n ).startViewTransition(async () => {\n await update();\n });\n\n await transition.finished;\n } finally {\n delete root.dataset.transitionDirection;\n }\n}\n\n/**\n * Apply view transition name to an element\n */\nexport function setViewTransitionName(element: HTMLElement, name: string): void {\n element.style.viewTransitionName = name;\n}\n\n/**\n * Remove view transition name from an element\n */\nexport function clearViewTransitionName(element: HTMLElement): void {\n element.style.viewTransitionName = '';\n}\n\n/**\n * CSS for View Transitions API integration\n * This can be injected into the page to enable smooth transitions\n */\nexport const VIEW_TRANSITIONS_CSS = `\n/* View Transitions API base styles */\n::view-transition-old(root),\n::view-transition-new(root) {\n animation-duration: 0.4s;\n animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);\n}\n\n/* iOS-style forward navigation */\n[data-transition-direction=\"forward\"]::view-transition-old(root) {\n animation-name: cap-slide-out-left;\n}\n\n[data-transition-direction=\"forward\"]::view-transition-new(root) {\n animation-name: cap-slide-in-right;\n}\n\n/* iOS-style back navigation */\n[data-transition-direction=\"back\"]::view-transition-old(root) {\n animation-name: cap-slide-out-right;\n}\n\n[data-transition-direction=\"back\"]::view-transition-new(root) {\n animation-name: cap-slide-in-left;\n}\n\n/* Root/replace navigation - fade */\n[data-transition-direction=\"root\"]::view-transition-old(root) {\n animation-name: cap-fade-out;\n}\n\n[data-transition-direction=\"root\"]::view-transition-new(root) {\n animation-name: cap-fade-in;\n}\n\n/* Header transitions */\n::view-transition-old(cap-header),\n::view-transition-new(cap-header) {\n animation-duration: 0.3s;\n}\n\n[data-transition-direction=\"forward\"]::view-transition-old(cap-header) {\n animation-name: cap-header-out-left;\n}\n\n[data-transition-direction=\"forward\"]::view-transition-new(cap-header) {\n animation-name: cap-header-in-right;\n}\n\n[data-transition-direction=\"back\"]::view-transition-old(cap-header) {\n animation-name: cap-header-out-right;\n}\n\n[data-transition-direction=\"back\"]::view-transition-new(cap-header) {\n animation-name: cap-header-in-left;\n}\n\n/* Content transitions */\n::view-transition-old(cap-content),\n::view-transition-new(cap-content) {\n animation-duration: 0.4s;\n animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);\n}\n\n[data-transition-direction=\"forward\"]::view-transition-old(cap-content) {\n animation-name: cap-slide-out-left;\n}\n\n[data-transition-direction=\"forward\"]::view-transition-new(cap-content) {\n animation-name: cap-slide-in-right;\n}\n\n[data-transition-direction=\"back\"]::view-transition-old(cap-content) {\n animation-name: cap-slide-out-right;\n}\n\n[data-transition-direction=\"back\"]::view-transition-new(cap-content) {\n animation-name: cap-slide-in-left;\n}\n\n/* Animation keyframes */\n@keyframes cap-slide-in-right {\n from {\n transform: translateX(100%);\n opacity: 1;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes cap-slide-out-left {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(-30%);\n opacity: 0.8;\n }\n}\n\n@keyframes cap-slide-in-left {\n from {\n transform: translateX(-30%);\n opacity: 0.8;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes cap-slide-out-right {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(100%);\n opacity: 1;\n }\n}\n\n@keyframes cap-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@keyframes cap-fade-out {\n from { opacity: 1; }\n to { opacity: 0; }\n}\n\n@keyframes cap-header-in-right {\n from {\n transform: translateX(20px);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes cap-header-out-left {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(-20px);\n opacity: 0;\n }\n}\n\n@keyframes cap-header-in-left {\n from {\n transform: translateX(-20px);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes cap-header-out-right {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(20px);\n opacity: 0;\n }\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n ::view-transition-old(root),\n ::view-transition-new(root),\n ::view-transition-old(cap-header),\n ::view-transition-new(cap-header),\n ::view-transition-old(cap-content),\n ::view-transition-new(cap-content) {\n animation-duration: 0.01ms !important;\n }\n}\n`;\n\n/**\n * Inject View Transitions CSS into the page\n */\nexport function injectViewTransitionsCSS(): void {\n if (typeof document === 'undefined') return;\n\n const styleId = 'cap-view-transitions-css';\n if (document.getElementById(styleId)) return;\n\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = VIEW_TRANSITIONS_CSS;\n document.head.appendChild(style);\n}\n","/**\n * Transition Controller\n * Orchestrates page transitions and manages the navigation stack\n */\n\nimport {\n createTransition,\n waitForAnimations,\n cancelAnimations,\n getDefaultDuration,\n getDefaultEasing,\n resolveEasing,\n detectPlatform,\n} from './animations';\nimport type {\n TransitionConfig,\n TransitionGlobalConfig,\n TransitionResult,\n PageState,\n NavigationEvent,\n TransitionLifecycle,\n TransitionAnimationOptions,\n NavigationAction,\n TransitionDirection,\n} from './types';\nimport {\n supportsViewTransitions,\n runViewTransition,\n injectViewTransitionsCSS,\n setViewTransitionName,\n clearViewTransitionName,\n} from './view-transitions';\n\n/** Default global configuration */\nconst DEFAULT_CONFIG: Required<TransitionGlobalConfig> = {\n platform: 'auto',\n duration: 0, // Will use platform default\n easing: '', // Will use platform default\n useViewTransitions: false,\n detectPlatform,\n};\n\ninterface InteractiveBackTransition {\n enteringState: PageState;\n leavingState: PageState;\n animations: Animation[];\n animationDurations: number[];\n duration: number;\n progress: number;\n}\n\n/**\n * Transition Controller\n * Central manager for all page transitions\n */\nexport class TransitionController {\n private config: Required<TransitionGlobalConfig>;\n private pageStack: PageState[] = [];\n private currentAnimations: Animation[] = [];\n private isAnimating = false;\n private interactiveBackTransition: InteractiveBackTransition | null = null;\n private lifecycleCallbacks: Map<string, TransitionLifecycle> = new Map();\n\n constructor(config: TransitionGlobalConfig = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n\n // Inject View Transitions CSS if using that feature\n if (this.config.useViewTransitions && supportsViewTransitions()) {\n injectViewTransitionsCSS();\n }\n }\n\n /**\n * Get the resolved platform\n */\n get platform(): 'ios' | 'android' {\n if (this.config.platform === 'ios') {\n return 'ios';\n }\n if (this.config.platform === 'android') {\n return 'android';\n }\n return this.config.detectPlatform();\n }\n\n /**\n * Get the current page state\n */\n get currentPage(): PageState | undefined {\n return this.pageStack[this.pageStack.length - 1];\n }\n\n /**\n * Get the page stack\n */\n get stack(): readonly PageState[] {\n return this.pageStack;\n }\n\n /**\n * Check if an animation is in progress\n */\n get animating(): boolean {\n return this.isAnimating;\n }\n\n /**\n * Update global configuration\n */\n configure(config: Partial<TransitionGlobalConfig>): void {\n this.config = { ...this.config, ...config };\n if (this.config.useViewTransitions && supportsViewTransitions()) {\n injectViewTransitionsCSS();\n }\n }\n\n /**\n * Register lifecycle callbacks for a page\n */\n registerLifecycle(pageId: string, lifecycle: TransitionLifecycle): void {\n this.lifecycleCallbacks.set(pageId, lifecycle);\n }\n\n /**\n * Unregister lifecycle callbacks for a page\n */\n unregisterLifecycle(pageId: string): void {\n this.lifecycleCallbacks.delete(pageId);\n }\n\n /**\n * Create a page state from an element\n */\n createPageState(element: HTMLElement, options: { id?: string; data?: Record<string, unknown> } = {}): PageState {\n const id = options.id || `page-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n\n // Find header, content, footer within the page\n const header = element.querySelector(\n '[data-cap-header], .cap-header, cap-header, [slot=\"header\"]',\n ) as HTMLElement | null;\n const content = element.querySelector(\n '[data-cap-content], .cap-content, cap-content, [slot=\"content\"]',\n ) as HTMLElement | null;\n const footer = element.querySelector(\n '[data-cap-footer], .cap-footer, cap-footer, [slot=\"footer\"]',\n ) as HTMLElement | null;\n\n return {\n id,\n element,\n header: header || undefined,\n content: content || undefined,\n footer: footer || undefined,\n isActive: false,\n data: options.data,\n };\n }\n\n /**\n * Navigate to a new page (push)\n */\n async push(enteringEl: HTMLElement, config: TransitionConfig = {}): Promise<TransitionResult> {\n return this.navigate(enteringEl, { ...config, direction: 'forward' });\n }\n\n /**\n * Navigate back (pop)\n */\n async pop(config: TransitionConfig = {}): Promise<TransitionResult> {\n if (this.pageStack.length <= 1) {\n return { success: false, duration: 0, error: new Error('Cannot pop: no page to go back to') };\n }\n\n const leavingState = this.pageStack[this.pageStack.length - 1];\n const enteringState = this.pageStack[this.pageStack.length - 2];\n\n return this.navigateWithStates(enteringState, leavingState, { ...config, direction: 'back' }, () => {\n // Remove the leaving page from stack after animation\n this.pageStack.pop();\n });\n }\n\n /**\n * Start an interactive iOS-style back transition using the cached previous page.\n */\n beginInteractiveBack(config: TransitionConfig = {}): boolean {\n if (this.pageStack.length <= 1 || this.isAnimating || this.interactiveBackTransition) {\n return false;\n }\n\n const leavingState = this.pageStack[this.pageStack.length - 1];\n const enteringState = this.pageStack[this.pageStack.length - 2];\n const direction = 'back';\n const duration = config.duration ?? (this.config.duration || getDefaultDuration(this.platform, direction));\n\n this.isAnimating = true;\n enteringState.element.style.display = '';\n enteringState.element.style.visibility = 'visible';\n\n const animOptions: TransitionAnimationOptions = {\n enteringEl: enteringState.element,\n leavingEl: leavingState.element,\n direction,\n duration,\n easing: 'linear',\n isBack: true,\n };\n\n const animations = createTransition(animOptions, this.platform);\n for (const animation of animations) {\n animation.pause();\n animation.currentTime = 0;\n }\n const animationDurations = animations.map((animation) => this.getAnimationDuration(animation, duration));\n\n this.currentAnimations = animations;\n this.interactiveBackTransition = {\n enteringState,\n leavingState,\n animations,\n animationDurations,\n duration,\n progress: 0,\n };\n\n return true;\n }\n\n /**\n * Move the current interactive back transition to a progress step from 0 to 1.\n */\n stepInteractiveBack(step: number): void {\n const transition = this.interactiveBackTransition;\n if (!transition) {\n return;\n }\n\n const progress = Math.max(0, Math.min(step, 0.9999));\n if (Math.abs(progress - transition.progress) < 0.0005) {\n return;\n }\n\n transition.progress = progress;\n\n for (const [index, animation] of transition.animations.entries()) {\n const duration = transition.animationDurations[index] ?? transition.duration;\n animation.currentTime = duration * progress;\n }\n }\n\n /**\n * Complete or cancel the current interactive back transition.\n */\n async endInteractiveBack(shouldComplete: boolean, releaseDuration: number, commitStack: boolean): Promise<void> {\n const transition = this.interactiveBackTransition;\n if (!transition) {\n return;\n }\n\n try {\n await this.playInteractiveAnimationsTo(shouldComplete ? 1 : 0, releaseDuration);\n\n if (shouldComplete && commitStack) {\n this.pageStack.pop();\n this.updatePageVisibility(transition.enteringState, transition.leavingState);\n transition.enteringState.isActive = true;\n transition.leavingState.isActive = false;\n cancelAnimations(transition.animations);\n } else if (!shouldComplete) {\n this.updatePageVisibility(transition.leavingState, transition.enteringState);\n transition.leavingState.isActive = true;\n transition.enteringState.isActive = false;\n cancelAnimations(transition.animations);\n }\n } finally {\n this.interactiveBackTransition = null;\n this.currentAnimations = [];\n this.isAnimating = false;\n }\n }\n\n /**\n * Cancel the current interactive back transition immediately.\n */\n cancelInteractiveBack(): void {\n const transition = this.interactiveBackTransition;\n if (!transition) {\n return;\n }\n\n cancelAnimations(transition.animations);\n this.updatePageVisibility(transition.leavingState, transition.enteringState);\n this.interactiveBackTransition = null;\n this.currentAnimations = [];\n this.isAnimating = false;\n }\n\n /**\n * Replace all pages with a new root\n */\n async setRoot(enteringEl: HTMLElement, config: TransitionConfig = {}): Promise<TransitionResult> {\n return this.navigate(enteringEl, {\n ...config,\n direction: config.direction ?? 'root',\n navigationAction: 'root',\n });\n }\n\n /**\n * Main navigation method\n */\n async navigate(enteringEl: HTMLElement, config: TransitionConfig = {}): Promise<TransitionResult> {\n const direction = config.direction || 'forward';\n const navigationAction = this.resolveNavigationAction(direction, config.navigationAction);\n const enteringState = this.createPageState(enteringEl);\n const leavingState = this.currentPage;\n\n return this.navigateWithStates(enteringState, leavingState, config, () => {\n if (navigationAction === 'root') {\n // Clear the stack and set new root\n this.pageStack = [enteringState];\n } else if (navigationAction === 'back' && this.pageStack.length > 0) {\n // Routers usually create a fresh element for the destination route.\n // Drop both the leaving page and the stale cached destination so the\n // internal stack mirrors the visible route stack.\n this.pageStack.pop();\n const staleEnteringState = this.pageStack.pop();\n if (staleEnteringState && staleEnteringState.element !== enteringState.element) {\n staleEnteringState.element.remove();\n this.lifecycleCallbacks.delete(staleEnteringState.id);\n }\n this.pageStack.push(enteringState);\n } else if (navigationAction === 'none' && this.pageStack.length > 0) {\n const staleState = this.pageStack.pop();\n if (staleState && staleState.element !== enteringState.element) {\n staleState.element.remove();\n this.lifecycleCallbacks.delete(staleState.id);\n }\n this.pageStack.push(enteringState);\n } else {\n // Push new page onto stack\n this.pageStack.push(enteringState);\n }\n });\n }\n\n private resolveNavigationAction(\n direction: TransitionDirection,\n navigationAction: NavigationAction | undefined,\n ): NavigationAction {\n if (navigationAction) {\n return navigationAction;\n }\n\n if (direction === 'root' || direction === 'back') {\n return direction;\n }\n\n return 'forward';\n }\n\n /**\n * Navigate between two known page states\n */\n private async navigateWithStates(\n enteringState: PageState,\n leavingState: PageState | undefined,\n config: TransitionConfig,\n updateStack: () => void,\n ): Promise<TransitionResult> {\n const startTime = performance.now();\n const direction = config.direction || 'forward';\n\n // Cancel any existing animations\n if (this.isAnimating) {\n cancelAnimations(this.currentAnimations);\n }\n\n this.isAnimating = true;\n\n const event: NavigationEvent = {\n direction,\n from: leavingState,\n to: enteringState,\n };\n\n try {\n // Call willLeave on leaving page\n if (leavingState) {\n const lifecycle = this.lifecycleCallbacks.get(leavingState.id);\n await lifecycle?.onWillLeave?.(event);\n config.onStart?.();\n }\n\n // Call willEnter on entering page\n const enteringLifecycle = this.lifecycleCallbacks.get(enteringState.id);\n await enteringLifecycle?.onWillEnter?.(event);\n\n // Determine animation parameters\n const duration = config.duration ?? (this.config.duration || getDefaultDuration(this.platform, direction));\n const easing = this.resolveTransitionEasing(config.easing || this.config.easing, direction);\n\n // Check if we should use View Transitions API\n const useViewTransitions =\n config.useViewTransitions !== false && this.config.useViewTransitions && supportsViewTransitions();\n\n if (useViewTransitions) {\n this.prepareViewTransitionElements(enteringState, leavingState);\n\n // Use View Transitions API\n await runViewTransition({\n direction,\n update: () => {\n updateStack();\n this.updatePageVisibility(enteringState, leavingState);\n this.applyViewTransitionNames(enteringState);\n this.clearViewTransitionNames(leavingState);\n },\n });\n\n this.clearViewTransitionNames(enteringState, leavingState);\n } else {\n // Use Web Animations API\n updateStack();\n\n const animOptions: TransitionAnimationOptions = {\n enteringEl: enteringState.element,\n leavingEl: leavingState?.element,\n direction,\n duration,\n easing: easing as string,\n isBack: direction === 'back',\n };\n\n // Create main content animations\n this.currentAnimations = createTransition(animOptions, this.platform);\n\n // Wait for animations\n await waitForAnimations(this.currentAnimations);\n\n // Update visibility\n this.updatePageVisibility(enteringState, leavingState);\n cancelAnimations(this.currentAnimations);\n }\n\n // Call didEnter on entering page\n enteringState.isActive = true;\n await enteringLifecycle?.onDidEnter?.(event);\n\n // Call didLeave on leaving page\n if (leavingState) {\n leavingState.isActive = false;\n const lifecycle = this.lifecycleCallbacks.get(leavingState.id);\n await lifecycle?.onDidLeave?.(event);\n }\n\n config.onComplete?.();\n\n const totalDuration = performance.now() - startTime;\n\n return { success: true, duration: totalDuration };\n } catch (error) {\n return {\n success: false,\n duration: performance.now() - startTime,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n } finally {\n this.isAnimating = false;\n this.currentAnimations = [];\n }\n }\n\n /**\n * Update page visibility after animation\n */\n private updatePageVisibility(enteringState: PageState, leavingState: PageState | undefined): void {\n // Make entering page visible\n enteringState.element.style.display = '';\n enteringState.element.style.visibility = 'visible';\n enteringState.element.style.opacity = '1';\n enteringState.element.style.transform = 'none';\n enteringState.element.style.position = 'relative';\n this.clearTransitionOnlyStyles(enteringState.element);\n this.clearPagePartTransitionStyles(enteringState);\n\n // Hide leaving page but keep in DOM\n if (leavingState) {\n leavingState.element.style.display = 'none';\n leavingState.element.style.visibility = 'hidden';\n leavingState.element.style.opacity = '1';\n leavingState.element.style.transform = 'none';\n this.clearTransitionOnlyStyles(leavingState.element);\n this.clearPagePartTransitionStyles(leavingState);\n }\n }\n\n private getAnimationDuration(animation: Animation, fallback: number): number {\n const duration = animation.effect?.getTiming().duration;\n return typeof duration === 'number' && Number.isFinite(duration) ? duration : fallback;\n }\n\n private async playInteractiveAnimationsTo(targetProgress: 0 | 1, releaseDuration: number): Promise<void> {\n const transition = this.interactiveBackTransition;\n if (!transition) {\n return;\n }\n\n if (releaseDuration <= 0) {\n transition.progress = targetProgress;\n for (const [index, animation] of transition.animations.entries()) {\n const duration = transition.animationDurations[index] ?? transition.duration;\n animation.pause();\n animation.currentTime = duration * targetProgress;\n }\n return;\n }\n\n const finished = transition.animations.map((animation, index) => {\n const duration = transition.animationDurations[index] ?? transition.duration;\n const currentTime = typeof animation.currentTime === 'number' ? animation.currentTime : 0;\n const targetTime = duration * targetProgress;\n const distance = Math.abs(targetTime - currentTime);\n\n if (distance < 1) {\n animation.currentTime = targetTime;\n return Promise.resolve();\n }\n\n animation.playbackRate = Math.max(distance / releaseDuration, 0.001) * (targetTime >= currentTime ? 1 : -1);\n animation.play();\n\n return animation.finished.catch(() => undefined);\n });\n\n await Promise.all(finished);\n transition.progress = targetProgress;\n }\n\n /**\n * Resolve configured easing presets after platform/direction are known.\n */\n private resolveTransitionEasing(\n easing: TransitionGlobalConfig['easing'],\n direction: TransitionConfig['direction'],\n ): string {\n if (!easing) {\n return getDefaultEasing(this.platform, direction || 'forward');\n }\n\n if (typeof easing === 'string' && ['ios', 'android'].includes(easing)) {\n return getDefaultEasing(easing as 'ios' | 'android', direction || 'forward');\n }\n\n return resolveEasing(easing);\n }\n\n /**\n * Remove styles that should only exist while a page is actively transitioning.\n */\n private clearTransitionOnlyStyles(element: HTMLElement): void {\n element.classList.remove('cap-transition-active');\n element.style.removeProperty('z-index');\n element.style.removeProperty('pointer-events');\n element.style.removeProperty('will-change');\n element.style.removeProperty('backface-visibility');\n element.style.removeProperty('transform-style');\n element.style.removeProperty('box-shadow');\n }\n\n private clearPagePartTransitionStyles(pageState: PageState): void {\n const { header, content, footer } = this.resolvePageParts(pageState);\n\n for (const element of [header, content, footer]) {\n if (!element) continue;\n\n this.clearTransitionOnlyStyles(element);\n }\n }\n\n /**\n * Prepare entering/leaving elements for a View Transition capture.\n * Entering page must be hidden in the \"old\" snapshot.\n */\n private prepareViewTransitionElements(enteringState: PageState, leavingState: PageState | undefined): void {\n this.clearAllKnownViewTransitionNames(enteringState, leavingState);\n\n if (leavingState) {\n this.applyViewTransitionNames(leavingState);\n enteringState.element.style.display = 'none';\n enteringState.element.style.visibility = 'hidden';\n }\n }\n\n /**\n * Assign view transition names to a page's layout parts.\n */\n private applyViewTransitionNames(pageState: PageState): void {\n const { header, content, footer } = this.resolvePageParts(pageState);\n\n if (header) {\n setViewTransitionName(header, 'cap-header');\n }\n if (content) {\n setViewTransitionName(content, 'cap-content');\n }\n if (footer) {\n setViewTransitionName(footer, 'cap-footer');\n }\n }\n\n /**\n * Clear view transition names for one or more page states.\n */\n private clearViewTransitionNames(...states: (PageState | undefined)[]): void {\n for (const state of states) {\n if (!state) continue;\n const { header, content, footer } = this.resolvePageParts(state);\n\n if (header) {\n clearViewTransitionName(header);\n }\n if (content) {\n clearViewTransitionName(content);\n }\n if (footer) {\n clearViewTransitionName(footer);\n }\n }\n }\n\n /**\n * Clear view transition names from all known pages plus transient states.\n */\n private clearAllKnownViewTransitionNames(...extraStates: (PageState | undefined)[]): void {\n const knownStates = new Set<PageState>();\n\n for (const state of this.pageStack) {\n knownStates.add(state);\n }\n for (const state of extraStates) {\n if (state) {\n knownStates.add(state);\n }\n }\n\n this.clearViewTransitionNames(...knownStates);\n }\n\n /**\n * Resolve page parts lazily to avoid timing issues with custom-element setup.\n */\n private resolvePageParts(pageState: PageState): {\n header?: HTMLElement;\n content?: HTMLElement;\n footer?: HTMLElement;\n } {\n const header =\n pageState.header ||\n (pageState.element.querySelector(\n '[data-cap-header], .cap-header, cap-header, [slot=\"header\"]',\n ) as HTMLElement | null) ||\n undefined;\n const content =\n pageState.content ||\n (pageState.element.querySelector(\n '[data-cap-content], .cap-content, cap-content, [slot=\"content\"]',\n ) as HTMLElement | null) ||\n undefined;\n const footer =\n pageState.footer ||\n (pageState.element.querySelector(\n '[data-cap-footer], .cap-footer, cap-footer, [slot=\"footer\"]',\n ) as HTMLElement | null) ||\n undefined;\n\n if (header) pageState.header = header;\n if (content) pageState.content = content;\n if (footer) pageState.footer = footer;\n\n return { header, content, footer };\n }\n\n /**\n * Save scroll position for a page\n */\n saveScrollPosition(pageId: string): void {\n const page = this.pageStack.find((p) => p.id === pageId);\n if (page?.content) {\n page.scrollPosition = {\n x: page.content.scrollLeft,\n y: page.content.scrollTop,\n };\n }\n }\n\n /**\n * Restore scroll position for a page\n */\n restoreScrollPosition(pageId: string): void {\n const page = this.pageStack.find((p) => p.id === pageId);\n if (page?.content && page.scrollPosition) {\n page.content.scrollLeft = page.scrollPosition.x;\n page.content.scrollTop = page.scrollPosition.y;\n }\n }\n\n /**\n * Remove a page from the stack (used when cleaning up)\n */\n removePage(pageId: string): void {\n const index = this.pageStack.findIndex((p) => p.id === pageId);\n if (index !== -1) {\n this.pageStack.splice(index, 1);\n this.lifecycleCallbacks.delete(pageId);\n }\n }\n\n /**\n * Clear all pages\n */\n clear(): void {\n this.pageStack = [];\n this.lifecycleCallbacks.clear();\n cancelAnimations(this.currentAnimations);\n this.currentAnimations = [];\n this.isAnimating = false;\n }\n}\n\n// Singleton instance for convenience\nlet defaultController: TransitionController | null = null;\n\n/**\n * Get or create the default transition controller\n */\nexport function getTransitionController(config?: TransitionGlobalConfig): TransitionController {\n if (!defaultController) {\n defaultController = new TransitionController(config);\n } else if (config) {\n defaultController.configure(config);\n }\n return defaultController;\n}\n\n/**\n * Create a new transition controller\n */\nexport function createTransitionController(config?: TransitionGlobalConfig): TransitionController {\n return new TransitionController(config);\n}\n","/**\n * Cap Router Outlet\n * A web component that manages page transitions\n * Works with any framework's router\n */\n\nimport { isNativeSwipeGesturePlatform } from '../core/native-platform';\nimport { getDefaultNavigationDirection, setOutletDirectionIntent, setOutletNavigationIntent } from '../core/navigation';\nimport type { TransitionController } from '../core/transition-controller';\nimport { createTransitionController } from '../core/transition-controller';\nimport type {\n TransitionConfig,\n TransitionGlobalConfig,\n TransitionDirection,\n NavigationAction,\n PageState,\n SwipeGestureOption,\n} from '../core/types';\n\nexport interface CapRouterOutletOptions extends TransitionGlobalConfig {\n /** Keep pages in DOM after navigating away */\n keepInDom?: boolean;\n /** Maximum cached pages */\n maxCached?: number;\n /** Edge swipe-back gesture support */\n swipeGesture?: SwipeGestureOption;\n}\n\ninterface SwipeGesturePointerState {\n pointerId: number;\n startX: number;\n startY: number;\n currentX: number;\n currentY: number;\n width: number;\n startTime: number;\n dragging: boolean;\n transitionStarted: boolean;\n}\n\n/**\n * Custom element for managing page transitions\n * Usage: <cap-router-outlet></cap-router-outlet>\n */\nexport class CapRouterOutlet extends HTMLElement {\n private controller: TransitionController;\n private options: CapRouterOutletOptions;\n private observer: MutationObserver | null = null;\n private pendingPage: HTMLElement | null = null;\n private ignoredNodes = new WeakSet<HTMLElement>();\n private swipeGesturePointer: SwipeGesturePointerState | null = null;\n private swipeGestureFrame = 0;\n private swipeGesturePendingStep: number | null = null;\n private swipeGestureListenersActive = false;\n private skipNextHistoryBackTransition = false;\n private swipeBackDepth = 0;\n private lastNavigationHref: string | null = null;\n private lastNavigationPosition: number | null = null;\n private pendingHistoryDirection: TransitionDirection | null = null;\n private navigationHrefs: (string | null)[] = [];\n\n private readonly swipeGestureEdgeWidth = 50;\n private readonly swipeGestureThreshold = 10;\n private readonly swipeGestureMinimumVelocity = 0.2;\n private readonly handleHistoryPopState = (): void => {\n const currentPosition = this.getCurrentNavigationPosition();\n\n if (currentPosition !== null && this.lastNavigationPosition !== null) {\n if (currentPosition < this.lastNavigationPosition) {\n this.pendingHistoryDirection = 'back';\n return;\n }\n\n if (currentPosition > this.lastNavigationPosition) {\n this.pendingHistoryDirection = 'forward';\n return;\n }\n }\n\n this.pendingHistoryDirection = 'back';\n };\n\n static get observedAttributes(): string[] {\n return ['platform', 'duration', 'keep-in-dom', 'max-cached', 'swipe-gesture'];\n }\n\n constructor() {\n super();\n\n this.options = {\n keepInDom: true,\n maxCached: 10,\n swipeGesture: 'auto',\n };\n\n this.controller = createTransitionController();\n }\n\n connectedCallback(): void {\n // Set up styles\n this.style.display = 'block';\n this.style.position = 'relative';\n this.style.width = '100%';\n this.style.height = '100%';\n this.style.overflow = 'hidden';\n this.style.overscrollBehaviorX = 'contain';\n this.lastNavigationHref = this.getCurrentNavigationHref();\n this.lastNavigationPosition = this.getCurrentNavigationPosition();\n this.ownerDocument.defaultView?.addEventListener('popstate', this.handleHistoryPopState);\n\n // Observe child changes to detect page additions\n this.observer = new MutationObserver((mutations) => {\n this.handleMutations(mutations);\n });\n\n this.observer.observe(this, {\n childList: true,\n subtree: false,\n });\n\n // Initialize with existing children\n const children = Array.from(this.children) as HTMLElement[];\n if (children.length > 0) {\n this.initializeFirstPage(children[children.length - 1]);\n }\n\n this.updateSwipeGestureListeners();\n }\n\n disconnectedCallback(): void {\n this.observer?.disconnect();\n this.ownerDocument.defaultView?.removeEventListener('popstate', this.handleHistoryPopState);\n this.removeSwipeGestureListeners();\n this.controller.clear();\n this.swipeBackDepth = 0;\n this.lastNavigationHref = null;\n this.lastNavigationPosition = null;\n this.pendingHistoryDirection = null;\n this.navigationHrefs = [];\n }\n\n attributeChangedCallback(name: string, _oldValue: string, newValue: string): void {\n switch (name) {\n case 'platform':\n this.controller.configure({ platform: newValue as 'ios' | 'android' | 'auto' });\n break;\n case 'duration':\n this.controller.configure({ duration: parseInt(newValue, 10) });\n break;\n case 'keep-in-dom':\n this.options.keepInDom = newValue !== 'false';\n break;\n case 'max-cached':\n this.options.maxCached = parseInt(newValue, 10);\n break;\n case 'swipe-gesture':\n this.options.swipeGesture = this.parseSwipeGestureAttribute(newValue);\n this.updateSwipeGestureListeners();\n break;\n }\n }\n\n /**\n * Handle DOM mutations (child additions/removals)\n */\n private handleMutations(mutations: MutationRecord[]) {\n const addedNodes: HTMLElement[] = [];\n const removedNodes: HTMLElement[] = [];\n\n for (const mutation of mutations) {\n for (const node of mutation.removedNodes) {\n if (node instanceof HTMLElement) {\n removedNodes.push(node);\n }\n }\n\n for (const node of mutation.addedNodes) {\n if (node instanceof HTMLElement) {\n addedNodes.push(node);\n }\n }\n }\n\n // Some routers remove the current page before adding the next one.\n // Re-insert it temporarily so leaving animations remain visible.\n const currentEl = this.controller.currentPage?.element;\n if (currentEl && removedNodes.includes(currentEl) && addedNodes.length > 0 && !currentEl.isConnected) {\n this.stylePageForTransition(currentEl);\n currentEl.style.display = '';\n currentEl.style.visibility = 'visible';\n\n const anchor = addedNodes[0];\n this.ignoredNodes.add(currentEl);\n if (anchor.parentElement === this) {\n this.insertBefore(currentEl, anchor);\n } else {\n this.appendChild(currentEl);\n }\n }\n\n // Remove detached historical pages from internal stack bookkeeping.\n for (const node of removedNodes) {\n if (node === currentEl) continue;\n const state = this.controller.stack.find((pageState) => pageState.element === node);\n if (state) {\n this.controller.removePage(state.id);\n }\n }\n\n for (const node of addedNodes) {\n if (node === this.pendingPage) continue;\n if (this.ignoredNodes.has(node)) {\n this.ignoredNodes.delete(node);\n continue;\n }\n\n // New page added - trigger transition\n this.handleNewPage(node);\n }\n }\n\n /**\n * Initialize the first page without animation\n */\n private initializeFirstPage(page: HTMLElement) {\n page.style.position = 'relative';\n page.style.width = '100%';\n page.style.height = '100%';\n\n const state = this.controller.createPageState(page);\n state.isActive = true;\n\n // Add to controller stack manually\n (this.controller as unknown as { pageStack: PageState[] }).pageStack.push(state);\n this.swipeBackDepth = 0;\n this.lastNavigationHref = this.getCurrentNavigationHref();\n this.lastNavigationPosition = this.getCurrentNavigationPosition();\n this.navigationHrefs = [this.lastNavigationHref];\n }\n\n /**\n * Handle a new page being added\n */\n private async handleNewPage(page: HTMLElement) {\n // Determine direction from page, outlet, or default to forward.\n // Framework adapters can set direction on the outlet right before navigation.\n const outletDirection = this.dataset.direction as TransitionDirection | undefined;\n const outletNavigationAction = this.dataset.navigationAction as NavigationAction | undefined;\n const explicitDirection = (page.dataset.direction as TransitionDirection | undefined) || outletDirection;\n const explicitNavigationAction =\n (page.dataset.navigationAction as NavigationAction | undefined) || outletNavigationAction;\n const direction = this.resolveNavigationDirection(explicitDirection);\n if (outletDirection) {\n delete this.dataset.direction;\n }\n if (outletNavigationAction) {\n delete this.dataset.navigationAction;\n }\n const skipTransition = this.skipNextHistoryBackTransition && direction === 'back';\n this.skipNextHistoryBackTransition = false;\n const hadPageBefore = this.controller.stack.length > 0;\n\n // Set up the page element\n this.stylePageForTransition(page);\n\n this.pendingPage = page;\n\n try {\n const result = await this.controller.navigate(page, {\n direction,\n navigationAction: explicitNavigationAction,\n duration: skipTransition ? 0 : undefined,\n });\n if (result.success) {\n this.recordCompletedNavigation(explicitNavigationAction ?? direction, { hadPageBefore });\n }\n } finally {\n this.pendingPage = null;\n }\n\n // Clean up old pages if not keeping in DOM\n if (!this.options.keepInDom) {\n this.cleanupOldPages();\n } else {\n this.enforceCacheLimit();\n }\n }\n\n /**\n * Clean up pages that are no longer needed\n */\n private cleanupOldPages() {\n const stack = this.controller.stack;\n const children = Array.from(this.children) as HTMLElement[];\n\n for (const child of children) {\n const inStack = stack.some((s) => s.element === child);\n if (!inStack && !child.dataset.keepInDom) {\n child.remove();\n }\n }\n }\n\n /**\n * Enforce the cache limit\n */\n private enforceCacheLimit() {\n const stack = this.controller.stack;\n const maxCached = this.options.maxCached || 10;\n\n if (stack.length > maxCached) {\n // Remove oldest pages (keeping the newest maxCached)\n const toRemove = stack.slice(0, stack.length - maxCached);\n for (const page of toRemove) {\n if (!page.isActive) {\n page.element.remove();\n this.controller.removePage(page.id);\n }\n }\n }\n }\n\n /**\n * Programmatic navigation - push a new page\n */\n async push(page: HTMLElement, config: TransitionConfig = {}): Promise<void> {\n this.stylePageForTransition(page);\n\n const hadPageBefore = this.controller.stack.length > 0;\n this.pendingPage = page;\n this.appendChild(page);\n\n try {\n const result = await this.controller.push(page, config);\n if (result.success) {\n this.recordCompletedNavigation('forward', { hadPageBefore, forceForward: true });\n }\n } finally {\n this.pendingPage = null;\n }\n }\n\n /**\n * Programmatic navigation - pop current page\n */\n async pop(config: TransitionConfig = {}): Promise<void> {\n const result = await this.controller.pop(config);\n\n if (result.success) {\n this.recordCompletedNavigation('back', { hadPageBefore: true });\n\n if (!this.options.keepInDom) {\n // Remove the popped page from DOM\n const children = Array.from(this.children) as HTMLElement[];\n const lastChild = children[children.length - 1];\n if (lastChild) {\n lastChild.remove();\n }\n }\n }\n }\n\n /**\n * Programmatic navigation - set root page\n */\n async setRoot(page: HTMLElement, config: TransitionConfig = {}): Promise<void> {\n const oldChildren = Array.from(this.children) as HTMLElement[];\n\n this.stylePageForTransition(page);\n\n this.pendingPage = page;\n this.appendChild(page);\n\n try {\n const result = await this.controller.setRoot(page, config);\n if (result.success) {\n this.recordCompletedNavigation('root', { hadPageBefore: true });\n }\n } finally {\n this.pendingPage = null;\n }\n\n // Remove all old pages\n for (const child of oldChildren) {\n child.remove();\n }\n }\n\n /**\n * Get the current page stack length\n */\n get stackLength(): number {\n return this.controller.stack.length;\n }\n\n /**\n * Check if we can go back\n */\n get canGoBack(): boolean {\n return this.getSwipeBackDestination() !== null;\n }\n\n /**\n * Get whether edge swipe-back gesture is enabled.\n */\n get swipeGesture(): SwipeGestureOption {\n return this.options.swipeGesture ?? 'auto';\n }\n\n /**\n * Enable, disable, or auto-detect edge swipe-back gesture.\n */\n set swipeGesture(value: SwipeGestureOption) {\n this.setSwipeGesture(value);\n }\n\n /**\n * Enable, disable, or auto-detect edge swipe-back gesture.\n */\n setSwipeGesture(value: SwipeGestureOption): void {\n this.options.swipeGesture = value;\n\n const serialized = this.serializeSwipeGesture(value);\n if (this.getAttribute('swipe-gesture') !== serialized) {\n this.setAttribute('swipe-gesture', serialized);\n } else {\n this.updateSwipeGestureListeners();\n }\n }\n\n /**\n * Set the navigation stack action and animation direction for the next router-driven navigation.\n */\n setNavigation(\n action: NavigationAction,\n direction: TransitionDirection = getDefaultNavigationDirection(action),\n ): void {\n setOutletNavigationIntent(this, action, direction);\n }\n\n /**\n * Get the transition controller for advanced usage\n */\n getController(): TransitionController {\n return this.controller;\n }\n\n /**\n * Apply layout styles required for transition animations.\n */\n private stylePageForTransition(page: HTMLElement): void {\n page.style.position = 'absolute';\n page.style.top = '0';\n page.style.left = '0';\n page.style.width = '100%';\n page.style.height = '100%';\n }\n\n private parseSwipeGestureAttribute(value: string | null): SwipeGestureOption {\n if (value === null || value === 'auto') {\n return 'auto';\n }\n\n if (value === 'false') {\n return false;\n }\n\n return true;\n }\n\n private serializeSwipeGesture(value: SwipeGestureOption): string {\n return typeof value === 'boolean' ? String(value) : value;\n }\n\n private updateSwipeGestureListeners(): void {\n if (this.options.swipeGesture === false) {\n this.removeSwipeGestureListeners();\n return;\n }\n\n if (this.swipeGestureListenersActive || typeof PointerEvent === 'undefined') {\n return;\n }\n\n this.addEventListener('pointerdown', this.handleSwipeGesturePointerDown);\n this.addEventListener('pointermove', this.handleSwipeGesturePointerMove, { passive: false });\n this.addEventListener('pointerup', this.handleSwipeGesturePointerEnd);\n this.addEventListener('pointercancel', this.handleSwipeGesturePointerCancel);\n this.swipeGestureListenersActive = true;\n }\n\n private removeSwipeGestureListeners(): void {\n if (!this.swipeGestureListenersActive) {\n return;\n }\n\n this.removeEventListener('pointerdown', this.handleSwipeGesturePointerDown);\n this.removeEventListener('pointermove', this.handleSwipeGesturePointerMove);\n this.removeEventListener('pointerup', this.handleSwipeGesturePointerEnd);\n this.removeEventListener('pointercancel', this.handleSwipeGesturePointerCancel);\n this.swipeGestureListenersActive = false;\n this.clearQueuedSwipeGestureStep();\n if (this.swipeGesturePointer?.transitionStarted) {\n this.controller.cancelInteractiveBack();\n }\n this.swipeGesturePointer = null;\n }\n\n private isSwipeGestureEnabled(): boolean {\n const option = this.options.swipeGesture ?? 'auto';\n\n if (option === true) {\n return true;\n }\n\n if (option === false) {\n return false;\n }\n\n return isNativeSwipeGesturePlatform();\n }\n\n private getCurrentNavigationHref(): string | null {\n return this.ownerDocument.defaultView?.location.href ?? null;\n }\n\n private getCurrentNavigationPosition(): number | null {\n const win = this.ownerDocument.defaultView;\n if (!win) {\n return null;\n }\n\n const navigationIndex = (\n win as Window & {\n navigation?: {\n currentEntry?: {\n index?: unknown;\n };\n };\n }\n ).navigation?.currentEntry?.index;\n if (typeof navigationIndex === 'number' && Number.isFinite(navigationIndex)) {\n return navigationIndex;\n }\n\n const state = win.history.state as Record<string, unknown> | null;\n for (const key of ['idx', 'position', 'index']) {\n const value = state?.[key];\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n }\n\n return null;\n }\n\n private resolveNavigationDirection(explicitDirection: TransitionDirection | undefined): TransitionDirection {\n if (explicitDirection) {\n this.pendingHistoryDirection = null;\n return explicitDirection;\n }\n\n const currentHref = this.getCurrentNavigationHref();\n const existingHrefIndex = this.findNavigationHrefIndex(currentHref, this.navigationHrefs.length - 2);\n if (existingHrefIndex !== -1) {\n this.pendingHistoryDirection = null;\n return 'back';\n }\n\n if (currentHref !== null && currentHref === this.lastNavigationHref) {\n this.pendingHistoryDirection = null;\n return 'none';\n }\n\n if (this.pendingHistoryDirection) {\n const direction = this.pendingHistoryDirection;\n this.pendingHistoryDirection = null;\n return direction;\n }\n\n const currentPosition = this.getCurrentNavigationPosition();\n if (currentPosition !== null && this.lastNavigationPosition !== null) {\n if (currentPosition < this.lastNavigationPosition) {\n return 'back';\n }\n\n if (currentPosition === this.lastNavigationPosition) {\n return 'none';\n }\n }\n\n return 'forward';\n }\n\n private recordCompletedNavigation(\n direction: TransitionDirection,\n options: { hadPageBefore: boolean; forceForward?: boolean },\n ): void {\n const currentHref = this.getCurrentNavigationHref();\n const currentPosition = this.getCurrentNavigationPosition();\n\n if (!options.hadPageBefore || direction === 'root') {\n this.resetNavigationDepth(currentHref, currentPosition);\n return;\n }\n\n if (direction === 'back') {\n this.recordBackNavigation(currentHref);\n this.lastNavigationPosition = currentPosition;\n return;\n }\n\n if (direction === 'none') {\n if (this.navigationHrefs.length === 0) {\n this.navigationHrefs = [currentHref];\n } else {\n this.navigationHrefs[this.navigationHrefs.length - 1] = currentHref;\n }\n\n this.syncSwipeBackDepth();\n this.lastNavigationHref = currentHref;\n this.lastNavigationPosition = currentPosition;\n return;\n }\n\n if (direction === 'forward') {\n const hrefChanged =\n currentHref === null || this.lastNavigationHref === null || currentHref !== this.lastNavigationHref;\n\n if (options.forceForward || hrefChanged) {\n this.navigationHrefs.push(currentHref);\n } else if (this.navigationHrefs.length === 0) {\n this.navigationHrefs = [currentHref];\n }\n\n this.syncSwipeBackDepth();\n this.lastNavigationHref = currentHref;\n this.lastNavigationPosition = currentPosition;\n return;\n }\n\n this.lastNavigationHref = currentHref;\n this.lastNavigationPosition = currentPosition;\n }\n\n private resetNavigationDepth(currentHref: string | null, currentPosition: number | null): void {\n this.navigationHrefs = [currentHref];\n this.swipeBackDepth = 0;\n this.lastNavigationHref = currentHref;\n this.lastNavigationPosition = currentPosition;\n }\n\n private recordBackNavigation(currentHref: string | null): void {\n const existingHrefIndex = this.findNavigationHrefIndex(currentHref, this.navigationHrefs.length - 2);\n\n if (existingHrefIndex !== -1) {\n this.navigationHrefs = this.navigationHrefs.slice(0, existingHrefIndex + 1);\n } else if (this.navigationHrefs.length > 1) {\n // Router redirects can land on an unexpected URL; drop the stale entry and align with currentHref.\n this.navigationHrefs.pop();\n this.navigationHrefs[this.navigationHrefs.length - 1] = currentHref;\n } else {\n this.navigationHrefs = [currentHref];\n }\n\n this.syncSwipeBackDepth();\n this.lastNavigationHref = currentHref;\n }\n\n private findNavigationHrefIndex(href: string | null, fromIndex: number): number {\n for (let index = Math.min(fromIndex, this.navigationHrefs.length - 1); index >= 0; index -= 1) {\n if (this.navigationHrefs[index] === href) {\n return index;\n }\n }\n\n return -1;\n }\n\n private syncSwipeBackDepth(): void {\n this.swipeBackDepth = Math.max(0, this.navigationHrefs.length - 1);\n }\n\n private getSwipeBackDestination(): PageState | null {\n const stack = this.controller.stack;\n\n if (this.swipeBackDepth <= 0 || stack.length <= 1) {\n return null;\n }\n\n return stack[stack.length - 2] ?? null;\n }\n\n private canStartSwipeGesture(event: PointerEvent): boolean {\n if (\n !this.isSwipeGestureEnabled() ||\n this.controller.animating ||\n this.pendingPage ||\n !this.getSwipeBackDestination()\n ) {\n return false;\n }\n\n if (!event.isPrimary || (event.pointerType === 'mouse' && event.button !== 0)) {\n return false;\n }\n\n if (this.isInteractiveSwipeTarget(event.target) || this.hasScrollableInlineAncestor(event.target)) {\n return false;\n }\n\n const rect = this.getBoundingClientRect();\n const startX = event.clientX - rect.left;\n\n if (event.clientY < rect.top || event.clientY > rect.bottom) {\n return false;\n }\n\n return this.isRTL() ? startX >= rect.width - this.swipeGestureEdgeWidth : startX <= this.swipeGestureEdgeWidth;\n }\n\n private isRTL(): boolean {\n const doc = this.ownerDocument;\n return doc.dir === 'rtl' || doc.documentElement.dir === 'rtl' || getComputedStyle(this).direction === 'rtl';\n }\n\n private getSwipeGestureDeltaX(pointer: SwipeGesturePointerState): number {\n const deltaX = pointer.currentX - pointer.startX;\n return this.isRTL() ? -deltaX : deltaX;\n }\n\n private isInteractiveSwipeTarget(target: EventTarget | null): boolean {\n if (!(target instanceof Element)) {\n return false;\n }\n\n return Boolean(\n target.closest(\n 'a, button, input, textarea, select, option, [contenteditable=\"true\"], [data-swipe-gesture-ignore], [data-swipe-back-ignore]',\n ),\n );\n }\n\n private hasScrollableInlineAncestor(target: EventTarget | null): boolean {\n let element = target instanceof Element ? target : null;\n\n while (element && element !== this) {\n if (element instanceof HTMLElement) {\n const style = getComputedStyle(element);\n const canScrollInline = /(auto|scroll)/.test(style.overflowX) && element.scrollWidth > element.clientWidth + 1;\n\n if (canScrollInline && element.scrollLeft > 0) {\n return true;\n }\n }\n\n element = element.parentElement;\n }\n\n return false;\n }\n\n private handleSwipeGesturePointerDown = (event: PointerEvent): void => {\n if (!this.canStartSwipeGesture(event)) {\n return;\n }\n\n const width = Math.max(this.getBoundingClientRect().width, 1);\n\n this.swipeGesturePointer = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startY: event.clientY,\n currentX: event.clientX,\n currentY: event.clientY,\n width,\n startTime: performance.now(),\n dragging: false,\n transitionStarted: false,\n };\n\n try {\n this.setPointerCapture(event.pointerId);\n } catch {\n // Some WebViews can throw if capture is unavailable for this pointer.\n }\n };\n\n private handleSwipeGesturePointerMove = (event: PointerEvent): void => {\n const pointer = this.swipeGesturePointer;\n if (!pointer || pointer.pointerId !== event.pointerId) {\n return;\n }\n\n pointer.currentX = event.clientX;\n pointer.currentY = event.clientY;\n\n const deltaX = this.getSwipeGestureDeltaX(pointer);\n const deltaY = pointer.currentY - pointer.startY;\n const absX = Math.abs(deltaX);\n const absY = Math.abs(deltaY);\n\n if (!pointer.dragging && absY > 12 && absY > absX) {\n this.cancelSwipeGesturePointer(event.pointerId);\n return;\n }\n\n if (deltaX < -this.swipeGestureThreshold) {\n this.cancelSwipeGesture(event.pointerId);\n return;\n }\n\n if (!pointer.dragging && deltaX > this.swipeGestureThreshold && absX > absY) {\n if (!this.getSwipeBackDestination()) {\n this.cancelSwipeGesturePointer(event.pointerId);\n return;\n }\n\n pointer.dragging = true;\n pointer.transitionStarted = this.controller.beginInteractiveBack({ direction: 'back' });\n\n if (!pointer.transitionStarted) {\n this.cancelSwipeGesturePointer(event.pointerId);\n return;\n }\n }\n\n if (pointer.dragging && pointer.transitionStarted) {\n if (!this.getSwipeBackDestination()) {\n this.cancelSwipeGesture(event.pointerId);\n return;\n }\n\n if (event.cancelable) event.preventDefault();\n this.queueSwipeGestureStep(deltaX / pointer.width);\n }\n };\n\n private handleSwipeGesturePointerEnd = (event: PointerEvent): void => {\n const pointer = this.swipeGesturePointer;\n if (!pointer || pointer.pointerId !== event.pointerId) {\n return;\n }\n\n pointer.currentX = event.clientX;\n pointer.currentY = event.clientY;\n\n const deltaX = this.getSwipeGestureDeltaX(pointer);\n const elapsed = Math.max(performance.now() - pointer.startTime, 1);\n const velocityX = deltaX / elapsed;\n const width = pointer.width;\n const step = deltaX / width;\n const shouldCommit =\n pointer.dragging &&\n pointer.transitionStarted &&\n velocityX >= 0 &&\n (velocityX > this.swipeGestureMinimumVelocity || deltaX > width / 2);\n const missing = shouldCommit ? 1 - step : step;\n const missingDistance = Math.max(missing, 0) * width;\n const releaseDuration =\n missingDistance > 5 && Math.abs(velocityX) > 0 ? Math.min(missingDistance / Math.abs(velocityX), 540) : 0;\n\n if (pointer.transitionStarted) {\n this.flushQueuedSwipeGestureStep();\n } else {\n this.clearQueuedSwipeGestureStep();\n }\n\n this.releaseSwipeGesturePointer(event.pointerId);\n\n void this.finishSwipeGestureBack(shouldCommit, releaseDuration);\n };\n\n private handleSwipeGesturePointerCancel = (event: PointerEvent): void => {\n this.cancelSwipeGesture(event.pointerId);\n };\n\n private cancelSwipeGesturePointer(pointerId: number): void {\n this.clearQueuedSwipeGestureStep();\n this.releaseSwipeGesturePointer(pointerId);\n }\n\n private releaseSwipeGesturePointer(pointerId: number): void {\n if (this.swipeGesturePointer?.pointerId !== pointerId) {\n return;\n }\n\n try {\n this.releasePointerCapture(pointerId);\n } catch {\n // Ignore missing pointer capture.\n }\n\n this.swipeGesturePointer = null;\n }\n\n private cancelSwipeGesture(pointerId: number): void {\n const pointer = this.swipeGesturePointer;\n if (!pointer || pointer.pointerId !== pointerId) {\n return;\n }\n\n this.releaseSwipeGesturePointer(pointerId);\n this.clearQueuedSwipeGestureStep();\n\n if (pointer.transitionStarted) {\n void this.finishSwipeGestureBack(false, 0);\n }\n }\n\n private queueSwipeGestureStep(step: number): void {\n this.swipeGesturePendingStep = step;\n\n if (this.swipeGestureFrame !== 0) {\n return;\n }\n\n const win = this.ownerDocument.defaultView;\n if (!win) {\n this.flushQueuedSwipeGestureStep();\n return;\n }\n\n this.swipeGestureFrame = win.requestAnimationFrame(() => {\n this.swipeGestureFrame = 0;\n this.flushQueuedSwipeGestureStep();\n });\n }\n\n private flushQueuedSwipeGestureStep(): void {\n const step = this.swipeGesturePendingStep;\n this.swipeGesturePendingStep = null;\n\n if (this.swipeGestureFrame !== 0) {\n this.ownerDocument.defaultView?.cancelAnimationFrame(this.swipeGestureFrame);\n this.swipeGestureFrame = 0;\n }\n\n if (step !== null) {\n this.controller.stepInteractiveBack(step);\n }\n }\n\n private clearQueuedSwipeGestureStep(): void {\n if (this.swipeGestureFrame !== 0) {\n this.ownerDocument.defaultView?.cancelAnimationFrame(this.swipeGestureFrame);\n this.swipeGestureFrame = 0;\n }\n\n this.swipeGesturePendingStep = null;\n }\n\n private async finishSwipeGestureBack(shouldComplete: boolean, releaseDuration: number): Promise<void> {\n const canComplete = shouldComplete && this.getSwipeBackDestination() !== null;\n const shouldUseHistory = canComplete && typeof window !== 'undefined' && window.history.length > 1;\n\n await this.controller.endInteractiveBack(canComplete, canComplete ? releaseDuration : 0, !shouldUseHistory);\n\n if (!canComplete) {\n return;\n }\n\n if (shouldUseHistory) {\n this.skipNextHistoryBackTransition = true;\n setOutletDirectionIntent(this, 'back');\n window.history.back();\n return;\n }\n\n if (!this.options.keepInDom) {\n this.cleanupOldPages();\n }\n }\n}\n\n// Register the custom element\nif (typeof customElements !== 'undefined' && !customElements.get('cap-router-outlet')) {\n customElements.define('cap-router-outlet', CapRouterOutlet);\n}\n","/**\n * Cap Page\n * A container for page content with header, content, and footer slots\n * Integrates with cap-router-outlet for transitions\n */\n\nimport type { TransitionLifecycle, NavigationEvent } from '../core/types';\n\nexport interface CapPageOptions {\n /** Unique key for this page */\n key?: string;\n /** Cache scroll position */\n cacheScroll?: boolean;\n}\n\n/**\n * Custom element for a page container\n * Usage:\n * <cap-page>\n * <cap-header slot=\"header\">...</cap-header>\n * <cap-content slot=\"content\">...</cap-content>\n * <cap-footer slot=\"footer\">...</cap-footer>\n * </cap-page>\n */\nexport class CapPage extends HTMLElement {\n private _lifecycle: TransitionLifecycle = {};\n private _isActive = false;\n\n static get observedAttributes(): string[] {\n return ['key', 'cache-scroll'];\n }\n\n constructor() {\n super();\n\n // Create shadow DOM with slots\n const shadow = this.attachShadow({ mode: 'open' });\n\n shadow.innerHTML = `\n <style>\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n background: var(--cap-page-background, Canvas);\n color: var(--cap-page-color, CanvasText);\n }\n\n :host(.cap-transition-active) {\n overflow: visible;\n }\n\n .header-container {\n flex-shrink: 0;\n position: relative;\n z-index: 10;\n }\n\n .content-container {\n flex: 1;\n position: relative;\n overflow: hidden;\n }\n\n .footer-container {\n flex-shrink: 0;\n position: relative;\n z-index: 10;\n }\n\n ::slotted([slot=\"header\"]),\n ::slotted([data-cap-header]) {\n display: block;\n }\n\n ::slotted([slot=\"content\"]),\n ::slotted([data-cap-content]) {\n display: block;\n height: 100%;\n overflow: auto;\n }\n\n ::slotted([slot=\"footer\"]),\n ::slotted([data-cap-footer]) {\n display: block;\n }\n </style>\n\n <div class=\"header-container\" part=\"header\">\n <slot name=\"header\"></slot>\n </div>\n\n <div class=\"content-container\" part=\"content\">\n <slot name=\"content\"></slot>\n <slot></slot>\n </div>\n\n <div class=\"footer-container\" part=\"footer\">\n <slot name=\"footer\"></slot>\n </div>\n `;\n }\n\n connectedCallback(): void {\n // Mark elements for the transition controller to find\n this.markTransitionElements();\n\n // Dispatch connected event\n this.dispatchEvent(\n new CustomEvent('cap-page-connected', {\n bubbles: true,\n composed: true,\n detail: { page: this },\n }),\n );\n }\n\n disconnectedCallback(): void {\n this.dispatchEvent(\n new CustomEvent('cap-page-disconnected', {\n bubbles: true,\n composed: true,\n detail: { page: this },\n }),\n );\n }\n\n /**\n * Mark child elements for transition controller\n */\n private markTransitionElements() {\n // Find and mark header\n const header = this.querySelector('[slot=\"header\"]');\n if (header) {\n header.setAttribute('data-cap-header', '');\n }\n\n // Find and mark content\n const content = this.querySelector('[slot=\"content\"]');\n if (content) {\n content.setAttribute('data-cap-content', '');\n }\n\n // Find and mark footer\n const footer = this.querySelector('[slot=\"footer\"]');\n if (footer) {\n footer.setAttribute('data-cap-footer', '');\n }\n }\n\n /**\n * Set lifecycle callbacks\n */\n set lifecycle(callbacks: TransitionLifecycle) {\n this._lifecycle = callbacks;\n }\n\n get lifecycle(): TransitionLifecycle {\n return this._lifecycle;\n }\n\n /**\n * Check if page is active\n */\n get isActive(): boolean {\n return this._isActive;\n }\n\n /**\n * Called when page will enter view\n */\n async willEnter(event: NavigationEvent): Promise<void> {\n await this._lifecycle.onWillEnter?.(event);\n this.dispatchEvent(\n new CustomEvent('cap-will-enter', {\n bubbles: true,\n detail: event,\n }),\n );\n }\n\n /**\n * Called when page has entered view\n */\n async didEnter(event: NavigationEvent): Promise<void> {\n this._isActive = true;\n await this._lifecycle.onDidEnter?.(event);\n this.dispatchEvent(\n new CustomEvent('cap-did-enter', {\n bubbles: true,\n detail: event,\n }),\n );\n }\n\n /**\n * Called when page will leave view\n */\n async willLeave(event: NavigationEvent): Promise<void> {\n await this._lifecycle.onWillLeave?.(event);\n this.dispatchEvent(\n new CustomEvent('cap-will-leave', {\n bubbles: true,\n detail: event,\n }),\n );\n }\n\n /**\n * Called when page has left view\n */\n async didLeave(event: NavigationEvent): Promise<void> {\n this._isActive = false;\n await this._lifecycle.onDidLeave?.(event);\n this.dispatchEvent(\n new CustomEvent('cap-did-leave', {\n bubbles: true,\n detail: event,\n }),\n );\n }\n\n /**\n * Get the header element\n */\n get headerElement(): HTMLElement | null {\n return this.querySelector('[slot=\"header\"], [data-cap-header]');\n }\n\n /**\n * Get the content element\n */\n get contentElement(): HTMLElement | null {\n return this.querySelector('[slot=\"content\"], [data-cap-content]');\n }\n\n /**\n * Get the footer element\n */\n get footerElement(): HTMLElement | null {\n return this.querySelector('[slot=\"footer\"], [data-cap-footer]');\n }\n\n /**\n * Save scroll position\n */\n saveScrollPosition(): { x: number; y: number } | null {\n const content = this.contentElement;\n if (!content) return null;\n\n return {\n x: content.scrollLeft,\n y: content.scrollTop,\n };\n }\n\n /**\n * Restore scroll position\n */\n restoreScrollPosition(position: { x: number; y: number }): void {\n const content = this.contentElement;\n if (!content) return;\n\n content.scrollLeft = position.x;\n content.scrollTop = position.y;\n }\n}\n\n// Register the custom element\nif (typeof customElements !== 'undefined' && !customElements.get('cap-page')) {\n customElements.define('cap-page', CapPage);\n}\n","/**\n * Cap Header\n * A header container that participates in page transitions\n * No styling opinions - just transition awareness\n */\n\n/**\n * Custom element for header content\n * Usage: <cap-header>Your header content</cap-header>\n */\nexport class CapHeader extends HTMLElement {\n static get observedAttributes(): string[] {\n return ['translucent', 'collapse'];\n }\n\n constructor() {\n super();\n }\n\n connectedCallback(): void {\n // Set up minimal required styles\n this.style.display = 'block';\n this.style.position = 'relative';\n this.style.zIndex = '10';\n\n // Mark for transition controller\n this.setAttribute('data-cap-header', '');\n\n // Ensure slot assignment if inside cap-page\n if (this.parentElement?.tagName === 'CAP-PAGE' && !this.hasAttribute('slot')) {\n this.setAttribute('slot', 'header');\n }\n }\n\n attributeChangedCallback(name: string, _oldValue: string, newValue: string): void {\n switch (name) {\n case 'translucent':\n // Mark for framework-specific handling\n this.dataset.translucent = newValue !== null ? 'true' : 'false';\n break;\n case 'collapse':\n // Mark for collapsible header behavior\n this.dataset.collapse = newValue;\n break;\n }\n }\n\n /**\n * Get the current height of the header\n */\n get height(): number {\n return this.offsetHeight;\n }\n}\n\n// Register the custom element\nif (typeof customElements !== 'undefined' && !customElements.get('cap-header')) {\n customElements.define('cap-header', CapHeader);\n}\n","/**\n * Cap Content\n * Main scrollable content area that participates in page transitions\n * No styling opinions - just transition awareness and scroll management\n */\n\n/**\n * Custom element for main content\n * Usage: <cap-content>Your content here</cap-content>\n */\nexport class CapContent extends HTMLElement {\n private _scrollPosition: { x: number; y: number } = { x: 0, y: 0 };\n\n static get observedAttributes(): string[] {\n return ['fullscreen', 'scroll-x', 'scroll-y'];\n }\n\n constructor() {\n super();\n }\n\n connectedCallback(): void {\n // Set up minimal required styles\n this.style.display = 'block';\n this.style.position = 'relative';\n this.style.flex = '1';\n this.style.overflow = 'auto';\n this.style.overscrollBehavior = 'contain';\n\n // iOS-style momentum scrolling\n // @ts-expect-error vendor prefix\n this.style.webkitOverflowScrolling = 'touch';\n\n // Mark for transition controller\n this.setAttribute('data-cap-content', '');\n\n // Ensure slot assignment if inside cap-page\n if (this.parentElement?.tagName === 'CAP-PAGE' && !this.hasAttribute('slot')) {\n this.setAttribute('slot', 'content');\n }\n\n // Track scroll position\n this.addEventListener('scroll', this.handleScroll.bind(this), { passive: true });\n }\n\n disconnectedCallback(): void {\n this.removeEventListener('scroll', this.handleScroll.bind(this));\n }\n\n attributeChangedCallback(name: string, _oldValue: string, newValue: string): void {\n switch (name) {\n case 'fullscreen':\n // Mark for fullscreen content (scrolls behind header)\n this.dataset.fullscreen = newValue !== null ? 'true' : 'false';\n break;\n case 'scroll-x':\n this.style.overflowX = newValue === 'false' ? 'hidden' : 'auto';\n break;\n case 'scroll-y':\n this.style.overflowY = newValue === 'false' ? 'hidden' : 'auto';\n break;\n }\n }\n\n /**\n * Handle scroll events\n */\n private handleScroll() {\n this._scrollPosition = {\n x: this.scrollLeft,\n y: this.scrollTop,\n };\n\n // Dispatch scroll event for parent components\n this.dispatchEvent(\n new CustomEvent('cap-scroll', {\n bubbles: true,\n detail: this._scrollPosition,\n }),\n );\n }\n\n /**\n * Get current scroll position\n */\n get scrollPosition(): { x: number; y: number } {\n return { ...this._scrollPosition };\n }\n\n /**\n * Save current scroll position\n */\n saveScrollPosition(): { x: number; y: number } {\n this._scrollPosition = {\n x: this.scrollLeft,\n y: this.scrollTop,\n };\n return { ...this._scrollPosition };\n }\n\n /**\n * Restore scroll position\n */\n restoreScrollPosition(position?: { x: number; y: number }): void {\n const pos = position || this._scrollPosition;\n this.scrollLeft = pos.x;\n this.scrollTop = pos.y;\n }\n\n /**\n * Scroll to top\n */\n scrollToTop(smooth = true): void {\n this.scrollTo({\n top: 0,\n behavior: smooth ? 'smooth' : 'instant',\n });\n }\n\n /**\n * Scroll to bottom\n */\n scrollToBottom(smooth = true): void {\n this.scrollTo({\n top: this.scrollHeight,\n behavior: smooth ? 'smooth' : 'instant',\n });\n }\n\n /**\n * Scroll to element\n */\n scrollToElement(element: HTMLElement, smooth = true): void {\n element.scrollIntoView({\n behavior: smooth ? 'smooth' : 'instant',\n block: 'start',\n });\n }\n}\n\n// Register the custom element\nif (typeof customElements !== 'undefined' && !customElements.get('cap-content')) {\n customElements.define('cap-content', CapContent);\n}\n","/**\n * Cap Footer\n * A footer container that participates in page transitions\n * No styling opinions - just transition awareness\n */\n\n/**\n * Custom element for footer content\n * Usage: <cap-footer>Your footer content</cap-footer>\n */\nexport class CapFooter extends HTMLElement {\n static get observedAttributes(): string[] {\n return ['translucent'];\n }\n\n constructor() {\n super();\n }\n\n connectedCallback(): void {\n // Set up minimal required styles\n this.style.display = 'block';\n this.style.position = 'relative';\n this.style.zIndex = '10';\n\n // Mark for transition controller\n this.setAttribute('data-cap-footer', '');\n\n // Ensure slot assignment if inside cap-page\n if (this.parentElement?.tagName === 'CAP-PAGE' && !this.hasAttribute('slot')) {\n this.setAttribute('slot', 'footer');\n }\n }\n\n attributeChangedCallback(name: string, _oldValue: string, newValue: string): void {\n switch (name) {\n case 'translucent':\n // Mark for framework-specific handling\n this.dataset.translucent = newValue !== null ? 'true' : 'false';\n break;\n }\n }\n\n /**\n * Get the current height of the footer\n */\n get height(): number {\n return this.offsetHeight;\n }\n}\n\n// Register the custom element\nif (typeof customElements !== 'undefined' && !customElements.get('cap-footer')) {\n customElements.define('cap-footer', CapFooter);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
CapHeader,
|
|
5
5
|
CapPage,
|
|
6
6
|
CapRouterOutlet
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-B6BVMPJ3.mjs";
|
|
8
8
|
export {
|
|
9
9
|
CapContent,
|
|
10
10
|
CapFooter,
|
|
@@ -12,4 +12,4 @@ export {
|
|
|
12
12
|
CapPage,
|
|
13
13
|
CapRouterOutlet
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=components-
|
|
15
|
+
//# sourceMappingURL=components-HRZG74NZ.mjs.map
|