@flight-framework/transitions 0.1.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 (61) hide show
  1. package/README.md +232 -0
  2. package/dist/adapters/react/index.d.ts +210 -0
  3. package/dist/adapters/react/index.js +261 -0
  4. package/dist/adapters/react/index.js.map +1 -0
  5. package/dist/adapters/solid/index.d.ts +5 -0
  6. package/dist/adapters/solid/index.js +9 -0
  7. package/dist/adapters/solid/index.js.map +1 -0
  8. package/dist/adapters/svelte/index.d.ts +5 -0
  9. package/dist/adapters/svelte/index.js +9 -0
  10. package/dist/adapters/svelte/index.js.map +1 -0
  11. package/dist/adapters/vue/index.d.ts +5 -0
  12. package/dist/adapters/vue/index.js +9 -0
  13. package/dist/adapters/vue/index.js.map +1 -0
  14. package/dist/chunk-4SF4GHDQ.js +252 -0
  15. package/dist/chunk-4SF4GHDQ.js.map +1 -0
  16. package/dist/chunk-7R3FXL3A.js +442 -0
  17. package/dist/chunk-7R3FXL3A.js.map +1 -0
  18. package/dist/chunk-BAILQEFB.js +136 -0
  19. package/dist/chunk-BAILQEFB.js.map +1 -0
  20. package/dist/chunk-ITLC6KJ4.js +138 -0
  21. package/dist/chunk-ITLC6KJ4.js.map +1 -0
  22. package/dist/chunk-JRRJMJDL.js +121 -0
  23. package/dist/chunk-JRRJMJDL.js.map +1 -0
  24. package/dist/chunk-UZUZC3MA.js +190 -0
  25. package/dist/chunk-UZUZC3MA.js.map +1 -0
  26. package/dist/chunk-W7HSR35B.js +3 -0
  27. package/dist/chunk-W7HSR35B.js.map +1 -0
  28. package/dist/chunk-WDXXYC7B.js +70 -0
  29. package/dist/chunk-WDXXYC7B.js.map +1 -0
  30. package/dist/chunk-XLVYHPII.js +3 -0
  31. package/dist/chunk-XLVYHPII.js.map +1 -0
  32. package/dist/chunk-ZBJ6FSAK.js +438 -0
  33. package/dist/chunk-ZBJ6FSAK.js.map +1 -0
  34. package/dist/component/index.d.ts +87 -0
  35. package/dist/component/index.js +5 -0
  36. package/dist/component/index.js.map +1 -0
  37. package/dist/config/index.d.ts +93 -0
  38. package/dist/config/index.js +5 -0
  39. package/dist/config/index.js.map +1 -0
  40. package/dist/core/index.d.ts +107 -0
  41. package/dist/core/index.js +5 -0
  42. package/dist/core/index.js.map +1 -0
  43. package/dist/index.d.ts +10 -0
  44. package/dist/index.js +11 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/layout/index.d.ts +112 -0
  47. package/dist/layout/index.js +4 -0
  48. package/dist/layout/index.js.map +1 -0
  49. package/dist/page/index.d.ts +87 -0
  50. package/dist/page/index.js +7 -0
  51. package/dist/page/index.js.map +1 -0
  52. package/dist/presets/index.d.ts +192 -0
  53. package/dist/presets/index.js +3 -0
  54. package/dist/presets/index.js.map +1 -0
  55. package/dist/router/index.d.ts +104 -0
  56. package/dist/router/index.js +7 -0
  57. package/dist/router/index.js.map +1 -0
  58. package/dist/transition-manager-CuO0S_Yn.d.ts +62 -0
  59. package/dist/types-BT3SCjiY.d.ts +272 -0
  60. package/dist/view-transition-Hp-Q9vWJ.d.ts +97 -0
  61. package/package.json +110 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/layout/layout-transition.ts"],"names":[],"mappings":"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","file":"chunk-BAILQEFB.js","sourcesContent":["/**\r\n * @flight-framework/transitions - Layout Transitions\r\n * \r\n * Layout-level transitions for persistent UI elements across navigations.\r\n */\r\n\r\nimport type {\r\n LayoutTransitionConfig,\r\n SharedElementConfig,\r\n ResolvedTransition,\r\n} from '../core/types';\r\nimport { flip } from '../core/animation-engine';\r\n\r\n// =============================================================================\r\n// LAYOUT TRANSITION CONFIG\r\n// =============================================================================\r\n\r\n/** Storage for layout-specific transition configurations */\r\nconst layoutTransitionConfigs = new Map<string, LayoutTransitionConfig>();\r\n\r\n/**\r\n * Define transition configuration for a layout\r\n * \r\n * @example\r\n * ```tsx\r\n * // In a layout component\r\n * defineLayoutTransition({\r\n * default: 'fade',\r\n * persist: true, // Layout persists during page transitions\r\n * sharedElements: [\r\n * { name: 'header', animation: 'none' },\r\n * { name: 'sidebar', animation: 'none' },\r\n * ],\r\n * });\r\n * ```\r\n */\r\nexport function defineLayoutTransition(\r\n layoutId: string,\r\n config: LayoutTransitionConfig\r\n): void {\r\n layoutTransitionConfigs.set(layoutId, config);\r\n}\r\n\r\n/**\r\n * Get the transition configuration for a layout\r\n */\r\nexport function getLayoutTransition(\r\n layoutId: string\r\n): LayoutTransitionConfig | undefined {\r\n return layoutTransitionConfigs.get(layoutId);\r\n}\r\n\r\n/**\r\n * Clear all layout transition configurations\r\n */\r\nexport function clearLayoutTransitions(): void {\r\n layoutTransitionConfigs.clear();\r\n}\r\n\r\n// =============================================================================\r\n// SHARED ELEMENT TRANSITIONS\r\n// =============================================================================\r\n\r\n/** Registry of shared elements on the current page */\r\nconst sharedElementRegistry = new Map<string, HTMLElement>();\r\n\r\n/**\r\n * Register a shared element for transition\r\n * \r\n * @example\r\n * ```typescript\r\n * // Register an element\r\n * registerSharedElement('hero-image', document.getElementById('hero'));\r\n * \r\n * // On navigation, elements with matching names will animate between positions\r\n * ```\r\n */\r\nexport function registerSharedElement(name: string, element: HTMLElement): void {\r\n sharedElementRegistry.set(name, element);\r\n\r\n // Set the view-transition-name CSS property\r\n element.style.viewTransitionName = name;\r\n}\r\n\r\n/**\r\n * Unregister a shared element\r\n */\r\nexport function unregisterSharedElement(name: string): void {\r\n const element = sharedElementRegistry.get(name);\r\n if (element) {\r\n element.style.viewTransitionName = '';\r\n }\r\n sharedElementRegistry.delete(name);\r\n}\r\n\r\n/**\r\n * Get a registered shared element\r\n */\r\nexport function getSharedElement(name: string): HTMLElement | undefined {\r\n return sharedElementRegistry.get(name);\r\n}\r\n\r\n/**\r\n * Clear all shared elements\r\n */\r\nexport function clearSharedElements(): void {\r\n sharedElementRegistry.forEach((element) => {\r\n element.style.viewTransitionName = '';\r\n });\r\n sharedElementRegistry.clear();\r\n}\r\n\r\n/**\r\n * Get all registered shared element names\r\n */\r\nexport function getSharedElementNames(): string[] {\r\n return Array.from(sharedElementRegistry.keys());\r\n}\r\n\r\n// =============================================================================\r\n// SHARED ELEMENT ANIMATION\r\n// =============================================================================\r\n\r\n/**\r\n * Options for shared element transition\r\n */\r\nexport interface SharedElementTransitionOptions {\r\n /** Name of the shared element */\r\n name: string;\r\n /** Duration of the animation */\r\n duration?: number;\r\n /** Easing function */\r\n easing?: string;\r\n /** Callback when animation completes */\r\n onComplete?: () => void;\r\n}\r\n\r\n/**\r\n * Animate a shared element between two states using FLIP\r\n * \r\n * This manually implements shared element transitions for browsers\r\n * that don't support the View Transitions API.\r\n */\r\nexport async function animateSharedElement(\r\n options: SharedElementTransitionOptions\r\n): Promise<void> {\r\n const { name, duration = 300, easing, onComplete } = options;\r\n const element = sharedElementRegistry.get(name);\r\n\r\n if (!element) {\r\n console.warn(`[Flight Transitions] Shared element \"${name}\" not found`);\r\n return;\r\n }\r\n\r\n // Use FLIP animation\r\n await new Promise<void>((resolve) => {\r\n const handle = flip(element, () => {\r\n // This would be called after DOM update\r\n }, {\r\n duration,\r\n easing,\r\n onComplete: () => {\r\n onComplete?.();\r\n resolve();\r\n },\r\n });\r\n });\r\n}\r\n\r\n// =============================================================================\r\n// LAYOUT PERSISTENCE\r\n// =============================================================================\r\n\r\n/**\r\n * Track which layouts should persist during transitions\r\n */\r\nconst persistentLayouts = new Set<string>();\r\n\r\n/**\r\n * Mark a layout as persistent (it won't transition)\r\n */\r\nexport function markLayoutPersistent(layoutId: string): void {\r\n persistentLayouts.add(layoutId);\r\n}\r\n\r\n/**\r\n * Check if a layout is persistent\r\n */\r\nexport function isLayoutPersistent(layoutId: string): boolean {\r\n return persistentLayouts.has(layoutId);\r\n}\r\n\r\n/**\r\n * Clear persistent layout tracking\r\n */\r\nexport function clearPersistentLayouts(): void {\r\n persistentLayouts.clear();\r\n}\r\n\r\n// =============================================================================\r\n// LAYOUT TRANSITION EXECUTION\r\n// =============================================================================\r\n\r\n/**\r\n * Execute a layout transition\r\n * \r\n * Unlike page transitions, layout transitions are more subtle and\r\n * typically involve animating specific sections while preserving others.\r\n */\r\nexport async function executeLayoutTransition(\r\n fromLayoutId: string | null,\r\n toLayoutId: string,\r\n updateDOM: () => void | Promise<void>\r\n): Promise<void> {\r\n const toConfig = layoutTransitionConfigs.get(toLayoutId);\r\n\r\n // If layout is persistent and same, no transition needed\r\n if (fromLayoutId === toLayoutId && toConfig?.persist) {\r\n await updateDOM();\r\n return;\r\n }\r\n\r\n // Configure shared elements if specified\r\n if (toConfig?.sharedElements) {\r\n for (const config of toConfig.sharedElements) {\r\n const element = sharedElementRegistry.get(config.name);\r\n if (element) {\r\n element.style.viewTransitionName = config.name;\r\n }\r\n }\r\n }\r\n\r\n // Execute the DOM update\r\n await updateDOM();\r\n}\r\n\r\n// =============================================================================\r\n// AUTO-DETECTION OF SHARED ELEMENTS\r\n// =============================================================================\r\n\r\n/**\r\n * Automatically find and register shared elements based on data attributes\r\n * \r\n * Elements with `data-transition-name` or `transition:name` will be registered.\r\n */\r\nexport function autoRegisterSharedElements(): void {\r\n if (typeof document === 'undefined') return;\r\n\r\n // Find elements with data-transition-name\r\n const elements = document.querySelectorAll('[data-transition-name]');\r\n\r\n elements.forEach((el) => {\r\n if (el instanceof HTMLElement) {\r\n const name = el.dataset.transitionName;\r\n if (name) {\r\n registerSharedElement(name, el);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Set up a MutationObserver to auto-register shared elements\r\n */\r\nexport function setupSharedElementObserver(): () => void {\r\n if (typeof document === 'undefined') return () => { };\r\n\r\n const observer = new MutationObserver((mutations) => {\r\n for (const mutation of mutations) {\r\n // Check added nodes\r\n mutation.addedNodes.forEach((node) => {\r\n if (node instanceof HTMLElement) {\r\n // Check the node itself\r\n const name = node.dataset?.transitionName;\r\n if (name) {\r\n registerSharedElement(name, node);\r\n }\r\n\r\n // Check children\r\n const children = node.querySelectorAll('[data-transition-name]');\r\n children.forEach((child) => {\r\n if (child instanceof HTMLElement) {\r\n const childName = child.dataset.transitionName;\r\n if (childName) {\r\n registerSharedElement(childName, child);\r\n }\r\n }\r\n });\r\n }\r\n });\r\n\r\n // Check removed nodes\r\n mutation.removedNodes.forEach((node) => {\r\n if (node instanceof HTMLElement) {\r\n const name = node.dataset?.transitionName;\r\n if (name) {\r\n unregisterSharedElement(name);\r\n }\r\n }\r\n });\r\n }\r\n });\r\n\r\n observer.observe(document.body, {\r\n childList: true,\r\n subtree: true,\r\n });\r\n\r\n return () => observer.disconnect();\r\n}\r\n"]}
