@stacknav/core 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +235 -0
  2. package/dist/animate.d.ts +26 -0
  3. package/dist/animate.d.ts.map +1 -0
  4. package/dist/animate.js +69 -0
  5. package/dist/animate.js.map +1 -0
  6. package/dist/css-vars.d.ts +22 -0
  7. package/dist/css-vars.d.ts.map +1 -0
  8. package/dist/css-vars.js +89 -0
  9. package/dist/css-vars.js.map +1 -0
  10. package/dist/direction.d.ts +79 -0
  11. package/dist/direction.d.ts.map +1 -0
  12. package/dist/direction.js +98 -0
  13. package/dist/direction.js.map +1 -0
  14. package/dist/edge-pan-gesture.d.ts +33 -0
  15. package/dist/edge-pan-gesture.d.ts.map +1 -0
  16. package/dist/edge-pan-gesture.js +128 -0
  17. package/dist/edge-pan-gesture.js.map +1 -0
  18. package/dist/history-adapter.d.ts +17 -0
  19. package/dist/history-adapter.d.ts.map +1 -0
  20. package/dist/history-adapter.js +44 -0
  21. package/dist/history-adapter.js.map +1 -0
  22. package/dist/index.d.ts +34 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +30 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/ios-transition.d.ts +50 -0
  27. package/dist/ios-transition.d.ts.map +1 -0
  28. package/dist/ios-transition.js +122 -0
  29. package/dist/ios-transition.js.map +1 -0
  30. package/dist/navigation-stack.d.ts +177 -0
  31. package/dist/navigation-stack.d.ts.map +1 -0
  32. package/dist/navigation-stack.js +296 -0
  33. package/dist/navigation-stack.js.map +1 -0
  34. package/dist/stacknav.css +33 -0
  35. package/dist/styles.d.ts +29 -0
  36. package/dist/styles.d.ts.map +1 -0
  37. package/dist/styles.js +39 -0
  38. package/dist/styles.js.map +1 -0
  39. package/package.json +43 -0
  40. package/src/animate.ts +80 -0
  41. package/src/css-vars.ts +91 -0
  42. package/src/direction.ts +146 -0
  43. package/src/edge-pan-gesture.ts +162 -0
  44. package/src/history-adapter.ts +52 -0
  45. package/src/index.ts +86 -0
  46. package/src/ios-transition.ts +163 -0
  47. package/src/navigation-stack.ts +362 -0
  48. package/src/styles.ts +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"direction.js","sourceRoot":"","sources":["../src/direction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { NavigationStack } from './navigation-stack.ts';
2
+ export interface EdgePanGestureOptions {
3
+ /** px strip on the leading edge that starts the gesture */
4
+ edgeWidth: number;
5
+ /** recognize the drag from anywhere on the page */
6
+ anywhere: boolean;
7
+ /** px of horizontal movement before the drag begins */
8
+ startSlop: number;
9
+ /** px of vertical movement that hands the touch back to scrolling */
10
+ verticalCancelSlop: number;
11
+ /** fraction of the width dragged that completes without velocity */
12
+ completeThreshold: number;
13
+ /** px/s toward the trailing edge that completes the pop regardless of distance */
14
+ completeVelocity: number;
15
+ /** px/s back toward the leading edge that cancels the pop regardless of distance */
16
+ cancelVelocity: number;
17
+ velocitySamples: number;
18
+ }
19
+ export interface EdgePanGesture {
20
+ readonly options: EdgePanGestureOptions;
21
+ /** Re-reads options changed at runtime, such as `edgeWidth` and `anywhere`. */
22
+ refresh(): void;
23
+ attach(stack: NavigationStack): EdgePanGesture;
24
+ detach(): void;
25
+ }
26
+ /**
27
+ * Recognizes a horizontal drag from the leading edge and drives the stack's
28
+ * interactive pop from it. Built on pointer events, so it handles both mouse
29
+ * and touch. Vertical movement early in the gesture hands the touch back to
30
+ * native scrolling.
31
+ */
32
+ export declare function createEdgePanGesture(options?: Partial<EdgePanGestureOptions>): EdgePanGesture;
33
+ //# sourceMappingURL=edge-pan-gesture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-pan-gesture.d.ts","sourceRoot":"","sources":["../src/edge-pan-gesture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwB,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEnF,MAAM,WAAW,qBAAqB;IACpC,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oEAAoE;IACpE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kFAAkF;IAClF,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,+EAA+E;IAC/E,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,cAAc,CAAC;IAC/C,MAAM,IAAI,IAAI,CAAC;CAChB;AAYD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,OAAO,CAAC,qBAAqB,CAAM,GAAG,cAAc,CAqHjG"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Recognizes a horizontal drag from the leading edge and drives the stack's
3
+ * interactive pop from it. Built on pointer events, so it handles both mouse
4
+ * and touch. Vertical movement early in the gesture hands the touch back to
5
+ * native scrolling.
6
+ */
7
+ export function createEdgePanGesture(options = {}) {
8
+ const o = {
9
+ edgeWidth: 28,
10
+ anywhere: false,
11
+ startSlop: 6,
12
+ verticalCancelSlop: 10,
13
+ completeThreshold: 0.5,
14
+ completeVelocity: 500,
15
+ cancelVelocity: -500,
16
+ velocitySamples: 6,
17
+ ...options,
18
+ };
19
+ let stack;
20
+ let strip = null;
21
+ let drag = null;
22
+ let suppressClick = false;
23
+ let offs = [];
24
+ const onDown = (ev) => {
25
+ if (drag || !stack.canPop())
26
+ return;
27
+ if (ev.pointerType === 'mouse' && ev.button !== 0)
28
+ return;
29
+ if (ev.currentTarget === stack.container && !o.anywhere)
30
+ return;
31
+ drag = { id: ev.pointerId, target: ev.currentTarget, x0: ev.clientX, y0: ev.clientY, handle: null, p: 1, samples: [[ev.clientX, performance.now()]] };
32
+ };
33
+ const onMove = (ev) => {
34
+ if (!drag || ev.pointerId !== drag.id)
35
+ return;
36
+ const dx = ev.clientX - drag.x0;
37
+ const dy = ev.clientY - drag.y0;
38
+ if (!drag.handle) {
39
+ if (Math.abs(dy) > o.verticalCancelSlop && Math.abs(dy) > Math.abs(dx)) {
40
+ drag = null;
41
+ return;
42
+ }
43
+ if (dx < o.startSlop)
44
+ return;
45
+ const handle = stack.beginInteractivePop();
46
+ if (!handle) {
47
+ drag = null;
48
+ return;
49
+ }
50
+ drag.handle = handle;
51
+ try {
52
+ drag.target.setPointerCapture?.(ev.pointerId);
53
+ }
54
+ catch {
55
+ /* capture is best-effort */
56
+ }
57
+ }
58
+ drag.samples.push([ev.clientX, performance.now()]);
59
+ if (drag.samples.length > o.velocitySamples)
60
+ drag.samples.shift();
61
+ drag.p = 1 - Math.min(1, Math.max(0, (dx - o.startSlop) / stack.width()));
62
+ drag.handle.update(drag.p);
63
+ };
64
+ const onUp = (ev) => {
65
+ if (!drag || ev.pointerId !== drag.id)
66
+ return;
67
+ const d = drag;
68
+ drag = null;
69
+ if (!d.handle)
70
+ return;
71
+ const s = d.samples;
72
+ const [x1, t1] = s[0];
73
+ const [x2, t2] = s[s.length - 1];
74
+ const velocity = t2 > t1 ? ((x2 - x1) / (t2 - t1)) * 1000 : 0;
75
+ const cancelled = ev.type === 'pointercancel';
76
+ const complete = !cancelled && (velocity > o.completeVelocity || (d.p < 1 - o.completeThreshold && velocity > o.cancelVelocity));
77
+ // The click that follows a drag release must not activate whatever is under the pointer.
78
+ suppressClick = true;
79
+ setTimeout(() => {
80
+ suppressClick = false;
81
+ }, 0);
82
+ void d.handle.finish({ complete, velocity });
83
+ };
84
+ const onClick = (ev) => {
85
+ if (suppressClick) {
86
+ ev.stopPropagation();
87
+ ev.preventDefault();
88
+ }
89
+ };
90
+ const EVENTS = { pointerdown: onDown, pointermove: onMove, pointerup: onUp, pointercancel: onUp };
91
+ const listen = (el) => Object.entries(EVENTS).forEach(([k, f]) => el.addEventListener(k, f));
92
+ const unlisten = (el) => Object.entries(EVENTS).forEach(([k, f]) => el.removeEventListener(k, f));
93
+ const refresh = () => {
94
+ if (!strip)
95
+ return;
96
+ strip.style.width = o.edgeWidth + 'px';
97
+ strip.style.display = o.anywhere || stack.entries.length < 2 ? 'none' : '';
98
+ };
99
+ const gesture = {
100
+ options: o,
101
+ refresh,
102
+ attach(s) {
103
+ stack = s;
104
+ strip = document.createElement('div');
105
+ strip.setAttribute('aria-hidden', 'true');
106
+ Object.assign(strip.style, { position: 'absolute', left: '0', top: '0', bottom: '0', zIndex: '10', touchAction: 'none' });
107
+ stack.container.append(strip);
108
+ listen(strip);
109
+ listen(stack.container);
110
+ stack.container.addEventListener('click', onClick, true);
111
+ offs = ['push', 'pop', 'replace', 'reset'].map((e) => stack.on(e, refresh));
112
+ refresh();
113
+ return gesture;
114
+ },
115
+ detach() {
116
+ if (!strip)
117
+ return;
118
+ offs.forEach((f) => f());
119
+ unlisten(strip);
120
+ unlisten(stack.container);
121
+ stack.container.removeEventListener('click', onClick, true);
122
+ strip.remove();
123
+ strip = null;
124
+ },
125
+ };
126
+ return gesture;
127
+ }
128
+ //# sourceMappingURL=edge-pan-gesture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-pan-gesture.js","sourceRoot":"","sources":["../src/edge-pan-gesture.ts"],"names":[],"mappings":"AAsCA;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAA0C,EAAE;IAC/E,MAAM,CAAC,GAA0B;QAC/B,SAAS,EAAE,EAAE;QACb,QAAQ,EAAE,KAAK;QACf,SAAS,EAAE,CAAC;QACZ,kBAAkB,EAAE,EAAE;QACtB,iBAAiB,EAAE,GAAG;QACtB,gBAAgB,EAAE,GAAG;QACrB,cAAc,EAAE,CAAC,GAAG;QACpB,eAAe,EAAE,CAAC;QAClB,GAAG,OAAO;KACX,CAAC;IAEF,IAAI,KAAsB,CAAC;IAC3B,IAAI,KAAK,GAAuB,IAAI,CAAC;IACrC,IAAI,IAAI,GAAgB,IAAI,CAAC;IAC7B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,IAAI,GAAsB,EAAE,CAAC;IAEjC,MAAM,MAAM,GAAG,CAAC,EAAgB,EAAE,EAAE;QAClC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,OAAO;QACpC,IAAI,EAAE,CAAC,WAAW,KAAK,OAAO,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC1D,IAAI,EAAE,CAAC,aAAa,KAAK,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,QAAQ;YAAE,OAAO;QAChE,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,aAA+B,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;IAC1K,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,EAAgB,EAAE,EAAE;QAClC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,EAAE;YAAE,OAAO;QAC9C,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,kBAAkB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACvE,IAAI,GAAG,IAAI,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,IAAI,EAAE,GAAG,CAAC,CAAC,SAAS;gBAAE,OAAO;YAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,mBAAmB,EAAE,CAAC;YAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAI,GAAG,IAAI,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,4BAA4B;YAC9B,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,eAAe;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAClE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,CAAC,EAAgB,EAAE,EAAE;QAChC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,EAAE;YAAE,OAAO;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC;QACf,IAAI,GAAG,IAAI,CAAC;QACZ,IAAI,CAAC,CAAC,CAAC,MAAM;YAAE,OAAO;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,SAAS,GAAG,EAAE,CAAC,IAAI,KAAK,eAAe,CAAC;QAC9C,MAAM,QAAQ,GAAG,CAAC,SAAS,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,iBAAiB,IAAI,QAAQ,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;QACjI,yFAAyF;QACzF,aAAa,GAAG,IAAI,CAAC;QACrB,UAAU,CAAC,GAAG,EAAE;YACd,aAAa,GAAG,KAAK,CAAC;QACxB,CAAC,EAAE,CAAC,CAAC,CAAC;QACN,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,EAAS,EAAE,EAAE;QAC5B,IAAI,aAAa,EAAE,CAAC;YAClB,EAAE,CAAC,eAAe,EAAE,CAAC;YACrB,EAAE,CAAC,cAAc,EAAE,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAA+C,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IAC9I,MAAM,MAAM,GAAG,CAAC,EAAe,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAkB,CAAC,CAAC,CAAC;IAC3H,MAAM,QAAQ,GAAG,CAAC,EAAe,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAkB,CAAC,CAAC,CAAC;IAEhI,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC;QACvC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,CAAC,CAAC;IAEF,MAAM,OAAO,GAAmB;QAC9B,OAAO,EAAE,CAAC;QACV,OAAO;QACP,MAAM,CAAC,CAAC;YACN,KAAK,GAAG,CAAC,CAAC;YACV,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACtC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1H,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,CAAC;YACd,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACxB,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YACzD,IAAI,GAAI,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,CAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YACvF,OAAO,EAAE,CAAC;YACV,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM;YACJ,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YACzB,QAAQ,CAAC,KAAK,CAAC,CAAC;YAChB,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC1B,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC5D,KAAK,CAAC,MAAM,EAAE,CAAC;YACf,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;KACF,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { NavigationStack } from './navigation-stack.ts';
2
+ export interface BrowserHistoryOptions {
3
+ /** the `history.state` property that carries the depth */
4
+ key?: string;
5
+ /** animate pops triggered by the back button. Off on iOS browsers, which animate their own snapshot */
6
+ animateHistoryPop?: boolean;
7
+ /** forward navigation has no page to show. Re-push something here instead of bouncing back */
8
+ onForward?: ((targetDepth: number) => void) | null;
9
+ }
10
+ /**
11
+ * For apps without a router. Mirrors the stack depth into `history.state`, so
12
+ * the browser or hardware back button pops the stack and stack pops walk
13
+ * history back. Returns a function that detaches everything.
14
+ */
15
+ export declare function attachBrowserHistory(stack: NavigationStack, { key, animateHistoryPop, onForward }?: BrowserHistoryOptions): () => void;
16
+ export declare function isIOSBrowser(): boolean;
17
+ //# sourceMappingURL=history-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-adapter.d.ts","sourceRoot":"","sources":["../src/history-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uGAAuG;IACvG,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,8FAA8F;IAC9F,SAAS,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CACpD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,GAAe,EAAE,iBAAmC,EAAE,SAAgB,EAAE,GAAE,qBAA0B,GAAG,MAAM,IAAI,CA8B/K;AAED,wBAAgB,YAAY,IAAI,OAAO,CAGtC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * For apps without a router. Mirrors the stack depth into `history.state`, so
3
+ * the browser or hardware back button pops the stack and stack pops walk
4
+ * history back. Returns a function that detaches everything.
5
+ */
6
+ export function attachBrowserHistory(stack, { key = 'snDepth', animateHistoryPop = !isIOSBrowser(), onForward = null } = {}) {
7
+ const depthOf = (state) => {
8
+ const s = state;
9
+ return s && Number.isInteger(s[key]) ? s[key] : 0;
10
+ };
11
+ const write = (kind) => history[kind]({ ...(history.state || {}), [key]: stack.depth - 1 }, '');
12
+ write('replaceState');
13
+ const offPush = stack.on('push', ({ source }) => {
14
+ if (source !== 'history')
15
+ write('pushState');
16
+ });
17
+ const offPop = stack.on('pop', ({ source, removed }) => {
18
+ if (source !== 'history')
19
+ history.go(-removed.length);
20
+ });
21
+ const onPopState = (ev) => {
22
+ const target = depthOf(ev.state) + 1;
23
+ if (target === stack.depth)
24
+ return;
25
+ if (target < stack.depth)
26
+ void stack.popTo(target, { animated: animateHistoryPop, source: 'history' });
27
+ else if (onForward)
28
+ onForward(target);
29
+ else
30
+ history.back();
31
+ };
32
+ window.addEventListener('popstate', onPopState);
33
+ return () => {
34
+ offPush();
35
+ offPop();
36
+ window.removeEventListener('popstate', onPopState);
37
+ };
38
+ }
39
+ export function isIOSBrowser() {
40
+ if (typeof navigator === 'undefined')
41
+ return false;
42
+ return /iP(hone|ad|od)/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
43
+ }
44
+ //# sourceMappingURL=history-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-adapter.js","sourceRoot":"","sources":["../src/history-adapter.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAsB,EAAE,EAAE,GAAG,GAAG,SAAS,EAAE,iBAAiB,GAAG,CAAC,YAAY,EAAE,EAAE,SAAS,GAAG,IAAI,KAA4B,EAAE;IACjK,MAAM,OAAO,GAAG,CAAC,KAAc,EAAU,EAAE;QACzC,MAAM,CAAC,GAAG,KAAuC,CAAC;QAClD,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,GAAG,CAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,IAAkC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAE,OAAO,CAAC,KAAgB,IAAI,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAE1I,KAAK,CAAC,cAAc,CAAC,CAAC;IAEtB,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9C,IAAI,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACrD,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,CAAC,EAAiB,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,MAAM,KAAK,KAAK,CAAC,KAAK;YAAE,OAAO;QACnC,IAAI,MAAM,GAAG,KAAK,CAAC,KAAK;YAAE,KAAK,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;aAClG,IAAI,SAAS;YAAE,SAAS,CAAC,MAAM,CAAC,CAAC;;YACjC,OAAO,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC;IACF,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAEhD,OAAO,GAAG,EAAE;QACV,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,SAAS,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACnD,OAAO,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;AAC1H,CAAC"}
@@ -0,0 +1,34 @@
1
+ export { NavigationStack } from './navigation-stack.ts';
2
+ export type { StackEntry, Transition, TransitionKind, NavigationSource, MountOptions, NavigationStackOptions, InteractivePopHandle, SettleInput, StackEvents, PushEvent, PopEvent, ReplaceEvent, ResetEvent, TransitionEvent, ProgressEvent, } from './navigation-stack.ts';
3
+ export { createIOSTransition, IOS_TRANSITION_CSS_VARS } from './ios-transition.ts';
4
+ export type { IOSTransition, IOSTransitionOptions } from './ios-transition.ts';
5
+ export { cssVars, parseTime, parseNumber, parseRatio, parseEasing } from './css-vars.ts';
6
+ export type { CSSVarReader } from './css-vars.ts';
7
+ export { createEdgePanGesture } from './edge-pan-gesture.ts';
8
+ export type { EdgePanGesture, EdgePanGestureOptions } from './edge-pan-gesture.ts';
9
+ export { attachBrowserHistory, isIOSBrowser } from './history-adapter.ts';
10
+ export type { BrowserHistoryOptions } from './history-adapter.ts';
11
+ export { cubicBezier, easings, tween, prefersReducedMotion } from './animate.ts';
12
+ export type { Easing, TweenOptions, CancellableTween } from './animate.ts';
13
+ export { resolveDirection, createDirectionResolver, defaultStrategies, fromHint, fromHistory, fromStack, fromLevel, fromTree, always, segmentsOf, } from './direction.ts';
14
+ export type { Direction, DirectionOpinion, DirectionStrategy, DirectionResolver, NavigationContext, NavigationTrigger, RouteRef, LevelOptions, TreeOptions, } from './direction.ts';
15
+ export { STACKNAV_CSS, STACKNAV_STYLE_ID, injectStyles } from './styles.ts';
16
+ import { NavigationStack } from './navigation-stack.ts';
17
+ import { type IOSTransition, type IOSTransitionOptions } from './ios-transition.ts';
18
+ import { type EdgePanGesture, type EdgePanGestureOptions } from './edge-pan-gesture.ts';
19
+ export interface IOSStackOptions {
20
+ container: HTMLElement;
21
+ transition?: Partial<IOSTransitionOptions>;
22
+ gesture?: Partial<EdgePanGestureOptions>;
23
+ }
24
+ export interface IOSStack extends NavigationStack {
25
+ transition: IOSTransition;
26
+ gesture: EdgePanGesture;
27
+ }
28
+ /**
29
+ * Wires the three pieces together in one call: a stack in `container`, the iOS
30
+ * transition, and the edge-pan gesture. The gesture is exposed as
31
+ * `stack.gesture`, and destroying the stack detaches it.
32
+ */
33
+ export declare function createIOSStack({ container, transition, gesture }: IOSStackOptions): IOSStack;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,sBAAsB,EACtB,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,eAAe,EACf,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnF,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACzF,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC1E,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACjF,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,SAAS,EACT,SAAS,EACT,QAAQ,EACR,MAAM,EACN,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACzG,OAAO,EAAwB,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9G,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,QAAS,SAAQ,eAAe;IAC/C,UAAU,EAAE,aAAa,CAAC;IAC1B,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,UAAe,EAAE,OAAY,EAAE,EAAE,eAAe,GAAG,QAAQ,CAYtG"}
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ export { NavigationStack } from "./navigation-stack.js";
2
+ export { createIOSTransition, IOS_TRANSITION_CSS_VARS } from "./ios-transition.js";
3
+ export { cssVars, parseTime, parseNumber, parseRatio, parseEasing } from "./css-vars.js";
4
+ export { createEdgePanGesture } from "./edge-pan-gesture.js";
5
+ export { attachBrowserHistory, isIOSBrowser } from "./history-adapter.js";
6
+ export { cubicBezier, easings, tween, prefersReducedMotion } from "./animate.js";
7
+ export { resolveDirection, createDirectionResolver, defaultStrategies, fromHint, fromHistory, fromStack, fromLevel, fromTree, always, segmentsOf, } from "./direction.js";
8
+ export { STACKNAV_CSS, STACKNAV_STYLE_ID, injectStyles } from "./styles.js";
9
+ import { NavigationStack } from "./navigation-stack.js";
10
+ import { createIOSTransition } from "./ios-transition.js";
11
+ import { createEdgePanGesture } from "./edge-pan-gesture.js";
12
+ /**
13
+ * Wires the three pieces together in one call: a stack in `container`, the iOS
14
+ * transition, and the edge-pan gesture. The gesture is exposed as
15
+ * `stack.gesture`, and destroying the stack detaches it.
16
+ */
17
+ export function createIOSStack({ container, transition = {}, gesture = {} }) {
18
+ const t = createIOSTransition(transition);
19
+ const g = createEdgePanGesture(gesture);
20
+ const stack = new NavigationStack({ container, transition: t });
21
+ g.attach(stack);
22
+ stack.gesture = g;
23
+ const destroy = stack.destroy.bind(stack);
24
+ stack.destroy = () => {
25
+ g.detach();
26
+ destroy();
27
+ };
28
+ return stack;
29
+ }
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAkBxD,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEjF,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,SAAS,EACT,SAAS,EACT,QAAQ,EACR,MAAM,EACN,UAAU,GACX,MAAM,gBAAgB,CAAC;AAYxB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAiD,MAAM,qBAAqB,CAAC;AACzG,OAAO,EAAE,oBAAoB,EAAmD,MAAM,uBAAuB,CAAC;AAa9G;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,SAAS,EAAE,UAAU,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAmB;IAC1F,MAAM,CAAC,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,CAAa,CAAC;IAC5E,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChB,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,KAAK,CAAC,OAAO,GAAG,GAAG,EAAE;QACnB,CAAC,CAAC,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { type Easing } from './animate.ts';
2
+ import type { Transition } from './navigation-stack.ts';
3
+ export interface IOSTransitionOptions {
4
+ /** ms, programmatic push/pop */
5
+ duration: number;
6
+ /** the curve a programmatic push/pop runs on */
7
+ ease: Easing;
8
+ /** fraction of the width the lower page travels */
9
+ parallax: number;
10
+ dimColor: string;
11
+ /** lower-page overlay opacity at p = 1 (≈0.35 suits dark UIs) */
12
+ dimMax: number;
13
+ /** box-shadow on the incoming page */
14
+ shadow: string;
15
+ /** ms bounds for finishing an interactive pop */
16
+ settleMin: number;
17
+ settleMax: number;
18
+ /** the curve the remaining distance of an interactive pop runs on */
19
+ settleEase: Easing;
20
+ /** px/s assumed when the pointer was slower than this */
21
+ settleVelocityFloor: number;
22
+ /** multiplies every duration, for slow motion and tests */
23
+ timeScale: number;
24
+ }
25
+ /** The CSS custom property behind each option. */
26
+ export declare const IOS_TRANSITION_CSS_VARS: Readonly<Record<keyof IOSTransitionOptions, string>>;
27
+ export interface IOSTransition extends Transition {
28
+ /** The JS options: the defaults with the caller's merged in. Mutable at runtime. */
29
+ readonly options: IOSTransitionOptions;
30
+ /** The values currently in force: `options` with the CSS variables applied over them. */
31
+ readonly resolved: Readonly<IOSTransitionOptions>;
32
+ /**
33
+ * Re-reads the CSS variables, from `el` or from the container of the last
34
+ * transition. Called at the start of every transition. Call it directly
35
+ * after changing `options` or the variables mid-animation.
36
+ */
37
+ refresh(el?: Element | null): void;
38
+ }
39
+ /**
40
+ * The iOS navigation transition: the upper page slides in from the trailing
41
+ * edge with a shadow on its leading edge, while the lower page parallaxes
42
+ * toward the leading edge and dims. Every value is a function of one number, p.
43
+ *
44
+ * Every option is also a CSS custom property on the container (see
45
+ * `IOS_TRANSITION_CSS_VARS`), read when a transition starts. A variable that
46
+ * is set wins over the JS option, so a stylesheet can slow the animation down
47
+ * or restyle it per theme without the app rebuilding the transition.
48
+ */
49
+ export declare function createIOSTransition(options?: Partial<IOSTransitionOptions>): IOSTransition;
50
+ //# sourceMappingURL=ios-transition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ios-transition.d.ts","sourceRoot":"","sources":["../src/ios-transition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,KAAK,EAA2B,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEjF,MAAM,WAAW,oBAAoB;IACnC,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kDAAkD;AAClD,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,oBAAoB,EAAE,MAAM,CAAC,CAYvF,CAAC;AAEH,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAClD;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;CACpC;AAKD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAAG,aAAa,CA8F9F"}
@@ -0,0 +1,122 @@
1
+ import { easings, prefersReducedMotion } from "./animate.js";
2
+ import { cssVars, parseEasing, parseNumber, parseRatio, parseTime } from "./css-vars.js";
3
+ /** The CSS custom property behind each option. */
4
+ export const IOS_TRANSITION_CSS_VARS = /*#__PURE__*/ Object.freeze({
5
+ duration: '--sn-duration',
6
+ ease: '--sn-easing',
7
+ parallax: '--sn-parallax',
8
+ dimColor: '--sn-dim-color',
9
+ dimMax: '--sn-dim-max',
10
+ shadow: '--sn-shadow',
11
+ settleMin: '--sn-settle-min',
12
+ settleMax: '--sn-settle-max',
13
+ settleEase: '--sn-settle-easing',
14
+ settleVelocityFloor: '--sn-settle-velocity-floor',
15
+ timeScale: '--sn-time-scale',
16
+ });
17
+ const DIM = /*#__PURE__*/ Symbol('dim');
18
+ /**
19
+ * The iOS navigation transition: the upper page slides in from the trailing
20
+ * edge with a shadow on its leading edge, while the lower page parallaxes
21
+ * toward the leading edge and dims. Every value is a function of one number, p.
22
+ *
23
+ * Every option is also a CSS custom property on the container (see
24
+ * `IOS_TRANSITION_CSS_VARS`), read when a transition starts. A variable that
25
+ * is set wins over the JS option, so a stylesheet can slow the animation down
26
+ * or restyle it per theme without the app rebuilding the transition.
27
+ */
28
+ export function createIOSTransition(options = {}) {
29
+ const o = {
30
+ duration: 500,
31
+ ease: easings.ios,
32
+ parallax: 0.3,
33
+ dimColor: '#000',
34
+ dimMax: 0.1,
35
+ shadow: '-3px 0 14px rgba(0,0,0,0.16)',
36
+ settleMin: 120,
37
+ settleMax: 400,
38
+ settleEase: easings.easeOut,
39
+ settleVelocityFloor: 900,
40
+ timeScale: 1,
41
+ ...options,
42
+ };
43
+ let root = null;
44
+ let r = { ...o };
45
+ const refresh = (el) => {
46
+ if (el !== undefined)
47
+ root = el;
48
+ const read = cssVars(root);
49
+ const v = IOS_TRANSITION_CSS_VARS;
50
+ r = {
51
+ duration: parseTime(read(v.duration)) ?? o.duration,
52
+ ease: parseEasing(read(v.ease)) ?? o.ease,
53
+ parallax: parseRatio(read(v.parallax)) ?? o.parallax,
54
+ dimColor: read(v.dimColor) ?? o.dimColor,
55
+ dimMax: parseRatio(read(v.dimMax)) ?? o.dimMax,
56
+ shadow: read(v.shadow) ?? o.shadow,
57
+ settleMin: parseTime(read(v.settleMin)) ?? o.settleMin,
58
+ settleMax: parseTime(read(v.settleMax)) ?? o.settleMax,
59
+ settleEase: parseEasing(read(v.settleEase)) ?? o.settleEase,
60
+ settleVelocityFloor: parseNumber(read(v.settleVelocityFloor)) ?? o.settleVelocityFloor,
61
+ timeScale: parseNumber(read(v.timeScale)) ?? o.timeScale,
62
+ };
63
+ };
64
+ const dimOf = (entry) => {
65
+ let d = entry[DIM];
66
+ if (!d) {
67
+ d = document.createElement('div');
68
+ d.setAttribute('aria-hidden', 'true');
69
+ Object.assign(d.style, { position: 'fixed', inset: '0', pointerEvents: 'none', opacity: '0', zIndex: '2147483647' });
70
+ entry[DIM] = d;
71
+ }
72
+ d.style.background = r.dimColor;
73
+ if (d.parentElement !== entry.el)
74
+ entry.el.append(d);
75
+ return d;
76
+ };
77
+ return {
78
+ options: o,
79
+ get resolved() {
80
+ return r;
81
+ },
82
+ refresh,
83
+ get duration() {
84
+ return prefersReducedMotion() ? 0 : r.duration * r.timeScale;
85
+ },
86
+ get ease() {
87
+ return r.ease;
88
+ },
89
+ /** How long the remaining distance of an interactive pop should take. */
90
+ settle({ remainingPx, velocity }) {
91
+ if (prefersReducedMotion())
92
+ return { duration: 0, ease: r.settleEase };
93
+ const raw = (remainingPx / Math.max(Math.abs(velocity), r.settleVelocityFloor)) * 1000;
94
+ return { duration: Math.min(r.settleMax, Math.max(r.settleMin, raw)) * r.timeScale, ease: r.settleEase };
95
+ },
96
+ begin(lower, upper) {
97
+ refresh(upper.el.parentElement);
98
+ upper.el.style.boxShadow = r.shadow;
99
+ if (lower)
100
+ dimOf(lower);
101
+ },
102
+ apply(lower, upper, p) {
103
+ const w = upper.el.parentElement?.clientWidth ?? 0;
104
+ upper.el.style.transform = `translate3d(${(1 - p) * w}px,0,0)`;
105
+ if (lower) {
106
+ lower.el.style.transform = `translate3d(${-p * r.parallax * w}px,0,0)`;
107
+ dimOf(lower).style.opacity = String(p * r.dimMax);
108
+ }
109
+ },
110
+ end(lower, upper) {
111
+ upper.el.style.boxShadow = '';
112
+ upper.el.style.transform = '';
113
+ if (lower) {
114
+ lower.el.style.transform = '';
115
+ const d = lower[DIM];
116
+ if (d)
117
+ d.remove();
118
+ }
119
+ },
120
+ };
121
+ }
122
+ //# sourceMappingURL=ios-transition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ios-transition.js","sourceRoot":"","sources":["../src/ios-transition.ts"],"names":[],"mappings":"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"}