@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,5 @@
1
+ export { i as isViewTransitionSupported, s as startViewTransition } from '../../view-transition-LSN_PSbm.js';
2
+ export { c as createTransitionManager, g as getTransitionManager } from '../../transition-manager-QWm4OSFw.js';
3
+ export { definePageTransition, executePageTransition } from '../../page/index.js';
4
+ export { registerSharedElement, unregisterSharedElement } from '../../layout/index.js';
5
+ import '../../types-BA4L37s4.js';
@@ -0,0 +1,9 @@
1
+ import '../../chunk-W7HSR35B.js';
2
+ import '../../chunk-XLVYHPII.js';
3
+ export { definePageTransition, executePageTransition } from '../../chunk-SPUGO5I5.js';
4
+ export { registerSharedElement, unregisterSharedElement } from '../../chunk-ZI6E7GNQ.js';
5
+ import '../../chunk-QSB65CTV.js';
6
+ export { createTransitionManager, getTransitionManager, isViewTransitionSupported, startViewTransition } from '../../chunk-X2A7XWYR.js';
7
+ import '../../chunk-OV3U5STU.js';
8
+ //# sourceMappingURL=index.js.map
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,121 @@
1
+ import { executePageTransition, getPageTransition } from './chunk-SPUGO5I5.js';
2
+ import { getTransitionManager, isViewTransitionSupported } from './chunk-X2A7XWYR.js';
3
+
4
+ // src/router/router-integration.ts
5
+ async function navigateWithTransition(to, options = {}) {
6
+ const {
7
+ replace = false,
8
+ scroll = true,
9
+ state = {},
10
+ transition,
11
+ forceTransition = false,
12
+ direction
13
+ } = options;
14
+ const manager = getTransitionManager();
15
+ const from = getCurrentPath();
16
+ const shouldTransition = forceTransition || manager.isEnabled() && transition !== false;
17
+ if (!shouldTransition) {
18
+ performNavigation(to, { replace, state });
19
+ if (scroll) scrollToTop();
20
+ return;
21
+ }
22
+ if (direction) {
23
+ manager.setDirection(direction);
24
+ }
25
+ await executePageTransition({
26
+ to,
27
+ from,
28
+ transition,
29
+ direction,
30
+ updateDOM: async () => {
31
+ performNavigation(to, { replace, state });
32
+ await waitForRouteLoad();
33
+ if (scroll) scrollToTop();
34
+ }
35
+ });
36
+ }
37
+ function performNavigation(to, options) {
38
+ const { replace = false, state = {} } = options;
39
+ if (replace) {
40
+ window.history.replaceState(state, "", to);
41
+ } else {
42
+ window.history.pushState(state, "", to);
43
+ }
44
+ window.dispatchEvent(new PopStateEvent("popstate", { state }));
45
+ }
46
+ function getCurrentPath() {
47
+ if (typeof window === "undefined") return "/";
48
+ return window.location.pathname;
49
+ }
50
+ function scrollToTop() {
51
+ if (typeof window === "undefined") return;
52
+ window.scrollTo({
53
+ top: 0,
54
+ left: 0,
55
+ behavior: "instant"
56
+ });
57
+ }
58
+ async function waitForRouteLoad() {
59
+ await new Promise((resolve) => requestAnimationFrame(resolve));
60
+ await new Promise((resolve) => requestAnimationFrame(resolve));
61
+ }
62
+ var historyListenerSetup = false;
63
+ function setupHistoryTransitions() {
64
+ if (typeof window === "undefined") return () => {
65
+ };
66
+ if (historyListenerSetup) return () => {
67
+ };
68
+ historyListenerSetup = true;
69
+ const manager = getTransitionManager();
70
+ const handlePopState = async (event) => {
71
+ const direction = "auto";
72
+ manager.setDirection(direction);
73
+ if (manager.isEnabled() && isViewTransitionSupported()) ;
74
+ };
75
+ const handleBeforeUnload = (event) => {
76
+ manager.skipTransition();
77
+ };
78
+ window.addEventListener("popstate", handlePopState);
79
+ window.addEventListener("beforeunload", handleBeforeUnload);
80
+ return () => {
81
+ window.removeEventListener("popstate", handlePopState);
82
+ window.removeEventListener("beforeunload", handleBeforeUnload);
83
+ historyListenerSetup = false;
84
+ };
85
+ }
86
+ var prefetchedUrls = /* @__PURE__ */ new Set();
87
+ function prefetchRoute(url) {
88
+ if (typeof document === "undefined") return;
89
+ if (prefetchedUrls.has(url)) return;
90
+ prefetchedUrls.add(url);
91
+ const link = document.createElement("link");
92
+ link.rel = "prefetch";
93
+ link.href = url;
94
+ document.head.appendChild(link);
95
+ }
96
+ function isRoutePrefetched(url) {
97
+ return prefetchedUrls.has(url);
98
+ }
99
+ var routeTransitionConfigs = [];
100
+ function registerRouteTransitions(configs) {
101
+ routeTransitionConfigs.push(...configs);
102
+ }
103
+ function getRouteTransitionConfig(path) {
104
+ const pageConfig = getPageTransition(path);
105
+ if (pageConfig) return pageConfig;
106
+ for (const config of routeTransitionConfigs) {
107
+ if (matchRoutePattern(path, config.pattern)) {
108
+ return config.transition;
109
+ }
110
+ }
111
+ return void 0;
112
+ }
113
+ function matchRoutePattern(path, pattern) {
114
+ const regexStr = pattern.replace(/\*/g, ".*").replace(/\//g, "\\/");
115
+ const regex = new RegExp(`^${regexStr}$`);
116
+ return regex.test(path);
117
+ }
118
+
119
+ export { getRouteTransitionConfig, isRoutePrefetched, navigateWithTransition, prefetchRoute, registerRouteTransitions, setupHistoryTransitions };
120
+ //# sourceMappingURL=chunk-DZC3OLDU.js.map
121
+ //# sourceMappingURL=chunk-DZC3OLDU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/router/router-integration.ts"],"names":[],"mappings":"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","file":"chunk-DZC3OLDU.js","sourcesContent":["/**\r\n * @flightdev/transitions - Router Integration\r\n * \r\n * Integration with @flightdev/router for seamless page transitions.\r\n */\r\n\r\nimport type {\r\n TransitionPreset,\r\n CustomTransition,\r\n PageTransitionConfig,\r\n TransitionDirection,\r\n} from '../core/types';\r\nimport { getTransitionManager } from '../core/transition-manager';\r\nimport { startViewTransition, isViewTransitionSupported } from '../core/view-transition';\r\nimport { executePageTransition, getPageTransition } from '../page/page-transition';\r\n\r\n// =============================================================================\r\n// NAVIGATION INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * Options for navigating with transitions\r\n */\r\nexport interface NavigateWithTransitionOptions {\r\n /** Replace current history entry instead of push */\r\n replace?: boolean;\r\n /** Scroll to top after navigation */\r\n scroll?: boolean;\r\n /** State to pass to the new route */\r\n state?: Record<string, unknown>;\r\n /** Transition to use (overrides page default) */\r\n transition?: TransitionPreset | CustomTransition | false;\r\n /** Force transition even if globally disabled */\r\n forceTransition?: boolean;\r\n /** Direction hint for the transition */\r\n direction?: TransitionDirection;\r\n}\r\n\r\n/**\r\n * Navigate to a URL with transition support\r\n * \r\n * This function wraps the standard navigation with View Transitions API\r\n * support and integrates with the Flight transitions system.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { navigateWithTransition } from '@flightdev/transitions/router';\r\n * \r\n * // Simple navigation\r\n * await navigateWithTransition('/about');\r\n * \r\n * // With options\r\n * await navigateWithTransition('/dashboard', {\r\n * transition: 'slide-left',\r\n * replace: false,\r\n * });\r\n * ```\r\n */\r\nexport async function navigateWithTransition(\r\n to: string,\r\n options: NavigateWithTransitionOptions = {}\r\n): Promise<void> {\r\n const {\r\n replace = false,\r\n scroll = true,\r\n state = {},\r\n transition,\r\n forceTransition = false,\r\n direction,\r\n } = options;\r\n\r\n const manager = getTransitionManager();\r\n const from = getCurrentPath();\r\n\r\n // Check if we should transition\r\n const shouldTransition = forceTransition ||\r\n (manager.isEnabled() && transition !== false);\r\n\r\n if (!shouldTransition) {\r\n // Perform navigation without transition\r\n performNavigation(to, { replace, state });\r\n if (scroll) scrollToTop();\r\n return;\r\n }\r\n\r\n // Set direction hint\r\n if (direction) {\r\n manager.setDirection(direction);\r\n }\r\n\r\n // Execute page transition\r\n await executePageTransition({\r\n to,\r\n from,\r\n transition,\r\n direction,\r\n updateDOM: async () => {\r\n // Perform the actual navigation\r\n performNavigation(to, { replace, state });\r\n\r\n // Wait for any async route loading\r\n await waitForRouteLoad();\r\n\r\n // Scroll after content is ready\r\n if (scroll) scrollToTop();\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Perform standard browser navigation\r\n */\r\nfunction performNavigation(\r\n to: string,\r\n options: { replace?: boolean; state?: Record<string, unknown> }\r\n): void {\r\n const { replace = false, state = {} } = options;\r\n\r\n if (replace) {\r\n window.history.replaceState(state, '', to);\r\n } else {\r\n window.history.pushState(state, '', to);\r\n }\r\n\r\n // Dispatch popstate for router to pick up\r\n window.dispatchEvent(new PopStateEvent('popstate', { state }));\r\n}\r\n\r\n/**\r\n * Get current pathname\r\n */\r\nfunction getCurrentPath(): string {\r\n if (typeof window === 'undefined') return '/';\r\n return window.location.pathname;\r\n}\r\n\r\n/**\r\n * Scroll to top of page\r\n */\r\nfunction scrollToTop(): void {\r\n if (typeof window === 'undefined') return;\r\n\r\n window.scrollTo({\r\n top: 0,\r\n left: 0,\r\n behavior: 'instant',\r\n });\r\n}\r\n\r\n/**\r\n * Wait for route content to load\r\n * This is a placeholder - actual implementation depends on router\r\n */\r\nasync function waitForRouteLoad(): Promise<void> {\r\n // Give the router time to update\r\n await new Promise((resolve) => requestAnimationFrame(resolve));\r\n await new Promise((resolve) => requestAnimationFrame(resolve));\r\n}\r\n\r\n// =============================================================================\r\n// HISTORY INTEGRATION\r\n// =============================================================================\r\n\r\n/** Track if we've set up history listeners */\r\nlet historyListenerSetup = false;\r\n\r\n/**\r\n * Set up history navigation listeners for back/forward transitions\r\n * \r\n * Call this once during app initialization to enable transitions\r\n * for browser back/forward navigation.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { setupHistoryTransitions } from '@flightdev/transitions/router';\r\n * \r\n * // In your app initialization\r\n * setupHistoryTransitions();\r\n * ```\r\n */\r\nexport function setupHistoryTransitions(): () => void {\r\n if (typeof window === 'undefined') return () => { };\r\n if (historyListenerSetup) return () => { };\r\n\r\n historyListenerSetup = true;\r\n\r\n const manager = getTransitionManager();\r\n\r\n // Handle back/forward navigation\r\n const handlePopState = async (event: PopStateEvent) => {\r\n // Determine direction based on navigation type\r\n // This is a heuristic - actual direction detection would need\r\n // to track history entries\r\n const direction: TransitionDirection = 'auto';\r\n manager.setDirection(direction);\r\n\r\n // If View Transitions API is supported and enabled, use it\r\n if (manager.isEnabled() && isViewTransitionSupported()) {\r\n // The browser's View Transitions API will handle this\r\n // for same-document navigations\r\n }\r\n };\r\n\r\n // Handle beforeunload for cross-document transitions\r\n const handleBeforeUnload = (event: BeforeUnloadEvent) => {\r\n // Clean up any pending transitions\r\n manager.skipTransition();\r\n };\r\n\r\n window.addEventListener('popstate', handlePopState);\r\n window.addEventListener('beforeunload', handleBeforeUnload);\r\n\r\n // Return cleanup function\r\n return () => {\r\n window.removeEventListener('popstate', handlePopState);\r\n window.removeEventListener('beforeunload', handleBeforeUnload);\r\n historyListenerSetup = false;\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// PREFETCHING\r\n// =============================================================================\r\n\r\n/** Set of prefetched URLs */\r\nconst prefetchedUrls = new Set<string>();\r\n\r\n/**\r\n * Prefetch a route's assets for faster transitions\r\n * \r\n * @example\r\n * ```typescript\r\n * // Prefetch on hover\r\n * element.addEventListener('mouseenter', () => {\r\n * prefetchRoute('/about');\r\n * });\r\n * ```\r\n */\r\nexport function prefetchRoute(url: string): void {\r\n if (typeof document === 'undefined') return;\r\n if (prefetchedUrls.has(url)) return;\r\n\r\n prefetchedUrls.add(url);\r\n\r\n // Create prefetch link\r\n const link = document.createElement('link');\r\n link.rel = 'prefetch';\r\n link.href = url;\r\n document.head.appendChild(link);\r\n}\r\n\r\n/**\r\n * Check if a route has been prefetched\r\n */\r\nexport function isRoutePrefetched(url: string): boolean {\r\n return prefetchedUrls.has(url);\r\n}\r\n\r\n// =============================================================================\r\n// ROUTE MATCHING\r\n// =============================================================================\r\n\r\n/**\r\n * Configure transitions based on route patterns\r\n */\r\nexport interface RouteTransitionConfig {\r\n /** Route pattern (supports wildcards) */\r\n pattern: string;\r\n /** Transition configuration for this route */\r\n transition: PageTransitionConfig;\r\n}\r\n\r\n/** Registered route transition configs */\r\nconst routeTransitionConfigs: RouteTransitionConfig[] = [];\r\n\r\n/**\r\n * Register transition configs for route patterns\r\n * \r\n * @example\r\n * ```typescript\r\n * registerRouteTransitions([\r\n * { pattern: '/dashboard/*', transition: { default: 'slide-left' } },\r\n * { pattern: '/settings', transition: { default: 'fade' } },\r\n * ]);\r\n * ```\r\n */\r\nexport function registerRouteTransitions(\r\n configs: RouteTransitionConfig[]\r\n): void {\r\n routeTransitionConfigs.push(...configs);\r\n}\r\n\r\n/**\r\n * Get transition config for a route based on registered patterns\r\n */\r\nexport function getRouteTransitionConfig(\r\n path: string\r\n): PageTransitionConfig | undefined {\r\n // First check page-specific config\r\n const pageConfig = getPageTransition(path);\r\n if (pageConfig) return pageConfig;\r\n\r\n // Then check pattern-based configs\r\n for (const config of routeTransitionConfigs) {\r\n if (matchRoutePattern(path, config.pattern)) {\r\n return config.transition;\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Simple route pattern matching\r\n */\r\nfunction matchRoutePattern(path: string, pattern: string): boolean {\r\n // Convert pattern to regex\r\n const regexStr = pattern\r\n .replace(/\\*/g, '.*')\r\n .replace(/\\//g, '\\\\/');\r\n\r\n const regex = new RegExp(`^${regexStr}$`);\r\n return regex.test(path);\r\n}\r\n"]}
@@ -0,0 +1,190 @@
1
+ import { getPreset } from './chunk-QSB65CTV.js';
2
+ import { prefersReducedMotion, animateOut, animateIn, resolveTransition } from './chunk-OV3U5STU.js';
3
+
4
+ // src/component/component-transition.ts
5
+ function createPresence(element, options = {}) {
6
+ const {
7
+ type = "fade",
8
+ duration,
9
+ appear = false,
10
+ onEnterStart,
11
+ onEnterComplete,
12
+ onExitStart,
13
+ onExitComplete
14
+ } = options;
15
+ let isPresent = false;
16
+ let currentAnimation = null;
17
+ const transition = resolveTransitionType(type, prefersReducedMotion());
18
+ if (transition && duration !== void 0) {
19
+ transition.enter.options.duration = duration;
20
+ transition.leave.options.duration = duration;
21
+ }
22
+ return {
23
+ get isPresent() {
24
+ return isPresent;
25
+ },
26
+ async enter() {
27
+ if (!transition) {
28
+ isPresent = true;
29
+ return;
30
+ }
31
+ currentAnimation?.cancel();
32
+ onEnterStart?.();
33
+ isPresent = true;
34
+ element.style.display = "";
35
+ const handle = animateIn(element, transition);
36
+ currentAnimation = handle.animation;
37
+ await handle.finished;
38
+ currentAnimation = null;
39
+ onEnterComplete?.();
40
+ },
41
+ async exit() {
42
+ if (!transition) {
43
+ isPresent = false;
44
+ return;
45
+ }
46
+ currentAnimation?.cancel();
47
+ onExitStart?.();
48
+ const handle = animateOut(element, transition);
49
+ currentAnimation = handle.animation;
50
+ await handle.finished;
51
+ currentAnimation = null;
52
+ isPresent = false;
53
+ onExitComplete?.();
54
+ },
55
+ cancel() {
56
+ currentAnimation?.cancel();
57
+ currentAnimation = null;
58
+ }
59
+ };
60
+ }
61
+ function createTransitionGroup(container, options = {}) {
62
+ const {
63
+ type = "fade",
64
+ stagger = 0,
65
+ appear = true
66
+ } = options;
67
+ const items = /* @__PURE__ */ new Set();
68
+ const transition = resolveTransitionType(type, prefersReducedMotion());
69
+ return {
70
+ get items() {
71
+ return Array.from(items);
72
+ },
73
+ async addItems(newItems) {
74
+ if (!transition) {
75
+ newItems.forEach((item) => items.add(item));
76
+ return;
77
+ }
78
+ const animations = [];
79
+ newItems.forEach((item, index) => {
80
+ items.add(item);
81
+ container.appendChild(item);
82
+ const staggeredTransition = {
83
+ ...transition,
84
+ enter: {
85
+ ...transition.enter,
86
+ options: {
87
+ ...transition.enter.options,
88
+ delay: index * stagger
89
+ }
90
+ }
91
+ };
92
+ animations.push(animateIn(item, staggeredTransition).finished);
93
+ });
94
+ await Promise.all(animations);
95
+ },
96
+ async removeItems(itemsToRemove) {
97
+ if (!transition) {
98
+ itemsToRemove.forEach((item) => {
99
+ items.delete(item);
100
+ item.remove();
101
+ });
102
+ return;
103
+ }
104
+ const animations = [];
105
+ itemsToRemove.forEach((item, index) => {
106
+ const staggeredTransition = {
107
+ ...transition,
108
+ leave: {
109
+ ...transition.leave,
110
+ options: {
111
+ ...transition.leave.options,
112
+ delay: index * stagger
113
+ }
114
+ }
115
+ };
116
+ const animPromise = animateOut(item, staggeredTransition).finished.then(() => {
117
+ items.delete(item);
118
+ item.remove();
119
+ });
120
+ animations.push(animPromise);
121
+ });
122
+ await Promise.all(animations);
123
+ },
124
+ async reorderItems(newOrder, _animate = true) {
125
+ newOrder.forEach((item) => {
126
+ container.appendChild(item);
127
+ });
128
+ }
129
+ };
130
+ }
131
+ function resolveTransitionType(type, reducedMotion) {
132
+ if (typeof type === "string") {
133
+ const preset = getPreset(type);
134
+ if (preset) {
135
+ return resolveTransition(preset, reducedMotion);
136
+ }
137
+ return resolveTransition(type, reducedMotion);
138
+ }
139
+ return resolveTransition(type, reducedMotion);
140
+ }
141
+ async function toggleVisibility(element, show, options = {}) {
142
+ const { type = "fade" } = options;
143
+ const transition = resolveTransitionType(type, prefersReducedMotion());
144
+ if (!transition) {
145
+ element.style.display = show ? "" : "none";
146
+ return;
147
+ }
148
+ if (show) {
149
+ element.style.display = "";
150
+ await animateIn(element, transition).finished;
151
+ } else {
152
+ await animateOut(element, transition).finished;
153
+ element.style.display = "none";
154
+ }
155
+ }
156
+ async function crossfade(outElement, inElement, options = {}) {
157
+ const { type = "fade", mode = "simultaneous" } = options;
158
+ const transition = resolveTransitionType(type, prefersReducedMotion());
159
+ if (!transition) {
160
+ outElement.style.display = "none";
161
+ inElement.style.display = "";
162
+ return;
163
+ }
164
+ inElement.style.display = "";
165
+ switch (mode) {
166
+ case "out-in":
167
+ await animateOut(outElement, transition).finished;
168
+ outElement.style.display = "none";
169
+ await animateIn(inElement, transition).finished;
170
+ break;
171
+ case "in-out":
172
+ await animateIn(inElement, transition).finished;
173
+ await animateOut(outElement, transition).finished;
174
+ outElement.style.display = "none";
175
+ break;
176
+ case "simultaneous":
177
+ default:
178
+ await Promise.all([
179
+ animateOut(outElement, transition).finished.then(() => {
180
+ outElement.style.display = "none";
181
+ }),
182
+ animateIn(inElement, transition).finished
183
+ ]);
184
+ break;
185
+ }
186
+ }
187
+
188
+ export { createPresence, createTransitionGroup, crossfade, toggleVisibility };
189
+ //# sourceMappingURL=chunk-GEYKSLH6.js.map
190
+ //# sourceMappingURL=chunk-GEYKSLH6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/component/component-transition.ts"],"names":[],"mappings":";;;;AA4CO,SAAS,cAAA,CACZ,OAAA,EACA,OAAA,GAA2B,EAAC,EACV;AAClB,EAAA,MAAM;AAAA,IACF,IAAA,GAAO,MAAA;AAAA,IACP,QAAA;AAAA,IACA,MAAA,GAAS,KAAA;AAAA,IACT,YAAA;AAAA,IACA,eAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACJ,GAAI,OAAA;AAEJ,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,gBAAA,GAAqC,IAAA;AAGzC,EAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,IAAA,EAAM,oBAAA,EAAsB,CAAA;AAGrE,EAAA,IAAI,UAAA,IAAc,aAAa,MAAA,EAAW;AACtC,IAAA,UAAA,CAAW,KAAA,CAAM,QAAQ,QAAA,GAAW,QAAA;AACpC,IAAA,UAAA,CAAW,KAAA,CAAM,QAAQ,QAAA,GAAW,QAAA;AAAA,EACxC;AAEA,EAAA,OAAO;AAAA,IACH,IAAI,SAAA,GAAY;AACZ,MAAA,OAAO,SAAA;AAAA,IACX,CAAA;AAAA,IAEA,MAAM,KAAA,GAAuB;AACzB,MAAA,IAAI,CAAC,UAAA,EAAY;AACb,QAAA,SAAA,GAAY,IAAA;AACZ,QAAA;AAAA,MACJ;AAGA,MAAA,gBAAA,EAAkB,MAAA,EAAO;AAEzB,MAAA,YAAA,IAAe;AACf,MAAA,SAAA,GAAY,IAAA;AAGZ,MAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,EAAA;AAGxB,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,OAAA,EAAS,UAAU,CAAA;AAC5C,MAAA,gBAAA,GAAmB,MAAA,CAAO,SAAA;AAE1B,MAAA,MAAM,MAAA,CAAO,QAAA;AACb,MAAA,gBAAA,GAAmB,IAAA;AACnB,MAAA,eAAA,IAAkB;AAAA,IACtB,CAAA;AAAA,IAEA,MAAM,IAAA,GAAsB;AACxB,MAAA,IAAI,CAAC,UAAA,EAAY;AACb,QAAA,SAAA,GAAY,KAAA;AACZ,QAAA;AAAA,MACJ;AAGA,MAAA,gBAAA,EAAkB,MAAA,EAAO;AAEzB,MAAA,WAAA,IAAc;AAGd,MAAA,MAAM,MAAA,GAAS,UAAA,CAAW,OAAA,EAAS,UAAU,CAAA;AAC7C,MAAA,gBAAA,GAAmB,MAAA,CAAO,SAAA;AAE1B,MAAA,MAAM,MAAA,CAAO,QAAA;AACb,MAAA,gBAAA,GAAmB,IAAA;AACnB,MAAA,SAAA,GAAY,KAAA;AACZ,MAAA,cAAA,IAAiB;AAAA,IACrB,CAAA;AAAA,IAEA,MAAA,GAAe;AACX,MAAA,gBAAA,EAAkB,MAAA,EAAO;AACzB,MAAA,gBAAA,GAAmB,IAAA;AAAA,IACvB;AAAA,GACJ;AACJ;AAwCO,SAAS,qBAAA,CACZ,SAAA,EACA,OAAA,GAAkC,EAAC,EACV;AACzB,EAAA,MAAM;AAAA,IACF,IAAA,GAAO,MAAA;AAAA,IACP,OAAA,GAAU,CAAA;AAAA,IACV,MAAA,GAAS;AAAA,GACb,GAAI,OAAA;AAEJ,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAiB;AACnC,EAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,IAAA,EAAM,oBAAA,EAAsB,CAAA;AAErE,EAAA,OAAO;AAAA,IACH,IAAI,KAAA,GAAQ;AACR,MAAA,OAAO,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,IAC3B,CAAA;AAAA,IAEA,MAAM,SAAS,QAAA,EAAwC;AACnD,MAAA,IAAI,CAAC,UAAA,EAAY;AACb,QAAA,QAAA,CAAS,QAAQ,CAAC,IAAA,KAAS,KAAA,CAAM,GAAA,CAAI,IAAI,CAAC,CAAA;AAC1C,QAAA;AAAA,MACJ;AAEA,MAAA,MAAM,aAA8B,EAAC;AAErC,MAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,IAAA,EAAM,KAAA,KAAU;AAC9B,QAAA,KAAA,CAAM,IAAI,IAAI,CAAA;AACd,QAAA,SAAA,CAAU,YAAY,IAAI,CAAA;AAG1B,QAAA,MAAM,mBAAA,GAA0C;AAAA,UAC5C,GAAG,UAAA;AAAA,UACH,KAAA,EAAO;AAAA,YACH,GAAG,UAAA,CAAW,KAAA;AAAA,YACd,OAAA,EAAS;AAAA,cACL,GAAG,WAAW,KAAA,CAAM,OAAA;AAAA,cACpB,OAAO,KAAA,GAAQ;AAAA;AACnB;AACJ,SACJ;AAEA,QAAA,UAAA,CAAW,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,mBAAmB,EAAE,QAAQ,CAAA;AAAA,MACjE,CAAC,CAAA;AAED,MAAA,MAAM,OAAA,CAAQ,IAAI,UAAU,CAAA;AAAA,IAChC,CAAA;AAAA,IAEA,MAAM,YAAY,aAAA,EAA6C;AAC3D,MAAA,IAAI,CAAC,UAAA,EAAY;AACb,QAAA,aAAA,CAAc,OAAA,CAAQ,CAAC,IAAA,KAAS;AAC5B,UAAA,KAAA,CAAM,OAAO,IAAI,CAAA;AACjB,UAAA,IAAA,CAAK,MAAA,EAAO;AAAA,QAChB,CAAC,CAAA;AACD,QAAA;AAAA,MACJ;AAEA,MAAA,MAAM,aAA8B,EAAC;AAErC,MAAA,aAAA,CAAc,OAAA,CAAQ,CAAC,IAAA,EAAM,KAAA,KAAU;AAEnC,QAAA,MAAM,mBAAA,GAA0C;AAAA,UAC5C,GAAG,UAAA;AAAA,UACH,KAAA,EAAO;AAAA,YACH,GAAG,UAAA,CAAW,KAAA;AAAA,YACd,OAAA,EAAS;AAAA,cACL,GAAG,WAAW,KAAA,CAAM,OAAA;AAAA,cACpB,OAAO,KAAA,GAAQ;AAAA;AACnB;AACJ,SACJ;AAEA,QAAA,MAAM,cAAc,UAAA,CAAW,IAAA,EAAM,mBAAmB,CAAA,CAAE,QAAA,CAAS,KAAK,MAAM;AAC1E,UAAA,KAAA,CAAM,OAAO,IAAI,CAAA;AACjB,UAAA,IAAA,CAAK,MAAA,EAAO;AAAA,QAChB,CAAC,CAAA;AAED,QAAA,UAAA,CAAW,KAAK,WAAW,CAAA;AAAA,MAC/B,CAAC,CAAA;AAED,MAAA,MAAM,OAAA,CAAQ,IAAI,UAAU,CAAA;AAAA,IAChC,CAAA;AAAA,IAEA,MAAM,YAAA,CACF,QAAA,EACA,QAAA,GAAoB,IAAA,EACP;AAGb,MAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,IAAA,KAAS;AACvB,QAAA,SAAA,CAAU,YAAY,IAAI,CAAA;AAAA,MAC9B,CAAC,CAAA;AAAA,IACL;AAAA,GACJ;AACJ;AAsBA,SAAS,qBAAA,CACL,MACA,aAAA,EACyB;AACzB,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC1B,IAAA,MAAM,MAAA,GAAS,UAAU,IAAI,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ;AACR,MAAA,OAAO,iBAAA,CAAkB,QAAQ,aAAa,CAAA;AAAA,IAClD;AACA,IAAA,OAAO,iBAAA,CAAkB,MAAM,aAAa,CAAA;AAAA,EAChD;AACA,EAAA,OAAO,iBAAA,CAAkB,MAAM,aAAa,CAAA;AAChD;AAKA,eAAsB,gBAAA,CAClB,OAAA,EACA,IAAA,EACA,OAAA,GAGI,EAAC,EACQ;AACb,EAAA,MAAM,EAAE,IAAA,GAAO,MAAA,EAAO,GAAI,OAAA;AAC1B,EAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,IAAA,EAAM,oBAAA,EAAsB,CAAA;AAErE,EAAA,IAAI,CAAC,UAAA,EAAY;AACb,IAAA,OAAA,CAAQ,KAAA,CAAM,OAAA,GAAU,IAAA,GAAO,EAAA,GAAK,MAAA;AACpC,IAAA;AAAA,EACJ;AAEA,EAAA,IAAI,IAAA,EAAM;AACN,IAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,EAAA;AACxB,IAAA,MAAM,SAAA,CAAU,OAAA,EAAS,UAAU,CAAA,CAAE,QAAA;AAAA,EACzC,CAAA,MAAO;AACH,IAAA,MAAM,UAAA,CAAW,OAAA,EAAS,UAAU,CAAA,CAAE,QAAA;AACtC,IAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,MAAA;AAAA,EAC5B;AACJ;AAKA,eAAsB,SAAA,CAClB,UAAA,EACA,SAAA,EACA,OAAA,GAGI,EAAC,EACQ;AACb,EAAA,MAAM,EAAE,IAAA,GAAO,MAAA,EAAQ,IAAA,GAAO,gBAAe,GAAI,OAAA;AACjD,EAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,IAAA,EAAM,oBAAA,EAAsB,CAAA;AAErE,EAAA,IAAI,CAAC,UAAA,EAAY;AACb,IAAA,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAC3B,IAAA,SAAA,CAAU,MAAM,OAAA,GAAU,EAAA;AAC1B,IAAA;AAAA,EACJ;AAEA,EAAA,SAAA,CAAU,MAAM,OAAA,GAAU,EAAA;AAE1B,EAAA,QAAQ,IAAA;AAAM,IACV,KAAK,QAAA;AACD,MAAA,MAAM,UAAA,CAAW,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA;AACzC,MAAA,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAC3B,MAAA,MAAM,SAAA,CAAU,SAAA,EAAW,UAAU,CAAA,CAAE,QAAA;AACvC,MAAA;AAAA,IAEJ,KAAK,QAAA;AACD,MAAA,MAAM,SAAA,CAAU,SAAA,EAAW,UAAU,CAAA,CAAE,QAAA;AACvC,MAAA,MAAM,UAAA,CAAW,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA;AACzC,MAAA,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAC3B,MAAA;AAAA,IAEJ,KAAK,cAAA;AAAA,IACL;AACI,MAAA,MAAM,QAAQ,GAAA,CAAI;AAAA,QACd,WAAW,UAAA,EAAY,UAAU,CAAA,CAAE,QAAA,CAAS,KAAK,MAAM;AACnD,UAAA,UAAA,CAAW,MAAM,OAAA,GAAU,MAAA;AAAA,QAC/B,CAAC,CAAA;AAAA,QACD,SAAA,CAAU,SAAA,EAAW,UAAU,CAAA,CAAE;AAAA,OACpC,CAAA;AACD,MAAA;AAAA;AAEZ","file":"chunk-GEYKSLH6.js","sourcesContent":["/**\r\n * @flightdev/transitions - Component Transitions\r\n * \r\n * Component-level transitions for enter/leave animations.\r\n * Framework-agnostic primitives that adapters build upon.\r\n */\r\n\r\nimport type {\r\n TransitionProps,\r\n TransitionGroupProps,\r\n CustomTransition,\r\n TransitionPreset,\r\n ResolvedTransition,\r\n} from '../core/types';\r\nimport {\r\n animate,\r\n animateIn,\r\n animateOut,\r\n resolveTransition,\r\n prefersReducedMotion,\r\n} from '../core/animation-engine';\r\nimport { getPreset } from '../presets';\r\n\r\n// =============================================================================\r\n// PRESENCE DETECTION\r\n// =============================================================================\r\n\r\n/**\r\n * Creates a presence controller for managing enter/exit animations\r\n * \r\n * @example\r\n * ```typescript\r\n * const presence = createPresence(element, {\r\n * type: 'fade',\r\n * onComplete: () => element.remove(),\r\n * });\r\n * \r\n * // Show\r\n * await presence.enter();\r\n * \r\n * // Hide\r\n * await presence.exit();\r\n * ```\r\n */\r\nexport function createPresence(\r\n element: HTMLElement,\r\n options: PresenceOptions = {}\r\n): PresenceController {\r\n const {\r\n type = 'fade',\r\n duration,\r\n appear = false,\r\n onEnterStart,\r\n onEnterComplete,\r\n onExitStart,\r\n onExitComplete,\r\n } = options;\r\n\r\n let isPresent = false;\r\n let currentAnimation: Animation | null = null;\r\n\r\n // Resolve the transition\r\n const transition = resolveTransitionType(type, prefersReducedMotion());\r\n\r\n // Apply duration override\r\n if (transition && duration !== undefined) {\r\n transition.enter.options.duration = duration;\r\n transition.leave.options.duration = duration;\r\n }\r\n\r\n return {\r\n get isPresent() {\r\n return isPresent;\r\n },\r\n\r\n async enter(): Promise<void> {\r\n if (!transition) {\r\n isPresent = true;\r\n return;\r\n }\r\n\r\n // Cancel any ongoing animation\r\n currentAnimation?.cancel();\r\n\r\n onEnterStart?.();\r\n isPresent = true;\r\n\r\n // Make element visible\r\n element.style.display = '';\r\n\r\n // Animate in\r\n const handle = animateIn(element, transition);\r\n currentAnimation = handle.animation;\r\n\r\n await handle.finished;\r\n currentAnimation = null;\r\n onEnterComplete?.();\r\n },\r\n\r\n async exit(): Promise<void> {\r\n if (!transition) {\r\n isPresent = false;\r\n return;\r\n }\r\n\r\n // Cancel any ongoing animation\r\n currentAnimation?.cancel();\r\n\r\n onExitStart?.();\r\n\r\n // Animate out\r\n const handle = animateOut(element, transition);\r\n currentAnimation = handle.animation;\r\n\r\n await handle.finished;\r\n currentAnimation = null;\r\n isPresent = false;\r\n onExitComplete?.();\r\n },\r\n\r\n cancel(): void {\r\n currentAnimation?.cancel();\r\n currentAnimation = null;\r\n },\r\n };\r\n}\r\n\r\nexport interface PresenceOptions {\r\n type?: TransitionPreset | CustomTransition;\r\n duration?: number;\r\n appear?: boolean;\r\n onEnterStart?: () => void;\r\n onEnterComplete?: () => void;\r\n onExitStart?: () => void;\r\n onExitComplete?: () => void;\r\n}\r\n\r\nexport interface PresenceController {\r\n readonly isPresent: boolean;\r\n enter(): Promise<void>;\r\n exit(): Promise<void>;\r\n cancel(): void;\r\n}\r\n\r\n// =============================================================================\r\n// TRANSITION GROUP\r\n// =============================================================================\r\n\r\n/**\r\n * Creates a transition group controller for list animations\r\n * \r\n * @example\r\n * ```typescript\r\n * const group = createTransitionGroup(containerElement, {\r\n * type: 'fade',\r\n * stagger: 50,\r\n * });\r\n * \r\n * // Animate items entering\r\n * group.addItems([item1, item2, item3]);\r\n * \r\n * // Animate items leaving\r\n * group.removeItems([item2]);\r\n * ```\r\n */\r\nexport function createTransitionGroup(\r\n container: HTMLElement,\r\n options: TransitionGroupOptions = {}\r\n): TransitionGroupController {\r\n const {\r\n type = 'fade',\r\n stagger = 0,\r\n appear = true,\r\n } = options;\r\n\r\n const items = new Set<HTMLElement>();\r\n const transition = resolveTransitionType(type, prefersReducedMotion());\r\n\r\n return {\r\n get items() {\r\n return Array.from(items);\r\n },\r\n\r\n async addItems(newItems: HTMLElement[]): Promise<void> {\r\n if (!transition) {\r\n newItems.forEach((item) => items.add(item));\r\n return;\r\n }\r\n\r\n const animations: Promise<void>[] = [];\r\n\r\n newItems.forEach((item, index) => {\r\n items.add(item);\r\n container.appendChild(item);\r\n\r\n // Apply staggered delay\r\n const staggeredTransition: ResolvedTransition = {\r\n ...transition,\r\n enter: {\r\n ...transition.enter,\r\n options: {\r\n ...transition.enter.options,\r\n delay: index * stagger,\r\n },\r\n },\r\n };\r\n\r\n animations.push(animateIn(item, staggeredTransition).finished);\r\n });\r\n\r\n await Promise.all(animations);\r\n },\r\n\r\n async removeItems(itemsToRemove: HTMLElement[]): Promise<void> {\r\n if (!transition) {\r\n itemsToRemove.forEach((item) => {\r\n items.delete(item);\r\n item.remove();\r\n });\r\n return;\r\n }\r\n\r\n const animations: Promise<void>[] = [];\r\n\r\n itemsToRemove.forEach((item, index) => {\r\n // Apply staggered delay\r\n const staggeredTransition: ResolvedTransition = {\r\n ...transition,\r\n leave: {\r\n ...transition.leave,\r\n options: {\r\n ...transition.leave.options,\r\n delay: index * stagger,\r\n },\r\n },\r\n };\r\n\r\n const animPromise = animateOut(item, staggeredTransition).finished.then(() => {\r\n items.delete(item);\r\n item.remove();\r\n });\r\n\r\n animations.push(animPromise);\r\n });\r\n\r\n await Promise.all(animations);\r\n },\r\n\r\n async reorderItems(\r\n newOrder: HTMLElement[],\r\n _animate: boolean = true\r\n ): Promise<void> {\r\n // FLIP animation for reordering\r\n // TODO: Implement FLIP-based reordering\r\n newOrder.forEach((item) => {\r\n container.appendChild(item);\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport interface TransitionGroupOptions {\r\n type?: TransitionPreset | CustomTransition;\r\n stagger?: number;\r\n appear?: boolean;\r\n}\r\n\r\nexport interface TransitionGroupController {\r\n readonly items: HTMLElement[];\r\n addItems(items: HTMLElement[]): Promise<void>;\r\n removeItems(items: HTMLElement[]): Promise<void>;\r\n reorderItems(newOrder: HTMLElement[], animate?: boolean): Promise<void>;\r\n}\r\n\r\n// =============================================================================\r\n// UTILITY FUNCTIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Resolve transition type to ResolvedTransition\r\n */\r\nfunction resolveTransitionType(\r\n type: TransitionPreset | CustomTransition,\r\n reducedMotion: boolean\r\n): ResolvedTransition | null {\r\n if (typeof type === 'string') {\r\n const preset = getPreset(type);\r\n if (preset) {\r\n return resolveTransition(preset, reducedMotion);\r\n }\r\n return resolveTransition(type, reducedMotion);\r\n }\r\n return resolveTransition(type, reducedMotion);\r\n}\r\n\r\n/**\r\n * Simple visibility toggle with transition\r\n */\r\nexport async function toggleVisibility(\r\n element: HTMLElement,\r\n show: boolean,\r\n options: {\r\n type?: TransitionPreset | CustomTransition;\r\n duration?: number;\r\n } = {}\r\n): Promise<void> {\r\n const { type = 'fade' } = options;\r\n const transition = resolveTransitionType(type, prefersReducedMotion());\r\n\r\n if (!transition) {\r\n element.style.display = show ? '' : 'none';\r\n return;\r\n }\r\n\r\n if (show) {\r\n element.style.display = '';\r\n await animateIn(element, transition).finished;\r\n } else {\r\n await animateOut(element, transition).finished;\r\n element.style.display = 'none';\r\n }\r\n}\r\n\r\n/**\r\n * Transition between two elements (one out, one in)\r\n */\r\nexport async function crossfade(\r\n outElement: HTMLElement,\r\n inElement: HTMLElement,\r\n options: {\r\n type?: TransitionPreset | CustomTransition;\r\n mode?: 'in-out' | 'out-in' | 'simultaneous';\r\n } = {}\r\n): Promise<void> {\r\n const { type = 'fade', mode = 'simultaneous' } = options;\r\n const transition = resolveTransitionType(type, prefersReducedMotion());\r\n\r\n if (!transition) {\r\n outElement.style.display = 'none';\r\n inElement.style.display = '';\r\n return;\r\n }\r\n\r\n inElement.style.display = '';\r\n\r\n switch (mode) {\r\n case 'out-in':\r\n await animateOut(outElement, transition).finished;\r\n outElement.style.display = 'none';\r\n await animateIn(inElement, transition).finished;\r\n break;\r\n\r\n case 'in-out':\r\n await animateIn(inElement, transition).finished;\r\n await animateOut(outElement, transition).finished;\r\n outElement.style.display = 'none';\r\n break;\r\n\r\n case 'simultaneous':\r\n default:\r\n await Promise.all([\r\n animateOut(outElement, transition).finished.then(() => {\r\n outElement.style.display = 'none';\r\n }),\r\n animateIn(inElement, transition).finished,\r\n ]);\r\n break;\r\n }\r\n}\r\n"]}
@@ -0,0 +1,70 @@
1
+ import { initTransitions, enableCrossDocumentTransitions, getTransitionManager } from './chunk-X2A7XWYR.js';
2
+
3
+ // src/config/config.ts
4
+ var defaultConfig = {
5
+ enabled: true,
6
+ viewTransitions: true,
7
+ pageTransition: "fade",
8
+ layoutTransition: false,
9
+ duration: 200,
10
+ easing: "cubic-bezier(0.4, 0, 0.2, 1)",
11
+ reduceMotion: "respect-system",
12
+ crossDocument: false
13
+ };
14
+ function defineTransitionsConfig(config) {
15
+ return {
16
+ ...defaultConfig,
17
+ ...config
18
+ };
19
+ }
20
+ function initializeTransitions(config = {}) {
21
+ const fullConfig = defineTransitionsConfig(config);
22
+ initTransitions(fullConfig);
23
+ if (fullConfig.crossDocument && typeof window !== "undefined") {
24
+ enableCrossDocumentTransitions({ enabled: true });
25
+ }
26
+ }
27
+ function updateTransitionsConfig(config) {
28
+ const manager = getTransitionManager();
29
+ manager.configure(config);
30
+ }
31
+ function getTransitionsConfig() {
32
+ const manager = getTransitionManager();
33
+ return manager.getConfig();
34
+ }
35
+ function isTransitionPreset(value) {
36
+ const presets = [
37
+ "fade",
38
+ "fade-scale",
39
+ "slide-left",
40
+ "slide-right",
41
+ "slide-up",
42
+ "slide-down",
43
+ "scale",
44
+ "scale-fade",
45
+ "morph",
46
+ "flip",
47
+ "none"
48
+ ];
49
+ return typeof value === "string" && presets.includes(value);
50
+ }
51
+ function isCustomTransition(value) {
52
+ return typeof value === "object" && value !== null && ("leave" in value || "enter" in value || "duration" in value);
53
+ }
54
+ function isTransitionsSupported() {
55
+ if (typeof window === "undefined") return false;
56
+ if (!("animate" in Element.prototype)) return false;
57
+ return true;
58
+ }
59
+ function getCapabilities() {
60
+ return {
61
+ viewTransitionsApi: typeof document !== "undefined" && "startViewTransition" in document,
62
+ webAnimationsApi: typeof Element !== "undefined" && "animate" in Element.prototype,
63
+ cssViewTransitions: typeof CSS !== "undefined" && CSS.supports?.("view-transition-name", "test"),
64
+ reducedMotion: typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches
65
+ };
66
+ }
67
+
68
+ export { defaultConfig, defineTransitionsConfig, getCapabilities, getTransitionsConfig, initializeTransitions, isCustomTransition, isTransitionPreset, isTransitionsSupported, updateTransitionsConfig };
69
+ //# sourceMappingURL=chunk-N7U5LD4Z.js.map
70
+ //# sourceMappingURL=chunk-N7U5LD4Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/config.ts"],"names":[],"mappings":";;;AAiBO,IAAM,aAAA,GAAmC;AAAA,EAC5C,OAAA,EAAS,IAAA;AAAA,EACT,eAAA,EAAiB,IAAA;AAAA,EACjB,cAAA,EAAgB,MAAA;AAAA,EAChB,gBAAA,EAAkB,KAAA;AAAA,EAClB,QAAA,EAAU,GAAA;AAAA,EACV,MAAA,EAAQ,8BAAA;AAAA,EACR,YAAA,EAAc,gBAAA;AAAA,EACd,aAAA,EAAe;AACnB;AAyBO,SAAS,wBACZ,MAAA,EACiB;AACjB,EAAA,OAAO;AAAA,IACH,GAAG,aAAA;AAAA,IACH,GAAG;AAAA,GACP;AACJ;AAiBO,SAAS,qBAAA,CACZ,MAAA,GAAqC,EAAC,EAClC;AACJ,EAAA,MAAM,UAAA,GAAa,wBAAwB,MAAM,CAAA;AAGjD,EAAA,eAAA,CAAgB,UAAU,CAAA;AAG1B,EAAA,IAAI,UAAA,CAAW,aAAA,IAAiB,OAAO,MAAA,KAAW,WAAA,EAAa;AAC3D,IAAA,8BAAA,CAA+B,EAAE,OAAA,EAAS,IAAA,EAAM,CAAA;AAAA,EACpD;AACJ;AAcO,SAAS,wBACZ,MAAA,EACI;AACJ,EAAA,MAAM,UAAU,oBAAA,EAAqB;AACrC,EAAA,OAAA,CAAQ,UAAU,MAAM,CAAA;AAC5B;AAKO,SAAS,oBAAA,GAA0C;AACtD,EAAA,MAAM,UAAU,oBAAA,EAAqB;AACrC,EAAA,OAAO,QAAQ,SAAA,EAAU;AAC7B;AASO,SAAS,mBAAmB,KAAA,EAA2C;AAC1E,EAAA,MAAM,OAAA,GAA8B;AAAA,IAChC,MAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACJ;AACA,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,OAAA,CAAQ,SAAS,KAAyB,CAAA;AAClF;AAKO,SAAS,mBAAmB,KAAA,EAA2C;AAC1E,EAAA,OACI,OAAO,UAAU,QAAA,IACjB,KAAA,KAAU,SACT,OAAA,IAAW,KAAA,IAAS,OAAA,IAAW,KAAA,IAAS,UAAA,IAAc,KAAA,CAAA;AAE/D;AASO,SAAS,sBAAA,GAAkC;AAC9C,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAG1C,EAAA,IAAI,EAAE,SAAA,IAAa,OAAA,CAAQ,SAAA,CAAA,EAAY,OAAO,KAAA;AAE9C,EAAA,OAAO,IAAA;AACX;AAKO,SAAS,eAAA,GAA0C;AACtD,EAAA,OAAO;AAAA,IACH,kBAAA,EAAoB,OAAO,QAAA,KAAa,WAAA,IACpC,qBAAA,IAAyB,QAAA;AAAA,IAC7B,gBAAA,EAAkB,OAAO,OAAA,KAAY,WAAA,IACjC,aAAa,OAAA,CAAQ,SAAA;AAAA,IACzB,oBAAoB,OAAO,GAAA,KAAQ,eAC/B,GAAA,CAAI,QAAA,GAAW,wBAAwB,MAAM,CAAA;AAAA,IACjD,eAAe,OAAO,MAAA,KAAW,eAC7B,MAAA,CAAO,UAAA,GAAa,kCAAkC,CAAA,CAAE;AAAA,GAChE;AACJ","file":"chunk-N7U5LD4Z.js","sourcesContent":["/**\r\n * @flightdev/transitions - Configuration Module\r\n * \r\n * Configuration helpers and defaults for the transitions system.\r\n */\r\n\r\nimport type { TransitionsConfig, TransitionPreset, CustomTransition } from '../core/types';\r\nimport { initTransitions, getTransitionManager } from '../core/transition-manager';\r\nimport { enableCrossDocumentTransitions } from '../core/view-transition';\r\n\r\n// =============================================================================\r\n// DEFAULT CONFIGURATION\r\n// =============================================================================\r\n\r\n/**\r\n * Default transitions configuration\r\n */\r\nexport const defaultConfig: TransitionsConfig = {\r\n enabled: true,\r\n viewTransitions: true,\r\n pageTransition: 'fade',\r\n layoutTransition: false,\r\n duration: 200,\r\n easing: 'cubic-bezier(0.4, 0, 0.2, 1)',\r\n reduceMotion: 'respect-system',\r\n crossDocument: false,\r\n};\r\n\r\n// =============================================================================\r\n// CONFIGURATION HELPERS\r\n// =============================================================================\r\n\r\n/**\r\n * Define transitions configuration\r\n * \r\n * Use this in flight.config.ts to configure transitions globally.\r\n * \r\n * @example\r\n * ```typescript\r\n * // flight.config.ts\r\n * import { defineConfig } from '@flightdev/core';\r\n * import { defineTransitionsConfig } from '@flightdev/transitions/config';\r\n * \r\n * export default defineConfig({\r\n * transitions: defineTransitionsConfig({\r\n * pageTransition: 'slide-left',\r\n * duration: 300,\r\n * }),\r\n * });\r\n * ```\r\n */\r\nexport function defineTransitionsConfig(\r\n config: Partial<TransitionsConfig>\r\n): TransitionsConfig {\r\n return {\r\n ...defaultConfig,\r\n ...config,\r\n };\r\n}\r\n\r\n/**\r\n * Initialize the transitions system with configuration\r\n * \r\n * Call this during app initialization to set up transitions.\r\n * \r\n * @example\r\n * ```typescript\r\n * import { initializeTransitions } from '@flightdev/transitions/config';\r\n * \r\n * initializeTransitions({\r\n * pageTransition: 'fade',\r\n * reduceMotion: 'respect-system',\r\n * });\r\n * ```\r\n */\r\nexport function initializeTransitions(\r\n config: Partial<TransitionsConfig> = {}\r\n): void {\r\n const fullConfig = defineTransitionsConfig(config);\r\n\r\n // Initialize the transition manager\r\n initTransitions(fullConfig);\r\n\r\n // Set up cross-document transitions if enabled\r\n if (fullConfig.crossDocument && typeof window !== 'undefined') {\r\n enableCrossDocumentTransitions({ enabled: true });\r\n }\r\n}\r\n\r\n/**\r\n * Update transitions configuration at runtime\r\n * \r\n * @example\r\n * ```typescript\r\n * // Disable transitions\r\n * updateTransitionsConfig({ enabled: false });\r\n * \r\n * // Change default transition\r\n * updateTransitionsConfig({ pageTransition: 'slide-left' });\r\n * ```\r\n */\r\nexport function updateTransitionsConfig(\r\n config: Partial<TransitionsConfig>\r\n): void {\r\n const manager = getTransitionManager();\r\n manager.configure(config);\r\n}\r\n\r\n/**\r\n * Get the current transitions configuration\r\n */\r\nexport function getTransitionsConfig(): TransitionsConfig {\r\n const manager = getTransitionManager();\r\n return manager.getConfig();\r\n}\r\n\r\n// =============================================================================\r\n// PRESET HELPERS\r\n// =============================================================================\r\n\r\n/**\r\n * Check if a value is a valid transition preset name\r\n */\r\nexport function isTransitionPreset(value: unknown): value is TransitionPreset {\r\n const presets: TransitionPreset[] = [\r\n 'fade',\r\n 'fade-scale',\r\n 'slide-left',\r\n 'slide-right',\r\n 'slide-up',\r\n 'slide-down',\r\n 'scale',\r\n 'scale-fade',\r\n 'morph',\r\n 'flip',\r\n 'none',\r\n ];\r\n return typeof value === 'string' && presets.includes(value as TransitionPreset);\r\n}\r\n\r\n/**\r\n * Check if a value is a custom transition definition\r\n */\r\nexport function isCustomTransition(value: unknown): value is CustomTransition {\r\n return (\r\n typeof value === 'object' &&\r\n value !== null &&\r\n ('leave' in value || 'enter' in value || 'duration' in value)\r\n );\r\n}\r\n\r\n// =============================================================================\r\n// ENVIRONMENT DETECTION\r\n// =============================================================================\r\n\r\n/**\r\n * Check if the current environment supports transitions\r\n */\r\nexport function isTransitionsSupported(): boolean {\r\n if (typeof window === 'undefined') return false;\r\n\r\n // Check for Web Animations API\r\n if (!('animate' in Element.prototype)) return false;\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Get browser capability information\r\n */\r\nexport function getCapabilities(): TransitionCapabilities {\r\n return {\r\n viewTransitionsApi: typeof document !== 'undefined' &&\r\n 'startViewTransition' in document,\r\n webAnimationsApi: typeof Element !== 'undefined' &&\r\n 'animate' in Element.prototype,\r\n cssViewTransitions: typeof CSS !== 'undefined' &&\r\n CSS.supports?.('view-transition-name', 'test'),\r\n reducedMotion: typeof window !== 'undefined' &&\r\n window.matchMedia?.('(prefers-reduced-motion: reduce)').matches,\r\n };\r\n}\r\n\r\nexport interface TransitionCapabilities {\r\n /** Browser supports View Transitions API */\r\n viewTransitionsApi: boolean;\r\n /** Browser supports Web Animations API */\r\n webAnimationsApi: boolean;\r\n /** Browser supports CSS view-transition-name */\r\n cssViewTransitions: boolean;\r\n /** User prefers reduced motion */\r\n reducedMotion: boolean;\r\n}\r\n"]}