@virtualstate/navigation
Version:
Native JavaScript [navigation](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API) implementation
93 lines • 3.23 kB
JavaScript
import { NavigationLocation, AppLocationAwaitFinished, AppLocationTransitionURL, } from "./location.js";
import { InvalidStateError } from "./navigation-errors.js";
const State = Symbol.for("@virtualstate/navigation/history/state");
/**
* @experimental
*/
export class NavigationHistory extends NavigationLocation {
#options;
#navigation;
constructor(options) {
super(options);
this.#options = options;
this.#navigation = options.navigation;
}
get length() {
return this.#navigation.entries().length;
}
scrollRestoration = "manual";
get state() {
const currentState = this.#navigation.currentEntry?.getState();
if (typeof currentState === "string" || typeof currentState === "number" || typeof currentState === "boolean") {
return currentState;
}
return this.#options[State] ?? undefined;
}
back() {
const entries = this.#navigation.entries();
const index = this.#navigation.currentEntry?.index ?? -1;
const back = entries[index - 1];
const url = back?.url;
if (!url)
throw new InvalidStateError("Cannot go back");
return this[AppLocationTransitionURL](url, () => this.#navigation.back());
}
forward() {
const entries = this.#navigation.entries();
const index = this.#navigation.currentEntry?.index ?? -1;
const forward = entries[index + 1];
const url = forward?.url;
if (!url)
throw new InvalidStateError("Cannot go forward");
return this[AppLocationTransitionURL](url, () => this.#navigation.forward());
}
go(delta) {
if (typeof delta !== "number" || delta === 0 || isNaN(delta)) {
return this[AppLocationAwaitFinished](this.#navigation.reload());
}
const entries = this.#navigation.entries();
const { currentEntry } = this.#navigation;
if (!currentEntry) {
throw new Error(`Could not go ${delta}`);
}
const nextIndex = currentEntry.index + delta;
const nextEntry = entries[nextIndex];
if (!nextEntry) {
throw new Error(`Could not go ${delta}`);
}
const nextEntryKey = nextEntry.key;
return this[AppLocationAwaitFinished](this.#navigation.traverseTo(nextEntryKey));
}
replaceState(data, unused, url) {
if (url) {
return this[AppLocationTransitionURL](url, (url) => this.#navigation.navigate(url.toString(), {
state: data,
history: "replace",
}));
}
else {
return this.#navigation.updateCurrentEntry({
state: data
});
}
}
pushState(data, unused, url) {
if (url) {
return this[AppLocationTransitionURL](url, (url) => this.#navigation.navigate(url.toString(), {
state: data,
}));
}
else {
return this.#navigation.updateCurrentEntry({
state: data,
});
}
}
}
/**
* @experimental
* @internal
*/
export class NavigationSync extends NavigationHistory {
}
//# sourceMappingURL=history.js.map