@capgo/capacitor-transitions 8.0.2 → 8.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,18 @@
1
1
  # @capgo/capacitor-transitions
2
2
 
3
+ <a href="https://capgo.app/">
4
+ <img
5
+ src="https://capgo.app/readme-banner.svg?repo=Cap-go/capacitor-transitions"
6
+ alt="Capgo - Instant updates for Capacitor"
7
+ />
8
+ </a>
9
+
3
10
  Framework-agnostic page transitions for Capacitor apps. iOS-style navigation without opinions.
4
11
 
12
+ ## Demo
13
+
14
+ <img src="./docs/demo.webp" alt="Demo of capacitor-transitions in action" width="300" />
15
+
5
16
  ## Features
6
17
 
7
18
  - **Framework Agnostic** - Works with React, Vue, Angular, Svelte, Solid, and any other framework
@@ -887,12 +887,15 @@ var TransitionController = class {
887
887
  animation.pause();
888
888
  animation.currentTime = 0;
889
889
  }
890
+ const animationDurations = animations.map((animation) => this.getAnimationDuration(animation, duration));
890
891
  this.currentAnimations = animations;
891
892
  this.interactiveBackTransition = {
892
893
  enteringState,
893
894
  leavingState,
894
895
  animations,
895
- duration
896
+ animationDurations,
897
+ duration,
898
+ progress: 0
896
899
  };
897
900
  return true;
898
901
  }
@@ -905,9 +908,12 @@ var TransitionController = class {
905
908
  return;
906
909
  }
907
910
  const progress = Math.max(0, Math.min(step, 0.9999));
908
- for (const animation of transition.animations) {
909
- const duration = this.getAnimationDuration(animation, transition.duration);
910
- animation.pause();
911
+ if (Math.abs(progress - transition.progress) < 5e-4) {
912
+ return;
913
+ }
914
+ transition.progress = progress;
915
+ for (const [index, animation] of transition.animations.entries()) {
916
+ const duration = transition.animationDurations[index] ?? transition.duration;
911
917
  animation.currentTime = duration * progress;
912
918
  }
913
919
  }
@@ -1086,15 +1092,16 @@ var TransitionController = class {
1086
1092
  return;
1087
1093
  }
