@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
package/README.md ADDED
@@ -0,0 +1,232 @@
1
+ # @flight-framework/transitions
2
+
3
+ Smooth page, layout, and component transitions for Flight Framework.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **Native View Transitions API** - Uses browser-native API when available
8
+ - 🎨 **20+ Built-in Presets** - Fade, slide, scale, flip, morph, and more
9
+ - ⚡ **Zero Dependencies** - Core bundle ~3kb gzipped
10
+ - 🎯 **Framework Agnostic** - Works with React, Vue, Svelte, Solid, and more
11
+ - ♿ **Accessible** - Respects `prefers-reduced-motion` by default
12
+ - 📱 **SSR Safe** - Works with server-side rendering
13
+ - 🔧 **Highly Configurable** - Global config or per-page overrides
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @flight-framework/transitions
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### Global Configuration
24
+
25
+ ```typescript
26
+ // flight.config.ts
27
+ import { defineConfig } from '@flight-framework/core';
28
+
29
+ export default defineConfig({
30
+ transitions: {
31
+ enabled: true,
32
+ pageTransition: 'fade',
33
+ duration: 200,
34
+ },
35
+ });
36
+ ```
37
+
38
+ ### React Usage
39
+
40
+ ```tsx
41
+ // RootLayout.tsx
42
+ import { TransitionProvider, PageTransition } from '@flight-framework/transitions/react';
43
+
44
+ export default function RootLayout({ children }) {
45
+ return (
46
+ <TransitionProvider config={{ pageTransition: 'fade' }}>
47
+ <Header />
48
+ <PageTransition>
49
+ {children}
50
+ </PageTransition>
51
+ <Footer />
52
+ </TransitionProvider>
53
+ );
54
+ }
55
+ ```
56
+
57
+ ### Page-Specific Transitions
58
+
59
+ ```tsx
60
+ // routes/dashboard.page.tsx
61
+ import { definePageTransition } from '@flight-framework/transitions';
62
+
63
+ definePageTransition({
64
+ default: 'slide-left',
65
+ backTransition: 'slide-right',
66
+ duration: 250,
67
+ });
68
+
69
+ export default function DashboardPage() {
70
+ return <div>Dashboard</div>;
71
+ }
72
+ ```
73
+
74
+ ## Presets
75
+
76
+ ### Fade
77
+ - `fade` - Simple opacity fade
78
+ - `fade-scale` - Fade with subtle scale
79
+ - `fade-blur` - Fade with blur effect
80
+ - `fade-slow` - Slow fade for emphasis
81
+ - `fade-fast` - Quick fade for snappy UI
82
+
83
+ ### Slide
84
+ - `slide-left` - Slide in from left
85
+ - `slide-right` - Slide in from right
86
+ - `slide-up` - Slide in from top
87
+ - `slide-down` - Slide in from bottom
88
+ - `slide-fade` - Subtle offset slide
89
+ - `slide-scale` - iOS-like slide with scale
90
+
91
+ ### Scale
92
+ - `scale` - Scale in/out
93
+ - `scale-up` - Zoom in effect
94
+ - `scale-down` - Zoom out effect
95
+ - `scale-fade` - Subtle scale with fade
96
+ - `pop` - Bouncy scale animation
97
+ - `expand` - Expand from center
98
+
99
+ ### Special
100
+ - `flip-x` - 3D horizontal flip
101
+ - `flip-y` - 3D vertical flip
102
+ - `rotate` - Rotation with fade
103
+ - `morph` - Shared element morphing
104
+ - `wipe-left` - Reveal wipe effect
105
+ - `circle-reveal` - Circular reveal from center
106
+ - `none` - Disable transitions
107
+
108
+ ## Custom Transitions
109
+
110
+ ```typescript
111
+ import { definePageTransition } from '@flight-framework/transitions';
112
+
113
+ definePageTransition({
114
+ default: {
115
+ name: 'my-custom',
116
+ leave: {
117
+ from: { opacity: '1', transform: 'scale(1)' },
118
+ to: { opacity: '0', transform: 'scale(0.9) rotate(5deg)' },
119
+ },
120
+ enter: {
121
+ from: { opacity: '0', transform: 'translateY(20px)' },
122
+ to: { opacity: '1', transform: 'translateY(0)' },
123
+ },
124
+ duration: { leave: 150, enter: 200 },
125
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
126
+ },
127
+ });
128
+ ```
129
+
130
+ ## Shared Element Transitions
131
+
132
+ ```tsx
133
+ // ProductList.tsx
134
+ <Link href={`/product/${id}`}>
135
+ <SharedElement name={`product-${id}`}>
136
+ <img src={product.image} alt={product.name} />
137
+ </SharedElement>
138
+ </Link>
139
+
140
+ // ProductDetail.tsx
141
+ <SharedElement name={`product-${id}`}>
142
+ <img src={product.image} alt={product.name} className="large" />
143
+ </SharedElement>
144
+ ```
145
+
146
+ ## Programmatic Navigation
147
+
148
+ ```typescript
149
+ import { navigateWithTransition } from '@flight-framework/transitions/router';
150
+
151
+ // With default transition
152
+ await navigateWithTransition('/dashboard');
153
+
154
+ // With custom transition
155
+ await navigateWithTransition('/settings', {
156
+ transition: 'slide-left',
157
+ replace: false,
158
+ });
159
+
160
+ // Disable transition
161
+ await navigateWithTransition('/login', {
162
+ transition: false,
163
+ });
164
+ ```
165
+
166
+ ## React Hooks
167
+
168
+ ```tsx
169
+ import {
170
+ useTransition,
171
+ useIsTransitioning,
172
+ useTransitionDirection,
173
+ useReducedMotion,
174
+ } from '@flight-framework/transitions/react';
175
+
176
+ function MyComponent() {
177
+ const { state, startTransition } = useTransition();
178
+ const isTransitioning = useIsTransitioning();
179
+ const direction = useTransitionDirection();
180
+ const prefersReduced = useReducedMotion();
181
+
182
+ return (
183
+ <div>
184
+ {isTransitioning && <LoadingIndicator />}
185
+ <p>Direction: {direction}</p>
186
+ </div>
187
+ );
188
+ }
189
+ ```
190
+
191
+ ## CSS-Only Usage
192
+
193
+ For CSS-only transitions without JavaScript:
194
+
195
+ ```css
196
+ /* Import base transitions */
197
+ @import '@flight-framework/transitions/css';
198
+
199
+ /* Import View Transitions API styles */
200
+ @import '@flight-framework/transitions/css/view-transitions';
201
+ ```
202
+
203
+ ```html
204
+ <div class="flight-transition flight-transition-fade">
205
+ Content with transition
206
+ </div>
207
+ ```
208
+
209
+ ## Configuration Options
210
+
211
+ | Option | Type | Default | Description |
212
+ |--------|------|---------|-------------|
213
+ | `enabled` | `boolean` | `true` | Enable/disable transitions globally |
214
+ | `viewTransitions` | `boolean` | `true` | Use native View Transitions API |
215
+ | `pageTransition` | `string \| object` | `'fade'` | Default page transition |
216
+ | `layoutTransition` | `string \| object` | `false` | Default layout transition |
217
+ | `duration` | `number` | `200` | Animation duration in ms |
218
+ | `easing` | `string` | `cubic-bezier(0.4, 0, 0.2, 1)` | Easing function |
219
+ | `reduceMotion` | `'respect-system' \| 'always-reduce' \| 'ignore'` | `'respect-system'` | Reduced motion handling |
220
+ | `crossDocument` | `boolean` | `false` | Enable MPA transitions |
221
+
222
+ ## Browser Support
223
+
224
+ | Feature | Chrome | Firefox | Safari | Edge |
225
+ |---------|--------|---------|--------|------|
226
+ | View Transitions API | 111+ | ❌ (fallback) | 18.4+ | 111+ |
227
+ | CSS Fallback | ✅ | ✅ | ✅ | ✅ |
228
+ | Web Animations API | ✅ | ✅ | ✅ | ✅ |
229
+
230
+ ## License
231
+
232
+ MIT © Flight Contributors
@@ -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-BT3SCjiY.js';
3
+ import { T as TransitionManager } from '../../transition-manager-CuO0S_Yn.js';
4
+
5
+ /**
6
+ * @flight-framework/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 '@flight-framework/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 @flight-framework/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-7R3FXL3A.js';
2
+ import { prefersReducedMotion } from '../../chunk-4SF4GHDQ.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