router-kit 0.1.1
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/dist/Link.d.ts +7 -0
- package/dist/Link.js +10 -0
- package/dist/NavLink.d.ts +8 -0
- package/dist/NavLink.js +14 -0
- package/dist/RouterContext.d.ts +3 -0
- package/dist/RouterContext.js +3 -0
- package/dist/RouterProvider.d.ts +5 -0
- package/dist/RouterProvider.js +61 -0
- package/dist/createRouter.d.ts +3 -0
- package/dist/createRouter.js +20 -0
- package/dist/hook.d.ts +6 -0
- package/dist/hook.js +27 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/pages/404/index.d.ts +3 -0
- package/dist/pages/404/index.js +10 -0
- package/dist/useRouter.d.ts +1 -0
- package/dist/useRouter.js +8 -0
- package/package.json +42 -0
package/dist/Link.d.ts
ADDED
package/dist/Link.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRouter } from "./useRouter";
|
|
3
|
+
function Link({ to, children, className, }) {
|
|
4
|
+
const { navigate } = useRouter();
|
|
5
|
+
return (_jsx("a", { onClick: (e) => {
|
|
6
|
+
e.preventDefault();
|
|
7
|
+
navigate(to);
|
|
8
|
+
}, className: className, href: to, children: children }));
|
|
9
|
+
}
|
|
10
|
+
export default Link;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
declare function NavLink({ to, children, className, activeClassName, }: {
|
|
3
|
+
to: string;
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
activeClassName?: string;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export default NavLink;
|
package/dist/NavLink.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRouter } from "./useRouter";
|
|
3
|
+
function NavLink({ to, children, className, activeClassName = "active", }) {
|
|
4
|
+
const { navigate, path } = useRouter();
|
|
5
|
+
const isActive = path === to;
|
|
6
|
+
const combinedClass = [className, isActive ? activeClassName : null]
|
|
7
|
+
.filter(Boolean)
|
|
8
|
+
.join(" ");
|
|
9
|
+
return (_jsx("a", { onClick: (e) => {
|
|
10
|
+
e.preventDefault();
|
|
11
|
+
navigate(to);
|
|
12
|
+
}, className: combinedClass, href: to, children: children }));
|
|
13
|
+
}
|
|
14
|
+
export default NavLink;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import join from "url-join";
|
|
4
|
+
import Page404 from "./pages/404";
|
|
5
|
+
import RouterContext from "./RouterContext";
|
|
6
|
+
const RouterProvider = ({ routes }) => {
|
|
7
|
+
const [path, setPath] = useState(window.location.pathname);
|
|
8
|
+
let fullPathWithParams = "";
|
|
9
|
+
const pathValidation = (fullPath, path) => {
|
|
10
|
+
const fakePathArr = path.split("/");
|
|
11
|
+
let fakePath = "/";
|
|
12
|
+
fullPath.split("/").forEach((e, index) => {
|
|
13
|
+
if (e.startsWith(":")) {
|
|
14
|
+
fakePathArr[index] = e;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
fakePathArr.forEach((e) => {
|
|
18
|
+
fakePath = join(fakePath, `/${e}`);
|
|
19
|
+
});
|
|
20
|
+
if (fullPath === fakePath) {
|
|
21
|
+
fakePath = "";
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
fakePath = "";
|
|
25
|
+
return false;
|
|
26
|
+
};
|
|
27
|
+
const getComponent = (routes, currentPath, parentPath = "/") => {
|
|
28
|
+
let component = _jsx(Page404, {});
|
|
29
|
+
for (const route of routes) {
|
|
30
|
+
if (route.path === "/404" && route.component)
|
|
31
|
+
component = route.component;
|
|
32
|
+
const fullPath = join(parentPath, `/${route.path}`);
|
|
33
|
+
if (pathValidation(fullPath, currentPath)) {
|
|
34
|
+
fullPathWithParams = fullPath;
|
|
35
|
+
component = route.component;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
if (route.children) {
|
|
39
|
+
component = getComponent(route.children, currentPath, fullPath);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return component;
|
|
43
|
+
};
|
|
44
|
+
const component = getComponent(routes, path);
|
|
45
|
+
const navigate = (to, options) => {
|
|
46
|
+
if (options && options.replace) {
|
|
47
|
+
window.history.replaceState({}, "", to);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
window.history.pushState({}, "", to);
|
|
51
|
+
}
|
|
52
|
+
setPath(to);
|
|
53
|
+
};
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
const handlePop = () => setPath(window.location.pathname);
|
|
56
|
+
window.addEventListener("popstate", handlePop);
|
|
57
|
+
return () => window.removeEventListener("popstate", handlePop);
|
|
58
|
+
}, []);
|
|
59
|
+
return (_jsx(RouterContext.Provider, { value: { path, fullPathWithParams, navigate }, children: component }));
|
|
60
|
+
};
|
|
61
|
+
export default RouterProvider;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Normalize routes: remove leading slashes from paths and normalize children recursively
|
|
2
|
+
function normalizeRoutes(routes) {
|
|
3
|
+
return routes.map((route) => {
|
|
4
|
+
const normalizedPath = route.path.startsWith("/")
|
|
5
|
+
? route.path.replace(/^\/+/, "")
|
|
6
|
+
: route.path;
|
|
7
|
+
const normalized = {
|
|
8
|
+
...route,
|
|
9
|
+
path: normalizedPath,
|
|
10
|
+
};
|
|
11
|
+
if (route.children) {
|
|
12
|
+
normalized.children = normalizeRoutes(route.children);
|
|
13
|
+
}
|
|
14
|
+
return normalized;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function createRouter(routes) {
|
|
18
|
+
return normalizeRoutes(routes);
|
|
19
|
+
}
|
|
20
|
+
export default createRouter;
|
package/dist/hook.d.ts
ADDED
package/dist/hook.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useRouter } from "./useRouter";
|
|
2
|
+
// Retourne un objet { [paramName]: value }
|
|
3
|
+
export const useParams = () => {
|
|
4
|
+
const { path, fullPathWithParams } = useRouter();
|
|
5
|
+
const params = {};
|
|
6
|
+
const fullSegments = fullPathWithParams.split("/").filter(Boolean);
|
|
7
|
+
const pathSegments = path.split("/").filter(Boolean);
|
|
8
|
+
fullSegments.forEach((seg, idx) => {
|
|
9
|
+
var _a;
|
|
10
|
+
if (seg.startsWith(":")) {
|
|
11
|
+
const name = seg.slice(1);
|
|
12
|
+
params[name] = (_a = pathSegments[idx]) !== null && _a !== void 0 ? _a : "";
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return params;
|
|
16
|
+
};
|
|
17
|
+
// Parse la query string proprement (ex: ?a=1&b=2)
|
|
18
|
+
export const useQuery = () => {
|
|
19
|
+
const query = {};
|
|
20
|
+
if (typeof window === "undefined")
|
|
21
|
+
return query;
|
|
22
|
+
const usp = new URLSearchParams(window.location.search);
|
|
23
|
+
usp.forEach((value, key) => {
|
|
24
|
+
query[key] = value;
|
|
25
|
+
});
|
|
26
|
+
return query;
|
|
27
|
+
};
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRouter } from "../../useRouter";
|
|
3
|
+
import "./styles.css";
|
|
4
|
+
const Page404 = () => {
|
|
5
|
+
const { navigate } = useRouter();
|
|
6
|
+
return (_jsx("div", { className: "error-page", children: _jsxs("div", { className: "error-container", children: [_jsx("h1", { className: "error-title", children: "404" }), _jsx("h2", { className: "error-subtitle", children: "Page Not Found" }), _jsx("p", { className: "error-message", children: "Sorry, the page you are looking for does not exist or has been moved." }), _jsx("button", { onClick: () => {
|
|
7
|
+
navigate("/");
|
|
8
|
+
}, className: "error-button", children: "Go Back Home" })] }) }));
|
|
9
|
+
};
|
|
10
|
+
export default Page404;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useRouter(): import("./types").RouterContextType;
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "router-kit",
|
|
3
|
+
"author": {
|
|
4
|
+
"name": "Mohammed Ben Cheikh",
|
|
5
|
+
"email": "mohammed.bencheikh.dev@gmail.com",
|
|
6
|
+
"url": "https://mohammedbencheikh.com/"
|
|
7
|
+
},
|
|
8
|
+
"version": "0.1.1",
|
|
9
|
+
"description": "A small React routing provider library",
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"types": "dist/*.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"clean": "rm -rf dist",
|
|
17
|
+
"build": "tsc -p tsconfig.json",
|
|
18
|
+
"build:watch": "tsc -p tsconfig.json --watch",
|
|
19
|
+
"prepare": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"react": ">=17 <19",
|
|
23
|
+
"react-dom": ">=17 <19"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"url-join": "^5.0.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"typescript": "^5.2.0",
|
|
30
|
+
"@types/react": "^18.2.0",
|
|
31
|
+
"@types/react-dom": "^18.2.0",
|
|
32
|
+
"@types/url-join": "^4.0.3"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"react",
|
|
36
|
+
"route",
|
|
37
|
+
"provider",
|
|
38
|
+
"routing",
|
|
39
|
+
"route-provider"
|
|
40
|
+
],
|
|
41
|
+
"license": "MIT"
|
|
42
|
+
}
|