router-kit 0.1.2 → 0.1.4
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/LICENSE +21 -0
- package/README.md +180 -0
- package/dist/{Link.js → components/Link.js} +1 -1
- package/dist/{NavLink.js → components/NavLink.js} +1 -1
- package/dist/{RouterContext.d.ts → context/RouterContext.d.ts} +1 -1
- package/dist/{RouterProvider.d.ts → context/RouterProvider.d.ts} +1 -1
- package/dist/{RouterProvider.js → context/RouterProvider.js} +1 -1
- package/dist/{createRouter.d.ts → core/createRouter.d.ts} +1 -1
- package/dist/hooks/useRouter.d.ts +1 -0
- package/dist/{useRouter.js → hooks/useRouter.js} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/pages/404/index.d.ts +0 -1
- package/dist/pages/404/index.js +50 -4
- package/package.json +7 -5
- package/dist/useRouter.d.ts +0 -1
- /package/dist/{Link.d.ts → components/Link.d.ts} +0 -0
- /package/dist/{NavLink.d.ts → components/NavLink.d.ts} +0 -0
- /package/dist/{RouterContext.js → context/RouterContext.js} +0 -0
- /package/dist/{createRouter.js → core/createRouter.js} +0 -0
- /package/dist/{hook.d.ts → hooks/hook.d.ts} +0 -0
- /package/dist/{hook.js → hooks/hook.js} +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mohammed Ben Cheikh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Router Kit
|
|
2
|
+
|
|
3
|
+
Un petit fournisseur de routing pour React, minimal et léger, créé par Mohammed Ben Cheikh.
|
|
4
|
+
|
|
5
|
+
Ce README documente l'utilisation publique du package `router-kit` : installation, API, exemples d'utilisation et bonnes pratiques.
|
|
6
|
+
|
|
7
|
+
## Table des matières
|
|
8
|
+
|
|
9
|
+
- Introduction
|
|
10
|
+
- Installation
|
|
11
|
+
- Concepts clés
|
|
12
|
+
- API publique
|
|
13
|
+
- `createRouter(routes)`
|
|
14
|
+
- `<RouterProvider routes={...} />`
|
|
15
|
+
- `<Link to="...">` et `<NavLink to="...">`
|
|
16
|
+
- Hooks : `useParams()`, `useQuery()` et `useRouter()`
|
|
17
|
+
- Exemple d'utilisation
|
|
18
|
+
- Routes et 404
|
|
19
|
+
- Développement
|
|
20
|
+
- Contribuer
|
|
21
|
+
- Licence
|
|
22
|
+
|
|
23
|
+
## Introduction
|
|
24
|
+
|
|
25
|
+
`router-kit` fournit un routeur côté client très simple pour les applications React. Il ne dépend que de React et d'une petite utilité `url-join` pour composer les chemins.
|
|
26
|
+
|
|
27
|
+
Le routeur :
|
|
28
|
+
|
|
29
|
+
- Résout les composants en fonction du `window.location.pathname`.
|
|
30
|
+
- Expose un contexte pour naviguer (`navigate`) et connaître le `path` courant.
|
|
31
|
+
- Prend en charge des paramètres de route de type `/:id` et l'extraction via `useParams()`.
|
|
32
|
+
- Fournit un 404 configurable.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
Installer en tant que dépendance (ex : npm) :
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install router-kit
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
N.B. `react` et `react-dom` sont des peerDependencies ; installez-les dans votre projet si nécessaire.
|
|
43
|
+
|
|
44
|
+
## Concepts clés
|
|
45
|
+
|
|
46
|
+
- Route : objet avec `path` (string) et `component` (JSX.Element). Les `children` sont supportés pour construire des arborescences.
|
|
47
|
+
- `createRouter(routes)` : normalise les chemins (supprime les slashs initiaux) et retourne la structure de routes.
|
|
48
|
+
- `RouterProvider` : fournit le contexte et rend le composant correspondant au `path` courant.
|
|
49
|
+
- `navigate(to, { replace })` : change l'URL en utilisant l'API History et met à jour le rendu.
|
|
50
|
+
|
|
51
|
+
## API publique
|
|
52
|
+
|
|
53
|
+
Voici l'API exposée par le package (extraits depuis `src/index.ts`).
|
|
54
|
+
|
|
55
|
+
- export { default as Link } from "./components/Link";
|
|
56
|
+
- export { default as NavLink } from "./components/NavLink";
|
|
57
|
+
- export { default as RouterProvider } from "./context/RouterProvider";
|
|
58
|
+
- export { default as createRouter } from "./core/createRouter";
|
|
59
|
+
- export { useParams, useQuery } from "./hooks/hook";
|
|
60
|
+
|
|
61
|
+
### createRouter(routes)
|
|
62
|
+
|
|
63
|
+
Fonction d'aide qui normalise une liste de routes. Elle supprime les slashs initiaux dans les `path` et renvoie la structure prête à être passée à `RouterProvider`.
|
|
64
|
+
|
|
65
|
+
Signature :
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
createRouter(routes: Route[]): Route[]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### RouterProvider
|
|
72
|
+
|
|
73
|
+
Composant qui prend une prop `routes` (Route[]) et rend le composant correspondant à l'URL actuelle.
|
|
74
|
+
|
|
75
|
+
Usage :
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { RouterProvider } from "router-kit";
|
|
79
|
+
|
|
80
|
+
const routes = createRouter([
|
|
81
|
+
{ path: "/", component: <Home /> },
|
|
82
|
+
{ path: "users/:id", component: <User /> },
|
|
83
|
+
{ path: "/404", component: <NotFound /> },
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
function App() {
|
|
87
|
+
return <RouterProvider routes={routes} />;
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Le provider expose via le contexte :
|
|
92
|
+
|
|
93
|
+
- `path` : le pathname courant (ex: `/users/42`)
|
|
94
|
+
- `fullPathWithParams` : le chemin défini dans la route incluant les paramètres (ex: `/users/:id`)
|
|
95
|
+
- `navigate(to: string, options?: { replace?: boolean })`
|
|
96
|
+
|
|
97
|
+
### Link et NavLink
|
|
98
|
+
|
|
99
|
+
`<Link to="...">` : rend un lien <a> qui empêche le comportement par défaut et appelle `navigate(to)`.
|
|
100
|
+
|
|
101
|
+
`<NavLink to="..." activeClassName="...">` : comme `Link` mais ajoute `activeClassName` quand la route est active (comparaison stricte `path === to`).
|
|
102
|
+
|
|
103
|
+
Exemple :
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
<Link to="/about">À propos</Link>
|
|
107
|
+
<NavLink to="/">Accueil</NavLink>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Hooks
|
|
111
|
+
|
|
112
|
+
- `useRouter()` : hook interne retournant le contexte `{ path, fullPathWithParams, navigate }`. Lance une erreur si utilisé hors du provider.
|
|
113
|
+
- `useParams()` : renvoie un objet clé/valeur pour les segments paramétrés de la route (ex: `{ id: "42" }`). Se base sur `fullPathWithParams` et `path`.
|
|
114
|
+
- `useQuery()` : parse `window.location.search` et renvoie un objet `{ [key]: value }`.
|
|
115
|
+
|
|
116
|
+
## Exemple complet
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
import React from "react";
|
|
120
|
+
import { createRouter, RouterProvider, Link } from "router-kit";
|
|
121
|
+
|
|
122
|
+
const Home = <div>Accueil</div>;
|
|
123
|
+
const About = <div>À propos</div>;
|
|
124
|
+
|
|
125
|
+
const routes = createRouter([
|
|
126
|
+
{ path: "/", component: Home },
|
|
127
|
+
{ path: "about", component: About },
|
|
128
|
+
{ path: "/404", component: <div>Not Found</div> },
|
|
129
|
+
]);
|
|
130
|
+
|
|
131
|
+
export default function App() {
|
|
132
|
+
return (
|
|
133
|
+
<div>
|
|
134
|
+
<nav>
|
|
135
|
+
<Link to="/">Home</Link>
|
|
136
|
+
<Link to="/about">About</Link>
|
|
137
|
+
</nav>
|
|
138
|
+
<RouterProvider routes={routes} />
|
|
139
|
+
</div>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Routes et 404
|
|
145
|
+
|
|
146
|
+
Le provider recherche les routes et compare le `fullPath` de chaque route avec le pathname courant en remplaçant dynamiquement les segments commençant par `:` (ex: `/:id`).
|
|
147
|
+
|
|
148
|
+
Pour afficher une page 404 personnalisée, ajoutez une route avec `path: "/404"` et `component` : elle sera utilisée par défaut quand aucune route ne matche.
|
|
149
|
+
|
|
150
|
+
## Développement
|
|
151
|
+
|
|
152
|
+
Scripts disponibles (définis dans `package.json`) :
|
|
153
|
+
|
|
154
|
+
- `npm run build` : compile TypeScript vers `dist/` (utilise `tsc`).
|
|
155
|
+
- `npm run typecheck` : vérifie les types sans émettre de fichiers.
|
|
156
|
+
- `npm run clean` : supprime `dist`.
|
|
157
|
+
|
|
158
|
+
Pour développer localement :
|
|
159
|
+
|
|
160
|
+
1. Cloner le dépôt et installer les dépendances.
|
|
161
|
+
2. Lancer `npm run build:watch` si vous modifiez le package et voulez recompiler automatiquement.
|
|
162
|
+
|
|
163
|
+
## Contribuer
|
|
164
|
+
|
|
165
|
+
Les contributions sont bienvenues. Pour des petites améliorations :
|
|
166
|
+
|
|
167
|
+
1. Ouvrir une issue décrivant le problème ou la fonctionnalité.
|
|
168
|
+
2. Soumettre une PR avec un seul changement logique par PR.
|
|
169
|
+
|
|
170
|
+
Propositions d'améliorations possibles :
|
|
171
|
+
|
|
172
|
+
- Support d'URL basées sur hash (/#/path).
|
|
173
|
+
- Support plus riche du matching (wildcards, regex, exact/partial).
|
|
174
|
+
- Tests unitaires et CI.
|
|
175
|
+
|
|
176
|
+
## Licence
|
|
177
|
+
|
|
178
|
+
MIT — voir le fichier `LICENSE`.
|
|
179
|
+
|
|
180
|
+
---
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useRouter } from "
|
|
2
|
+
import { useRouter } from "../hooks/useRouter";
|
|
3
3
|
function NavLink({ to, children, className, activeClassName = "active", }) {
|
|
4
4
|
const { navigate, path } = useRouter();
|
|
5
5
|
const isActive = path === to;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import join from "url-join";
|
|
4
|
-
import Page404 from "
|
|
4
|
+
import Page404 from "../pages/404";
|
|
5
5
|
import RouterContext from "./RouterContext";
|
|
6
6
|
const RouterProvider = ({ routes }) => {
|
|
7
7
|
const [path, setPath] = useState(window.location.pathname);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useRouter(): import("../types").RouterContextType;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export {
|
|
3
|
-
export { default as
|
|
4
|
-
export { default as
|
|
5
|
-
export {
|
|
1
|
+
export { default as Link } from "./components/Link";
|
|
2
|
+
export { default as NavLink } from "./components/NavLink";
|
|
3
|
+
export { default as RouterProvider } from "./context/RouterProvider";
|
|
4
|
+
export { default as createRouter } from "./core/createRouter";
|
|
5
|
+
export { useParams, useQuery } from "./hooks/hook";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export {
|
|
3
|
-
export { default as
|
|
4
|
-
export { default as
|
|
5
|
-
export {
|
|
1
|
+
export { default as Link } from "./components/Link";
|
|
2
|
+
export { default as NavLink } from "./components/NavLink";
|
|
3
|
+
export { default as RouterProvider } from "./context/RouterProvider";
|
|
4
|
+
export { default as createRouter } from "./core/createRouter";
|
|
5
|
+
export { useParams, useQuery } from "./hooks/hook";
|
package/dist/pages/404/index.js
CHANGED
|
@@ -1,10 +1,56 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import "
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useRouter } from "../../hooks/useRouter";
|
|
4
|
+
const staile = {
|
|
5
|
+
errorPage: {
|
|
6
|
+
minHeight: "100vh",
|
|
7
|
+
display: "flex",
|
|
8
|
+
alignItems: "center",
|
|
9
|
+
justifyContent: "center",
|
|
10
|
+
backgroundColor: "#f3f4f6",
|
|
11
|
+
},
|
|
12
|
+
errorContainer: {
|
|
13
|
+
textAlign: "center",
|
|
14
|
+
padding: "0 1rem",
|
|
15
|
+
},
|
|
16
|
+
errorTitle: {
|
|
17
|
+
fontSize: "9rem",
|
|
18
|
+
fontWeight: 700,
|
|
19
|
+
color: "#1f2937",
|
|
20
|
+
margin: 0,
|
|
21
|
+
},
|
|
22
|
+
errorSubtitle: {
|
|
23
|
+
fontSize: "1.5rem",
|
|
24
|
+
fontWeight: 600,
|
|
25
|
+
color: "#4b5563",
|
|
26
|
+
marginTop: "1rem",
|
|
27
|
+
marginBottom: 0,
|
|
28
|
+
},
|
|
29
|
+
errorMessage: {
|
|
30
|
+
color: "#6b7280",
|
|
31
|
+
margin: "1rem 0 2rem 0",
|
|
32
|
+
},
|
|
33
|
+
errorButton: {
|
|
34
|
+
padding: "0.75rem 1.5rem",
|
|
35
|
+
backgroundColor: "#2563eb",
|
|
36
|
+
color: "white",
|
|
37
|
+
border: "none",
|
|
38
|
+
borderRadius: "0.5rem",
|
|
39
|
+
cursor: "pointer",
|
|
40
|
+
transition: "background-color 0.2s",
|
|
41
|
+
},
|
|
42
|
+
errorButtonHover: {
|
|
43
|
+
backgroundColor: "#1d4ed8",
|
|
44
|
+
},
|
|
45
|
+
};
|
|
4
46
|
const Page404 = () => {
|
|
5
47
|
const { navigate } = useRouter();
|
|
6
|
-
|
|
48
|
+
const [hover, setHover] = useState(false);
|
|
49
|
+
return (_jsx("div", { style: staile.errorPage, children: _jsxs("div", { style: staile.errorContainer, children: [_jsx("h1", { style: staile.errorTitle, children: "404" }), _jsx("h2", { style: staile.errorSubtitle, children: "Page Not Found" }), _jsx("p", { style: staile.errorMessage, children: "Sorry, the page you are looking for does not exist or has been moved." }), _jsx("button", { onClick: () => {
|
|
7
50
|
navigate("/");
|
|
8
|
-
},
|
|
51
|
+
}, onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), style: {
|
|
52
|
+
...staile.errorButton,
|
|
53
|
+
...(hover ? staile.errorButtonHover : {}),
|
|
54
|
+
}, children: "Go Back Home" })] }) }));
|
|
9
55
|
};
|
|
10
56
|
export default Page404;
|
package/package.json
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
"email": "mohammed.bencheikh.dev@gmail.com",
|
|
6
6
|
"url": "https://mohammedbencheikh.com/"
|
|
7
7
|
},
|
|
8
|
-
"version": "0.1.
|
|
8
|
+
"version": "0.1.4",
|
|
9
9
|
"description": "A small React routing provider library",
|
|
10
10
|
"main": "dist/index.js",
|
|
11
|
-
"types": "dist
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist"
|
|
14
14
|
],
|
|
@@ -16,11 +16,13 @@
|
|
|
16
16
|
"clean": "rm -rf dist",
|
|
17
17
|
"build": "tsc -p tsconfig.json",
|
|
18
18
|
"build:watch": "tsc -p tsconfig.json --watch",
|
|
19
|
-
"prepare": "npm run build"
|
|
19
|
+
"prepare": "npm run build",
|
|
20
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
21
|
+
"pack:verify": "npm pack --dry-run"
|
|
20
22
|
},
|
|
21
23
|
"peerDependencies": {
|
|
22
|
-
"react": ">=
|
|
23
|
-
"react-dom": ">=
|
|
24
|
+
"react": ">=16 <20",
|
|
25
|
+
"react-dom": ">=16 <20"
|
|
24
26
|
},
|
|
25
27
|
"dependencies": {
|
|
26
28
|
"url-join": "^5.0.0"
|
package/dist/useRouter.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function useRouter(): import("./types").RouterContextType;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|