preact-hashish-router 0.0.7 → 0.0.8

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "preact-hashish-router",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "type": "module",
5
5
  "module": "dist/index.js",
6
6
  "description": "A simple router for preact",
@@ -37,7 +37,6 @@
37
37
  "vite": "^6.1.0"
38
38
  },
39
39
  "files": [
40
- "src",
41
40
  "dist",
42
41
  "LICENSE",
43
42
  "package.json",
package/src/A.tsx DELETED
@@ -1,32 +0,0 @@
1
- import { AnchorHTMLAttributes, forwardRef, MouseEventHandler, PropsWithChildren } from "preact/compat";
2
- import { useCallback, useMemo } from "preact/hooks";
3
- import { useRouter } from "./useRouter";
4
-
5
- export type AProps = PropsWithChildren & AnchorHTMLAttributes;
6
-
7
- export const A = forwardRef<HTMLAnchorElement, AProps>(({ href, className, ...props }) => {
8
- const router = useRouter();
9
-
10
- const isActive = useMemo(() => {
11
- return router.path === href;
12
- }, [router.path, href]);
13
-
14
- const browserRouterClickAnchorHandler: MouseEventHandler<HTMLAnchorElement> = useCallback(
15
- (e) => {
16
- e.preventDefault();
17
- e.stopPropagation();
18
- router.go(href.toString());
19
- },
20
- [router.type]
21
- );
22
-
23
- return (
24
- <a
25
- href={router.type === "browser" ? href : `#${href}`}
26
- className={className}
27
- data-route-active={isActive}
28
- {...props}
29
- onClick={router.type === "browser" ? browserRouterClickAnchorHandler : undefined}
30
- />
31
- );
32
- });
@@ -1,14 +0,0 @@
1
- import { PropsWithChildren, Suspense } from "preact/compat";
2
- import { useRouter } from "./useRouter";
3
-
4
- export function ErrorRoute(props: PropsWithChildren<{ lazy?: boolean }>) {
5
- const router = useRouter();
6
-
7
- if (router.itMatch) return null;
8
-
9
- if (props.lazy) {
10
- return <Suspense fallback={<div>Loading...</div>}>{props.children}</Suspense>;
11
- }
12
-
13
- return props.children;
14
- }
package/src/Route.tsx DELETED
@@ -1,27 +0,0 @@
1
- import { VNode } from "preact";
2
- import { PropsWithChildren, Suspense } from "preact/compat";
3
- import { useRouter } from "./useRouter";
4
-
5
- type RouteProps = PropsWithChildren & { path: string; exact?: boolean; lazy?: boolean; fallback?: VNode };
6
-
7
- export function Route(props: RouteProps) {
8
- const router = useRouter();
9
-
10
- if (props.exact === undefined) {
11
- props.exact = true;
12
- }
13
-
14
- if (props.exact && router.path !== props.path) {
15
- return null;
16
- } else if (!router.path.includes(props.path)) {
17
- return null;
18
- }
19
-
20
- router.setItMatch(true);
21
-
22
- if (props.lazy) {
23
- return <Suspense fallback={props.fallback ?? <div>Loading...</div>}>{props.children}</Suspense>;
24
- }
25
-
26
- return props.children;
27
- }
package/src/Router.tsx DELETED
@@ -1,86 +0,0 @@
1
- import { PropsWithChildren } from "preact/compat";
2
- import { useEffect, useMemo, useState } from "preact/hooks";
3
- import { RouterContext, router_context } from "./context";
4
-
5
- const get_hash_route = () => location.hash.slice(1) || "/";
6
-
7
- type RouterProps = PropsWithChildren & {
8
- type: RouterContext["type"];
9
- };
10
-
11
- export const Router = (props: RouterProps) => {
12
- const [path, setPath] = useState(get_hash_route());
13
- const [query, setQuery] = useState("");
14
- const [itMatch, setItMatch] = useState(false);
15
-
16
- const router_type = useMemo(() => {
17
- return props.type;
18
- }, [props.type]);
19
-
20
- const hashEffectHandler = {
21
- listener: () => {
22
- const [path, query] = get_hash_route().split("?");
23
- setQuery(query || "");
24
- setPath(path);
25
- setItMatch(false);
26
- },
27
- effect: () => {
28
- if (location.hash === "") location.hash = "/";
29
- window.addEventListener("hashchange", hashEffectHandler.listener);
30
- },
31
- cleanUp: () => {
32
- window.removeEventListener("hashchange", hashEffectHandler.listener);
33
- },
34
- };
35
-
36
- const browserEffectHandler = {
37
- listener: () => {
38
- setPath(location.pathname);
39
- setQuery(location.search || "");
40
- setItMatch(false);
41
- },
42
- effect: () => {
43
- window.addEventListener("popstate", browserEffectHandler.listener);
44
- },
45
- cleanUp: () => {
46
- window.removeEventListener("hashchange", browserEffectHandler.listener);
47
- },
48
- };
49
-
50
- useEffect(() => {
51
- if (router_type !== "hash") return;
52
- const [path, query] = get_hash_route().split("?");
53
- setQuery(query || "");
54
- setPath(path);
55
-
56
- hashEffectHandler.effect();
57
- return () => hashEffectHandler.cleanUp();
58
- }, []);
59
-
60
- useEffect(() => {
61
- if (router_type !== "browser") return;
62
- setPath(location.pathname);
63
- setQuery(location.search || "");
64
- browserEffectHandler.effect();
65
- return () => browserEffectHandler.cleanUp();
66
- }, []);
67
-
68
- const handlerManualRouteChange = (r: string) => {
69
- setPath(r);
70
- setItMatch(false);
71
- if (router_type === "hash") {
72
- location.hash = r;
73
- return;
74
- }
75
- if (router_type === "browser") {
76
- history.pushState(null, "", new URL(r, location.origin));
77
- return;
78
- }
79
- };
80
-
81
- const ProviderValue: RouterContext = useMemo(() => {
82
- return { path, go: handlerManualRouteChange, itMatch, setItMatch, type: router_type, query };
83
- }, [path, handlerManualRouteChange, itMatch, setItMatch, router_type]);
84
-
85
- return <router_context.Provider value={ProviderValue}>{props.children}</router_context.Provider>;
86
- };
@@ -1,24 +0,0 @@
1
- import { Component, VNode } from "preact";
2
- import { PropsWithChildren } from "preact/compat";
3
-
4
- export class RouterErrorBoundary extends Component<PropsWithChildren & { fallback?: VNode }> {
5
- state = { error: null };
6
-
7
- static getDerivedStateFromError(error: any) {
8
- return { error: error.message };
9
- }
10
-
11
- componentDidCatch(error: any) {
12
- console.error(error);
13
- this.setState({ error: error.message });
14
- }
15
-
16
- render() {
17
- if (this.state.error) {
18
- if (this.props.fallback) return this.props.fallback;
19
-
20
- return <p>Oh no! We ran into an error: {this.state.error}</p>;
21
- }
22
- return this.props.children;
23
- }
24
- }
package/src/context.tsx DELETED
@@ -1,12 +0,0 @@
1
- import { createContext } from "preact";
2
-
3
- export type RouterContext = {
4
- path: string;
5
- query: string;
6
- go: (r: string) => void;
7
- itMatch: boolean;
8
- setItMatch: (r: boolean) => void;
9
- type: "hash" | "browser";
10
- };
11
-
12
- export const router_context = createContext<RouterContext>(null);
package/src/index.ts DELETED
@@ -1,6 +0,0 @@
1
- export * from "./A";
2
- export * from "./ErrorRoute";
3
- export * from "./Route";
4
- export * from "./Router";
5
- export * from "./RouterErrorBoundary";
6
- export * from "./useRouter";
package/src/useRouter.tsx DELETED
@@ -1,12 +0,0 @@
1
- import { useContext } from "preact/hooks";
2
- import { router_context } from "./context";
3
-
4
- export function useRouter() {
5
- const context = useContext(router_context);
6
-
7
- if (!context) {
8
- throw new Error("useRoute should be used within a Router");
9
- }
10
-
11
- return context;
12
- }