StackedRouter: new router simulates app behaviour #45
1 changed files with 25 additions and 10 deletions
|
@ -6,17 +6,18 @@ import {
|
|||
createRenderEffect,
|
||||
createUniqueId,
|
||||
Index,
|
||||
onMount,
|
||||
Show,
|
||||
untrack,
|
||||
useContext,
|
||||
type Accessor,
|
||||
} from "solid-js";
|
||||
import { createStore, unwrap } from "solid-js/store";
|
||||
import { insert, render } from "solid-js/web";
|
||||
import "./StackedRouter.css";
|
||||
import { animateSlideInFromRight, animateSlideOutToRight } from "./anim";
|
||||
import { ANIM_CURVE_DECELERATION, ANIM_CURVE_STD } from "../material/theme";
|
||||
import {
|
||||
makeEventListener,
|
||||
} from "@solid-primitives/event-listener";
|
||||
|
||||
export type StackedRouterProps = Omit<RouterProps, "url">;
|
||||
|
||||
|
@ -24,7 +25,6 @@ export type StackFrame = {
|
|||
path: string;
|
||||
rootId: string;
|
||||
state: unknown;
|
||||
beforeShow?: (element: HTMLElement) => void;
|
||||
};
|
||||
|
||||
export type NewFrameOptions<T> = (T extends undefined
|
||||
|
@ -141,10 +141,21 @@ const StackedRouter: Component<StackedRouterProps> = (oprops) => {
|
|||
state: opts?.state,
|
||||
rootId: createUniqueId(),
|
||||
};
|
||||
|
||||
mutStack(opts?.replace ? stack.length - 1 : stack.length, frame);
|
||||
if (opts?.replace) {
|
||||
window.history.replaceState(unwrap(stack), "", path);
|
||||
} else {
|
||||
window.history.pushState(unwrap(stack), "", path);
|
||||
}
|
||||
return frame;
|
||||
});
|
||||
|
||||
const onlyPopFrame = (depth: number) => {
|
||||
mutStack((o) => o.toSpliced(o.length - depth, depth));
|
||||
window.history.go(-depth);
|
||||
};
|
||||
|
||||
const popFrame = (depth: number = 1) =>
|
||||
untrack(() => {
|
||||
if (import.meta.env.DEV) {
|
||||
|
@ -157,14 +168,10 @@ const StackedRouter: Component<StackedRouterProps> = (oprops) => {
|
|||
const element = document.getElementById(lastFrame.rootId)!;
|
||||
requestAnimationFrame(() => {
|
||||
const animation = animateClose(element);
|
||||
animation.addEventListener("finish", () =>
|
||||
mutStack((o) => o.toSpliced(o.length - depth, depth)),
|
||||
);
|
||||
animation.addEventListener("finish", () => onlyPopFrame(depth));
|
||||
});
|
||||
} else {
|
||||
mutStack((o) => {
|
||||
return o.toSpliced(o.length - depth, depth);
|
||||
});
|
||||
onlyPopFrame(depth);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -175,10 +182,18 @@ const StackedRouter: Component<StackedRouterProps> = (oprops) => {
|
|||
|
||||
createRenderEffect(() => {
|
||||
if (stack.length === 0) {
|
||||
pushFrame("/", undefined);
|
||||
pushFrame(window.location.pathname);
|
||||
}
|
||||
});
|
||||
|
||||
createRenderEffect(() => {
|
||||
makeEventListener(window, "popstate", (event) => {
|
||||
if (event.state && stack.length !== event.state.length) {
|
||||
mutStack(event.state);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const onBeforeDialogMount = (element: HTMLDialogElement) => {
|
||||
createEffect(() => {
|
||||
requestAnimationFrame(() => {
|
||||
|
|
Loading…
Reference in a new issue