eddev 2.0.0-beta.27 → 2.0.0-beta.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ import { ReactNode } from "react";
2
+ import { RouteState } from "../types";
3
+ type BackButtonProps = {
4
+ /**
5
+ * An optional matching function, which will stop the render button from appearing unless the function returns true.
6
+ *
7
+ * The below example will only render a back button if the last route was a project archive.
8
+ *
9
+ * eg. `filter={(route) => route.view === 'archive-projects'}`
10
+ *
11
+ * @param route The last route in the history stack.
12
+ */
13
+ filter?: (route: RouteState) => boolean;
14
+ /**
15
+ * An optional href, which will be used if no back route is found.
16
+ *
17
+ * When used, the back button will always render.
18
+ */
19
+ fallbackHref?: string;
20
+ /**
21
+ * A function to render the back button, if one should be rendered.
22
+ *
23
+ * Receives a `route` prop to further inspect the route, and an `onClick` function to navigate back.
24
+ *
25
+ * @param props
26
+ * @returns
27
+ */
28
+ render: (props: {
29
+ route: RouteState;
30
+ onClick: (e?: any) => void;
31
+ }) => ReactNode;
32
+ };
33
+ /**
34
+ * Display a back button that will navigate to the previous page in the router's history.
35
+ *
36
+ * This will allow you to render a back button on the condition that the back button will not send the user to a different website.
37
+ */
38
+ export declare function BackButton(props: BackButtonProps): ReactNode;
39
+ export {};
@@ -0,0 +1,45 @@
1
+ import { useMemo } from "react";
2
+ import { useRouter } from "../hooks/useRouter";
3
+ import { useRouterState } from "../hooks/useRouterState";
4
+ import { getLinkHandlerMode } from "../utils";
5
+ import { useRoute } from "../hooks/useRoute";
6
+ /**
7
+ * Display a back button that will navigate to the previous page in the router's history.
8
+ *
9
+ * This will allow you to render a back button on the condition that the back button will not send the user to a different website.
10
+ */
11
+ export function BackButton(props) {
12
+ const router = useRouter();
13
+ const route = useRoute();
14
+ const prevRoute = useRouterState((state) => state.history[state.history.length - 2]);
15
+ const backAction = useMemo(() => {
16
+ if (prevRoute && (!props.filter || props.filter(prevRoute))) {
17
+ return (e) => {
18
+ const { mode } = getLinkHandlerMode(e, prevRoute.uri);
19
+ if (mode === "navigate") {
20
+ e.preventDefault();
21
+ history.back();
22
+ // history.length
23
+ }
24
+ else if (mode === "ignore") {
25
+ e.preventDefault();
26
+ }
27
+ };
28
+ }
29
+ else if (props.fallbackHref) {
30
+ return (e) => {
31
+ const { mode } = getLinkHandlerMode(e, props.fallbackHref);
32
+ if (mode === "navigate") {
33
+ e.preventDefault();
34
+ router.navigate(props.fallbackHref);
35
+ }
36
+ else if (mode === "ignore") {
37
+ e.preventDefault();
38
+ }
39
+ };
40
+ }
41
+ }, [route, props.filter, props.fallbackHref]);
42
+ if (backAction) {
43
+ return props.render ? props.render({ route: prevRoute, onClick: backAction }) : null;
44
+ }
45
+ }
@@ -28,6 +28,7 @@ if (env.client && !env.admin) {
28
28
  tags: initialData.meta?.head,
29
29
  },
30
30
  });
31
+ history.replaceState(historyStateForRoute(initialRoute), "", document.location.href);
31
32
  $routeMetaStore.data = getRouteMeta(initialData);
32
33
  }
