{"id":47664066,"url":"https://github.com/lemoncloud-io/page-transition","last_synced_at":"2026-04-02T11:48:46.753Z","repository":{"id":345185255,"uuid":"1183929810","full_name":"lemoncloud-io/page-transition","owner":"lemoncloud-io","description":"iOS/Android style page transitions for React, Vue, and Angular using View Transitions API","archived":false,"fork":false,"pushed_at":"2026-03-25T07:09:32.000Z","size":5338,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-26T11:44:51.980Z","etag":null,"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"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@lemoncloud/react-page-transition","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lemoncloud-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-17T04:44:16.000Z","updated_at":"2026-03-25T07:09:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lemoncloud-io/page-transition","commit_stats":null,"previous_names":["lemoncloud-io/page-transition"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/lemoncloud-io/page-transition","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemoncloud-io%2Fpage-transition","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemoncloud-io%2Fpage-transition/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemoncloud-io%2Fpage-transition/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemoncloud-io%2Fpage-transition/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lemoncloud-io","download_url":"https://codeload.github.com/lemoncloud-io/page-transition/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lemoncloud-io%2Fpage-transition/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31305809,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T09:48:21.550Z","status":"ssl_error","status_checked_at":"2026-04-02T09:48:19.196Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["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"],"created_at":"2026-04-02T11:48:46.605Z","updated_at":"2026-04-02T11:48:46.746Z","avatar_url":"https://github.com/lemoncloud-io.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Page Transition\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178C6?logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n\n**iOS/Android-style page transitions using the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API).**\nBuilt for hybrid mobile apps that need native-feeling navigation in WebView.\n\n| iOS Style | Android Style |\n|:---------:|:-------------:|\n| ![iOS](https://raw.githubusercontent.com/lemoncloud-io/page-transition/main/.github/ios.gif) | ![Android](https://raw.githubusercontent.com/lemoncloud-io/page-transition/main/.github/android.gif) |\n| Horizontal slide (350ms) | Vertical lift (450ms) |\n\n## Features\n\n- iOS/Android platform auto-detection\n- Multiple animation types (slide, lift, fade, zoom)\n- Customizable via CSS custom properties (`--pt-*`)\n- Per-navigation timing override (duration, easing)\n- Promise-based navigation\n- SSR safe\n- Zero dependencies (except framework peer deps)\n\n## Packages\n\n| Package | Version | Size | Description |\n|---------|---------|------|-------------|\n| [@lemoncloud/react-page-transition](./packages/react) | [![npm](https://img.shields.io/npm/v/@lemoncloud/react-page-transition.svg)](https://www.npmjs.com/package/@lemoncloud/react-page-transition) | [![size](https://img.shields.io/bundlephobia/minzip/@lemoncloud/react-page-transition)](https://bundlephobia.com/package/@lemoncloud/react-page-transition) | React hooks |\n| [@lemoncloud/vue-page-transition](./packages/vue) | [![npm](https://img.shields.io/npm/v/@lemoncloud/vue-page-transition.svg)](https://www.npmjs.com/package/@lemoncloud/vue-page-transition) | [![size](https://img.shields.io/bundlephobia/minzip/@lemoncloud/vue-page-transition)](https://bundlephobia.com/package/@lemoncloud/vue-page-transition) | Vue composables |\n| [@lemoncloud/page-transition-core](./packages/core) | [![npm](https://img.shields.io/npm/v/@lemoncloud/page-transition-core.svg)](https://www.npmjs.com/package/@lemoncloud/page-transition-core) | [![size](https://img.shields.io/bundlephobia/minzip/@lemoncloud/page-transition-core)](https://bundlephobia.com/package/@lemoncloud/page-transition-core) | Core + CSS |\n\n\u003e **Angular 17+:** Uses built-in `withViewTransitions()`. Only needs CSS from core package.\n\n## Quick Start\n\n### React\n\n```bash\nnpm install @lemoncloud/react-page-transition\n```\n\n```tsx\n// main.tsx\nimport '@lemoncloud/page-transition-core/styles.css';\nimport { useNavigateWithTransition } from '@lemoncloud/react-page-transition';\n\nfunction MyComponent() {\n    const navigate = useNavigateWithTransition();\n\n    return (\n        \u003c\u003e\n            \u003cbutton onClick={() =\u003e navigate('/settings')}\u003eSettings\u003c/button\u003e\n            \u003cbutton onClick={() =\u003e navigate(-1)}\u003eBack\u003c/button\u003e\n        \u003c/\u003e\n    );\n}\n```\n\n### Vue\n\n```bash\nnpm install @lemoncloud/vue-page-transition\n```\n\n```vue\n\u003cscript setup lang=\"ts\"\u003e\nimport '@lemoncloud/page-transition-core/styles.css';\nimport { useNavigateWithTransition } from '@lemoncloud/vue-page-transition';\n\nconst { navigate, goBack } = useNavigateWithTransition();\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n    \u003cbutton @click=\"navigate('/settings')\"\u003eSettings\u003c/button\u003e\n    \u003cbutton @click=\"goBack()\"\u003eBack\u003c/button\u003e\n\u003c/template\u003e\n```\n\n### Angular\n\n```bash\nnpm install @lemoncloud/page-transition-core\n```\n\n```typescript\n// main.ts\nimport { provideRouter, withViewTransitions } from '@angular/router';\n\nbootstrapApplication(AppComponent, {\n    providers: [provideRouter(routes, withViewTransitions())]\n});\n```\n\n```json\n// angular.json - add to styles array\n\"styles\": [\n    \"node_modules/@lemoncloud/page-transition-core/dist/styles.css\",\n    \"src/styles.css\"\n]\n```\n\n## API\n\n```ts\nconst navigate = useNavigateWithTransition({\n    platform?: 'ios' | 'android' | 'auto',  // default: 'auto'\n    detectPlatform?: () =\u003e 'ios' | 'android' | undefined\n});\n\n// Navigation\nnavigate('/path');                          // Forward\nnavigate(-1);                               // Back\nnavigate('/home', { direction: 'back' });   // Path with back animation\nnavigate('/modal', { animation: 'fade' });  // Custom animation\nnavigate('/tab', { replace: true });        // No transition (tab switch)\n\n// Per-navigation customization\nnavigate('/modal', {\n    animation: 'fade',\n    customization: { duration: 500, easing: 'ease-in-out' }\n});\n```\n\n### Animation Types\n\n| Type | Duration | Use Case |\n|------|----------|----------|\n| `slide` | 350ms | iOS default - horizontal |\n| `lift` | 450ms | Android default - vertical |\n| `fade` | 350ms | Modals, overlays |\n| `zoom` | 350ms | Galleries, images |\n| `none` | 0ms | Instant switch |\n\n## Customization\n\n### CSS Custom Properties\n\nOverride default animation timings globally via CSS variables:\n\n```css\n:root {\n    /* iOS Slide */\n    --pt-slide-duration: 500ms;\n    --pt-slide-easing: ease-in-out;\n\n    /* Android Lift */\n    --pt-lift-duration: 500ms;\n    --pt-lift-easing: ease-out;\n\n    /* Fade */\n    --pt-fade-duration: 500ms;\n    --pt-fade-easing: ease-in-out;\n\n    /* Zoom */\n    --pt-zoom-duration: 500ms;\n    --pt-zoom-easing: ease-in-out;\n}\n```\n\n### Per-Navigation Override\n\nOverride timing for a single navigation via the `customization` option:\n\n```tsx\n// React\nnavigate('/modal', {\n    animation: 'fade',\n    customization: { duration: 500, easing: 'ease-in-out' }\n});\n```\n\n```vue\n\u003c!-- Vue --\u003e\n\u003cscript setup\u003e\nnavigate('/modal', {\n    animation: 'fade',\n    customization: { duration: 500, easing: 'ease-in-out' }\n});\n\u003c/script\u003e\n```\n\n### CSS Variable Reference\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `--pt-slide-duration` | `350ms` | iOS slide animation duration |\n| `--pt-slide-easing` | `cubic-bezier(0.32, 0.72, 0, 1)` | iOS slide easing |\n| `--pt-lift-duration` | `450ms` | Android lift animation duration |\n| `--pt-lift-easing` | `cubic-bezier(0.2, 0, 0, 1)` | Android lift easing (MD3 Emphasized) |\n| `--pt-fade-duration` | `350ms` | Fade animation duration |\n| `--pt-fade-easing` | `cubic-bezier(0.42, 0, 0.58, 1)` | Fade easing (ease-in-out) |\n| `--pt-zoom-duration` | `350ms` | Zoom animation duration |\n| `--pt-zoom-easing` | `cubic-bezier(0.32, 0.72, 0, 1)` | Zoom easing (iOS spring) |\n\n## Browser Support\n\n| Browser | Version |\n|---------|---------|\n| Chrome | 111+ |\n| Edge | 111+ |\n| Safari | 18+ |\n| Firefox | 133+ |\n\nUnsupported browsers fall back to instant navigation (no animation).\n\n## Development\n\n```bash\npnpm install\npnpm build        # Build all packages\npnpm dev          # Watch mode\npnpm test         # Run tests (42 tests)\n```\n\n### Examples\n\n```bash\npnpm --filter @example/basic dev    # React - localhost:3000\npnpm --filter @example/vue dev      # Vue - localhost:3001\npnpm --filter @example/angular dev  # Angular - localhost:4200\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create feature branch (`git checkout -b feature/amazing`)\n3. Commit changes (`git commit -m 'feat: add amazing feature'`)\n4. Push (`git push origin feature/amazing`)\n5. Open Pull Request\n\n## License\n\nMIT © [LemonCloud](https://lemoncloud.io)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flemoncloud-io%2Fpage-transition","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flemoncloud-io%2Fpage-transition","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flemoncloud-io%2Fpage-transition/lists"}