@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 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 { initTransitions, setDirection, setupPage, setupRouterOutlet } from '@capgo/capacitor-transitions/react';
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, { ...config, direction: "root" });
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 (direction === "root") {
996
+ if (navigationAction === "root") {
977
997
  this.pageStack = [enteringState];
978
- } else if (direction === "back" && this.pageStack.length > 0) {
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, { direction, duration: skipTransition ? 0 : void 0 });
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.dataset.direction = "back";
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-LABKGL2K.mjs.map
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-LABKGL2K.mjs";
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-M5B63NYZ.mjs.map
15
+ //# sourceMappingURL=components-HRZG74NZ.mjs.map