@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Flight Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # @flight-framework/transitions
2
+
3
+ View transition utilities for Flight Framework. Smooth page transitions with the View Transitions API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @flight-framework/transitions
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { createTransition } from '@flight-framework/transitions';
15
+
16
+ const transition = createTransition();
17
+
18
+ // Wrap navigation with transition
19
+ await transition.navigate('/new-page', async () => {
20
+ await router.push('/new-page');
21
+ });
22
+ ```
23
+
24
+ ## React Integration
25
+
26
+ ```tsx
27
+ import { TransitionProvider, useTransition } from '@flight-framework/transitions/react';
28
+
29
+ function App() {
30
+ return (
31
+ <TransitionProvider>
32
+ <Routes />
33
+ </TransitionProvider>
34
+ );
35
+ }
36
+
37
+ function Navigation() {
38
+ const { navigate, isPending } = useTransition();
39
+
40
+ return (
41
+ <nav>
42
+ <button
43
+ onClick={() => navigate('/about')}
44
+ disabled={isPending}
45
+ >
46
+ About
47
+ </button>
48
+ </nav>
49
+ );
50
+ }
51
+ ```
52
+
53
+ ## Named Transitions
54
+
55
+ ```css
56
+ /* Shared element transitions */
57
+ .hero-image {
58
+ view-transition-name: hero;
59
+ }
60
+ ```
61
+
62
+ ```tsx
63
+ <img
64
+ src="/hero.jpg"
65
+ style={{ viewTransitionName: 'hero' }}
66
+ />
67
+ ```
68
+
69
+ ## Configuration
70
+
71
+ ```typescript
72
+ createTransition({
73
+ // Fallback for browsers without View Transitions
74
+ fallback: 'fade',
75
+
76
+ // Transition duration
77
+ duration: 300,
78
+
79
+ // Easing function
80
+ easing: 'ease-out',
81
+ });
82
+ ```
83
+
84
+ ## License
85
+
86
+ MIT
@@ -0,0 +1,210 @@
1
+ import React, { FC, ReactNode, CSSProperties } from 'react';
2
+ import { i as TransitionsConfig, j as TransitionState, P as PageTransitionConfig, T as TransitionPreset, C as CustomTransition } from '../../types-BA4L37s4.js';
3
+ import { T as TransitionManager } from '../../transition-manager-QWm4OSFw.js';
4
+
5
+ /**
6
+ * @flightdev/transitions - React Adapter
7
+ *
8
+ * React components and hooks for Flight Transitions.
9
+ */
10
+
11
+ interface TransitionContextValue {
12
+ /** Current transition state */
13
+ state: TransitionState;
14
+ /** Transition manager instance */
15
+ manager: TransitionManager;
16
+ /** Whether transitions are enabled */
17
+ isEnabled: boolean;
18
+ /** Whether View Transitions API is supported */
19
+ isViewTransitionSupported: boolean;
20
+ /** Start a page transition programmatically */
21
+ startTransition: (to: string, config?: PageTransitionConfig) => Promise<void>;
22
+ /** Skip the current transition */
23
+ skipTransition: () => void;
24
+ }
25
+ interface TransitionProviderProps {
26
+ children: ReactNode;
27
+ /** Initial transition configuration */
28
+ config?: TransitionsConfig;
29
+ /** Use a custom transition manager */
30
+ manager?: TransitionManager;
31
+ }
32
+ /**
33
+ * TransitionProvider - Provides transition context to the app
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * // In your root layout
38
+ * import { TransitionProvider } from '@flightdev/transitions/react';
39
+ *
40
+ * export default function RootLayout({ children }) {
41
+ * return (
42
+ * <TransitionProvider config={{ pageTransition: 'fade' }}>
43
+ * {children}
44
+ * </TransitionProvider>
45
+ * );
46
+ * }
47
+ * ```
48
+ */
49
+ declare const TransitionProvider: FC<TransitionProviderProps>;
50
+ /**
51
+ * useTransition - Access the transition context
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * function MyComponent() {
56
+ * const { state, startTransition } = useTransition();
57
+ *
58
+ * return (
59
+ * <div>
60
+ * {state.isTransitioning && <LoadingSpinner />}
61
+ * <button onClick={() => startTransition('/about')}>
62
+ * Go to About
63
+ * </button>
64
+ * </div>
65
+ * );
66
+ * }
67
+ * ```
68
+ */
69
+ declare function useTransition(): TransitionContextValue;
70
+ /**
71
+ * useTransitionState - Get just the transition state
72
+ */
73
+ declare function useTransitionState(): TransitionState;
74
+ /**
75
+ * useIsTransitioning - Check if a transition is in progress
76
+ */
77
+ declare function useIsTransitioning(): boolean;
78
+ /**
79
+ * useTransitionDirection - Get the current transition direction
80
+ */
81
+ declare function useTransitionDirection(): 'forward' | 'back' | 'auto';
82
+ /**
83
+ * useReducedMotion - Check if user prefers reduced motion
84
+ */
85
+ declare function useReducedMotion(): boolean;
86
+ interface PageTransitionProps {
87
+ children: ReactNode;
88
+ /** Transition type (overrides context config) */
89
+ type?: TransitionPreset | CustomTransition;
90
+ /** Duration override */
91
+ duration?: number;
92
+ /** Mode for sequencing enter/leave */
93
+ mode?: 'in-out' | 'out-in' | 'simultaneous';
94
+ /** Callback when transition starts */
95
+ onStart?: () => void;
96
+ /** Callback when transition ends */
97
+ onEnd?: () => void;
98
+ /** CSS class for the wrapper */
99
+ className?: string;
100
+ /** Inline styles for the wrapper */
101
+ style?: CSSProperties;
102
+ }
103
+ /**
104
+ * PageTransition - Wraps page content with transition animations
105
+ *
106
+ * @example
107
+ * ```tsx
108
+ * // In a layout
109
+ * export default function Layout({ children }) {
110
+ * return (
111
+ * <PageTransition type="slide-left">
112
+ * {children}
113
+ * </PageTransition>
114
+ * );
115
+ * }
116
+ * ```
117
+ */
118
+ declare const PageTransition: FC<PageTransitionProps>;
119
+ interface TransitionElementProps {
120
+ children: ReactNode;
121
+ /** Show or hide the element */
122
+ show: boolean;
123
+ /** Transition type */
124
+ type?: TransitionPreset | CustomTransition;
125
+ /** Duration override */
126
+ duration?: number;
127
+ /** Animate on initial mount */
128
+ appear?: boolean;
129
+ /** Unmount when hidden */
130
+ unmountOnHide?: boolean;
131
+ /** Callbacks */
132
+ onEnter?: () => void;
133
+ onEnterComplete?: () => void;
134
+ onLeave?: () => void;
135
+ onLeaveComplete?: () => void;
136
+ /** Wrapper element tag name */
137
+ as?: 'div' | 'span' | 'section' | 'article' | 'main' | 'aside' | 'header' | 'footer' | 'nav';
138
+ /** CSS class */
139
+ className?: string;
140
+ /** Inline styles */
141
+ style?: CSSProperties;
142
+ }
143
+ /**
144
+ * Transition - Animate element enter/leave
145
+ *
146
+ * @example
147
+ * ```tsx
148
+ * function Modal({ isOpen, onClose, children }) {
149
+ * return (
150
+ * <Transition show={isOpen} type="fade-scale">
151
+ * <div className="modal">
152
+ * {children}
153
+ * </div>
154
+ * </Transition>
155
+ * );
156
+ * }
157
+ * ```
158
+ */
159
+ declare const Transition: FC<TransitionElementProps>;
160
+ interface SharedElementProps {
161
+ children: ReactNode;
162
+ /** Unique name for matching across pages */
163
+ name: string;
164
+ /** Wrapper element tag name */
165
+ as?: 'div' | 'span' | 'section' | 'article' | 'main' | 'aside' | 'header' | 'footer' | 'img';
166
+ /** CSS class */
167
+ className?: string;
168
+ /** Inline styles */
169
+ style?: CSSProperties;
170
+ }
171
+ /**
172
+ * SharedElement - Mark an element for shared element transitions
173
+ *
174
+ * @example
175
+ * ```tsx
176
+ * // On list page
177
+ * <SharedElement name={`product-${product.id}`}>
178
+ * <img src={product.image} />
179
+ * </SharedElement>
180
+ *
181
+ * // On detail page
182
+ * <SharedElement name={`product-${product.id}`}>
183
+ * <img src={product.image} />
184
+ * </SharedElement>
185
+ * ```
186
+ */
187
+ declare const SharedElement: FC<SharedElementProps>;
188
+ interface TransitionLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
189
+ /** Transition type for this navigation */
190
+ transition?: TransitionPreset | CustomTransition | false;
191
+ /** Replace instead of push */
192
+ replace?: boolean;
193
+ /** Prefetch on hover */
194
+ prefetch?: boolean;
195
+ }
196
+ /**
197
+ * TransitionLink - Link component with transition support
198
+ *
199
+ * Use with @flightdev/router or wrap your router's Link component.
200
+ *
201
+ * @example
202
+ * ```tsx
203
+ * <TransitionLink href="/about" transition="slide-left">
204
+ * About Us
205
+ * </TransitionLink>
206
+ * ```
207
+ */
208
+ declare const TransitionLink: FC<TransitionLinkProps>;
209
+
210
+ export { PageTransition, type PageTransitionProps, SharedElement, type SharedElementProps, Transition, type TransitionElementProps, TransitionLink, type TransitionLinkProps, TransitionProvider, type TransitionProviderProps, useIsTransitioning, useReducedMotion, useTransition, useTransitionDirection, useTransitionState };
@@ -0,0 +1,261 @@
1
+ import { createTransitionManager, getTransitionManager } from '../../chunk-X2A7XWYR.js';
2
+ import { prefersReducedMotion } from '../../chunk-OV3U5STU.js';
3
+ import { createContext, useRef, useState, useEffect, useMemo, useContext, createElement, useCallback } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ var TransitionContext = createContext(null);
7
+ var TransitionProvider = ({
8
+ children,
9
+ config,
10
+ manager: customManager
11
+ }) => {
12
+ const managerRef = useRef(null);
13
+ if (!managerRef.current) {
14
+ managerRef.current = customManager ?? createTransitionManager(config);
15
+ }
16
+ const manager = managerRef.current;
17
+ const [state, setState] = useState(manager.getState());
18
+ useEffect(() => {
19
+ const unsubscribe = manager.subscribe((newState) => {
20
+ setState(newState);
21
+ });
22
+ return unsubscribe;
23
+ }, [manager]);
24
+ useEffect(() => {
25
+ if (config) {
26
+ manager.configure(config);
27
+ }
28
+ }, [config, manager]);
29
+ useEffect(() => {
30
+ return () => {
31
+ if (!customManager) {
32
+ manager.destroy();
33
+ }
34
+ };
35
+ }, [manager, customManager]);
36
+ const value = useMemo(() => ({
37
+ state,
38
+ manager,
39
+ isEnabled: manager.isEnabled(),
40
+ isViewTransitionSupported: manager.isViewTransitionSupported(),
41
+ startTransition: (to, pageConfig) => manager.startPageTransition(to, pageConfig),
42
+ skipTransition: () => manager.skipTransition()
43
+ }), [state, manager]);
44
+ return /* @__PURE__ */ jsx(TransitionContext.Provider, { value, children });
45
+ };
46
+ function useTransition() {
47
+ const context = useContext(TransitionContext);
48
+ if (!context) {
49
+ const manager = getTransitionManager();
50
+ return {
51
+ state: manager.getState(),
52
+ manager,
53
+ isEnabled: manager.isEnabled(),
54
+ isViewTransitionSupported: manager.isViewTransitionSupported(),
55
+ startTransition: (to, config) => manager.startPageTransition(to, config),
56
+ skipTransition: () => manager.skipTransition()
57
+ };
58
+ }
59
+ return context;
60
+ }
61
+ function useTransitionState() {
62
+ const { state } = useTransition();
63
+ return state;
64
+ }
65
+ function useIsTransitioning() {
66
+ const { state } = useTransition();
67
+ return state.isTransitioning;
68
+ }
69
+ function useTransitionDirection() {
70
+ const { state } = useTransition();
71
+ return state.direction;
72
+ }
73
+ function useReducedMotion() {
74
+ const [reduced, setReduced] = useState(() => prefersReducedMotion());
75
+ useEffect(() => {
76
+ const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
77
+ const handler = (event) => {
78
+ setReduced(event.matches);
79
+ };
80
+ mediaQuery.addEventListener("change", handler);
81
+ return () => mediaQuery.removeEventListener("change", handler);
82
+ }, []);
83
+ return reduced;
84
+ }
85
+ var PageTransition = ({
86
+ children,
87
+ type,
88
+ duration,
89
+ mode = "out-in",
90
+ onStart,
91
+ onEnd,
92
+ className,
93
+ style
94
+ }) => {
95
+ const { state } = useTransition();
96
+ const containerRef = useRef(null);
97
+ useEffect(() => {
98
+ if (state.isTransitioning && state.phase === "leaving") {
99
+ onStart?.();
100
+ }
101
+ if (!state.isTransitioning && state.phase === "idle") {
102
+ onEnd?.();
103
+ }
104
+ }, [state.isTransitioning, state.phase, onStart, onEnd]);
105
+ const transitionClass = useMemo(() => {
106
+ const classes = ["flight-page-transition"];
107
+ if (className) {
108
+ classes.push(className);
109
+ }
110
+ if (state.isTransitioning) {
111
+ classes.push("flight-transitioning");
112
+ classes.push(`flight-transition-${state.phase}`);
113
+ classes.push(`flight-direction-${state.direction}`);
114
+ }
115
+ return classes.join(" ");
116
+ }, [className, state.isTransitioning, state.phase, state.direction]);
117
+ const inlineStyle = useMemo(() => {
118
+ const styles = { ...style };
119
+ if (duration !== void 0) {
120
+ styles["--flight-transition-duration"] = `${duration}ms`;
121
+ }
122
+ if (type && typeof type === "string") {
123
+ styles["--flight-transition-type"] = type;
124
+ }
125
+ return styles;
126
+ }, [style, duration, type]);
127
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, className: transitionClass, style: inlineStyle, children });
128
+ };
129
+ var Transition = ({
130
+ children,
131
+ show,
132
+ type = "fade",
133
+ duration,
134
+ appear = false,
135
+ unmountOnHide = true,
136
+ onEnter,
137
+ onEnterComplete,
138
+ onLeave,
139
+ onLeaveComplete,
140
+ as: Component = "div",
141
+ className,
142
+ style
143
+ }) => {
144
+ const [shouldRender, setShouldRender] = useState(show);
145
+ const [phase, setPhase] = useState(
146
+ show ? "entered" : "left"
147
+ );
148
+ const isInitialMount = useRef(true);
149
+ useEffect(() => {
150
+ const isMount = isInitialMount.current;
151
+ isInitialMount.current = false;
152
+ if (show) {
153
+ setShouldRender(true);
154
+ if (!isMount || appear) {
155
+ setPhase("entering");
156
+ onEnter?.();
157
+ const timer = setTimeout(() => {
158
+ setPhase("entered");
159
+ onEnterComplete?.();
160
+ }, duration ?? 200);
161
+ return () => clearTimeout(timer);
162
+ } else {
163
+ setPhase("entered");
164
+ }
165
+ } else {
166
+ setPhase("leaving");
167
+ onLeave?.();
168
+ const timer = setTimeout(() => {
169
+ setPhase("left");
170
+ onLeaveComplete?.();
171
+ if (unmountOnHide) {
172
+ setShouldRender(false);
173
+ }
174
+ }, duration ?? 200);
175
+ return () => clearTimeout(timer);
176
+ }
177
+ }, [show, appear, duration, unmountOnHide, onEnter, onEnterComplete, onLeave, onLeaveComplete]);
178
+ if (!shouldRender) {
179
+ return null;
180
+ }
181
+ const transitionClass = [
182
+ "flight-transition",
183
+ `flight-transition-${phase}`,
184
+ typeof type === "string" ? `flight-transition-${type}` : void 0,
185
+ className
186
+ ].filter(Boolean).join(" ");
187
+ const inlineStyle = {
188
+ ...style
189
+ };
190
+ if (duration !== void 0) {
191
+ inlineStyle["--flight-transition-duration"] = `${duration}ms`;
192
+ }
193
+ return createElement(
194
+ Component,
195
+ { className: transitionClass, style: inlineStyle },
196
+ children
197
+ );
198
+ };
199
+ var SharedElement = ({
200
+ children,
201
+ name,
202
+ as: Component = "div",
203
+ className,
204
+ style
205
+ }) => {
206
+ const ref = useRef(null);
207
+ useEffect(() => {
208
+ const element = ref.current;
209
+ if (element) {
210
+ element.style.viewTransitionName = name;
211
+ return () => {
212
+ element.style.viewTransitionName = "";
213
+ };
214
+ }
215
+ }, [name]);
216
+ return createElement(
217
+ Component,
218
+ {
219
+ ref,
220
+ className,
221
+ style,
222
+ "data-transition-name": name
223
+ },
224
+ children
225
+ );
226
+ };
227
+ var TransitionLink = ({
228
+ children,
229
+ href,
230
+ transition,
231
+ replace = false,
232
+ prefetch = false,
233
+ onClick,
234
+ ...props
235
+ }) => {
236
+ const { startTransition, manager } = useTransition();
237
+ const handleClick = useCallback(async (e) => {
238
+ onClick?.(e);
239
+ if (e.defaultPrevented) return;
240
+ if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
241
+ return;
242
+ }
243
+ if (href && !href.startsWith("/") && !href.startsWith(window.location.origin)) {
244
+ return;
245
+ }
246
+ e.preventDefault();
247
+ const targetPath = href?.startsWith("/") ? href : new URL(href ?? "", window.location.origin).pathname;
248
+ await startTransition(targetPath, transition !== void 0 ? { default: transition } : void 0);
249
+ if (replace) {
250
+ window.history.replaceState({}, "", targetPath);
251
+ } else {
252
+ window.history.pushState({}, "", targetPath);
253
+ }
254
+ window.dispatchEvent(new PopStateEvent("popstate"));
255
+ }, [href, transition, replace, onClick, startTransition]);
256
+ return /* @__PURE__ */ jsx("a", { href, onClick: handleClick, ...props, children });
257
+ };
258
+
259
+ export { PageTransition, SharedElement, Transition, TransitionLink, TransitionProvider, useIsTransitioning, useReducedMotion, useTransition, useTransitionDirection, useTransitionState };
260
+ //# sourceMappingURL=index.js.map
261
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/react/components.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * @flightdev/transitions - React Adapter\r\n * \r\n * React components and hooks for Flight Transitions.\r\n */\r\n\r\n'use client';\r\n\r\nimport React, {\r\n createContext,\r\n useContext,\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n createElement,\r\n type ReactNode,\r\n type FC,\r\n type CSSProperties,\r\n type ElementType,\r\n} from 'react';\r\n\r\nimport type {\r\n TransitionsConfig,\r\n TransitionState,\r\n TransitionPreset,\r\n CustomTransition,\r\n PageTransitionConfig,\r\n} from '../../core/types';\r\nimport {\r\n createTransitionManager,\r\n getTransitionManager,\r\n type TransitionManager,\r\n} from '../../core/transition-manager';\r\nimport { prefersReducedMotion } from '../../core/animation-engine';\r\n\r\n// =============================================================================\r\n// CONTEXT\r\n// =============================================================================\r\n\r\ninterface TransitionContextValue {\r\n /** Current transition state */\r\n state: TransitionState;\r\n /** Transition manager instance */\r\n manager: TransitionManager;\r\n /** Whether transitions are enabled */\r\n isEnabled: boolean;\r\n /** Whether View Transitions API is supported */\r\n isViewTransitionSupported: boolean;\r\n /** Start a page transition programmatically */\r\n startTransition: (to: string, config?: PageTransitionConfig) => Promise<void>;\r\n /** Skip the current transition */\r\n skipTransition: () => void;\r\n}\r\n\r\nconst TransitionContext = createContext<TransitionContextValue | null>(null);\r\n\r\n// =============================================================================\r\n// PROVIDER\r\n// =============================================================================\r\n\r\nexport interface TransitionProviderProps {\r\n children: ReactNode;\r\n /** Initial transition configuration */\r\n config?: TransitionsConfig;\r\n /** Use a custom transition manager */\r\n manager?: TransitionManager;\r\n}\r\n\r\n/**\r\n * TransitionProvider - Provides transition context to the app\r\n * \r\n * @example\r\n * ```tsx\r\n * // In your root layout\r\n * import { TransitionProvider } from '@flightdev/transitions/react';\r\n * \r\n * export default function RootLayout({ children }) {\r\n * return (\r\n * <TransitionProvider config={{ pageTransition: 'fade' }}>\r\n * {children}\r\n * </TransitionProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const TransitionProvider: FC<TransitionProviderProps> = ({\r\n children,\r\n config,\r\n manager: customManager,\r\n}) => {\r\n // Create or use provided manager\r\n const managerRef = useRef<TransitionManager | null>(null);\r\n\r\n if (!managerRef.current) {\r\n managerRef.current = customManager ?? createTransitionManager(config);\r\n }\r\n\r\n const manager = managerRef.current;\r\n\r\n // Track transition state\r\n const [state, setState] = useState<TransitionState>(manager.getState());\r\n\r\n // Subscribe to state changes\r\n useEffect(() => {\r\n const unsubscribe = manager.subscribe((newState) => {\r\n setState(newState);\r\n });\r\n return unsubscribe;\r\n }, [manager]);\r\n\r\n // Update config when it changes\r\n useEffect(() => {\r\n if (config) {\r\n manager.configure(config);\r\n }\r\n }, [config, manager]);\r\n\r\n // Cleanup on unmount\r\n useEffect(() => {\r\n return () => {\r\n if (!customManager) {\r\n manager.destroy();\r\n }\r\n };\r\n }, [manager, customManager]);\r\n\r\n const value = useMemo<TransitionContextValue>(() => ({\r\n state,\r\n manager,\r\n isEnabled: manager.isEnabled(),\r\n isViewTransitionSupported: manager.isViewTransitionSupported(),\r\n startTransition: (to, pageConfig) => manager.startPageTransition(to, pageConfig),\r\n skipTransition: () => manager.skipTransition(),\r\n }), [state, manager]);\r\n\r\n return (\r\n <TransitionContext.Provider value={value}>\r\n {children}\r\n </TransitionContext.Provider>\r\n );\r\n};\r\n\r\n// =============================================================================\r\n// HOOKS\r\n// =============================================================================\r\n\r\n/**\r\n * useTransition - Access the transition context\r\n * \r\n * @example\r\n * ```tsx\r\n * function MyComponent() {\r\n * const { state, startTransition } = useTransition();\r\n * \r\n * return (\r\n * <div>\r\n * {state.isTransitioning && <LoadingSpinner />}\r\n * <button onClick={() => startTransition('/about')}>\r\n * Go to About\r\n * </button>\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useTransition(): TransitionContextValue {\r\n const context = useContext(TransitionContext);\r\n\r\n if (!context) {\r\n // Return a fallback for components outside provider\r\n const manager = getTransitionManager();\r\n return {\r\n state: manager.getState(),\r\n manager,\r\n isEnabled: manager.isEnabled(),\r\n isViewTransitionSupported: manager.isViewTransitionSupported(),\r\n startTransition: (to, config) => manager.startPageTransition(to, config),\r\n skipTransition: () => manager.skipTransition(),\r\n };\r\n }\r\n\r\n return context;\r\n}\r\n\r\n/**\r\n * useTransitionState - Get just the transition state\r\n */\r\nexport function useTransitionState(): TransitionState {\r\n const { state } = useTransition();\r\n return state;\r\n}\r\n\r\n/**\r\n * useIsTransitioning - Check if a transition is in progress\r\n */\r\nexport function useIsTransitioning(): boolean {\r\n const { state } = useTransition();\r\n return state.isTransitioning;\r\n}\r\n\r\n/**\r\n * useTransitionDirection - Get the current transition direction\r\n */\r\nexport function useTransitionDirection(): 'forward' | 'back' | 'auto' {\r\n const { state } = useTransition();\r\n return state.direction;\r\n}\r\n\r\n/**\r\n * useReducedMotion - Check if user prefers reduced motion\r\n */\r\nexport function useReducedMotion(): boolean {\r\n const [reduced, setReduced] = useState(() => prefersReducedMotion());\r\n\r\n useEffect(() => {\r\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\r\n\r\n const handler = (event: MediaQueryListEvent) => {\r\n setReduced(event.matches);\r\n };\r\n\r\n mediaQuery.addEventListener('change', handler);\r\n return () => mediaQuery.removeEventListener('change', handler);\r\n }, []);\r\n\r\n return reduced;\r\n}\r\n\r\n// =============================================================================\r\n// PAGE TRANSITION COMPONENT\r\n// =============================================================================\r\n\r\nexport interface PageTransitionProps {\r\n children: ReactNode;\r\n /** Transition type (overrides context config) */\r\n type?: TransitionPreset | CustomTransition;\r\n /** Duration override */\r\n duration?: number;\r\n /** Mode for sequencing enter/leave */\r\n mode?: 'in-out' | 'out-in' | 'simultaneous';\r\n /** Callback when transition starts */\r\n onStart?: () => void;\r\n /** Callback when transition ends */\r\n onEnd?: () => void;\r\n /** CSS class for the wrapper */\r\n className?: string;\r\n /** Inline styles for the wrapper */\r\n style?: CSSProperties;\r\n}\r\n\r\n/**\r\n * PageTransition - Wraps page content with transition animations\r\n * \r\n * @example\r\n * ```tsx\r\n * // In a layout\r\n * export default function Layout({ children }) {\r\n * return (\r\n * <PageTransition type=\"slide-left\">\r\n * {children}\r\n * </PageTransition>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const PageTransition: FC<PageTransitionProps> = ({\r\n children,\r\n type,\r\n duration,\r\n mode = 'out-in',\r\n onStart,\r\n onEnd,\r\n className,\r\n style,\r\n}) => {\r\n const { state } = useTransition();\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // Call callbacks\r\n useEffect(() => {\r\n if (state.isTransitioning && state.phase === 'leaving') {\r\n onStart?.();\r\n }\r\n if (!state.isTransitioning && state.phase === 'idle') {\r\n onEnd?.();\r\n }\r\n }, [state.isTransitioning, state.phase, onStart, onEnd]);\r\n\r\n // Build transition class\r\n const transitionClass = useMemo(() => {\r\n const classes = ['flight-page-transition'];\r\n\r\n if (className) {\r\n classes.push(className);\r\n }\r\n\r\n if (state.isTransitioning) {\r\n classes.push('flight-transitioning');\r\n classes.push(`flight-transition-${state.phase}`);\r\n classes.push(`flight-direction-${state.direction}`);\r\n }\r\n\r\n return classes.join(' ');\r\n }, [className, state.isTransitioning, state.phase, state.direction]);\r\n\r\n // Build inline styles with CSS custom properties\r\n const inlineStyle = useMemo<CSSProperties>(() => {\r\n const styles: CSSProperties = { ...style };\r\n\r\n if (duration !== undefined) {\r\n (styles as Record<string, unknown>)['--flight-transition-duration'] = `${duration}ms`;\r\n }\r\n\r\n if (type && typeof type === 'string') {\r\n (styles as Record<string, unknown>)['--flight-transition-type'] = type;\r\n }\r\n\r\n return styles;\r\n }, [style, duration, type]);\r\n\r\n return (\r\n <div ref={containerRef} className={transitionClass} style={inlineStyle}>\r\n {children}\r\n </div>\r\n );\r\n};\r\n\r\n// =============================================================================\r\n// TRANSITION COMPONENT (for elements)\r\n// =============================================================================\r\n\r\nexport interface TransitionElementProps {\r\n children: ReactNode;\r\n /** Show or hide the element */\r\n show: boolean;\r\n /** Transition type */\r\n type?: TransitionPreset | CustomTransition;\r\n /** Duration override */\r\n duration?: number;\r\n /** Animate on initial mount */\r\n appear?: boolean;\r\n /** Unmount when hidden */\r\n unmountOnHide?: boolean;\r\n /** Callbacks */\r\n onEnter?: () => void;\r\n onEnterComplete?: () => void;\r\n onLeave?: () => void;\r\n onLeaveComplete?: () => void;\r\n /** Wrapper element tag name */\r\n as?: 'div' | 'span' | 'section' | 'article' | 'main' | 'aside' | 'header' | 'footer' | 'nav';\r\n /** CSS class */\r\n className?: string;\r\n /** Inline styles */\r\n style?: CSSProperties;\r\n}\r\n\r\n/**\r\n * Transition - Animate element enter/leave\r\n * \r\n * @example\r\n * ```tsx\r\n * function Modal({ isOpen, onClose, children }) {\r\n * return (\r\n * <Transition show={isOpen} type=\"fade-scale\">\r\n * <div className=\"modal\">\r\n * {children}\r\n * </div>\r\n * </Transition>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const Transition: FC<TransitionElementProps> = ({\r\n children,\r\n show,\r\n type = 'fade',\r\n duration,\r\n appear = false,\r\n unmountOnHide = true,\r\n onEnter,\r\n onEnterComplete,\r\n onLeave,\r\n onLeaveComplete,\r\n as: Component = 'div',\r\n className,\r\n style,\r\n}) => {\r\n const [shouldRender, setShouldRender] = useState(show);\r\n const [phase, setPhase] = useState<'entering' | 'entered' | 'leaving' | 'left'>(\r\n show ? 'entered' : 'left'\r\n );\r\n const isInitialMount = useRef(true);\r\n\r\n useEffect(() => {\r\n const isMount = isInitialMount.current;\r\n isInitialMount.current = false;\r\n\r\n if (show) {\r\n setShouldRender(true);\r\n\r\n if (!isMount || appear) {\r\n setPhase('entering');\r\n onEnter?.();\r\n\r\n const timer = setTimeout(() => {\r\n setPhase('entered');\r\n onEnterComplete?.();\r\n }, duration ?? 200);\r\n\r\n return () => clearTimeout(timer);\r\n } else {\r\n setPhase('entered');\r\n }\r\n } else {\r\n setPhase('leaving');\r\n onLeave?.();\r\n\r\n const timer = setTimeout(() => {\r\n setPhase('left');\r\n onLeaveComplete?.();\r\n if (unmountOnHide) {\r\n setShouldRender(false);\r\n }\r\n }, duration ?? 200);\r\n\r\n return () => clearTimeout(timer);\r\n }\r\n }, [show, appear, duration, unmountOnHide, onEnter, onEnterComplete, onLeave, onLeaveComplete]);\r\n\r\n if (!shouldRender) {\r\n return null;\r\n }\r\n\r\n const transitionClass = [\r\n 'flight-transition',\r\n `flight-transition-${phase}`,\r\n typeof type === 'string' ? `flight-transition-${type}` : undefined,\r\n className,\r\n ].filter(Boolean).join(' ');\r\n\r\n const inlineStyle: CSSProperties = {\r\n ...style,\r\n };\r\n\r\n if (duration !== undefined) {\r\n (inlineStyle as Record<string, unknown>)['--flight-transition-duration'] = `${duration}ms`;\r\n }\r\n\r\n return createElement(\r\n Component,\r\n { className: transitionClass, style: inlineStyle },\r\n children\r\n );\r\n};\r\n\r\n// =============================================================================\r\n// SHARED ELEMENT\r\n// =============================================================================\r\n\r\nexport interface SharedElementProps {\r\n children: ReactNode;\r\n /** Unique name for matching across pages */\r\n name: string;\r\n /** Wrapper element tag name */\r\n as?: 'div' | 'span' | 'section' | 'article' | 'main' | 'aside' | 'header' | 'footer' | 'img';\r\n /** CSS class */\r\n className?: string;\r\n /** Inline styles */\r\n style?: CSSProperties;\r\n}\r\n\r\n/**\r\n * SharedElement - Mark an element for shared element transitions\r\n * \r\n * @example\r\n * ```tsx\r\n * // On list page\r\n * <SharedElement name={`product-${product.id}`}>\r\n * <img src={product.image} />\r\n * </SharedElement>\r\n * \r\n * // On detail page\r\n * <SharedElement name={`product-${product.id}`}>\r\n * <img src={product.image} />\r\n * </SharedElement>\r\n * ```\r\n */\r\nexport const SharedElement: FC<SharedElementProps> = ({\r\n children,\r\n name,\r\n as: Component = 'div',\r\n className,\r\n style,\r\n}) => {\r\n const ref = useRef<HTMLElement>(null);\r\n\r\n useEffect(() => {\r\n const element = ref.current;\r\n if (element) {\r\n // Set view-transition-name for native View Transitions API\r\n element.style.viewTransitionName = name;\r\n\r\n return () => {\r\n element.style.viewTransitionName = '';\r\n };\r\n }\r\n }, [name]);\r\n\r\n return createElement(\r\n Component,\r\n {\r\n ref: ref as React.Ref<HTMLDivElement>,\r\n className,\r\n style,\r\n 'data-transition-name': name,\r\n },\r\n children\r\n );\r\n};\r\n\r\n// =============================================================================\r\n// ANIMATED LINK\r\n// =============================================================================\r\n\r\nexport interface TransitionLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\r\n /** Transition type for this navigation */\r\n transition?: TransitionPreset | CustomTransition | false;\r\n /** Replace instead of push */\r\n replace?: boolean;\r\n /** Prefetch on hover */\r\n prefetch?: boolean;\r\n}\r\n\r\n/**\r\n * TransitionLink - Link component with transition support\r\n * \r\n * Use with @flightdev/router or wrap your router's Link component.\r\n * \r\n * @example\r\n * ```tsx\r\n * <TransitionLink href=\"/about\" transition=\"slide-left\">\r\n * About Us\r\n * </TransitionLink>\r\n * ```\r\n */\r\nexport const TransitionLink: FC<TransitionLinkProps> = ({\r\n children,\r\n href,\r\n transition,\r\n replace = false,\r\n prefetch = false,\r\n onClick,\r\n ...props\r\n}) => {\r\n const { startTransition, manager } = useTransition();\r\n\r\n const handleClick = useCallback(async (e: React.MouseEvent<HTMLAnchorElement>) => {\r\n // Call original onClick if provided\r\n onClick?.(e);\r\n\r\n // If default prevented, don't handle\r\n if (e.defaultPrevented) return;\r\n\r\n // Only handle left clicks without modifiers\r\n if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {\r\n return;\r\n }\r\n\r\n // Only handle same-origin links\r\n if (href && !href.startsWith('/') && !href.startsWith(window.location.origin)) {\r\n return;\r\n }\r\n\r\n // Prevent default navigation\r\n e.preventDefault();\r\n\r\n const targetPath = href?.startsWith('/')\r\n ? href\r\n : new URL(href ?? '', window.location.origin).pathname;\r\n\r\n // Start transition\r\n await startTransition(targetPath, transition !== undefined ? { default: transition } : undefined);\r\n\r\n // Perform actual navigation\r\n if (replace) {\r\n window.history.replaceState({}, '', targetPath);\r\n } else {\r\n window.history.pushState({}, '', targetPath);\r\n }\r\n\r\n // Dispatch popstate for router to pick up\r\n window.dispatchEvent(new PopStateEvent('popstate'));\r\n }, [href, transition, replace, onClick, startTransition]);\r\n\r\n return (\r\n <a href={href} onClick={handleClick} {...props}>\r\n {children}\r\n </a>\r\n );\r\n};\r\n"]}
@@ -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,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"}