@capgo/capacitor-transitions 8.0.1 → 8.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RLOQDT3I.mjs → chunk-X3P7VCWP.mjs} +149 -12
- package/dist/chunk-X3P7VCWP.mjs.map +1 -0
- package/dist/{components-6C46YYFQ.mjs → components-OPL2TMTE.mjs} +2 -2
- package/dist/index.d.mts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +148 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/react/index.js +148 -11
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +148 -11
- package/dist/react/index.mjs.map +1 -1
- package/dist/solid/index.js +148 -11
- package/dist/solid/index.js.map +1 -1
- package/dist/solid/index.mjs +148 -11
- package/dist/solid/index.mjs.map +1 -1
- package/dist/svelte/index.js +148 -11
- package/dist/svelte/index.js.map +1 -1
- package/dist/svelte/index.mjs +148 -11
- package/dist/svelte/index.mjs.map +1 -1
- package/dist/vue/index.js +148 -11
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/index.mjs +148 -11
- package/dist/vue/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-RLOQDT3I.mjs.map +0 -1
- /package/dist/{components-6C46YYFQ.mjs.map → components-OPL2TMTE.mjs.map} +0 -0
|
@@ -1285,9 +1285,26 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1285
1285
|
skipNextHistoryBackTransition = false;
|
|
1286
1286
|
swipeBackDepth = 0;
|
|
1287
1287
|
lastNavigationHref = null;
|
|
1288
|
+
lastNavigationPosition = null;
|
|
1289
|
+
pendingHistoryDirection = null;
|
|
1290
|
+
navigationHrefs = [];
|
|
1288
1291
|
swipeGestureEdgeWidth = 50;
|
|
1289
1292
|
swipeGestureThreshold = 10;
|
|
1290
1293
|
swipeGestureMinimumVelocity = 0.2;
|
|
1294
|
+
handleHistoryPopState = () => {
|
|
1295
|
+
const currentPosition = this.getCurrentNavigationPosition();
|
|
1296
|
+
if (currentPosition !== null && this.lastNavigationPosition !== null) {
|
|
1297
|
+
if (currentPosition < this.lastNavigationPosition) {
|
|
1298
|
+
this.pendingHistoryDirection = "back";
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
if (currentPosition > this.lastNavigationPosition) {
|
|
1302
|
+
this.pendingHistoryDirection = "forward";
|
|
1303
|
+
return;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
this.pendingHistoryDirection = "back";
|
|
1307
|
+
};
|
|
1291
1308
|
static get observedAttributes() {
|
|
1292
1309
|
return ["platform", "duration", "keep-in-dom", "max-cached", "swipe-gesture"];
|
|
1293
1310
|
}
|
|
@@ -1307,6 +1324,8 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1307
1324
|
this.style.height = "100%";
|
|
1308
1325
|
this.style.overflow = "hidden";
|
|
1309
1326
|
this.lastNavigationHref = this.getCurrentNavigationHref();
|
|
1327
|
+
this.lastNavigationPosition = this.getCurrentNavigationPosition();
|
|
1328
|
+
this.ownerDocument.defaultView?.addEventListener("popstate", this.handleHistoryPopState);
|
|
1310
1329
|
this.observer = new MutationObserver((mutations) => {
|
|
1311
1330
|
this.handleMutations(mutations);
|
|
1312
1331
|
});
|
|
@@ -1322,10 +1341,14 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1322
1341
|
}
|
|
1323
1342
|
disconnectedCallback() {
|
|
1324
1343
|
this.observer?.disconnect();
|
|
1344
|
+
this.ownerDocument.defaultView?.removeEventListener("popstate", this.handleHistoryPopState);
|
|
1325
1345
|
this.removeSwipeGestureListeners();
|
|
1326
1346
|
this.controller.clear();
|
|
1327
1347
|
this.swipeBackDepth = 0;
|
|
1328
1348
|
this.lastNavigationHref = null;
|
|
1349
|
+
this.lastNavigationPosition = null;
|
|
1350
|
+
this.pendingHistoryDirection = null;
|
|
1351
|
+
this.navigationHrefs = [];
|
|
1329
1352
|
}
|
|
1330
1353
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
1331
1354
|
switch (name) {
|
|
@@ -1406,13 +1429,16 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1406
1429
|
this.controller.pageStack.push(state);
|
|
1407
1430
|
this.swipeBackDepth = 0;
|
|
1408
1431
|
this.lastNavigationHref = this.getCurrentNavigationHref();
|
|
1432
|
+
this.lastNavigationPosition = this.getCurrentNavigationPosition();
|
|
1433
|
+
this.navigationHrefs = [this.lastNavigationHref];
|
|
1409
1434
|
}
|
|
1410
1435
|
/**
|
|
1411
1436
|
* Handle a new page being added
|
|
1412
1437
|
*/
|
|
1413
1438
|
async handleNewPage(page) {
|
|
1414
1439
|
const outletDirection = this.dataset.direction;
|
|
1415
|
-
const
|
|
1440
|
+
const explicitDirection = page.dataset.direction || outletDirection;
|
|
1441
|
+
const direction = this.resolveNavigationDirection(explicitDirection);
|
|
1416
1442
|
if (outletDirection) {
|
|
1417
1443
|
delete this.dataset.direction;
|
|
1418
1444
|
}
|
|
@@ -1527,7 +1553,7 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1527
1553
|
* Check if we can go back
|
|
1528
1554
|
*/
|
|
1529
1555
|
get canGoBack() {
|
|
1530
|
-
return this.
|
|
1556
|
+
return this.getSwipeBackDestination() !== null;
|
|
1531
1557
|
}
|
|
1532
1558
|
/**
|
|
1533
1559
|
* Get whether edge swipe-back gesture is enabled.
|
|
@@ -1619,30 +1645,132 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1619
1645
|
getCurrentNavigationHref() {
|
|
1620
1646
|
return this.ownerDocument.defaultView?.location.href ?? null;
|
|
1621
1647
|
}
|
|
1648
|
+
getCurrentNavigationPosition() {
|
|
1649
|
+
const win = this.ownerDocument.defaultView;
|
|
1650
|
+
if (!win) {
|
|
1651
|
+
return null;
|
|
1652
|
+
}
|
|
1653
|
+
const navigationIndex = win.navigation?.currentEntry?.index;
|
|
1654
|
+
if (typeof navigationIndex === "number" && Number.isFinite(navigationIndex)) {
|
|
1655
|
+
return navigationIndex;
|
|
1656
|
+
}
|
|
1657
|
+
const state = win.history.state;
|
|
1658
|
+
for (const key of ["idx", "position", "index"]) {
|
|
1659
|
+
const value = state?.[key];
|
|
1660
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1661
|
+
return value;
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
return null;
|
|
1665
|
+
}
|
|
1666
|
+
resolveNavigationDirection(explicitDirection) {
|
|
1667
|
+
if (explicitDirection) {
|
|
1668
|
+
this.pendingHistoryDirection = null;
|
|
1669
|
+
return explicitDirection;
|
|
1670
|
+
}
|
|
1671
|
+
const currentHref = this.getCurrentNavigationHref();
|
|
1672
|
+
const existingHrefIndex = this.findNavigationHrefIndex(currentHref, this.navigationHrefs.length - 2);
|
|
1673
|
+
if (existingHrefIndex !== -1) {
|
|
1674
|
+
this.pendingHistoryDirection = null;
|
|
1675
|
+
return "back";
|
|
1676
|
+
}
|
|
1677
|
+
if (currentHref !== null && currentHref === this.lastNavigationHref) {
|
|
1678
|
+
this.pendingHistoryDirection = null;
|
|
1679
|
+
return "none";
|
|
1680
|
+
}
|
|
1681
|
+
if (this.pendingHistoryDirection) {
|
|
1682
|
+
const direction = this.pendingHistoryDirection;
|
|
1683
|
+
this.pendingHistoryDirection = null;
|
|
1684
|
+
return direction;
|
|
1685
|
+
}
|
|
1686
|
+
const currentPosition = this.getCurrentNavigationPosition();
|
|
1687
|
+
if (currentPosition !== null && this.lastNavigationPosition !== null) {
|
|
1688
|
+
if (currentPosition < this.lastNavigationPosition) {
|
|
1689
|
+
return "back";
|
|
1690
|
+
}
|
|
1691
|
+
if (currentPosition === this.lastNavigationPosition) {
|
|
1692
|
+
return "none";
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
return "forward";
|
|
1696
|
+
}
|
|
1622
1697
|
recordCompletedNavigation(direction, options) {
|
|
1623
1698
|
const currentHref = this.getCurrentNavigationHref();
|
|
1699
|
+
const currentPosition = this.getCurrentNavigationPosition();
|
|
1624
1700
|
if (!options.hadPageBefore || direction === "root") {
|
|
1625
|
-
this.
|
|
1626
|
-
this.lastNavigationHref = currentHref;
|
|
1701
|
+
this.resetNavigationDepth(currentHref, currentPosition);
|
|
1627
1702
|
return;
|
|
1628
1703
|
}
|
|
1629
1704
|
if (direction === "back") {
|
|
1630
|
-
this.
|
|
1705
|
+
this.recordBackNavigation(currentHref);
|
|
1706
|
+
this.lastNavigationPosition = currentPosition;
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1709
|
+
if (direction === "none") {
|
|
1710
|
+
if (this.navigationHrefs.length === 0) {
|
|
1711
|
+
this.navigationHrefs = [currentHref];
|
|
1712
|
+
} else {
|
|
1713
|
+
this.navigationHrefs[this.navigationHrefs.length - 1] = currentHref;
|
|
1714
|
+
}
|
|
1715
|
+
this.syncSwipeBackDepth();
|
|
1631
1716
|
this.lastNavigationHref = currentHref;
|
|
1717
|
+
this.lastNavigationPosition = currentPosition;
|
|
1632
1718
|
return;
|
|
1633
1719
|
}
|
|
1634
|
-
if (direction === "forward"
|
|
1720
|
+
if (direction === "forward") {
|
|
1635
1721
|
const hrefChanged = currentHref === null || this.lastNavigationHref === null || currentHref !== this.lastNavigationHref;
|
|
1636
1722
|
if (options.forceForward || hrefChanged) {
|
|
1637
|
-
this.
|
|
1723
|
+
this.navigationHrefs.push(currentHref);
|
|
1724
|
+
} else if (this.navigationHrefs.length === 0) {
|
|
1725
|
+
this.navigationHrefs = [currentHref];
|
|
1638
1726
|
}
|
|
1727
|
+
this.syncSwipeBackDepth();
|
|
1639
1728
|
this.lastNavigationHref = currentHref;
|
|
1729
|
+
this.lastNavigationPosition = currentPosition;
|
|
1640
1730
|
return;
|
|
1641
1731
|
}
|
|
1642
1732
|
this.lastNavigationHref = currentHref;
|
|
1733
|
+
this.lastNavigationPosition = currentPosition;
|
|
1734
|
+
}
|
|
1735
|
+
resetNavigationDepth(currentHref, currentPosition) {
|
|
1736
|
+
this.navigationHrefs = [currentHref];
|
|
1737
|
+
this.swipeBackDepth = 0;
|
|
1738
|
+
this.lastNavigationHref = currentHref;
|
|
1739
|
+
this.lastNavigationPosition = currentPosition;
|
|
1740
|
+
}
|
|
1741
|
+
recordBackNavigation(currentHref) {
|
|
1742
|
+
const existingHrefIndex = this.findNavigationHrefIndex(currentHref, this.navigationHrefs.length - 2);
|
|
1743
|
+
if (existingHrefIndex !== -1) {
|
|
1744
|
+
this.navigationHrefs = this.navigationHrefs.slice(0, existingHrefIndex + 1);
|
|
1745
|
+
} else if (this.navigationHrefs.length > 1) {
|
|
1746
|
+
this.navigationHrefs.pop();
|
|
1747
|
+
this.navigationHrefs[this.navigationHrefs.length - 1] = currentHref;
|
|
1748
|
+
} else {
|
|
1749
|
+
this.navigationHrefs = [currentHref];
|
|
1750
|
+
}
|
|
1751
|
+
this.syncSwipeBackDepth();
|
|
1752
|
+
this.lastNavigationHref = currentHref;
|
|
1753
|
+
}
|
|
1754
|
+
findNavigationHrefIndex(href, fromIndex) {
|
|
1755
|
+
for (let index = Math.min(fromIndex, this.navigationHrefs.length - 1); index >= 0; index -= 1) {
|
|
1756
|
+
if (this.navigationHrefs[index] === href) {
|
|
1757
|
+
return index;
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
return -1;
|
|
1761
|
+
}
|
|
1762
|
+
syncSwipeBackDepth() {
|
|
1763
|
+
this.swipeBackDepth = Math.max(0, this.navigationHrefs.length - 1);
|
|
1764
|
+
}
|
|
1765
|
+
getSwipeBackDestination() {
|
|
1766
|
+
const stack = this.controller.stack;
|
|
1767
|
+
if (this.swipeBackDepth <= 0 || stack.length <= 1) {
|
|
1768
|
+
return null;
|
|
1769
|
+
}
|
|
1770
|
+
return stack[stack.length - 2] ?? null;
|
|
1643
1771
|
}
|
|
1644
1772
|
canStartSwipeGesture(event) {
|
|
1645
|
-
if (!this.isSwipeGestureEnabled() || this.controller.animating || this.pendingPage || !this.
|
|
1773
|
+
if (!this.isSwipeGestureEnabled() || this.controller.animating || this.pendingPage || !this.getSwipeBackDestination()) {
|
|
1646
1774
|
return false;
|
|
1647
1775
|
}
|
|
1648
1776
|
if (!event.isPrimary || event.pointerType === "mouse" && event.button !== 0) {
|
|
@@ -1729,6 +1857,10 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1729
1857
|
return;
|
|
1730
1858
|
}
|
|
1731
1859
|
if (!pointer.dragging && deltaX > this.swipeGestureThreshold && absX > absY) {
|
|
1860
|
+
if (!this.getSwipeBackDestination()) {
|
|
1861
|
+
this.cancelSwipeGesturePointer(event.pointerId);
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1732
1864
|
pointer.dragging = true;
|
|
1733
1865
|
pointer.transitionStarted = this.controller.beginInteractiveBack({ direction: "back" });
|
|
1734
1866
|
if (!pointer.transitionStarted) {
|
|
@@ -1737,6 +1869,10 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1737
1869
|
}
|
|
1738
1870
|
}
|
|
1739
1871
|
if (pointer.dragging && pointer.transitionStarted) {
|
|
1872
|
+
if (!this.getSwipeBackDestination()) {
|
|
1873
|
+
this.cancelSwipeGesture(event.pointerId);
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1740
1876
|
if (event.cancelable) event.preventDefault();
|
|
1741
1877
|
const width = Math.max(this.getBoundingClientRect().width, 1);
|
|
1742
1878
|
this.controller.stepInteractiveBack(deltaX / width);
|
|
@@ -1788,9 +1924,10 @@ var CapRouterOutlet = class extends HTMLElement {
|
|
|
1788
1924
|
}
|
|
1789
1925
|
}
|
|
1790
1926
|
async finishSwipeGestureBack(shouldComplete, releaseDuration) {
|
|
1791
|
-
const
|
|
1792
|
-
|
|
1793
|
-
|
|
1927
|
+
const canComplete = shouldComplete && this.getSwipeBackDestination() !== null;
|
|
1928
|
+
const shouldUseHistory = canComplete && typeof window !== "undefined" && window.history.length > 1;
|
|
1929
|
+
await this.controller.endInteractiveBack(canComplete, canComplete ? releaseDuration : 0, !shouldUseHistory);
|
|
1930
|
+
if (!canComplete) {
|
|
1794
1931
|
return;
|
|
1795
1932
|
}
|
|
1796
1933
|
if (shouldUseHistory) {
|
|
@@ -2245,4 +2382,4 @@ export {
|
|
|
2245
2382
|
CapContent,
|
|
2246
2383
|
CapFooter
|
|
2247
2384
|
};
|
|
2248
|
-
//# sourceMappingURL=chunk-
|
|
2385
|
+
//# sourceMappingURL=chunk-X3P7VCWP.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 duration: 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\n this.currentAnimations = animations;\n this.interactiveBackTransition = {\n enteringState,\n leavingState,\n animations,\n duration,\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 for (const animation of transition.animations) {\n const duration = this.getAnimationDuration(animation, transition.duration);\n animation.pause();\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 for (const animation of transition.animations) {\n const duration = this.getAnimationDuration(animation, transition.duration);\n animation.pause();\n animation.currentTime = duration * targetProgress;\n }\n return;\n }\n\n const finished = transition.animations.map((animation) => {\n const duration = this.getAnimationDuration(animation, 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 }\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 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 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.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.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 this.swipeGesturePointer = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startY: event.clientY,\n currentX: event.clientX,\n currentY: event.clientY,\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 const width = Math.max(this.getBoundingClientRect().width, 1);\n this.controller.stepInteractiveBack(deltaX / 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 = Math.max(this.getBoundingClientRect().width, 1);\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 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.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\n if (pointer.transitionStarted) {\n void this.finishSwipeGestureBack(false, 0);\n }\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-
|
|
7
|
+
} from "./chunk-X3P7VCWP.mjs";
|
|
8
8
|
export {
|
|
9
9
|
CapContent,
|
|
10
10
|
CapFooter,
|
|
@@ -12,4 +12,4 @@ export {
|
|
|
12
12
|
CapPage,
|
|
13
13
|
CapRouterOutlet
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=components-
|
|
15
|
+
//# sourceMappingURL=components-OPL2TMTE.mjs.map
|
package/dist/index.d.mts
CHANGED
|
@@ -321,9 +321,13 @@ declare class CapRouterOutlet extends HTMLElement {
|
|
|
321
321
|
private skipNextHistoryBackTransition;
|
|
322
322
|
private swipeBackDepth;
|
|
323
323
|
private lastNavigationHref;
|
|
324
|
+
private lastNavigationPosition;
|
|
325
|
+
private pendingHistoryDirection;
|
|
326
|
+
private navigationHrefs;
|
|
324
327
|
private readonly swipeGestureEdgeWidth;
|
|
325
328
|
private readonly swipeGestureThreshold;
|
|
326
329
|
private readonly swipeGestureMinimumVelocity;
|
|
330
|
+
private readonly handleHistoryPopState;
|
|
327
331
|
static get observedAttributes(): string[];
|
|
328
332
|
constructor();
|
|
329
333
|
connectedCallback(): void;
|
|
@@ -395,7 +399,14 @@ declare class CapRouterOutlet extends HTMLElement {
|
|
|
395
399
|
private removeSwipeGestureListeners;
|
|
396
400
|
private isSwipeGestureEnabled;
|
|
397
401
|
private getCurrentNavigationHref;
|
|
402
|
+
private getCurrentNavigationPosition;
|
|
403
|
+
private resolveNavigationDirection;
|
|
398
404
|
private recordCompletedNavigation;
|
|
405
|
+
private resetNavigationDepth;
|
|
406
|
+
private recordBackNavigation;
|
|
407
|
+
private findNavigationHrefIndex;
|
|
408
|
+
private syncSwipeBackDepth;
|
|
409
|
+
private getSwipeBackDestination;
|
|
399
410
|
private canStartSwipeGesture;
|
|
400
411
|
private isRTL;
|
|
401
412
|
private getSwipeGestureDeltaX;
|