105 lines
4.9 KiB
Markdown
105 lines
4.9 KiB
Markdown
# Native Vue Router
|
|
|
|
Native Vue Router is a gesture-first navigation runtime for Vue 3 and Vue Router 5. It keeps Vue Router in charge of matching, URLs, guards, and history while rendering live route stacks that can be manipulated interactively.
|
|
|
|
The repository includes a reusable headless core, a platform-adaptive visual preset, Capacitor and Electron adapters, and one messaging demo delivered as a PWA and through native hosts.
|
|
|
|
## What works
|
|
|
|
- Interactive edge pop that can be held indefinitely at any progress.
|
|
- Ordered horizontal route paging with replace-by-default history.
|
|
- Component-originated route dragging with a live target route.
|
|
- Interactive push, adjacent-page sibling slide, modal, sheet, fade, and application-defined presentations.
|
|
- Concurrent `from` and `to` routes using only public Vue Router 5 APIs.
|
|
- Guarded commits: previews do not alter the URL, and rejected navigation springs back.
|
|
- Cold-start predictive back through declared parent routes.
|
|
- Bounded live view caching, nested router views, focus isolation, RTL, and reduced motion.
|
|
- PWA, Electron, and Capacitor iOS/Android hosts.
|
|
|
|
## Run it
|
|
|
|
```bash
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
The default app is the installable messaging PWA. Other useful commands:
|
|
|
|
```bash
|
|
npm run build # packages, declarations, demo, and service worker
|
|
npm test # core transaction tests
|
|
npm run test:e2e # desktop and mobile Playwright projects
|
|
npm run pwa:preview # production PWA on every local network interface
|
|
npm run electron # build and launch the Electron host
|
|
npm run cap:sync # build and synchronize iOS and Android projects
|
|
```
|
|
|
|
Native projects live under `apps/capacitor/ios` and `apps/capacitor/android`. Open or run them from `apps/capacitor` with `npx cap open ios`, `npx cap open android`, or `npx cap run <platform>`.
|
|
|
|
### Test the installed iOS PWA
|
|
|
|
Build and serve the production app with `npm run pwa:preview`, expose it through an HTTPS URL, and open that URL on the iPhone. Safari requires a secure context for the service worker; a plain LAN `http://` address is not sufficient. Choose **Share → Add to Home Screen**, then launch **NVR Messenger** from its Home Screen icon.
|
|
|
|
The Navigation Lab reports `Standalone`, `ready`, and `App reserved` when the correct environment is active. Open a conversation and drag from the extreme left edge. The “Leading-edge touches claimed” counter should increment while the router renders its live predictive-back view.
|
|
|
|
An installed web app cannot access `WKWebView.allowsBackForwardNavigationGestures`. The demo therefore reserves leading-edge touch sequences at the web-content boundary as an iOS standalone-only safeguard. Capacitor remains the deterministic option when native-level gesture suppression is required.
|
|
|
|
## Minimal integration
|
|
|
|
```ts
|
|
import { createApp } from 'vue'
|
|
import { createRouter, createWebHistory } from 'vue-router'
|
|
import { createNativeRouter } from '@native-vue-router/core'
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(),
|
|
routes: [
|
|
{ path: '/', component: Home },
|
|
{
|
|
path: '/chat/:id',
|
|
component: Chat,
|
|
meta: {
|
|
native: { presentation: 'push', parent: '/', gesture: 'edge' },
|
|
},
|
|
},
|
|
],
|
|
})
|
|
|
|
const nativeRouter = createNativeRouter({ router })
|
|
createApp(App).use(router).use(nativeRouter).mount('#app')
|
|
```
|
|
|
|
```vue
|
|
<script setup lang="ts">
|
|
import { NativeGestureLink, NativeNavigator, NativeRouterView } from '@native-vue-router/core'
|
|
</script>
|
|
|
|
<template>
|
|
<NativeNavigator :siblings="['/', '/stories', '/profile']">
|
|
<NativeRouterView />
|
|
</NativeNavigator>
|
|
<NativeGestureLink to="/chat/maya" presentation="reveal">
|
|
Drag this row into the chat route
|
|
</NativeGestureLink>
|
|
</template>
|
|
```
|
|
|
|
Import `@native-vue-router/core/style.css` for the built-in presentation layers. The demo imports `@native-vue-router/preset-native/style.css` as well.
|
|
|
|
Use `nativeRouter.sibling(to)` for tab or peer-route navigation. Direction is derived from `siblingOrder`, repeated navigation to the active route is a no-op, and `siblingHistory: 'replace'` keeps cached tab views out of the back stack.
|
|
|
|
## Packages
|
|
|
|
- `@native-vue-router/core` — transactions, route ledger, concurrent views, gestures, caching, and public components/composables.
|
|
- `@native-vue-router/preset-native` — adaptive tab/back controls, safe-area CSS, and platform motion defaults.
|
|
- `@native-vue-router/capacitor` — hardware back, deep links, pause cancellation, root exit, and haptics.
|
|
- `@native-vue-router/electron` — Chromium history-gesture suppression and renderer back/forward bridging.
|
|
|
|
See [architecture](docs/architecture.md) and [platform integration](docs/platforms.md) for the transaction lifecycle and host-specific behavior.
|
|
|
|
## Support contract
|
|
|
|
The target is Vue 3.5+ and Vue Router 5. Installed PWAs, current Electron, and Capacitor 8 are first-class. Normal browser tabs remain functional but browsers can reserve edge gestures that page content cannot consistently override.
|
|
|
|
MIT
|