v1.0.1-alpha.95
Repository
Current version released
3 years ago
Versions
@virtualstate/navigation
Native JavaScript navigation implementation
Support
Test Coverage
Install
Skypack
const { Navigation } = await import("https://cdn.skypack.dev/@virtualstate/navigation");
Or
import { Navigation } from "https://cdn.skypack.dev/@virtualstate/navigation";
npm / yarn / GitHub
npm i --save @virtualstate/navigation
Or
yarn add @virtualstate/navigation
Then
import { Navigation } from "@virtualstate/navigation";
Navigation
import { Navigation } from "@virtualstate/navigation";
const navigation = new Navigation();
// Set initial url
navigation.navigate("/");
navigation.navigate("/skipped");
// Use .finished to wait for the transition to complete
await navigation.navigate("/awaited").finished;
Waiting for events
import { Navigation } from "@virtualstate/navigation";
const navigation = new Navigation();
navigation.addEventListener("navigate", async ({ destination }) => {
if (destination.url === "/disallow") {
throw new Error("No!");
}
});
await navigation.navigate("/allowed").finished; // Resolves
await navigation.navigate("/disallow").finished; // Rejects
Transitions
import { Navigation } from "@virtualstate/navigation";
import { loadPhotoIntoCache } from "./cache";
const navigation = new Navigation();
navigation.addEventListener("navigate", async ({ destination, transitionWhile }) => {
transitionWhile(loadPhotoIntoCache(destination.url));
});
URLPattern
You can match destination.url
using URLPattern
import {Navigation} from "@virtualstate/navigation";
import {URLPattern} from "urlpattern-polyfill";
const navigation = new Navigation();
navigation.addEventListener("navigate", async ({destination, transitionWhile}) => {
const pattern = new URLPattern({ pathname: "/books/:id" });
const match = pattern.exec(destination.url);
if (match) {
transitionWhile(transition());
}
async function transition() {
console.log("load book", match.pathname.groups.id)
}
});
navigation.navigate("/book/1");
State
import { Navigation } from "@virtualstate/navigation";
const navigation = new Navigation();
navigation.addEventListener("currentchange", () => {
console.log({ updatedState: navigation.current?.getState() });
});
await navigation.updateCurrent({
state: {
items: [
"first",
"second"
],
index: 0
}
}).finished;
await navigation.updateCurrent({
state: {
...navigation.current.getState(),
index: 1
}
}).finished;
Updating browser url
This is a pending development task. The below code will help visually update the window
This can be achieved various ways, but if your application completely utilises
the app history interface, then you can directly use pushState
to immediately
update the window’s url.
This does not take into account the browser’s native back/forward functionality, which would need to be investigated further.
import { Navigation } from "@virtualstate/navigation";
const navigation = new Navigation();
const origin = typeof location === "undefined" ? "https://example.com" : location.origin;
navigation.addEventListener("currentchange", () => {
const { current } = navigation;
if (!current || !current.sameDocument) return;
const state = current.getState() ?? {};
const { pathname } = new URL(current.url, origin);
if (typeof window !== "undefined" && window.history) {
window.history.pushState(state, state.title, origin)
}
})