1088
1094
  if (releaseDuration <= 0) {
1089
- for (const animation of transition.animations) {
1090
- const duration = this.getAnimationDuration(animation, transition.duration);
1095
+ transition.progress = targetProgress;
1096
+ for (const [index, animation] of transition.animations.entries()) {
1097
+ const duration = transition.animationDurations[index] ?? transition.duration;
1091
1098
  animation.pause();
1092
1099
  animation.currentTime = duration * targetProgress;
1093
1100
  }
1094
1101
  return;
1095
1102
  }
1096
- const finished = transition.animations.map((animation) => {
1097
- const duration = this.getAnimationDuration(animation, transition.duration);
1103
+ const finished = transition.animations.map((animation, index) => {
1104
+ const duration = transition.animationDurations[index] ?? transition.duration;
1098
1105
  const currentTime = typeof animation.currentTime === "number" ? animation.currentTime : 0;
1099
1106
  const targetTime = duration * targetProgress;
1100
1107
  const distance = Math.abs(targetTime - currentTime);
@@ -1107,6 +1114,7 @@ var TransitionController = class {
1107
1114
  return animation.finished.catch(() => void 0);
1108
1115
  });
1109
1116
  await Promise.all(finished);
1117
+ transition.progress = targetProgress;
1110
1118
  }
1111
1119
  /**
1112
1120
  * Resolve configured easing presets after platform/direction are known.
@@ -1281,6 +1289,8 @@ var CapRouterOutlet = class extends HTMLElement {
1281
1289
  pendingPage = null;
1282
1290
  ignoredNodes = /* @__PURE__ */ new WeakSet();
1283
1291
  swipeGesturePointer = null;
1292
+ swipeGestureFrame = 0;
1293
+ swipeGesturePendingStep = null;
1284
1294
  swipeGestureListenersActive = false;
1285
1295
  skipNextHistoryBackTransition = false;
1286
1296
  swipeBackDepth = 0;
@@ -1323,6 +1333,7 @@ var CapRouterOutlet = class extends HTMLElement {
1323
1333
  this.style.width = "100%";
1324
1334
  this.style.height = "100%";
1325
1335
  this.style.overflow = "hidden";
1336
+ this.style.overscrollBehaviorX = "contain";
1326
1337
  this.lastNavigationHref = this.getCurrentNavigationHref();
1327
1338
  this.lastNavigationPosition = this.getCurrentNavigationPosition();
1328
1339
  this.ownerDocument.defaultView?.addEventListener("popstate", this.handleHistoryPopState);
@@ -1630,6 +1641,10 @@ var CapRouterOutlet = class extends HTMLElement {
1630
1641
  this.removeEventListener("pointerup", this.handleSwipeGesturePointerEnd);
1631
1642
  this.removeEventListener("pointercancel", this.handleSwipeGesturePointerCancel);
1632
1643
  this.swipeGestureListenersActive = false;
1644
+ this.clearQueuedSwipeGestureStep();
1645
+ if (this.swipeGesturePointer?.transitionStarted) {
1646
+ this.controller.cancelInteractiveBack();
1647
+ }
1633
1648
  this.swipeGesturePointer = null;
1634
1649
  }
1635
1650
  isSwipeGestureEnabled() {
@@ -1822,12 +1837,14 @@ var CapRouterOutlet = class extends HTMLElement {
1822
1837
  if (!this.canStartSwipeGesture(event)) {
1823
1838
  return;
1824
1839
  }
1840
+ const width = Math.max(this.getBoundingClientRect().width, 1);
1825
1841
  this.swipeGesturePointer = {
1826
1842
  pointerId: event.pointerId,
1827
1843
  startX: event.clientX,
1828
1844
  startY: event.clientY,
1829
1845
  currentX: event.clientX,
1830
1846
  currentY: event.clientY,
1847
+ width,
1831
1848
  startTime: performance.now(),
1832
1849
  dragging: false,
1833
1850
  transitionStarted: false
@@ -1874,8 +1891,7 @@ var CapRouterOutlet = class extends HTMLElement {
1874
1891
  return;
1875
1892
  }
1876
1893
  if (event.cancelable) event.preventDefault();
1877
- const width = Math.max(this.getBoundingClientRect().width, 1);
1878
- this.controller.stepInteractiveBack(deltaX / width);
1894
+ this.queueSwipeGestureStep(deltaX / pointer.width);
1879
1895
  }
1880
1896
  };
1881
1897
  handleSwipeGesturePointerEnd = (event) => {
@@ -1888,12 +1904,17 @@ var CapRouterOutlet = class extends HTMLElement {
1888
1904
  const deltaX = this.getSwipeGestureDeltaX(pointer);
1889
1905
  const elapsed = Math.max(performance.now() - pointer.startTime, 1);
1890
1906
  const velocityX = deltaX / elapsed;
1891
- const width = Math.max(this.getBoundingClientRect().width, 1);
1907
+ const width = pointer.width;
1892
1908
  const step = deltaX / width;
1893
1909
  const shouldCommit = pointer.dragging && pointer.transitionStarted && velocityX >= 0 && (velocityX > this.swipeGestureMinimumVelocity || deltaX > width / 2);
1894
1910
  const missing = shouldCommit ? 1 - step : step;
1895
1911
  const missingDistance = Math.max(missing, 0) * width;
1896
1912
  const releaseDuration = missingDistance > 5 && Math.abs(velocityX) > 0 ? Math.min(missingDistance / Math.abs(velocityX), 540) : 0;
1913
+ if (pointer.transitionStarted) {
1914
+ this.flushQueuedSwipeGestureStep();
1915
+ } else {
1916
+ this.clearQueuedSwipeGestureStep();
1917
+ }
1897
1918
  this.releaseSwipeGesturePointer(event.pointerId);
1898
1919
  void this.finishSwipeGestureBack(shouldCommit, releaseDuration);
1899
1920
  };
@@ -1901,6 +1922,7 @@ var CapRouterOutlet = class extends HTMLElement {
1901
1922
  this.cancelSwipeGesture(event.pointerId);
1902
1923
  };
1903
1924
  cancelSwipeGesturePointer(pointerId) {
1925
+ this.clearQueuedSwipeGestureStep();
1904
1926
  this.releaseSwipeGesturePointer(pointerId);
1905
1927
  }
1906
1928
  releaseSwipeGesturePointer(pointerId) {
@@ -1919,10 +1941,44 @@ var CapRouterOutlet = class extends HTMLElement {
1919
1941
  return;
1920
1942
  }
1921
1943
  this.releaseSwipeGesturePointer(pointerId);
1944
+ this.clearQueuedSwipeGestureStep();
1922
1945
  if (pointer.transitionStarted) {
1923
1946
  void this.finishSwipeGestureBack(false, 0);
1924
1947
  }
1925
1948
  }
1949
+ queueSwipeGestureStep(step) {
1950
+ this.swipeGesturePendingStep = step;
1951
+ if (this.swipeGestureFrame !== 0) {
1952
+ return;
1953
+ }
1954
+ const win = this.ownerDocument.defaultView;
1955
+ if (!win) {
1956
+ this.flushQueuedSwipeGestureStep();
1957
+ return;
1958
+ }
1959
+ this.swipeGestureFrame = win.requestAnimationFrame(() => {
1960
+ this.swipeGestureFrame = 0;
1961
+ this.flushQueuedSwipeGestureStep();
1962
+ });
1963
+ }
1964
+ flushQueuedSwipeGestureStep() {
1965
+ const step = this.swipeGesturePendingStep;
1966
+ this.swipeGesturePendingStep = null;
1967
+ if (this.swipeGestureFrame !== 0) {
1968
+ this.ownerDocument.defaultView?.cancelAnimationFrame(this.swipeGestureFrame);
1969
+ this.swipeGestureFrame = 0;
1970
+ }
1971
+ if (step !== null) {
1972
+ this.controller.stepInteractiveBack(step);
1973
+ }
1974
+ }
1975
+ clearQueuedSwipeGestureStep() {
1976
+ if (this.swipeGestureFrame !== 0) {
1977
+ this.ownerDocument.defaultView?.cancelAnimationFrame(this.swipeGestureFrame);
1978
+ this.swipeGestureFrame = 0;
1979
+ }
1980
+ this.swipeGesturePendingStep = null;
1981
+ }
1926
1982
  async finishSwipeGestureBack(shouldComplete, releaseDuration) {
1927
1983
  const canComplete = shouldComplete && this.getSwipeBackDestination() !== null;
1928
1984
  const shouldUseHistory = canComplete && typeof window !== "undefined" && window.history.length > 1;
@@ -2382,4 +2438,4 @@ export {
2382
2438
  CapContent,
2383
2439
  CapFooter
2384
2440
  };
2385
- //# sourceMappingURL=chunk-X3P7VCWP.mjs.map
2441
+ //# sourceMappingURL=chunk-LABKGL2K.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/native-platform.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","/**\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} 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, { ...config, direction: 'root' });\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 enteringState = this.createPageState(enteringEl);\n const leavingState = this.currentPage;\n\n return this.navigateWithStates(enteringState, leavingState, config, () => {\n if (direction === 'root') {\n // Clear the stack and set new root\n this.pageStack = [enteringState];\n } else if (direction === '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 {\n // Push new page onto stack\n this.pageStack.push(enteringState);\n }\n });\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 type { TransitionController } from '../core/transition-controller';\nimport { createTransitionController } from '../core/transition-controller';\nimport type {\n TransitionConfig,\n TransitionGlobalConfig,\n TransitionDirection,\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 explicitDirection = (page.dataset.direction as TransitionDirection | undefined) || outletDirection;\n const direction = this.resolveNavigationDirection(explicitDirection);\n if (outletDirection) {\n delete this.dataset.direction;\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, { direction, duration: skipTransition ? 0 : undefined });\n if (result.success) {\n this.recordCompletedNavigation(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 * 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 this.dataset.direction = '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-X3P7VCWP.mjs";
7
+ } from "./chunk-LABKGL2K.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-OPL2TMTE.mjs.map
15
+ //# sourceMappingURL=components-M5B63NYZ.mjs.map
package/dist/index.d.mts CHANGED
@@ -317,6 +317,8 @@ declare class CapRouterOutlet extends HTMLElement {
317
317
  private pendingPage;
318
318
  private ignoredNodes;
319
319
  private swipeGesturePointer;
320
+ private swipeGestureFrame;
321
+ private swipeGesturePendingStep;
320
322
  private swipeGestureListenersActive;
321
323
  private skipNextHistoryBackTransition;
322
324
  private swipeBackDepth;
@@ -419,6 +421,9 @@ declare class CapRouterOutlet extends HTMLElement {
419
421
  private cancelSwipeGesturePointer;
420
422
  private releaseSwipeGesturePointer;
421
423
  private cancelSwipeGesture;
424
+ private queueSwipeGestureStep;
425
+ private flushQueuedSwipeGestureStep;
426
+ private clearQueuedSwipeGestureStep;
422
427
  private finishSwipeGestureBack;
423
428
  }
424
429
 
package/dist/index.d.ts CHANGED
@@ -317,6 +317,8 @@ declare class CapRouterOutlet extends HTMLElement {
317
317
  private pendingPage;
318
318
  private ignoredNodes;
319
319
  private swipeGesturePointer;
320
+ private swipeGestureFrame;
321
+ private swipeGesturePendingStep;
320
322
  private swipeGestureListenersActive;
321
323
  private skipNextHistoryBackTransition;
322
324
  private swipeBackDepth;
@@ -419,6 +421,9 @@ declare class CapRouterOutlet extends HTMLElement {
419
421
  private cancelSwipeGesturePointer;
420
422
  private releaseSwipeGesturePointer;
421
423
  private cancelSwipeGesture;
424
+ private queueSwipeGestureStep;
425
+ private flushQueuedSwipeGestureStep;
426
+ private clearQueuedSwipeGestureStep;
422
427
  private finishSwipeGestureBack;
423
428
  }
424
429