33
34
  function parseHrefPath(url) {
@@ -120,6 +121,7 @@ export function BrowserRouter(props) {
120
121
  }
121
122
  internals.poppedState = (href, data) => {
122
123
  const stack = state.history;
124
+ console.log("Popped state", stack);
123
125
  // Is the route in our history stack? (going back)
124
126
  const index = stack.findIndex((item) => item.id === data.id);
125
127
  if (index >= 0) {
@@ -330,6 +332,39 @@ export function BrowserRouter(props) {
330
332
  }
331
333
  },
332
334
  emitEvent,
335
+ restoreRoute(route) {
336
+ const stack = state.history;
337
+ // Is the route in our history stack? (going back)
338
+ const index = stack.findIndex((item) => item.id === route.id);
339
+ if (index >= 0) {
340
+ return doRouteTransition({
341
+ url: route.uri,
342
+ route,
343
+ goingBack: true,
344
+ history: stack.slice(0, index),
345
+ restoreState: route.returnState,
346
+ shouldPush: false,
347
+ });
348
+ }
349
+ // Is the route in our history _cache_? (probably going forward)
350
+ if (historyCache.has(route.id)) {
351
+ return doRouteTransition({
352
+ url: route.uri,
353
+ route,
354
+ goingBack: false,
355
+ history: stack,
356
+ restoreState: route.returnState,
357
+ shouldPush: false,
358
+ });
359
+ }
360
+ return doRouteTransition({
361
+ url: route.uri,
362
+ goingBack: false,
363
+ history: stack,
364
+ restoreState: route.returnState,
365
+ shouldPush: false,
366
+ });
367
+ },
333
368
  };
334
369
  return {
335
370
  api,
@@ -358,6 +393,7 @@ export function BrowserRouter(props) {
358
393
  // Handle popState
359
394
  // const router = useRouterStore.getState()
360
395
  const onPopState = (e) => {
396
+ console.log("Popped", e.state);
361
397
  internals.poppedState?.(document.location.href, e.state ?? {});
362
398
  };
363
399
  window.addEventListener("popstate", onPopState);
@@ -29,6 +29,7 @@ export const RouterContext = createContext({
29
29
  getState() {
30
30
  return null;
31
31
  },
32
+ restoreRoute(route) { },
32
33
  });
33
34
  export const RouterStateContext = createContext({
34
35
  history: [NOOP_ROUTE],
@@ -3,6 +3,7 @@ export * from "./components/Link.js";
3
3
  export * from "./components/ScrollRestoration.js";
4
4
  export * from "./components/RouteRenderer.js";
5
5
  export * from "./components/ClientOnly.js";
6
+ export * from "./components/BackButton.js";
6
7
  export * from "./hooks/useRoute.js";
7
8
  export * from "./hooks/useRouteTransition.js";
8
9
  export * from "./hooks/useRouter.js";
@@ -3,6 +3,7 @@ export * from "./components/Link.js";
3
3
  export * from "./components/ScrollRestoration.js";
4
4
  export * from "./components/RouteRenderer.js";
5
5
  export * from "./components/ClientOnly.js";
6
+ export * from "./components/BackButton.js";
6
7
  export * from "./hooks/useRoute.js";
7
8
  export * from "./hooks/useRouteTransition.js";
8
9
  export * from "./hooks/useRouter.js";
@@ -111,6 +111,8 @@ export type RouterAPI = {
111
111
  emitEvent: (event: RouterEvent) => void;
112
112
  /** Returns the current RouterState */
113
113
  getState: () => RouterAPIState | null;
114
+ /** Go back to a previous route in the history stack, or push it onto the stack if it isn't currently on the stack. */
115
+ restoreRoute: (route: RouteState) => void;
114
116
  };
115
117
  export type TypedRouteState<T, TProps> = {
116
118
  /** A unique ID, representing this history item. */
@@ -1 +1 @@
1
- export declare const VERSION = "2.0.0-beta.27";
1
+ export declare const VERSION = "2.0.0-beta.28";
@@ -1 +1 @@
1
- export const VERSION = "2.0.0-beta.27";
1
+ export const VERSION = "2.0.0-beta.28";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eddev",
3
- "version": "2.0.0-beta.27",
3
+ "version": "2.0.0-beta.28",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",