@@ -0,0 +1,138 @@
1
+ import { getPreset } from './chunk-ZBJ6FSAK.js';
2
+ import { getTransitionManager } from './chunk-7R3FXL3A.js';
3
+ import { resolveTransition, prefersReducedMotion } from './chunk-4SF4GHDQ.js';
4
+
5
+ // src/page/page-transition.ts
6
+ var pageTransitionConfigs = /* @__PURE__ */ new Map();
7
+ function definePageTransition(config) {
8
+ const path = getCurrentPagePath();
9
+ if (path) {
10
+ pageTransitionConfigs.set(path, config);
11
+ }
12
+ }
13
+ function getPageTransition(path) {
14
+ return pageTransitionConfigs.get(path);
15
+ }
16
+ function clearPageTransitions() {
17
+ pageTransitionConfigs.clear();
18
+ }
19
+ async function executePageTransition(options) {
20
+ const manager = getTransitionManager();
21
+ if (!manager.isEnabled()) {
22
+ await options.updateDOM();
23
+ return;
24
+ }
25
+ const { to, from = getCurrentPagePath() ?? "/", updateDOM } = options;
26
+ const toPageConfig = getPageTransition(to);
27
+ const fromPageConfig = getPageTransition(from);
28
+ const direction = options.direction ?? determineDirection(from, to);
29
+ manager.setDirection(direction);
30
+ const transitionInput = resolveTransitionInput(
31
+ options.transition,
32
+ toPageConfig,
33
+ fromPageConfig,
34
+ direction,
35
+ manager.getConfig().pageTransition
36
+ );
37
+ if (transitionInput === false) {
38
+ await updateDOM();
39
+ return;
40
+ }
41
+ const shouldReduce = shouldApplyReducedMotion(
42
+ toPageConfig?.reduceMotion ?? manager.getConfig().reduceMotion
43
+ );
44
+ const resolved = resolveTransitionFromInput(transitionInput, shouldReduce);
45
+ if (!resolved) {
46
+ await updateDOM();
47
+ return;
48
+ }
49
+ await manager.startPageTransition(to, {
50
+ ...toPageConfig,
51
+ default: transitionInput
52
+ });
53
+ }
54
+ function resolveTransitionInput(explicit, toPageConfig, fromPageConfig, direction, globalDefault) {
55
+ if (explicit !== void 0) {
56
+ return explicit;
57
+ }
58
+ if (direction === "back") {
59
+ if (toPageConfig?.backTransition !== void 0) {
60
+ return toPageConfig.backTransition;
61
+ }
62
+ if (fromPageConfig?.backTransition !== void 0) {
63
+ return fromPageConfig.backTransition;
64
+ }
65
+ }
66
+ if (toPageConfig?.default !== void 0) {
67
+ return toPageConfig.default;
68
+ }
69
+ if (globalDefault !== void 0) {
70
+ return globalDefault;
71
+ }
72
+ return "fade";
73
+ }
74
+ function resolveTransitionFromInput(input, reducedMotion) {
75
+ if (typeof input === "string") {
76
+ const preset = getPreset(input);
77
+ if (preset) {
78
+ return resolveTransition(preset, reducedMotion);
79
+ }
80
+ return resolveTransition(input, reducedMotion);
81
+ }
82
+ return resolveTransition(input, reducedMotion);
83
+ }
84
+ function determineDirection(from, to) {
85
+ if (to === "/") {
86
+ return "forward";
87
+ }
88
+ if (from.startsWith(to) && from !== to) {
89
+ return "back";
90
+ }
91
+ if (to.startsWith(from) && from !== to) {
92
+ return "forward";
93
+ }
94
+ return "forward";
95
+ }
96
+ function getCurrentPagePath() {
97
+ if (typeof window === "undefined") {
98
+ return null;
99
+ }
100
+ return window.location.pathname;
101
+ }
102
+ function shouldApplyReducedMotion(behavior) {
103
+ switch (behavior) {
104
+ case "always-reduce":
105
+ return true;
106
+ case "ignore":
107
+ return false;
108
+ case "respect-system":
109
+ default:
110
+ return prefersReducedMotion();
111
+ }
112
+ }
113
+ var lifecycleCallbacks = {
114
+ beforeLeave: /* @__PURE__ */ new Set(),
115
+ afterLeave: /* @__PURE__ */ new Set(),
116
+ beforeEnter: /* @__PURE__ */ new Set(),
117
+ afterEnter: /* @__PURE__ */ new Set()
118
+ };
119
+ function onBeforePageLeave(callback) {
120
+ lifecycleCallbacks.beforeLeave.add(callback);
121
+ return () => lifecycleCallbacks.beforeLeave.delete(callback);
122
+ }
123
+ function onAfterPageLeave(callback) {
124
+ lifecycleCallbacks.afterLeave.add(callback);
125
+ return () => lifecycleCallbacks.afterLeave.delete(callback);
126
+ }
127
+ function onBeforePageEnter(callback) {
128
+ lifecycleCallbacks.beforeEnter.add(callback);
129
+ return () => lifecycleCallbacks.beforeEnter.delete(callback);
130
+ }
131
+ function onAfterPageEnter(callback) {
132
+ lifecycleCallbacks.afterEnter.add(callback);
133
+ return () => lifecycleCallbacks.afterEnter.delete(callback);
134
+ }
135
+
136
+ export { clearPageTransitions, definePageTransition, executePageTransition, getPageTransition, onAfterPageEnter, onAfterPageLeave, onBeforePageEnter, onBeforePageLeave };
137
+ //# sourceMappingURL=chunk-ITLC6KJ4.js.map
138
+ //# sourceMappingURL=chunk-ITLC6KJ4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/page/page-transition.ts"],"names":[],"mappings":"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","file":"chunk-ITLC6KJ4.js","sourcesContent":["/**\r\n * @flight-framework/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,121 @@
1
+ import { executePageTransition, getPageTransition } from './chunk-ITLC6KJ4.js';
2
+ import { getTransitionManager, isViewTransitionSupported } from './chunk-7R3FXL3A.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-JRRJMJDL.js.map
121
+ //# sourceMappingURL=chunk-JRRJMJDL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/router/router-integration.ts"],"names":[],"mappings":"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","file":"chunk-JRRJMJDL.js","sourcesContent":["/**\r\n * @flight-framework/transitions - Router Integration\r\n * \r\n * Integration with @flight-framework/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 '@flight-framework/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 '@flight-framework/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-ZBJ6FSAK.js';
2
+ import { prefersReducedMotion, animateOut, animateIn, resolveTransition } from './chunk-4SF4GHDQ.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-UZUZC3MA.js.map
190
+ //# sourceMappingURL=chunk-UZUZC3MA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/component/component-transition.ts"],"names":[],"mappings":"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","file":"chunk-UZUZC3MA.js","sourcesContent":["/**\r\n * @flight-framework/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,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"}