@capgo/capacitor-transitions 8.0.1

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.
@@ -0,0 +1,400 @@
1
+ /**
2
+ * Core types for @capgo/capacitor-transitions
3
+ * Framework-agnostic page transitions for Capacitor apps
4
+ */
5
+ /** Direction of the navigation transition */
6
+ type TransitionDirection = 'forward' | 'back' | 'root' | 'none';
7
+ /** Platform-specific animation styles */
8
+ type TransitionPlatform = 'ios' | 'android' | 'auto';
9
+ /** Whether the edge swipe-back gesture is enabled, disabled, or native-detected */
10
+ type SwipeGestureOption = boolean | 'auto';
11
+ /** Which parts of the page to animate */
12
+ type TransitionTarget = 'header' | 'content' | 'footer' | 'all';
13
+ /** Animation easing presets */
14
+ type TransitionEasing = 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'ios' | 'android' | string;
15
+ /** Configuration for a single transition animation */
16
+ interface TransitionConfig {
17
+ /** Duration in milliseconds (default: 540 for iOS, 280/200 for Android forward/back) */
18
+ duration?: number;
19
+ /** Easing function (default: 'ios' or 'android' based on platform) */
20
+ easing?: TransitionEasing;
21
+ /** Direction of transition */
22
+ direction?: TransitionDirection;
23
+ /** Which elements to animate (default: 'all') */
24
+ targets?: TransitionTarget[];
25
+ /** Custom animation keyframes for entering element */
26
+ enterKeyframes?: Keyframe[];
27
+ /** Custom animation keyframes for leaving element */
28
+ leaveKeyframes?: Keyframe[];
29
+ /** Callback before animation starts */
30
+ onStart?: () => void;
31
+ /** Callback after animation completes */
32
+ onComplete?: () => void;
33
+ /** Whether to use View Transitions API when available (default: false) */
34
+ useViewTransitions?: boolean;
35
+ }
36
+ /** Resolved platform type (excludes 'auto') */
37
+ type ResolvedPlatform = 'ios' | 'android';
38
+ /** Global configuration for the transition system */
39
+ interface TransitionGlobalConfig {
40
+ /** Default platform style (default: 'auto') */
41
+ platform?: TransitionPlatform;
42
+ /** Default duration in ms */
43
+ duration?: number;
44
+ /** Default easing */
45
+ easing?: TransitionEasing;
46
+ /** Whether to use View Transitions API (default: false) */
47
+ useViewTransitions?: boolean;
48
+ /** Custom platform detection function */
49
+ detectPlatform?: () => ResolvedPlatform;
50
+ }
51
+ /** State of a page in the navigation stack */
52
+ interface PageState {
53
+ /** Unique identifier for the page */
54
+ id: string;
55
+ /** The page element */
56
+ element: HTMLElement;
57
+ /** Header element if present */
58
+ header?: HTMLElement;
59
+ /** Content element if present */
60
+ content?: HTMLElement;
61
+ /** Footer element if present */
62
+ footer?: HTMLElement;
63
+ /** Whether this page is currently visible */
64
+ isActive: boolean;
65
+ /** Scroll position to restore */
66
+ scrollPosition?: {
67
+ x: number;
68
+ y: number;
69
+ };
70
+ /** Any custom data attached to this page */
71
+ data?: Record<string, unknown>;
72
+ }
73
+ /** Navigation event details */
74
+ interface NavigationEvent {
75
+ /** Direction of navigation */
76
+ direction: TransitionDirection;
77
+ /** Page being navigated from */
78
+ from?: PageState;
79
+ /** Page being navigated to */
80
+ to: PageState;
81
+ /** Whether animation should be skipped */
82
+ skipAnimation?: boolean;
83
+ }
84
+ /** Lifecycle hooks for page transitions */
85
+ interface TransitionLifecycle {
86
+ /** Called before the page becomes visible (before animation) */
87
+ onWillEnter?: (event: NavigationEvent) => void | Promise<void>;
88
+ /** Called after the page becomes visible (after animation) */
89
+ onDidEnter?: (event: NavigationEvent) => void | Promise<void>;
90
+ /** Called before the page leaves (before animation) */
91
+ onWillLeave?: (event: NavigationEvent) => void | Promise<void>;
92
+ /** Called after the page leaves (after animation) */
93
+ onDidLeave?: (event: NavigationEvent) => void | Promise<void>;
94
+ }
95
+ /** Result of a transition animation */
96
+ interface TransitionResult {
97
+ /** Whether the transition completed successfully */
98
+ success: boolean;
99
+ /** Duration of the transition in ms */
100
+ duration: number;
101
+ /** Any error that occurred */
102
+ error?: Error;
103
+ }
104
+
105
+ /**
106
+ * Transition Controller
107
+ * Orchestrates page transitions and manages the navigation stack
108
+ */
109
+
110
+ /**
111
+ * Transition Controller
112
+ * Central manager for all page transitions
113
+ */
114
+ declare class TransitionController {
115
+ private config;
116
+ private pageStack;
117
+ private currentAnimations;
118
+ private isAnimating;
119
+ private interactiveBackTransition;
120
+ private lifecycleCallbacks;
121
+ constructor(config?: TransitionGlobalConfig);
122
+ /**
123
+ * Get the resolved platform
124
+ */
125
+ get platform(): 'ios' | 'android';
126
+ /**
127
+ * Get the current page state
128
+ */
129
+ get currentPage(): PageState | undefined;
130
+ /**
131
+ * Get the page stack
132
+ */
133
+ get stack(): readonly PageState[];
134
+ /**
135
+ * Check if an animation is in progress
136
+ */
137
+ get animating(): boolean;
138
+ /**
139
+ * Update global configuration
140
+ */
141
+ configure(config: Partial<TransitionGlobalConfig>): void;
142
+ /**
143
+ * Register lifecycle callbacks for a page
144
+ */
145
+ registerLifecycle(pageId: string, lifecycle: TransitionLifecycle): void;
146
+ /**
147
+ * Unregister lifecycle callbacks for a page
148
+ */
149
+ unregisterLifecycle(pageId: string): void;
150
+ /**
151
+ * Create a page state from an element
152
+ */
153
+ createPageState(element: HTMLElement, options?: {
154
+ id?: string;
155
+ data?: Record<string, unknown>;
156
+ }): PageState;
157
+ /**
158
+ * Navigate to a new page (push)
159
+ */
160
+ push(enteringEl: HTMLElement, config?: TransitionConfig): Promise<TransitionResult>;
161
+ /**
162
+ * Navigate back (pop)
163
+ */
164
+ pop(config?: TransitionConfig): Promise<TransitionResult>;
165
+ /**
166
+ * Start an interactive iOS-style back transition using the cached previous page.
167
+ */
168
+ beginInteractiveBack(config?: TransitionConfig): boolean;
169
+ /**
170
+ * Move the current interactive back transition to a progress step from 0 to 1.
171
+ */
172
+ stepInteractiveBack(step: number): void;
173
+ /**
174
+ * Complete or cancel the current interactive back transition.
175
+ */
176
+ endInteractiveBack(shouldComplete: boolean, releaseDuration: number, commitStack: boolean): Promise<void>;
177
+ /**
178
+ * Cancel the current interactive back transition immediately.
179
+ */
180
+ cancelInteractiveBack(): void;
181
+ /**
182
+ * Replace all pages with a new root
183
+ */
184
+ setRoot(enteringEl: HTMLElement, config?: TransitionConfig): Promise<TransitionResult>;
185
+ /**
186
+ * Main navigation method
187
+ */
188
+ navigate(enteringEl: HTMLElement, config?: TransitionConfig): Promise<TransitionResult>;
189
+ /**
190
+ * Navigate between two known page states
191
+ */
192
+ private navigateWithStates;
193
+ /**
194
+ * Update page visibility after animation
195
+ */
196
+ private updatePageVisibility;
197
+ private getAnimationDuration;
198
+ private playInteractiveAnimationsTo;
199
+ /**
200
+ * Resolve configured easing presets after platform/direction are known.
201
+ */
202
+ private resolveTransitionEasing;
203
+ /**
204
+ * Remove styles that should only exist while a page is actively transitioning.
205
+ */
206
+ private clearTransitionOnlyStyles;
207
+ private clearPagePartTransitionStyles;
208
+ /**
209
+ * Prepare entering/leaving elements for a View Transition capture.
210
+ * Entering page must be hidden in the "old" snapshot.
211
+ */
212
+ private prepareViewTransitionElements;
213
+ /**
214
+ * Assign view transition names to a page's layout parts.
215
+ */
216
+ private applyViewTransitionNames;
217
+ /**
218
+ * Clear view transition names for one or more page states.
219
+ */
220
+ private clearViewTransitionNames;
221
+ /**
222
+ * Clear view transition names from all known pages plus transient states.
223
+ */
224
+ private clearAllKnownViewTransitionNames;
225
+ /**
226
+ * Resolve page parts lazily to avoid timing issues with custom-element setup.
227
+ */
228
+ private resolvePageParts;
229
+ /**
230
+ * Save scroll position for a page
231
+ */
232
+ saveScrollPosition(pageId: string): void;
233
+ /**
234
+ * Restore scroll position for a page
235
+ */
236
+ restoreScrollPosition(pageId: string): void;
237
+ /**
238
+ * Remove a page from the stack (used when cleaning up)
239
+ */
240
+ removePage(pageId: string): void;
241
+ /**
242
+ * Clear all pages
243
+ */
244
+ clear(): void;
245
+ }
246
+
247
+ /**
248
+ * React bindings for @capgo/capacitor-transitions
249
+ * Helper functions for using web components in React
250
+ */
251
+
252
+ /**
253
+ * Initialize the transition system
254
+ */
255
+ declare function initTransitions(config?: TransitionGlobalConfig): TransitionController;
256
+ /**
257
+ * Get the global transition controller
258
+ */
259
+ declare function getController(): TransitionController;
260
+ /**
261
+ * Get/set the current transition direction
262
+ */
263
+ declare function getDirection(): TransitionDirection;
264
+ declare function setDirection(direction: TransitionDirection): void;
265
+ /**
266
+ * Set up a router outlet element
267
+ * Call this in useEffect with a ref to the cap-router-outlet element
268
+ */
269
+ declare function setupRouterOutlet(element: HTMLElement, options?: {
270
+ keepInDom?: boolean;
271
+ maxCached?: number;
272
+ platform?: 'ios' | 'android' | 'auto';
273
+ duration?: number;
274
+ swipeGesture?: SwipeGestureOption;
275
+ }): void;
276
+ /**
277
+ * Set up a page element with lifecycle callbacks
278
+ * Call this in useEffect with a ref to the cap-page element
279
+ * Returns a cleanup function to call in the effect cleanup
280
+ *
281
+ * @example
282
+ * ```tsx
283
+ * function MyPage() {
284
+ * const pageRef = useRef<HTMLElement>(null)
285
+ *
286
+ * useEffect(() => {
287
+ * if (pageRef.current) {
288
+ * return setupPage(pageRef.current, {
289
+ * onDidEnter: () => console.log('entered'),
290
+ * onDidLeave: () => console.log('left'),
291
+ * })
292
+ * }
293
+ * }, [])
294
+ *
295
+ * return <cap-page ref={pageRef}>...</cap-page>
296
+ * }
297
+ * ```
298
+ */
299
+ declare function setupPage(element: HTMLElement, callbacks?: {
300
+ onWillEnter?: (event: NavigationEvent) => void;
301
+ onDidEnter?: (event: NavigationEvent) => void;
302
+ onWillLeave?: (event: NavigationEvent) => void;
303
+ onDidLeave?: (event: NavigationEvent) => void;
304
+ }): () => void;
305
+ /**
306
+ * Create a transition-aware navigate function
307
+ * Wraps your router's navigate function to set the direction before navigating
308
+ *
309
+ * @example
310
+ * ```tsx
311
+ * const navigate = useNavigate()
312
+ * const transitionNavigate = createTransitionNavigate(navigate)
313
+ *
314
+ * // Forward navigation
315
+ * transitionNavigate('/details/1')
316
+ *
317
+ * // Back navigation
318
+ * transitionNavigate('/', 'back')
319
+ * ```
320
+ */
321
+ declare function createTransitionNavigate(navigate: (to: string) => void): (to: string, direction?: TransitionDirection) => void;
322
+
323
+ type CapElementAttributes = {
324
+ key?: unknown;
325
+ ref?: unknown;
326
+ children?: unknown;
327
+ id?: string;
328
+ class?: string;
329
+ className?: string;
330
+ style?: unknown;
331
+ slot?: string;
332
+ role?: string;
333
+ part?: string;
334
+ title?: string;
335
+ tabIndex?: number;
336
+ [attribute: `data-${string}`]: unknown;
337
+ [attribute: `aria-${string}`]: unknown;
338
+ [eventHandler: `on${string}`]: unknown;
339
+ };
340
+ type Booleanish = boolean | 'true' | 'false';
341
+ interface CapTransitionsIntrinsicElements {
342
+ 'cap-router-outlet': CapElementAttributes & {
343
+ platform?: 'ios' | 'android' | 'auto';
344
+ duration?: number | string;
345
+ 'keep-in-dom'?: Booleanish;
346
+ 'max-cached'?: number | string;
347
+ 'swipe-gesture'?: boolean | 'true' | 'false' | 'auto';
348
+ };
349
+ 'cap-page': CapElementAttributes & {
350
+ 'cache-scroll'?: Booleanish;
351
+ 'data-direction'?: 'forward' | 'back' | 'root' | 'none';
352
+ };
353
+ 'cap-header': CapElementAttributes & {
354
+ translucent?: Booleanish;
355
+ collapse?: string;
356
+ };
357
+ 'cap-content': CapElementAttributes & {
358
+ fullscreen?: Booleanish;
359
+ 'scroll-x'?: Booleanish;
360
+ 'scroll-y'?: Booleanish;
361
+ };
362
+ 'cap-footer': CapElementAttributes & {
363
+ translucent?: Booleanish;
364
+ };
365
+ }
366
+ declare global {
367
+ namespace JSX {
368
+ interface IntrinsicElements {
369
+ 'cap-router-outlet': CapTransitionsIntrinsicElements['cap-router-outlet'];
370
+ 'cap-page': CapTransitionsIntrinsicElements['cap-page'];
371
+ 'cap-header': CapTransitionsIntrinsicElements['cap-header'];
372
+ 'cap-content': CapTransitionsIntrinsicElements['cap-content'];
373
+ 'cap-footer': CapTransitionsIntrinsicElements['cap-footer'];
374
+ }
375
+ }
376
+ }
377
+ declare module 'react' {
378
+ namespace JSX {
379
+ interface IntrinsicElements {
380
+ 'cap-router-outlet': CapTransitionsIntrinsicElements['cap-router-outlet'];
381
+ 'cap-page': CapTransitionsIntrinsicElements['cap-page'];
382
+ 'cap-header': CapTransitionsIntrinsicElements['cap-header'];
383
+ 'cap-content': CapTransitionsIntrinsicElements['cap-content'];
384
+ 'cap-footer': CapTransitionsIntrinsicElements['cap-footer'];
385
+ }
386
+ }
387
+ }
388
+ declare module 'react/jsx-runtime' {
389
+ namespace JSX {
390
+ interface IntrinsicElements {
391
+ 'cap-router-outlet': CapTransitionsIntrinsicElements['cap-router-outlet'];
392
+ 'cap-page': CapTransitionsIntrinsicElements['cap-page'];
393
+ 'cap-header': CapTransitionsIntrinsicElements['cap-header'];
394
+ 'cap-content': CapTransitionsIntrinsicElements['cap-content'];
395
+ 'cap-footer': CapTransitionsIntrinsicElements['cap-footer'];
396
+ }
397
+ }
398
+ }
399
+
400
+ export { type NavigationEvent, type SwipeGestureOption, TransitionController, type TransitionDirection, type TransitionGlobalConfig, createTransitionNavigate, getController, getDirection, initTransitions, setDirection, setupPage, setupRouterOutlet };