@flightdev/transitions 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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/dist/adapters/react/index.d.ts +210 -0
  4. package/dist/adapters/react/index.js +261 -0
  5. package/dist/adapters/react/index.js.map +1 -0
  6. package/dist/adapters/solid/index.d.ts +5 -0
  7. package/dist/adapters/solid/index.js +9 -0
  8. package/dist/adapters/solid/index.js.map +1 -0
  9. package/dist/adapters/svelte/index.d.ts +5 -0
  10. package/dist/adapters/svelte/index.js +9 -0
  11. package/dist/adapters/svelte/index.js.map +1 -0
  12. package/dist/adapters/vue/index.d.ts +5 -0
  13. package/dist/adapters/vue/index.js +9 -0
  14. package/dist/adapters/vue/index.js.map +1 -0
  15. package/dist/chunk-DZC3OLDU.js +121 -0
  16. package/dist/chunk-DZC3OLDU.js.map +1 -0
  17. package/dist/chunk-GEYKSLH6.js +190 -0
  18. package/dist/chunk-GEYKSLH6.js.map +1 -0
  19. package/dist/chunk-N7U5LD4Z.js +70 -0
  20. package/dist/chunk-N7U5LD4Z.js.map +1 -0
  21. package/dist/chunk-OV3U5STU.js +252 -0
  22. package/dist/chunk-OV3U5STU.js.map +1 -0
  23. package/dist/chunk-QSB65CTV.js +438 -0
  24. package/dist/chunk-QSB65CTV.js.map +1 -0
  25. package/dist/chunk-SPUGO5I5.js +138 -0
  26. package/dist/chunk-SPUGO5I5.js.map +1 -0
  27. package/dist/chunk-W7HSR35B.js +3 -0
  28. package/dist/chunk-W7HSR35B.js.map +1 -0
  29. package/dist/chunk-X2A7XWYR.js +442 -0
  30. package/dist/chunk-X2A7XWYR.js.map +1 -0
  31. package/dist/chunk-XLVYHPII.js +3 -0
  32. package/dist/chunk-XLVYHPII.js.map +1 -0
  33. package/dist/chunk-ZI6E7GNQ.js +136 -0
  34. package/dist/chunk-ZI6E7GNQ.js.map +1 -0
  35. package/dist/component/index.d.ts +87 -0
  36. package/dist/component/index.js +5 -0
  37. package/dist/component/index.js.map +1 -0
  38. package/dist/config/index.d.ts +93 -0
  39. package/dist/config/index.js +5 -0
  40. package/dist/config/index.js.map +1 -0
  41. package/dist/core/index.d.ts +107 -0
  42. package/dist/core/index.js +5 -0
  43. package/dist/core/index.js.map +1 -0
  44. package/dist/index.d.ts +10 -0
  45. package/dist/index.js +11 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/layout/index.d.ts +112 -0
  48. package/dist/layout/index.js +4 -0
  49. package/dist/layout/index.js.map +1 -0
  50. package/dist/page/index.d.ts +87 -0
  51. package/dist/page/index.js +7 -0
  52. package/dist/page/index.js.map +1 -0
  53. package/dist/presets/index.d.ts +192 -0
  54. package/dist/presets/index.js +3 -0
  55. package/dist/presets/index.js.map +1 -0
  56. package/dist/router/index.d.ts +104 -0
  57. package/dist/router/index.js +7 -0
  58. package/dist/router/index.js.map +1 -0
  59. package/dist/transition-manager-QWm4OSFw.d.ts +62 -0
  60. package/dist/types-BA4L37s4.d.ts +272 -0
  61. package/dist/view-transition-LSN_PSbm.d.ts +97 -0
  62. package/package.json +148 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/page/page-transition.ts"],"names":[],"mappings":"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","file":"chunk-SPUGO5I5.js","sourcesContent":["/**\r\n * @flightdev/transitions - Page Transitions\r\n * \r\n * Page-level transition management for route navigation.\r\n */\r\n\r\nimport type {\r\n PageTransitionConfig,\r\n TransitionPreset,\r\n CustomTransition,\r\n TransitionDirection,\r\n TransitionContext,\r\n ResolvedTransition,\r\n} from '../core/types';\r\nimport { getTransitionManager } from '../core/transition-manager';\r\nimport { resolveTransition, prefersReducedMotion } from '../core/animation-engine';\r\nimport { getPreset } from '../presets';\r\n\r\n// =============================================================================\r\n// PAGE METADATA STORE\r\n// =============================================================================\r\n\r\n/** Storage for page-specific transition configurations */\r\nconst pageTransitionConfigs = new Map<string, PageTransitionConfig>();\r\n\r\n/**\r\n * Define transition configuration for the current page\r\n * Similar to Nuxt's definePageMeta but for transitions only\r\n * \r\n * @example\r\n * ```tsx\r\n * // In a page component\r\n * definePageTransition({\r\n * default: 'slide-left',\r\n * backTransition: 'slide-right',\r\n * duration: 250,\r\n * });\r\n * \r\n * export default function DashboardPage() {\r\n * return <div>Dashboard</div>;\r\n * }\r\n * ```\r\n */\r\nexport function definePageTransition(config: PageTransitionConfig): void {\r\n // Get current page path (works in browser and during SSR build)\r\n const path = getCurrentPagePath();\r\n\r\n if (path) {\r\n pageTransitionConfigs.set(path, config);\r\n }\r\n}\r\n\r\n/**\r\n * Get the transition configuration for a specific page\r\n */\r\nexport function getPageTransition(path: string): PageTransitionConfig | undefined {\r\n return pageTransitionConfigs.get(path);\r\n}\r\n\r\n/**\r\n * Clear all page transition configurations\r\n * Useful for testing or hot module replacement\r\n */\r\nexport function clearPageTransitions(): void {\r\n pageTransitionConfigs.clear();\r\n}\r\n\r\n// =============================================================================\r\n// PAGE TRANSITION HOOKS\r\n// =============================================================================\r\n\r\n/**\r\n * Options for executing a page transition\r\n */\r\nexport interface ExecutePageTransitionOptions {\r\n /** The path being navigated to */\r\n to: string;\r\n /** The path being navigated from */\r\n from?: string;\r\n /** Override the transition type */\r\n transition?: TransitionPreset | CustomTransition | false;\r\n /** Force a specific direction */\r\n direction?: TransitionDirection;\r\n /** Callback to execute the actual DOM update */\r\n updateDOM: () => void | Promise<void>;\r\n}\r\n\r\n/**\r\n * Execute a page transition\r\n * \r\n * This is the main function used by the router integration to\r\n * perform transitions between pages.\r\n * \r\n * @example\r\n * ```typescript\r\n * await executePageTransition({\r\n * to: '/dashboard',\r\n * from: '/home',\r\n * updateDOM: () => {\r\n * // Update the page content\r\n * },\r\n * });\r\n * ```\r\n */\r\nexport async function executePageTransition(\r\n options: ExecutePageTransitionOptions\r\n): Promise<void> {\r\n const manager = getTransitionManager();\r\n\r\n // Check if transitions are enabled\r\n if (!manager.isEnabled()) {\r\n await options.updateDOM();\r\n return;\r\n }\r\n\r\n const { to, from = getCurrentPagePath() ?? '/', updateDOM } = options;\r\n\r\n // Get page-specific config\r\n const toPageConfig = getPageTransition(to);\r\n const fromPageConfig = getPageTransition(from);\r\n\r\n // Determine direction\r\n const direction = options.direction ?? determineDirection(from, to);\r\n manager.setDirection(direction);\r\n\r\n // Resolve which transition to use\r\n const transitionInput = resolveTransitionInput(\r\n options.transition,\r\n toPageConfig,\r\n fromPageConfig,\r\n direction,\r\n manager.getConfig().pageTransition\r\n );\r\n\r\n // If transitions disabled, just update DOM\r\n if (transitionInput === false) {\r\n await updateDOM();\r\n return;\r\n }\r\n\r\n // Resolve to full transition definition\r\n const shouldReduce = shouldApplyReducedMotion(\r\n toPageConfig?.reduceMotion ?? manager.getConfig().reduceMotion\r\n );\r\n const resolved = resolveTransitionFromInput(transitionInput, shouldReduce);\r\n\r\n if (!resolved) {\r\n await updateDOM();\r\n return;\r\n }\r\n\r\n // Execute the transition - pass the original input, not the resolved version\r\n await manager.startPageTransition(to, {\r\n ...toPageConfig,\r\n default: transitionInput,\r\n });\r\n}\r\n\r\n/**\r\n * Determine the transition input to use based on priority:\r\n * 1. Explicit override from navigate call\r\n * 2. Target page's definePageTransition\r\n * 3. Source page's definePageTransition (for back navigation)\r\n * 4. Global config\r\n */\r\nfunction resolveTransitionInput(\r\n explicit: TransitionPreset | CustomTransition | false | undefined,\r\n toPageConfig: PageTransitionConfig | undefined,\r\n fromPageConfig: PageTransitionConfig | undefined,\r\n direction: TransitionDirection,\r\n globalDefault: TransitionPreset | CustomTransition | false | undefined\r\n): TransitionPreset | CustomTransition | false {\r\n // Explicit override takes priority\r\n if (explicit !== undefined) {\r\n return explicit;\r\n }\r\n\r\n // For back navigation, check if target page has a specific back transition\r\n if (direction === 'back') {\r\n if (toPageConfig?.backTransition !== undefined) {\r\n return toPageConfig.backTransition;\r\n }\r\n // Also check if source page defined a back transition\r\n if (fromPageConfig?.backTransition !== undefined) {\r\n return fromPageConfig.backTransition;\r\n }\r\n }\r\n\r\n // Target page's default transition\r\n if (toPageConfig?.default !== undefined) {\r\n return toPageConfig.default;\r\n }\r\n\r\n // Global default\r\n if (globalDefault !== undefined) {\r\n return globalDefault;\r\n }\r\n\r\n // Ultimate fallback\r\n return 'fade';\r\n}\r\n\r\n/**\r\n * Resolve a transition input to a full ResolvedTransition\r\n */\r\nfunction resolveTransitionFromInput(\r\n input: TransitionPreset | CustomTransition,\r\n reducedMotion: boolean\r\n): ResolvedTransition | null {\r\n if (typeof input === 'string') {\r\n const preset = getPreset(input);\r\n if (preset) {\r\n return resolveTransition(preset, reducedMotion);\r\n }\r\n // Fallback to built-in resolution\r\n return resolveTransition(input, reducedMotion);\r\n }\r\n\r\n return resolveTransition(input, reducedMotion);\r\n}\r\n\r\n/**\r\n * Determine navigation direction heuristically\r\n */\r\nfunction determineDirection(from: string, to: string): TransitionDirection {\r\n // Root is always forward\r\n if (to === '/') {\r\n return 'forward';\r\n }\r\n\r\n // Going to a parent path is \"back\"\r\n if (from.startsWith(to) && from !== to) {\r\n return 'back';\r\n }\r\n\r\n // Going to a child path is \"forward\"\r\n if (to.startsWith(from) && from !== to) {\r\n return 'forward';\r\n }\r\n\r\n // Siblings or unrelated - default to forward\r\n return 'forward';\r\n}\r\n\r\n/**\r\n * Get current page path\r\n */\r\nfunction getCurrentPagePath(): string | null {\r\n if (typeof window === 'undefined') {\r\n // During SSR, we might get this from context\r\n return null;\r\n }\r\n return window.location.pathname;\r\n}\r\n\r\n/**\r\n * Check if reduced motion should be applied\r\n */\r\nfunction shouldApplyReducedMotion(\r\n behavior: 'respect-system' | 'always-reduce' | 'ignore' | undefined\r\n): boolean {\r\n switch (behavior) {\r\n case 'always-reduce':\r\n return true;\r\n case 'ignore':\r\n return false;\r\n case 'respect-system':\r\n default:\r\n return prefersReducedMotion();\r\n }\r\n}\r\n\r\n// =============================================================================\r\n// TRANSITION LIFECYCLE HOOKS\r\n// =============================================================================\r\n\r\n/** Registered lifecycle callbacks */\r\nconst lifecycleCallbacks = {\r\n beforeLeave: new Set<(context: TransitionContext) => void>(),\r\n afterLeave: new Set<(context: TransitionContext) => void>(),\r\n beforeEnter: new Set<(context: TransitionContext) => void>(),\r\n afterEnter: new Set<(context: TransitionContext) => void>(),\r\n};\r\n\r\n/**\r\n * Register a callback to run before a page leaves\r\n */\r\nexport function onBeforePageLeave(\r\n callback: (context: TransitionContext) => void\r\n): () => void {\r\n lifecycleCallbacks.beforeLeave.add(callback);\r\n return () => lifecycleCallbacks.beforeLeave.delete(callback);\r\n}\r\n\r\n/**\r\n * Register a callback to run after a page leaves\r\n */\r\nexport function onAfterPageLeave(\r\n callback: (context: TransitionContext) => void\r\n): () => void {\r\n lifecycleCallbacks.afterLeave.add(callback);\r\n return () => lifecycleCallbacks.afterLeave.delete(callback);\r\n}\r\n\r\n/**\r\n * Register a callback to run before a page enters\r\n */\r\nexport function onBeforePageEnter(\r\n callback: (context: TransitionContext) => void\r\n): () => void {\r\n lifecycleCallbacks.beforeEnter.add(callback);\r\n return () => lifecycleCallbacks.beforeEnter.delete(callback);\r\n}\r\n\r\n/**\r\n * Register a callback to run after a page enters\r\n */\r\nexport function onAfterPageEnter(\r\n callback: (context: TransitionContext) => void\r\n): () => void {\r\n lifecycleCallbacks.afterEnter.add(callback);\r\n return () => lifecycleCallbacks.afterEnter.delete(callback);\r\n}\r\n\r\n/**\r\n * Invoke lifecycle callbacks\r\n * @internal\r\n */\r\nexport function invokeLifecycleCallbacks(\r\n phase: keyof typeof lifecycleCallbacks,\r\n context: TransitionContext\r\n): void {\r\n lifecycleCallbacks[phase].forEach((callback) => {\r\n try {\r\n callback(context);\r\n } catch (error) {\r\n console.error(`[Flight Transitions] ${phase} callback error:`, error);\r\n }\r\n });\r\n}\r\n"]}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-W7HSR35B.js.map
