https://github.com/lemoncloud-io/page-transition
iOS/Android style page transitions for React, Vue, and Angular using View Transitions API
https://github.com/lemoncloud-io/page-transition
android angular animations capacitor cordova hybrid-apps ionic ios mobile page-transitions react react-native react-router typescript view-transitions-api vue vue-router webview
Last synced: 3 months ago
JSON representation
iOS/Android style page transitions for React, Vue, and Angular using View Transitions API
- Host: GitHub
- URL: https://github.com/lemoncloud-io/page-transition
- Owner: lemoncloud-io
- License: mit
- Created: 2026-03-17T04:44:16.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-03-25T07:09:32.000Z (3 months ago)
- Last Synced: 2026-03-26T11:44:51.980Z (3 months ago)
- Topics: android, angular, animations, capacitor, cordova, hybrid-apps, ionic, ios, mobile, page-transitions, react, react-native, react-router, typescript, view-transitions-api, vue, vue-router, webview
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/@lemoncloud/react-page-transition
- Size: 5.09 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Page Transition
[](https://opensource.org/licenses/MIT)
[](https://www.typescriptlang.org/)
**iOS/Android-style page transitions using the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API).**
Built for hybrid mobile apps that need native-feeling navigation in WebView.
| iOS Style | Android Style |
|:---------:|:-------------:|
|  |  |
| Horizontal slide (350ms) | Vertical lift (450ms) |
## Features
- iOS/Android platform auto-detection
- Multiple animation types (slide, lift, fade, zoom)
- Customizable via CSS custom properties (`--pt-*`)
- Per-navigation timing override (duration, easing)
- Promise-based navigation
- SSR safe
- Zero dependencies (except framework peer deps)
## Packages
| Package | Version | Size | Description |
|---------|---------|------|-------------|
| [@lemoncloud/react-page-transition](./packages/react) | [](https://www.npmjs.com/package/@lemoncloud/react-page-transition) | [](https://bundlephobia.com/package/@lemoncloud/react-page-transition) | React hooks |
| [@lemoncloud/vue-page-transition](./packages/vue) | [](https://www.npmjs.com/package/@lemoncloud/vue-page-transition) | [](https://bundlephobia.com/package/@lemoncloud/vue-page-transition) | Vue composables |
| [@lemoncloud/page-transition-core](./packages/core) | [](https://www.npmjs.com/package/@lemoncloud/page-transition-core) | [](https://bundlephobia.com/package/@lemoncloud/page-transition-core) | Core + CSS |
> **Angular 17+:** Uses built-in `withViewTransitions()`. Only needs CSS from core package.
## Quick Start
### React
```bash
npm install @lemoncloud/react-page-transition
```
```tsx
// main.tsx
import '@lemoncloud/page-transition-core/styles.css';
import { useNavigateWithTransition } from '@lemoncloud/react-page-transition';
function MyComponent() {
const navigate = useNavigateWithTransition();
return (
<>
navigate('/settings')}>Settings
navigate(-1)}>Back
>
);
}
```
### Vue
```bash
npm install @lemoncloud/vue-page-transition
```
```vue
import '@lemoncloud/page-transition-core/styles.css';
import { useNavigateWithTransition } from '@lemoncloud/vue-page-transition';
const { navigate, goBack } = useNavigateWithTransition();
Settings
Back
```
### Angular
```bash
npm install @lemoncloud/page-transition-core
```
```typescript
// main.ts
import { provideRouter, withViewTransitions } from '@angular/router';
bootstrapApplication(AppComponent, {
providers: [provideRouter(routes, withViewTransitions())]
});
```
```json
// angular.json - add to styles array
"styles": [
"node_modules/@lemoncloud/page-transition-core/dist/styles.css",
"src/styles.css"
]
```
## API
```ts
const navigate = useNavigateWithTransition({
platform?: 'ios' | 'android' | 'auto', // default: 'auto'
detectPlatform?: () => 'ios' | 'android' | undefined
});
// Navigation
navigate('/path'); // Forward
navigate(-1); // Back
navigate('/home', { direction: 'back' }); // Path with back animation
navigate('/modal', { animation: 'fade' }); // Custom animation
navigate('/tab', { replace: true }); // No transition (tab switch)
// Per-navigation customization
navigate('/modal', {
animation: 'fade',
customization: { duration: 500, easing: 'ease-in-out' }
});
```
### Animation Types
| Type | Duration | Use Case |
|------|----------|----------|
| `slide` | 350ms | iOS default - horizontal |
| `lift` | 450ms | Android default - vertical |
| `fade` | 350ms | Modals, overlays |
| `zoom` | 350ms | Galleries, images |
| `none` | 0ms | Instant switch |
## Customization
### CSS Custom Properties
Override default animation timings globally via CSS variables:
```css
:root {
/* iOS Slide */
--pt-slide-duration: 500ms;
--pt-slide-easing: ease-in-out;
/* Android Lift */
--pt-lift-duration: 500ms;
--pt-lift-easing: ease-out;
/* Fade */
--pt-fade-duration: 500ms;
--pt-fade-easing: ease-in-out;
/* Zoom */
--pt-zoom-duration: 500ms;
--pt-zoom-easing: ease-in-out;
}
```
### Per-Navigation Override
Override timing for a single navigation via the `customization` option:
```tsx
// React
navigate('/modal', {
animation: 'fade',
customization: { duration: 500, easing: 'ease-in-out' }
});
```
```vue
navigate('/modal', {
animation: 'fade',
customization: { duration: 500, easing: 'ease-in-out' }
});
```
### CSS Variable Reference
| Variable | Default | Description |
|----------|---------|-------------|
| `--pt-slide-duration` | `350ms` | iOS slide animation duration |
| `--pt-slide-easing` | `cubic-bezier(0.32, 0.72, 0, 1)` | iOS slide easing |
| `--pt-lift-duration` | `450ms` | Android lift animation duration |
| `--pt-lift-easing` | `cubic-bezier(0.2, 0, 0, 1)` | Android lift easing (MD3 Emphasized) |
| `--pt-fade-duration` | `350ms` | Fade animation duration |
| `--pt-fade-easing` | `cubic-bezier(0.42, 0, 0.58, 1)` | Fade easing (ease-in-out) |
| `--pt-zoom-duration` | `350ms` | Zoom animation duration |
| `--pt-zoom-easing` | `cubic-bezier(0.32, 0.72, 0, 1)` | Zoom easing (iOS spring) |
## Browser Support
| Browser | Version |
|---------|---------|
| Chrome | 111+ |
| Edge | 111+ |
| Safari | 18+ |
| Firefox | 133+ |
Unsupported browsers fall back to instant navigation (no animation).
## Development
```bash
pnpm install
pnpm build # Build all packages
pnpm dev # Watch mode
pnpm test # Run tests (42 tests)
```
### Examples
```bash
pnpm --filter @example/basic dev # React - localhost:3000
pnpm --filter @example/vue dev # Vue - localhost:3001
pnpm --filter @example/angular dev # Angular - localhost:4200
```
## Contributing
1. Fork the repository
2. Create feature branch (`git checkout -b feature/amazing`)
3. Commit changes (`git commit -m 'feat: add amazing feature'`)
4. Push (`git push origin feature/amazing`)
5. Open Pull Request
## License
MIT © [LemonCloud](https://lemoncloud.io)