3
+ //# sourceMappingURL=chunk-W7HSR35B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-W7HSR35B.js"}
@@ -0,0 +1,442 @@
1
+ import { prefersReducedMotion, onReducedMotionChange, DEFAULT_EASING, DEFAULT_DURATION, resolveTransition } from './chunk-OV3U5STU.js';
2
+
3
+ // src/core/view-transition.ts
4
+ var isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
5
+ function isViewTransitionSupported() {
6
+ if (!isBrowser) return false;
7
+ return "startViewTransition" in document && typeof document.startViewTransition === "function";
8
+ }
9
+ function isCrossDocumentTransitionSupported() {
10
+ if (!isBrowser) return false;
11
+ return "onpagereveal" in window;
12
+ }
13
+ function startViewTransition(updateCallback, options = {}) {
14
+ if (!isBrowser) {
15
+ return createImmediateTransition(updateCallback);
16
+ }
17
+ if (options.skipTransition) {
18
+ return createImmediateTransition(updateCallback);
19
+ }
20
+ if (isViewTransitionSupported()) {
21
+ return createNativeTransition(updateCallback, options);
22
+ }
23
+ return createFallbackTransition(updateCallback, options);
24
+ }
25
+ function createNativeTransition(updateCallback, options) {
26
+ if (options.name) {
27
+ document.documentElement.style.setProperty(
28
+ "view-transition-name",
29
+ options.name
30
+ );
31
+ }
32
+ const typesAttr = options.types?.join(" ");
33
+ if (typesAttr) {
34
+ document.documentElement.setAttribute("data-transition-types", typesAttr);
35
+ }
36
+ const nativeTransition = document.startViewTransition(async () => {
37
+ if (options.classes?.old) {
38
+ document.documentElement.classList.add(options.classes.old);
39
+ }
40
+ await updateCallback();
41
+ if (options.classes?.new) {
42
+ document.documentElement.classList.add(options.classes.new);
43
+ }
44
+ });
45
+ nativeTransition.finished.finally(() => {
46
+ if (options.classes?.old) {
47
+ document.documentElement.classList.remove(options.classes.old);
48
+ }
49
+ if (options.classes?.new) {
50
+ document.documentElement.classList.remove(options.classes.new);
51
+ }
52
+ if (options.name) {
53
+ document.documentElement.style.removeProperty("view-transition-name");
54
+ }
55
+ if (typesAttr) {
56
+ document.documentElement.removeAttribute("data-transition-types");
57
+ }
58
+ });
59
+ return {
60
+ ready: nativeTransition.ready,
61
+ finished: nativeTransition.finished,
62
+ updateCallbackDone: nativeTransition.updateCallbackDone,
63
+ skipTransition: () => nativeTransition.skipTransition(),
64
+ isNative: true
65
+ };
66
+ }
67
+ function createFallbackTransition(updateCallback, options) {
68
+ let skipRequested = false;
69
+ const execute = async () => {
70
+ const container = document.documentElement;
71
+ container.classList.add("flight-transition-leaving");
72
+ if (options.classes?.old) {
73
+ container.classList.add(options.classes.old);
74
+ }
75
+ if (!skipRequested) {
76
+ await waitForTransition(container);
77
+ }
78
+ await updateCallback();
79
+ container.classList.remove("flight-transition-leaving");
80
+ if (options.classes?.old) {
81
+ container.classList.remove(options.classes.old);
82
+ }
83
+ container.classList.add("flight-transition-entering");
84
+ if (options.classes?.new) {
85
+ container.classList.add(options.classes.new);
86
+ }
87
+ if (!skipRequested) {
88
+ await waitForTransition(container);
89
+ }
90
+ container.classList.remove("flight-transition-entering");
91
+ if (options.classes?.new) {
92
+ container.classList.remove(options.classes.new);
93
+ }
94
+ return { ready: true, finished: true };
95
+ };
96
+ let readyResolve;
97
+ let finishedResolve;
98
+ let updateDoneResolve;
99
+ const ready = new Promise((resolve) => {
100
+ readyResolve = resolve;
101
+ });
102
+ const finished = new Promise((resolve) => {
103
+ finishedResolve = resolve;
104
+ });
105
+ const updateCallbackDone = new Promise((resolve) => {
106
+ updateDoneResolve = resolve;
107
+ });
108
+ queueMicrotask(async () => {
109
+ try {
110
+ readyResolve();
111
+ await execute();
112
+ updateDoneResolve();
113
+ finishedResolve();
114
+ } catch (error) {
115
+ console.error("[Flight Transitions] Fallback transition error:", error);
116
+ finishedResolve();
117
+ }
118
+ });
119
+ return {
120
+ ready,
121
+ finished,
122
+ updateCallbackDone,
123
+ skipTransition: () => {
124
+ skipRequested = true;
125
+ },
126
+ isNative: false
127
+ };
128
+ }
129
+ function waitForTransition(element, _phase) {
130
+ return new Promise((resolve) => {
131
+ const styles = getComputedStyle(element);
132
+ const duration = parseFloat(styles.transitionDuration) || 0;
133
+ const delay = parseFloat(styles.transitionDelay) || 0;
134
+ const totalTime = (duration + delay) * 1e3;
135
+ if (totalTime <= 0) {
136
+ resolve();
137
+ return;
138
+ }
139
+ let resolved = false;
140
+ const onEnd = () => {
141
+ if (resolved) return;
142
+ resolved = true;
143
+ element.removeEventListener("transitionend", onEnd);
144
+ resolve();
145
+ };
146
+ element.addEventListener("transitionend", onEnd, { once: true });
147
+ setTimeout(onEnd, totalTime + 50);
148
+ });
149
+ }
150
+ function createImmediateTransition(updateCallback) {
151
+ const updateCallbackDone = (async () => {
152
+ await updateCallback();
153
+ })();
154
+ return {
155
+ ready: Promise.resolve(),
156
+ finished: updateCallbackDone.then(() => {
157
+ }),
158
+ updateCallbackDone,
159
+ skipTransition: () => {
160
+ },
161
+ isNative: false
162
+ };
163
+ }
164
+ function enableCrossDocumentTransitions(options = {}) {
165
+ if (!isBrowser || !isCrossDocumentTransitionSupported()) {
166
+ return () => {
167
+ };
168
+ }
169
+ const { enabled = true, types = [] } = options;
170
+ if (!enabled) {
171
+ return () => {
172
+ };
173
+ }
174
+ const styleId = "flight-cross-document-transitions";
175
+ let style = document.getElementById(styleId);
176
+ if (!style) {
177
+ style = document.createElement("style");
178
+ style.id = styleId;
179
+ style.textContent = `
180
+ @view-transition {
181
+ navigation: auto;
182
+ }
183
+ `;
184
+ document.head.appendChild(style);
185
+ }
186
+ const handlePageReveal = (event) => {
187
+ const pageRevealEvent = event;
188
+ const viewTransition = pageRevealEvent.viewTransition;
189
+ if (viewTransition && types.length > 0) {
190
+ document.documentElement.setAttribute(
191
+ "data-transition-types",
192
+ types.join(" ")
193
+ );
194
+ viewTransition.finished.then(() => {
195
+ document.documentElement.removeAttribute("data-transition-types");
196
+ });
197
+ }
198
+ };
199
+ const handlePageSwap = (event) => {
200
+ const pageSwapEvent = event;
201
+ const viewTransition = pageSwapEvent.viewTransition;
202
+ if (viewTransition && types.length > 0) {
203
+ document.documentElement.setAttribute(
204
+ "data-transition-types",
205
+ types.join(" ")
206
+ );
207
+ }
208
+ };
209
+ window.addEventListener("pagereveal", handlePageReveal);
210
+ window.addEventListener("pageswap", handlePageSwap);
211
+ return () => {
212
+ window.removeEventListener("pagereveal", handlePageReveal);
213
+ window.removeEventListener("pageswap", handlePageSwap);
214
+ style?.remove();
215
+ };
216
+ }
217
+
218
+ // src/core/transition-manager.ts
219
+ function createTransitionManager(initialConfig = {}) {
220
+ let config = normalizeConfig(initialConfig);
221
+ let state = createInitialState();
222
+ const listeners = /* @__PURE__ */ new Set();
223
+ let reducedMotionCleanup = null;
224
+ let shouldReduceMotion = false;
225
+ if (typeof window !== "undefined") {
226
+ shouldReduceMotion = prefersReducedMotion();
227
+ reducedMotionCleanup = onReducedMotionChange((prefersReduced) => {
228
+ shouldReduceMotion = prefersReduced;
229
+ });
230
+ }
231
+ function createInitialState() {
232
+ return {
233
+ isTransitioning: false,
234
+ direction: "forward",
235
+ phase: "idle",
236
+ currentTransition: null,
237
+ fromPath: null,
238
+ toPath: null
239
+ };
240
+ }
241
+ function setState(partial) {
242
+ state = { ...state, ...partial };
243
+ notifyListeners();
244
+ }
245
+ function notifyListeners() {
246
+ listeners.forEach((listener) => {
247
+ try {
248
+ listener(state);
249
+ } catch (error) {
250
+ console.error("[Flight Transitions] Listener error:", error);
251
+ }
252
+ });
253
+ }
254
+ function normalizeConfig(input) {
255
+ return {
256
+ enabled: input.enabled ?? true,
257
+ viewTransitions: input.viewTransitions ?? true,
258
+ pageTransition: input.pageTransition ?? "fade",
259
+ layoutTransition: input.layoutTransition ?? false,
260
+ duration: input.duration ?? DEFAULT_DURATION,
261
+ easing: input.easing ?? DEFAULT_EASING,
262
+ reduceMotion: input.reduceMotion ?? "respect-system",
263
+ crossDocument: input.crossDocument ?? false
264
+ };
265
+ }
266
+ function shouldApplyReducedMotion() {
267
+ switch (config.reduceMotion) {
268
+ case "always-reduce":
269
+ return true;
270
+ case "ignore":
271
+ return false;
272
+ case "respect-system":
273
+ default:
274
+ return shouldReduceMotion;
275
+ }
276
+ }
277
+ async function startPageTransition(to, pageConfig) {
278
+ if (!config.enabled) {
279
+ return;
280
+ }
281
+ if (state.isTransitioning) {
282
+ console.warn("[Flight Transitions] Transition already in progress");
283
+ return;
284
+ }
285
+ const from = state.toPath ?? getCurrentPath();
286
+ const direction = determineDirection(from, to);
287
+ const transitionInput = getTransitionForNavigation(
288
+ direction,
289
+ pageConfig
290
+ );
291
+ const transition = resolveTransition(
292
+ transitionInput,
293
+ shouldApplyReducedMotion()
294
+ );
295
+ if (!transition) {
296
+ return;
297
+ }
298
+ const context = {
299
+ from,
300
+ to,
301
+ direction,
302
+ transition,
303
+ startTime: performance.now()
304
+ };
305
+ pageConfig?.onStart?.(context);
306
+ setState({
307
+ isTransitioning: true,
308
+ direction,
309
+ phase: "leaving",
310
+ currentTransition: transition,
311
+ fromPath: from,
312
+ toPath: to
313
+ });
314
+ try {
315
+ if (config.viewTransitions && isViewTransitionSupported()) {
316
+ await executeWithViewTransition(transition);
317
+ } else {
318
+ await executeWithFallback(transition);
319
+ }
320
+ } finally {
321
+ setState({
322
+ isTransitioning: false,
323
+ phase: "idle",
324
+ currentTransition: null
325
+ });
326
+ pageConfig?.onComplete?.(context);
327
+ }
328
+ }
329
+ function getTransitionForNavigation(direction, pageConfig) {
330
+ if (pageConfig) {
331
+ if (direction === "back" && pageConfig.backTransition !== void 0) {
332
+ return pageConfig.backTransition;
333
+ }
334
+ if (pageConfig.default !== void 0) {
335
+ return pageConfig.default;
336
+ }
337
+ }
338
+ return config.pageTransition ?? "fade";
339
+ }
340
+ function determineDirection(from, to) {
341
+ if (from.length > to.length && to !== "/") {
342
+ return "back";
343
+ }
344
+ return "forward";
345
+ }
346
+ function getCurrentPath() {
347
+ if (typeof window === "undefined") return "/";
348
+ return window.location.pathname;
349
+ }
350
+ async function executeWithViewTransition(transition) {
351
+ return new Promise((resolve) => {
352
+ const viewTransition = startViewTransition(
353
+ () => {
354
+ setState({ phase: "entering" });
355
+ },
356
+ {
357
+ name: transition.name,
358
+ classes: {
359
+ old: `flight-transition-${transition.name}-leave`,
360
+ new: `flight-transition-${transition.name}-enter`
361
+ }
362
+ }
363
+ );
364
+ viewTransition.finished.then(() => {
365
+ setState({ phase: "complete" });
366
+ resolve();
367
+ });
368
+ });
369
+ }
370
+ async function executeWithFallback(transition) {
371
+ const leaveDuration = transition.leave.options.duration || 150;
372
+ const enterDuration = transition.enter.options.duration || 150;
373
+ await wait(leaveDuration);
374
+ setState({ phase: "entering" });
375
+ await wait(enterDuration);
376
+ setState({ phase: "complete" });
377
+ }
378
+ const manager = {
379
+ getState() {
380
+ return { ...state };
381
+ },
382
+ getConfig() {
383
+ return { ...config };
384
+ },
385
+ configure(newConfig) {
386
+ config = normalizeConfig({ ...config, ...newConfig });
387
+ },
388
+ subscribe(listener) {
389
+ listeners.add(listener);
390
+ return () => {
391
+ listeners.delete(listener);
392
+ };
393
+ },
394
+ startPageTransition,
395
+ skipTransition() {
396
+ if (state.isTransitioning) {
397
+ setState({
398
+ isTransitioning: false,
399
+ phase: "idle",
400
+ currentTransition: null
401
+ });
402
+ }
403
+ },
404
+ isEnabled() {
405
+ return config.enabled ?? false;
406
+ },
407
+ isViewTransitionSupported() {
408
+ return isViewTransitionSupported();
409
+ },
410
+ setDirection(direction) {
411
+ setState({ direction });
412
+ },
413
+ destroy() {
414
+ listeners.clear();
415
+ reducedMotionCleanup?.();
416
+ state = createInitialState();
417
+ }
418
+ };
419
+ return manager;
420
+ }
421
+ var globalManager = null;
422
+ function getTransitionManager() {
423
+ if (!globalManager) {
424
+ globalManager = createTransitionManager();
425
+ }
426
+ return globalManager;
427
+ }
428
+ function initTransitions(config) {
429
+ if (globalManager) {
430
+ globalManager.configure(config);
431
+ } else {
432
+ globalManager = createTransitionManager(config);
433
+ }
434
+ return globalManager;
435
+ }
436
+ function wait(ms) {
437
+ return new Promise((resolve) => setTimeout(resolve, ms));
438
+ }
439
+
440
+ export { createTransitionManager, enableCrossDocumentTransitions, getTransitionManager, initTransitions, isCrossDocumentTransitionSupported, isViewTransitionSupported, startViewTransition };
441
+ //# sourceMappingURL=chunk-X2A7XWYR.js.map
442
+ //# sourceMappingURL=chunk-X2A7XWYR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/view-transition.ts","../src/core/transition-manager.ts"],"names":[],"mappings":"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","file":"chunk-X2A7XWYR.js","sourcesContent":["/**\r\n * @flightdev/transitions - View Transition API Wrapper\r\n * \r\n * Provides a cross-browser wrapper for the View Transitions API with\r\n * automatic fallback for unsupported browsers.\r\n * \r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API\r\n */\r\n\r\nimport type {\r\n ViewTransition,\r\n ViewTransitionOptions,\r\n ViewTransitionResult,\r\n} from './types';\r\n\r\n// =============================================================================\r\n// BROWSER DETECTION\r\n// =============================================================================\r\n\r\n/** Check if code is running in browser environment */\r\nconst isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\r\n\r\n/**\r\n * Check if the browser supports the View Transitions API\r\n * @returns true if startViewTransition is available\r\n */\r\nexport function isViewTransitionSupported(): boolean {\r\n if (!isBrowser) return false;\r\n return 'startViewTransition' in document &&\r\n typeof document.startViewTransition === 'function';\r\n}\r\n\r\n/**\r\n * Check if cross-document view transitions are supported\r\n * @returns true if @view-transition CSS at-rule is supported\r\n */\r\nexport function isCrossDocumentTransitionSupported(): boolean {\r\n if (!isBrowser) return false;\r\n // Check for pagereveal event support (indicates cross-document support)\r\n return 'onpagereveal' in window;\r\n}\r\n\r\n// =============================================================================\r\n// VIEW TRANSITION WRAPPER\r\n// =============================================================================\r\n\r\n/**\r\n * Start a view transition with automatic fallback\r\n * \r\n * Uses the native View Transitions API when available, otherwise\r\n * provides a compatible fallback that executes the callback immediately.\r\n * \r\n * @example\r\n * ```typescript\r\n * const transition = startViewTransition(() => {\r\n * // Update the DOM\r\n * document.getElementById('content').innerHTML = newContent;\r\n * });\r\n * \r\n * // Wait for animation to be ready\r\n * await transition.ready;\r\n * \r\n * // Wait for animation to complete\r\n * await transition.finished;\r\n * ```\r\n */\r\nexport function startViewTransition(\r\n updateCallback: () => void | Promise<void>,\r\n options: ViewTransitionOptions = {}\r\n): ViewTransitionResult {\r\n // Server-side rendering: return immediate resolution\r\n if (!isBrowser) {\r\n return createImmediateTransition(updateCallback);\r\n }\r\n\r\n // Skip transition if explicitly requested\r\n if (options.skipTransition) {\r\n return createImmediateTransition(updateCallback);\r\n }\r\n\r\n // Use native API if supported\r\n if (isViewTransitionSupported()) {\r\n return createNativeTransition(updateCallback, options);\r\n }\r\n\r\n // Fallback for unsupported browsers\r\n return createFallbackTransition(updateCallback, options);\r\n}\r\n\r\n// =============================================================================\r\n// NATIVE IMPLEMENTATION\r\n// =============================================================================\r\n\r\n/**\r\n * Create a transition using the native View Transitions API\r\n */\r\nfunction createNativeTransition(\r\n updateCallback: () => void | Promise<void>,\r\n options: ViewTransitionOptions\r\n): ViewTransitionResult {\r\n // Set view-transition-name if provided\r\n if (options.name) {\r\n document.documentElement.style.setProperty(\r\n 'view-transition-name',\r\n options.name\r\n );\r\n }\r\n\r\n // Set transition types if provided (for @starting-style support)\r\n const typesAttr = options.types?.join(' ');\r\n if (typesAttr) {\r\n document.documentElement.setAttribute('data-transition-types', typesAttr);\r\n }\r\n\r\n // Start the native transition\r\n const nativeTransition = document.startViewTransition!(async () => {\r\n // Apply old phase class\r\n if (options.classes?.old) {\r\n document.documentElement.classList.add(options.classes.old);\r\n }\r\n\r\n // Execute the DOM update\r\n await updateCallback();\r\n\r\n // Apply new phase class\r\n if (options.classes?.new) {\r\n document.documentElement.classList.add(options.classes.new);\r\n }\r\n }) as ViewTransition;\r\n\r\n // Clean up after transition\r\n nativeTransition.finished.finally(() => {\r\n // Remove custom classes\r\n if (options.classes?.old) {\r\n document.documentElement.classList.remove(options.classes.old);\r\n }\r\n if (options.classes?.new) {\r\n document.documentElement.classList.remove(options.classes.new);\r\n }\r\n // Remove transition name\r\n if (options.name) {\r\n document.documentElement.style.removeProperty('view-transition-name');\r\n }\r\n // Remove types\r\n if (typesAttr) {\r\n document.documentElement.removeAttribute('data-transition-types');\r\n }\r\n });\r\n\r\n return {\r\n ready: nativeTransition.ready,\r\n finished: nativeTransition.finished,\r\n updateCallbackDone: nativeTransition.updateCallbackDone,\r\n skipTransition: () => nativeTransition.skipTransition(),\r\n isNative: true,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// FALLBACK IMPLEMENTATION\r\n// =============================================================================\r\n\r\n/**\r\n * Create a fallback transition for browsers without View Transitions API\r\n * Uses CSS transitions with class-based animation\r\n */\r\nfunction createFallbackTransition(\r\n updateCallback: () => void | Promise<void>,\r\n options: ViewTransitionOptions\r\n): ViewTransitionResult {\r\n let skipRequested = false;\r\n\r\n const execute = async (): Promise<{ ready: boolean; finished: boolean }> => {\r\n const container = document.documentElement;\r\n\r\n // Add leaving class for CSS transition\r\n container.classList.add('flight-transition-leaving');\r\n if (options.classes?.old) {\r\n container.classList.add(options.classes.old);\r\n }\r\n\r\n // Wait for leave animation (or skip if requested)\r\n if (!skipRequested) {\r\n await waitForTransition(container, 'leave');\r\n }\r\n\r\n // Execute the DOM update\r\n await updateCallback();\r\n\r\n // Switch to entering phase\r\n container.classList.remove('flight-transition-leaving');\r\n if (options.classes?.old) {\r\n container.classList.remove(options.classes.old);\r\n }\r\n container.classList.add('flight-transition-entering');\r\n if (options.classes?.new) {\r\n container.classList.add(options.classes.new);\r\n }\r\n\r\n // Wait for enter animation (or skip if requested)\r\n if (!skipRequested) {\r\n await waitForTransition(container, 'enter');\r\n }\r\n\r\n // Clean up\r\n container.classList.remove('flight-transition-entering');\r\n if (options.classes?.new) {\r\n container.classList.remove(options.classes.new);\r\n }\r\n\r\n return { ready: true, finished: true };\r\n };\r\n\r\n // Track promises\r\n let readyResolve: () => void;\r\n let finishedResolve: () => void;\r\n let updateDoneResolve: () => void;\r\n\r\n const ready = new Promise<void>((resolve) => { readyResolve = resolve; });\r\n const finished = new Promise<void>((resolve) => { finishedResolve = resolve; });\r\n const updateCallbackDone = new Promise<void>((resolve) => { updateDoneResolve = resolve; });\r\n\r\n // Execute asynchronously\r\n queueMicrotask(async () => {\r\n try {\r\n readyResolve!();\r\n await execute();\r\n updateDoneResolve!();\r\n finishedResolve!();\r\n } catch (error) {\r\n console.error('[Flight Transitions] Fallback transition error:', error);\r\n finishedResolve!();\r\n }\r\n });\r\n\r\n return {\r\n ready,\r\n finished,\r\n updateCallbackDone,\r\n skipTransition: () => { skipRequested = true; },\r\n isNative: false,\r\n };\r\n}\r\n\r\n/**\r\n * Wait for CSS transition to complete on an element\r\n */\r\nfunction waitForTransition(\r\n element: HTMLElement,\r\n _phase: 'leave' | 'enter'\r\n): Promise<void> {\r\n return new Promise((resolve) => {\r\n // Get computed transition duration\r\n const styles = getComputedStyle(element);\r\n const duration = parseFloat(styles.transitionDuration) || 0;\r\n const delay = parseFloat(styles.transitionDelay) || 0;\r\n const totalTime = (duration + delay) * 1000;\r\n\r\n if (totalTime <= 0) {\r\n resolve();\r\n return;\r\n }\r\n\r\n // Use transitionend event with timeout fallback\r\n let resolved = false;\r\n\r\n const onEnd = () => {\r\n if (resolved) return;\r\n resolved = true;\r\n element.removeEventListener('transitionend', onEnd);\r\n resolve();\r\n };\r\n\r\n element.addEventListener('transitionend', onEnd, { once: true });\r\n\r\n // Fallback timeout (add 50ms buffer)\r\n setTimeout(onEnd, totalTime + 50);\r\n });\r\n}\r\n\r\n// =============================================================================\r\n// IMMEDIATE TRANSITION (SSR/Skip)\r\n// =============================================================================\r\n\r\n/**\r\n * Create an immediate transition (no animation)\r\n * Used for SSR or when transitions are skipped\r\n */\r\nfunction createImmediateTransition(\r\n updateCallback: () => void | Promise<void>\r\n): ViewTransitionResult {\r\n let updateDone = false;\r\n\r\n const updateCallbackDone = (async () => {\r\n await updateCallback();\r\n updateDone = true;\r\n })();\r\n\r\n return {\r\n ready: Promise.resolve(),\r\n finished: updateCallbackDone.then(() => { }),\r\n updateCallbackDone,\r\n skipTransition: () => { },\r\n isNative: false,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// CROSS-DOCUMENT TRANSITIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Options for cross-document (MPA) transitions\r\n */\r\nexport interface CrossDocumentTransitionOptions {\r\n /** Enable transitions for same-origin navigations */\r\n enabled?: boolean;\r\n /** Types to apply to the transition */\r\n types?: string[];\r\n}\r\n\r\n/**\r\n * Enable cross-document view transitions for MPA navigations\r\n * \r\n * This injects the necessary CSS and sets up event listeners for\r\n * pagereveal and pageswap events.\r\n * \r\n * @example\r\n * ```typescript\r\n * enableCrossDocumentTransitions({\r\n * enabled: true,\r\n * types: ['slide-left']\r\n * });\r\n * ```\r\n */\r\nexport function enableCrossDocumentTransitions(\r\n options: CrossDocumentTransitionOptions = {}\r\n): () => void {\r\n if (!isBrowser || !isCrossDocumentTransitionSupported()) {\r\n return () => { };\r\n }\r\n\r\n const { enabled = true, types = [] } = options;\r\n\r\n if (!enabled) {\r\n return () => { };\r\n }\r\n\r\n // Inject @view-transition CSS rule\r\n const styleId = 'flight-cross-document-transitions';\r\n let style = document.getElementById(styleId) as HTMLStyleElement | null;\r\n\r\n if (!style) {\r\n style = document.createElement('style');\r\n style.id = styleId;\r\n style.textContent = `\r\n @view-transition {\r\n navigation: auto;\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n }\r\n\r\n // Handle page reveal (incoming page)\r\n const handlePageReveal = (event: Event) => {\r\n const pageRevealEvent = event as PageRevealEvent;\r\n const viewTransition = pageRevealEvent.viewTransition;\r\n\r\n if (viewTransition && types.length > 0) {\r\n // Apply transition types\r\n document.documentElement.setAttribute(\r\n 'data-transition-types',\r\n types.join(' ')\r\n );\r\n\r\n viewTransition.finished.then(() => {\r\n document.documentElement.removeAttribute('data-transition-types');\r\n });\r\n }\r\n };\r\n\r\n // Handle page swap (outgoing page)\r\n const handlePageSwap = (event: Event) => {\r\n const pageSwapEvent = event as PageSwapEvent;\r\n const viewTransition = pageSwapEvent.viewTransition;\r\n\r\n if (viewTransition && types.length > 0) {\r\n document.documentElement.setAttribute(\r\n 'data-transition-types',\r\n types.join(' ')\r\n );\r\n }\r\n };\r\n\r\n window.addEventListener('pagereveal', handlePageReveal);\r\n window.addEventListener('pageswap', handlePageSwap);\r\n\r\n // Return cleanup function\r\n return () => {\r\n window.removeEventListener('pagereveal', handlePageReveal);\r\n window.removeEventListener('pageswap', handlePageSwap);\r\n style?.remove();\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// TYPE DECLARATIONS FOR BROWSER EVENTS\r\n// =============================================================================\r\n\r\ninterface PageRevealEvent extends Event {\r\n readonly viewTransition: ViewTransition | null;\r\n}\r\n\r\ninterface PageSwapEvent extends Event {\r\n readonly viewTransition: ViewTransition | null;\r\n readonly activation: NavigationActivation | null;\r\n}\r\n\r\ninterface NavigationActivation {\r\n readonly entry: NavigationHistoryEntry;\r\n readonly from: NavigationHistoryEntry | null;\r\n readonly navigationType: NavigationHistoryEntryType;\r\n}\r\n\r\ninterface NavigationHistoryEntry {\r\n readonly id: string;\r\n readonly index: number;\r\n readonly key: string;\r\n readonly sameDocument: boolean;\r\n readonly url: string | null;\r\n}\r\n\r\ntype NavigationHistoryEntryType = 'push' | 'replace' | 'reload' | 'traverse';\r\n\r\n// Extend Document interface for startViewTransition\r\ndeclare global {\r\n interface Document {\r\n startViewTransition(callback: () => void | Promise<void>): ViewTransition;\r\n }\r\n\r\n interface WindowEventMap {\r\n pagereveal: PageRevealEvent;\r\n pageswap: PageSwapEvent;\r\n }\r\n}\r\n\r\nexport { };\r\n","/**\r\n * @flightdev/transitions - Transition Manager\r\n * \r\n * Central orchestrator for all transition operations.\r\n * Manages state, configuration, and coordinates between different\r\n * transition types (page, layout, component).\r\n */\r\n\r\nimport type {\r\n TransitionsConfig,\r\n TransitionState,\r\n TransitionListener,\r\n ResolvedTransition,\r\n TransitionDirection,\r\n TransitionContext,\r\n PageTransitionConfig,\r\n TransitionPreset,\r\n CustomTransition,\r\n} from './types';\r\nimport {\r\n startViewTransition,\r\n isViewTransitionSupported,\r\n} from './view-transition';\r\nimport {\r\n resolveTransition,\r\n prefersReducedMotion,\r\n onReducedMotionChange,\r\n DEFAULT_DURATION,\r\n DEFAULT_EASING,\r\n} from './animation-engine';\r\n\r\n// =============================================================================\r\n// TRANSITION MANAGER\r\n// =============================================================================\r\n\r\n/**\r\n * Create a new transition manager instance\r\n * \r\n * @example\r\n * ```typescript\r\n * const manager = createTransitionManager({\r\n * pageTransition: 'fade',\r\n * duration: 200,\r\n * });\r\n * \r\n * // Subscribe to state changes\r\n * manager.subscribe((state) => {\r\n * console.log('Transition state:', state);\r\n * });\r\n * \r\n * // Start a transition\r\n * await manager.startPageTransition('/new-page');\r\n * ```\r\n */\r\nexport function createTransitionManager(\r\n initialConfig: TransitionsConfig = {}\r\n): TransitionManager {\r\n // Internal state\r\n let config: TransitionsConfig = normalizeConfig(initialConfig);\r\n let state: TransitionState = createInitialState();\r\n const listeners: Set<TransitionListener> = new Set();\r\n let reducedMotionCleanup: (() => void) | null = null;\r\n let shouldReduceMotion = false;\r\n\r\n // Initialize reduced motion detection\r\n if (typeof window !== 'undefined') {\r\n shouldReduceMotion = prefersReducedMotion();\r\n reducedMotionCleanup = onReducedMotionChange((prefersReduced) => {\r\n shouldReduceMotion = prefersReduced;\r\n });\r\n }\r\n\r\n // ==========================================================================\r\n // STATE MANAGEMENT\r\n // ==========================================================================\r\n\r\n function createInitialState(): TransitionState {\r\n return {\r\n isTransitioning: false,\r\n direction: 'forward',\r\n phase: 'idle',\r\n currentTransition: null,\r\n fromPath: null,\r\n toPath: null,\r\n };\r\n }\r\n\r\n function setState(partial: Partial<TransitionState>): void {\r\n state = { ...state, ...partial };\r\n notifyListeners();\r\n }\r\n\r\n function notifyListeners(): void {\r\n listeners.forEach((listener) => {\r\n try {\r\n listener(state);\r\n } catch (error) {\r\n console.error('[Flight Transitions] Listener error:', error);\r\n }\r\n });\r\n }\r\n\r\n // ==========================================================================\r\n // CONFIGURATION\r\n // ==========================================================================\r\n\r\n function normalizeConfig(input: TransitionsConfig): TransitionsConfig {\r\n return {\r\n enabled: input.enabled ?? true,\r\n viewTransitions: input.viewTransitions ?? true,\r\n pageTransition: input.pageTransition ?? 'fade',\r\n layoutTransition: input.layoutTransition ?? false,\r\n duration: input.duration ?? DEFAULT_DURATION,\r\n easing: input.easing ?? DEFAULT_EASING,\r\n reduceMotion: input.reduceMotion ?? 'respect-system',\r\n crossDocument: input.crossDocument ?? false,\r\n };\r\n }\r\n\r\n function shouldApplyReducedMotion(): boolean {\r\n switch (config.reduceMotion) {\r\n case 'always-reduce':\r\n return true;\r\n case 'ignore':\r\n return false;\r\n case 'respect-system':\r\n default:\r\n return shouldReduceMotion;\r\n }\r\n }\r\n\r\n // ==========================================================================\r\n // PAGE TRANSITIONS\r\n // ==========================================================================\r\n\r\n async function startPageTransition(\r\n to: string,\r\n pageConfig?: PageTransitionConfig\r\n ): Promise<void> {\r\n // Check if transitions are enabled\r\n if (!config.enabled) {\r\n return;\r\n }\r\n\r\n // Already transitioning - skip\r\n if (state.isTransitioning) {\r\n console.warn('[Flight Transitions] Transition already in progress');\r\n return;\r\n }\r\n\r\n const from = state.toPath ?? getCurrentPath();\r\n const direction = determineDirection(from, to);\r\n\r\n // Resolve the transition to use\r\n const transitionInput = getTransitionForNavigation(\r\n direction,\r\n pageConfig\r\n );\r\n\r\n const transition = resolveTransition(\r\n transitionInput,\r\n shouldApplyReducedMotion()\r\n );\r\n\r\n // If no transition resolved, just return\r\n if (!transition) {\r\n return;\r\n }\r\n\r\n // Create context for callbacks\r\n const context: TransitionContext = {\r\n from,\r\n to,\r\n direction,\r\n transition,\r\n startTime: performance.now(),\r\n };\r\n\r\n // Call onStart callback\r\n pageConfig?.onStart?.(context);\r\n\r\n // Update state to transitioning\r\n setState({\r\n isTransitioning: true,\r\n direction,\r\n phase: 'leaving',\r\n currentTransition: transition,\r\n fromPath: from,\r\n toPath: to,\r\n });\r\n\r\n try {\r\n // Use View Transitions API if enabled and supported\r\n if (config.viewTransitions && isViewTransitionSupported()) {\r\n await executeWithViewTransition(transition);\r\n } else {\r\n await executeWithFallback(transition);\r\n }\r\n } finally {\r\n // Update state to complete\r\n setState({\r\n isTransitioning: false,\r\n phase: 'idle',\r\n currentTransition: null,\r\n });\r\n\r\n // Call onComplete callback\r\n pageConfig?.onComplete?.(context);\r\n }\r\n }\r\n\r\n function getTransitionForNavigation(\r\n direction: TransitionDirection,\r\n pageConfig?: PageTransitionConfig\r\n ): TransitionPreset | CustomTransition | false {\r\n // Page-specific config takes priority\r\n if (pageConfig) {\r\n if (direction === 'back' && pageConfig.backTransition !== undefined) {\r\n return pageConfig.backTransition;\r\n }\r\n if (pageConfig.default !== undefined) {\r\n return pageConfig.default;\r\n }\r\n }\r\n\r\n // Fall back to global config\r\n return config.pageTransition ?? 'fade';\r\n }\r\n\r\n function determineDirection(from: string, to: string): TransitionDirection {\r\n // Simple heuristic: if going to a shorter path, it's likely \"back\"\r\n // This can be overridden by the navigation API\r\n if (from.length > to.length && to !== '/') {\r\n return 'back';\r\n }\r\n return 'forward';\r\n }\r\n\r\n function getCurrentPath(): string {\r\n if (typeof window === 'undefined') return '/';\r\n return window.location.pathname;\r\n }\r\n\r\n // ==========================================================================\r\n // TRANSITION EXECUTION\r\n // ==========================================================================\r\n\r\n async function executeWithViewTransition(\r\n transition: ResolvedTransition\r\n ): Promise<void> {\r\n return new Promise((resolve) => {\r\n const viewTransition = startViewTransition(\r\n () => {\r\n // DOM update happens here\r\n // This is called by the router when it updates the page\r\n setState({ phase: 'entering' });\r\n },\r\n {\r\n name: transition.name,\r\n classes: {\r\n old: `flight-transition-${transition.name}-leave`,\r\n new: `flight-transition-${transition.name}-enter`,\r\n },\r\n }\r\n );\r\n\r\n viewTransition.finished.then(() => {\r\n setState({ phase: 'complete' });\r\n resolve();\r\n });\r\n });\r\n }\r\n\r\n async function executeWithFallback(\r\n transition: ResolvedTransition\r\n ): Promise<void> {\r\n // For fallback, we just wait for the durations\r\n const leaveDuration = transition.leave.options.duration as number || 150;\r\n const enterDuration = transition.enter.options.duration as number || 150;\r\n\r\n // Leave phase\r\n await wait(leaveDuration);\r\n setState({ phase: 'entering' });\r\n\r\n // Enter phase\r\n await wait(enterDuration);\r\n setState({ phase: 'complete' });\r\n }\r\n\r\n // ==========================================================================\r\n // PUBLIC INTERFACE\r\n // ==========================================================================\r\n\r\n const manager: TransitionManager = {\r\n getState(): TransitionState {\r\n return { ...state };\r\n },\r\n\r\n getConfig(): TransitionsConfig {\r\n return { ...config };\r\n },\r\n\r\n configure(newConfig: TransitionsConfig): void {\r\n config = normalizeConfig({ ...config, ...newConfig });\r\n },\r\n\r\n subscribe(listener: TransitionListener): () => void {\r\n listeners.add(listener);\r\n return () => {\r\n listeners.delete(listener);\r\n };\r\n },\r\n\r\n startPageTransition,\r\n\r\n skipTransition(): void {\r\n if (state.isTransitioning) {\r\n setState({\r\n isTransitioning: false,\r\n phase: 'idle',\r\n currentTransition: null,\r\n });\r\n }\r\n },\r\n\r\n isEnabled(): boolean {\r\n return config.enabled ?? false;\r\n },\r\n\r\n isViewTransitionSupported(): boolean {\r\n return isViewTransitionSupported();\r\n },\r\n\r\n setDirection(direction: TransitionDirection): void {\r\n setState({ direction });\r\n },\r\n\r\n destroy(): void {\r\n listeners.clear();\r\n reducedMotionCleanup?.();\r\n state = createInitialState();\r\n },\r\n };\r\n\r\n return manager;\r\n}\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\nexport interface TransitionManager {\r\n /** Get current transition state (readonly copy) */\r\n getState(): TransitionState;\r\n /** Get current configuration (readonly copy) */\r\n getConfig(): TransitionsConfig;\r\n /** Update configuration */\r\n configure(config: TransitionsConfig): void;\r\n /** Subscribe to state changes, returns unsubscribe function */\r\n subscribe(listener: TransitionListener): () => void;\r\n /** Start a page transition */\r\n startPageTransition(to: string, config?: PageTransitionConfig): Promise<void>;\r\n /** Skip the current transition immediately */\r\n skipTransition(): void;\r\n /** Check if transitions are enabled */\r\n isEnabled(): boolean;\r\n /** Check if View Transitions API is supported */\r\n isViewTransitionSupported(): boolean;\r\n /** Set the navigation direction */\r\n setDirection(direction: TransitionDirection): void;\r\n /** Clean up resources */\r\n destroy(): void;\r\n}\r\n\r\n// =============================================================================\r\n// SINGLETON INSTANCE\r\n// =============================================================================\r\n\r\nlet globalManager: TransitionManager | null = null;\r\n\r\n/**\r\n * Get or create the global transition manager instance\r\n */\r\nexport function getTransitionManager(): TransitionManager {\r\n if (!globalManager) {\r\n globalManager = createTransitionManager();\r\n }\r\n return globalManager;\r\n}\r\n\r\n/**\r\n * Initialize the global transition manager with configuration\r\n */\r\nexport function initTransitions(config: TransitionsConfig): TransitionManager {\r\n if (globalManager) {\r\n globalManager.configure(config);\r\n } else {\r\n globalManager = createTransitionManager(config);\r\n }\r\n return globalManager;\r\n}\r\n\r\n// =============================================================================\r\n// UTILITIES\r\n// =============================================================================\r\n\r\nfunction wait(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n"]}
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=chunk-XLVYHPII.js.map
3
+ //# sourceMappingURL=chunk-XLVYHPII.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-XLVYHPII.js"}