router-kit 1.3.0 → 1.3.2
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/README.md +379 -106
- package/dist/context/RouterProvider.js +27 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,186 +1,459 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Documentation Index
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Complete documentation for Router-Kit v1.3.1
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
🌐 **Website:** [https://routerkit.com/](https://routerkit.com/)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📚 Documentation Structure
|
|
8
10
|
|
|
9
|
-
-
|
|
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
|
|
11
|
+
This directory contains comprehensive documentation for Router-Kit. Choose the documentation that best fits your needs:
|
|
22
12
|
|
|
23
|
-
|
|
13
|
+
### For Users
|
|
24
14
|
|
|
25
|
-
|
|
15
|
+
- **[Quick Start Guide](#quick-start-guide)** - Get up and running in 5 minutes
|
|
16
|
+
- **[Complete Documentation](./DOCUMENTATION.md)** - Full feature guide with examples
|
|
17
|
+
- **[API Reference](./API_REFERENCE.md)** - Detailed API documentation
|
|
18
|
+
- **[Examples](./EXAMPLES.md)** - Real-world usage examples
|
|
26
19
|
|
|
27
|
-
|
|
20
|
+
### For Developers
|
|
28
21
|
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
- Prend en charge des paramètres de route de type `/:id` et l'extraction via `useParams()`.
|
|
32
|
-
- Fournit un 404 configurable.
|
|
22
|
+
- **[Architecture](./ARCHITECTURE.md)** - Internal implementation details
|
|
23
|
+
- **[Contributing Guide](#contributing)** - How to contribute to Router-Kit
|
|
33
24
|
|
|
34
|
-
|
|
25
|
+
---
|
|
35
26
|
|
|
36
|
-
|
|
27
|
+
## Quick Start Guide
|
|
28
|
+
|
|
29
|
+
### Installation
|
|
37
30
|
|
|
38
31
|
```bash
|
|
39
32
|
npm install router-kit
|
|
40
33
|
```
|
|
41
34
|
|
|
42
|
-
|
|
35
|
+
### Basic Setup
|
|
43
36
|
|
|
44
|
-
|
|
37
|
+
```tsx
|
|
38
|
+
import React from "react";
|
|
39
|
+
import { createRouter, RouterProvider, Link } from "router-kit";
|
|
45
40
|
|
|
46
|
-
|
|
41
|
+
// 1. Define your components
|
|
42
|
+
const Home = () => <h1>Home Page</h1>;
|
|
43
|
+
const About = () => <h1>About Page</h1>;
|
|
47
44
|
|
|
48
|
-
|
|
45
|
+
// 2. Create routes
|
|
46
|
+
const routes = createRouter([
|
|
47
|
+
{ path: "/", component: <Home /> },
|
|
48
|
+
{ path: "about", component: <About /> },
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
// 3. Wrap your app with RouterProvider
|
|
52
|
+
function App() {
|
|
53
|
+
return <RouterProvider routes={routes} />;
|
|
54
|
+
}
|
|
49
55
|
|
|
56
|
+
export default App;
|
|
50
57
|
```
|
|
51
|
-
|
|
58
|
+
|
|
59
|
+
### Navigation
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { Link, NavLink } from "router-kit";
|
|
63
|
+
|
|
64
|
+
function Navigation() {
|
|
65
|
+
return (
|
|
66
|
+
<nav>
|
|
67
|
+
<Link to="/">Home</Link>
|
|
68
|
+
<NavLink to="/about" activeClassName="active">
|
|
69
|
+
About
|
|
70
|
+
</NavLink>
|
|
71
|
+
</nav>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
52
74
|
```
|
|
53
75
|
|
|
54
|
-
|
|
76
|
+
### Dynamic Routes
|
|
55
77
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
- `RouterProvider` : fournit le contexte et rend le composant correspondant au `path` courant.
|
|
59
|
-
- `navigate(to, { replace })` : change l'URL en utilisant l'API History et met à jour le rendu.
|
|
78
|
+
```tsx
|
|
79
|
+
import { useParams } from "router-kit";
|
|
60
80
|
|
|
61
|
-
|
|
81
|
+
// Route: /users/:id
|
|
82
|
+
const routes = createRouter([
|
|
83
|
+
{ path: "users/:id", component: <UserProfile /> },
|
|
84
|
+
]);
|
|
62
85
|
|
|
63
|
-
|
|
86
|
+
function UserProfile() {
|
|
87
|
+
const { id } = useParams();
|
|
88
|
+
return <h1>User {id}</h1>;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
64
91
|
|
|
65
|
-
|
|
66
|
-
- export { default as NavLink } from "./components/NavLink";
|
|
67
|
-
- export { default as RouterProvider } from "./context/RouterProvider";
|
|
68
|
-
- export { default as createRouter } from "./core/createRouter";
|
|
69
|
-
- export { useParams, useQuery } from "./hooks/hook";
|
|
92
|
+
### Programmatic Navigation
|
|
70
93
|
|
|
71
|
-
|
|
94
|
+
```tsx
|
|
95
|
+
import { useRouter } from "router-kit";
|
|
72
96
|
|
|
73
|
-
|
|
97
|
+
function LoginForm() {
|
|
98
|
+
const { navigate } = useRouter();
|
|
74
99
|
|
|
75
|
-
|
|
100
|
+
const handleLogin = () => {
|
|
101
|
+
// After successful login
|
|
102
|
+
navigate("/dashboard");
|
|
103
|
+
};
|
|
76
104
|
|
|
77
|
-
|
|
78
|
-
|
|
105
|
+
return <button onClick={handleLogin}>Login</button>;
|
|
106
|
+
}
|
|
79
107
|
```
|
|
80
108
|
|
|
81
|
-
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Documentation Files
|
|
82
112
|
|
|
83
|
-
|
|
113
|
+
### [DOCUMENTATION.md](./DOCUMENTATION.md)
|
|
84
114
|
|
|
85
|
-
|
|
115
|
+
**Complete user guide covering:**
|
|
86
116
|
|
|
87
|
-
|
|
88
|
-
|
|
117
|
+
- Introduction and key features
|
|
118
|
+
- Installation instructions
|
|
119
|
+
- Core concepts explained
|
|
120
|
+
- API reference with examples
|
|
121
|
+
- Advanced usage patterns
|
|
122
|
+
- Error handling strategies
|
|
123
|
+
- TypeScript support
|
|
124
|
+
- Best practices
|
|
125
|
+
- Migration guide from other routers
|
|
126
|
+
- Real-world examples
|
|
127
|
+
|
|
128
|
+
**Best for:** Learning Router-Kit from scratch, understanding concepts, and finding usage examples.
|
|
129
|
+
|
|
130
|
+
### [API_REFERENCE.md](./API_REFERENCE.md)
|
|
131
|
+
|
|
132
|
+
**Comprehensive API documentation including:**
|
|
133
|
+
|
|
134
|
+
- `createRouter()` function
|
|
135
|
+
- `RouterProvider` component
|
|
136
|
+
- `Link` and `NavLink` components
|
|
137
|
+
- `useRouter()` hook
|
|
138
|
+
- `useParams()` hook
|
|
139
|
+
- `useQuery()` hook
|
|
140
|
+
- `useLocation()` hook
|
|
141
|
+
- `useDynamicComponents()` hook
|
|
142
|
+
- Type definitions
|
|
143
|
+
- Error system reference
|
|
89
144
|
|
|
145
|
+
**Best for:** Looking up specific APIs, understanding function signatures, and exploring available options.
|
|
146
|
+
|
|
147
|
+
### [EXAMPLES.md](./EXAMPLES.md)
|
|
148
|
+
|
|
149
|
+
**Practical examples featuring:**
|
|
150
|
+
|
|
151
|
+
- Basic routing examples
|
|
152
|
+
- E-commerce application
|
|
153
|
+
- Blog platform
|
|
154
|
+
- Dashboard application
|
|
155
|
+
- Multi-language website
|
|
156
|
+
- Authentication flow
|
|
157
|
+
- Advanced patterns (lazy loading, modals, breadcrumbs, animations)
|
|
158
|
+
|
|
159
|
+
**Best for:** Finding real-world implementation patterns and copy-paste solutions.
|
|
160
|
+
|
|
161
|
+
### [ARCHITECTURE.md](./ARCHITECTURE.md)
|
|
162
|
+
|
|
163
|
+
**Technical implementation details including:**
|
|
164
|
+
|
|
165
|
+
- System architecture overview
|
|
166
|
+
- Core component implementations
|
|
167
|
+
- Route matching algorithm
|
|
168
|
+
- History management
|
|
169
|
+
- Context system
|
|
170
|
+
- Error handling system
|
|
171
|
+
- Type system
|
|
172
|
+
- Performance considerations
|
|
173
|
+
- Build and distribution
|
|
174
|
+
|
|
175
|
+
**Best for:** Understanding internals, contributing to the project, or debugging complex issues.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Common Use Cases
|
|
180
|
+
|
|
181
|
+
### Simple Website
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
90
184
|
const routes = createRouter([
|
|
91
185
|
{ path: "/", component: <Home /> },
|
|
92
|
-
{ path: "
|
|
186
|
+
{ path: "about", component: <About /> },
|
|
187
|
+
{ path: "contact", component: <Contact /> },
|
|
93
188
|
{ path: "/404", component: <NotFound /> },
|
|
94
189
|
]);
|
|
190
|
+
```
|
|
95
191
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
192
|
+
📖 **See:** [Basic Examples in EXAMPLES.md](./EXAMPLES.md#basic-examples)
|
|
193
|
+
|
|
194
|
+
### Blog or CMS
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
const routes = createRouter([
|
|
198
|
+
{ path: "/", component: <BlogHome /> },
|
|
199
|
+
{ path: "posts/:category/:slug", component: <BlogPost /> },
|
|
200
|
+
{ path: "author/:username", component: <AuthorProfile /> },
|
|
201
|
+
]);
|
|
99
202
|
```
|
|
100
203
|
|
|
101
|
-
|
|
204
|
+
📖 **See:** [Blog Platform in EXAMPLES.md](./EXAMPLES.md#blog-platform)
|
|
102
205
|
|
|
103
|
-
|
|
104
|
-
- `fullPathWithParams` : le chemin défini dans la route incluant les paramètres (ex: `/users/:id`)
|
|
105
|
-
- `navigate(to: string, options?: { replace?: boolean })`
|
|
206
|
+
### Dashboard Application
|
|
106
207
|
|
|
107
|
-
|
|
208
|
+
```tsx
|
|
209
|
+
const routes = createRouter([
|
|
210
|
+
{ path: "dashboard/:view", component: <Dashboard /> },
|
|
211
|
+
]);
|
|
212
|
+
|
|
213
|
+
function Dashboard() {
|
|
214
|
+
const views = {
|
|
215
|
+
overview: <OverviewView />,
|
|
216
|
+
analytics: <AnalyticsView />,
|
|
217
|
+
settings: <SettingsView />,
|
|
218
|
+
};
|
|
108
219
|
|
|
109
|
-
|
|
220
|
+
return useDynamicComponents(views, "view");
|
|
221
|
+
}
|
|
222
|
+
```
|
|
110
223
|
|
|
111
|
-
|
|
224
|
+
📖 **See:** [Dashboard Application in EXAMPLES.md](./EXAMPLES.md#dashboard-application)
|
|
112
225
|
|
|
113
|
-
|
|
226
|
+
### E-commerce Site
|
|
114
227
|
|
|
115
228
|
```tsx
|
|
116
|
-
|
|
117
|
-
|
|
229
|
+
const routes = createRouter([
|
|
230
|
+
{ path: "/", component: <HomePage /> },
|
|
231
|
+
{ path: "products", component: <ProductList /> },
|
|
232
|
+
{ path: "products/:id", component: <ProductDetail /> },
|
|
233
|
+
{ path: "cart", component: <Cart /> },
|
|
234
|
+
{ path: "checkout", component: <Checkout /> },
|
|
235
|
+
]);
|
|
118
236
|
```
|
|
119
237
|
|
|
120
|
-
|
|
238
|
+
📖 **See:** [E-commerce Application in EXAMPLES.md](./EXAMPLES.md#e-commerce-application)
|
|
121
239
|
|
|
122
|
-
|
|
123
|
-
- `useParams()` : renvoie un objet clé/valeur pour les segments paramétrés de la route (ex: `{ id: "42" }`). Se base sur `fullPathWithParams` et `path`.
|
|
124
|
-
- `useQuery()` : parse `window.location.search` et renvoie un objet `{ [key]: value }`.
|
|
125
|
-
- `useLocation()` : renvoie un objet avec les informations de localisation courante : `{ pathname, search, hash, state }`. Utile pour accéder aux détails de l'URL actuelle.
|
|
240
|
+
### Protected Routes
|
|
126
241
|
|
|
127
|
-
|
|
242
|
+
```tsx
|
|
243
|
+
const routes = createRouter([
|
|
244
|
+
{ path: "/", component: <PublicHome /> },
|
|
245
|
+
{
|
|
246
|
+
path: "dashboard",
|
|
247
|
+
component: (
|
|
248
|
+
<ProtectedRoute>
|
|
249
|
+
<Dashboard />
|
|
250
|
+
</ProtectedRoute>
|
|
251
|
+
),
|
|
252
|
+
},
|
|
253
|
+
]);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
📖 **See:** [Authentication Flow in EXAMPLES.md](./EXAMPLES.md#authentication-flow)
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Feature Matrix
|
|
261
|
+
|
|
262
|
+
| Feature | Status | Documentation |
|
|
263
|
+
| --------------------- | ------ | ------------------------------------------------ |
|
|
264
|
+
| Static Routes | ✅ | [Docs](./DOCUMENTATION.md#routes) |
|
|
265
|
+
| Dynamic Routes | ✅ | [Docs](./DOCUMENTATION.md#useparams) |
|
|
266
|
+
| Nested Routes | ✅ | [Docs](./DOCUMENTATION.md#nested-routes) |
|
|
267
|
+
| Multiple Path Aliases | ✅ | [Docs](./DOCUMENTATION.md#multiple-path-aliases) |
|
|
268
|
+
| Query Parameters | ✅ | [Docs](./DOCUMENTATION.md#usequery) |
|
|
269
|
+
| Navigation State | ✅ | [Docs](./DOCUMENTATION.md#navigation-state) |
|
|
270
|
+
| Custom 404 Pages | ✅ | [Docs](./DOCUMENTATION.md#custom-404-pages) |
|
|
271
|
+
| TypeScript Support | ✅ | [Docs](./DOCUMENTATION.md#typescript-support) |
|
|
272
|
+
| Error Handling | ✅ | [Docs](./DOCUMENTATION.md#error-handling) |
|
|
273
|
+
| Dynamic Components | ✅ | [Docs](./API_REFERENCE.md#usedynamiccomponents) |
|
|
274
|
+
| Hash Routing | ⏳ | Planned |
|
|
275
|
+
| Regex Routes | ⏳ | Planned |
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Quick Reference
|
|
280
|
+
|
|
281
|
+
### Imports
|
|
128
282
|
|
|
129
283
|
```tsx
|
|
130
|
-
|
|
284
|
+
// Core
|
|
131
285
|
import { createRouter, RouterProvider } from "router-kit";
|
|
132
286
|
|
|
133
|
-
|
|
134
|
-
|
|
287
|
+
// Components
|
|
288
|
+
import { Link, NavLink } from "router-kit";
|
|
289
|
+
|
|
290
|
+
// Hooks
|
|
291
|
+
import {
|
|
292
|
+
useRouter,
|
|
293
|
+
useParams,
|
|
294
|
+
useQuery,
|
|
295
|
+
useLocation,
|
|
296
|
+
useDynamicComponents,
|
|
297
|
+
} from "router-kit";
|
|
298
|
+
|
|
299
|
+
// Types
|
|
300
|
+
import type {
|
|
301
|
+
Route,
|
|
302
|
+
RouterContextType,
|
|
303
|
+
NavigateOptions,
|
|
304
|
+
Location,
|
|
305
|
+
RouterKitError,
|
|
306
|
+
} from "router-kit";
|
|
307
|
+
|
|
308
|
+
// Error System
|
|
309
|
+
import { RouterErrorCode, RouterErrors, createRouterError } from "router-kit";
|
|
310
|
+
```
|
|
135
311
|
|
|
136
|
-
|
|
137
|
-
{ path: "/", component: <Home /> },
|
|
138
|
-
{ path: "about", component: <About /> },
|
|
139
|
-
{ path: "/404", component: <div>Not Found</div> },
|
|
140
|
-
]);
|
|
312
|
+
### Route Patterns
|
|
141
313
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
314
|
+
```tsx
|
|
315
|
+
// Static route
|
|
316
|
+
{ path: "about", component: <About /> }
|
|
317
|
+
|
|
318
|
+
// Dynamic parameter
|
|
319
|
+
{ path: "users/:id", component: <UserProfile /> }
|
|
320
|
+
|
|
321
|
+
// Multiple parameters
|
|
322
|
+
{ path: "posts/:category/:slug", component: <BlogPost /> }
|
|
323
|
+
|
|
324
|
+
// Multiple paths
|
|
325
|
+
{ path: ["about", "about-us"], component: <About /> }
|
|
326
|
+
|
|
327
|
+
// Nested routes
|
|
328
|
+
{
|
|
329
|
+
path: "dashboard",
|
|
330
|
+
component: <Dashboard />,
|
|
331
|
+
children: [
|
|
332
|
+
{ path: "settings", component: <Settings /> }
|
|
333
|
+
]
|
|
145
334
|
}
|
|
146
335
|
|
|
147
|
-
|
|
336
|
+
// 404 page
|
|
337
|
+
{ path: "/404", component: <NotFound /> }
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Hook Usage
|
|
341
|
+
|
|
342
|
+
```tsx
|
|
343
|
+
// Get router context
|
|
344
|
+
const { path, navigate } = useRouter();
|
|
345
|
+
|
|
346
|
+
// Get route parameters
|
|
347
|
+
const { id, slug } = useParams();
|
|
348
|
+
|
|
349
|
+
// Get query parameters
|
|
350
|
+
const { search, page } = useQuery();
|
|
351
|
+
|
|
352
|
+
// Get location details
|
|
353
|
+
const { pathname, search, hash, state } = useLocation();
|
|
354
|
+
|
|
355
|
+
// Dynamic components
|
|
356
|
+
const component = useDynamicComponents(viewsObject, "paramName");
|
|
148
357
|
```
|
|
149
358
|
|
|
150
|
-
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Version Information
|
|
362
|
+
|
|
363
|
+
- **Current Version:** 1.3.1
|
|
364
|
+
- **React Version:** >=16 <20
|
|
365
|
+
- **TypeScript:** >=5.2.0
|
|
366
|
+
- **License:** MIT
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Support & Community
|
|
371
|
+
|
|
372
|
+
- **Website:** [routerkit.com](https://routerkit.com/)
|
|
373
|
+
- **GitHub Repository:** [github.com/Mohammed-Ben-Cheikh/router-kit](https://github.com/Mohammed-Ben-Cheikh/router-kit)
|
|
374
|
+
- **Issues:** [Report bugs or request features](https://github.com/Mohammed-Ben-Cheikh/router-kit/issues)
|
|
375
|
+
- **Author:** Mohammed Ben Cheikh
|
|
376
|
+
- **Email:** mohammed.bencheikh.dev@gmail.com
|
|
377
|
+
- **Website:** [mohammedbencheikh.com](https://mohammedbencheikh.com/)
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## Contributing
|
|
382
|
+
|
|
383
|
+
We welcome contributions! Here's how to get started:
|
|
384
|
+
|
|
385
|
+
1. **Fork the repository**
|
|
386
|
+
2. **Create a feature branch:** `git checkout -b feature/amazing-feature`
|
|
387
|
+
3. **Make your changes**
|
|
388
|
+
4. **Run tests and type checks:** `npm run typecheck`
|
|
389
|
+
5. **Commit your changes:** `git commit -m 'Add amazing feature'`
|
|
390
|
+
6. **Push to your fork:** `git push origin feature/amazing-feature`
|
|
391
|
+
7. **Open a Pull Request**
|
|
392
|
+
|
|
393
|
+
**See:** [ARCHITECTURE.md](./ARCHITECTURE.md) for implementation details.
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## Changelog
|
|
398
|
+
|
|
399
|
+
### v1.3.1 (Current)
|
|
400
|
+
|
|
401
|
+
- Full TypeScript support with comprehensive types
|
|
402
|
+
- Enhanced error handling system with detailed context
|
|
403
|
+
- New `useDynamicComponents` hook
|
|
404
|
+
- New `useLocation` hook with state support
|
|
405
|
+
- Improved type exports
|
|
406
|
+
- Better error messages
|
|
407
|
+
|
|
408
|
+
### Previous Versions
|
|
409
|
+
|
|
410
|
+
See [GitHub Releases](https://github.com/Mohammed-Ben-Cheikh/router-kit/releases) for full changelog.
|
|
411
|
+
|
|
412
|
+
---
|
|
151
413
|
|
|
152
|
-
|
|
414
|
+
## FAQ
|
|
153
415
|
|
|
154
|
-
|
|
416
|
+
### How does Router-Kit compare to React Router?
|
|
155
417
|
|
|
156
|
-
|
|
418
|
+
Router-Kit is simpler and lighter. It's perfect for small to medium projects that don't need the full complexity of React Router.
|
|
157
419
|
|
|
158
|
-
|
|
420
|
+
📖 **See:** [Migration Guide in DOCUMENTATION.md](./DOCUMENTATION.md#migration-guide)
|
|
159
421
|
|
|
160
|
-
|
|
161
|
-
- `npm run typecheck` : vérifie les types sans émettre de fichiers.
|
|
162
|
-
- `npm run clean` : supprime `dist`.
|
|
422
|
+
### Can I use Router-Kit with TypeScript?
|
|
163
423
|
|
|
164
|
-
|
|
424
|
+
Yes! Router-Kit is written in TypeScript and provides full type definitions.
|
|
165
425
|
|
|
166
|
-
|
|
167
|
-
2. Lancer `npm run build:watch` si vous modifiez le package et voulez recompiler automatiquement.
|
|
426
|
+
📖 **See:** [TypeScript Support in DOCUMENTATION.md](./DOCUMENTATION.md#typescript-support)
|
|
168
427
|
|
|
169
|
-
|
|
428
|
+
### How do I handle authentication?
|
|
170
429
|
|
|
171
|
-
|
|
430
|
+
Use the ProtectedRoute pattern with useRouter and useLocation hooks.
|
|
172
431
|
|
|
173
|
-
|
|
174
|
-
2. Soumettre une PR avec un seul changement logique par PR.
|
|
432
|
+
📖 **See:** [Authentication Flow in EXAMPLES.md](./EXAMPLES.md#authentication-flow)
|
|
175
433
|
|
|
176
|
-
|
|
434
|
+
### How do I create nested routes?
|
|
177
435
|
|
|
178
|
-
|
|
179
|
-
- Support plus riche du matching (wildcards, regex, exact/partial).
|
|
180
|
-
- Tests unitaires et CI.
|
|
436
|
+
Use the `children` property in route configuration.
|
|
181
437
|
|
|
182
|
-
|
|
438
|
+
📖 **See:** [Nested Routes in DOCUMENTATION.md](./DOCUMENTATION.md#nested-routes)
|
|
183
439
|
|
|
184
|
-
|
|
440
|
+
### What about 404 pages?
|
|
441
|
+
|
|
442
|
+
Add a route with `path: "/404"` and Router-Kit will use it automatically.
|
|
443
|
+
|
|
444
|
+
📖 **See:** [Custom 404 Pages in DOCUMENTATION.md](./DOCUMENTATION.md#custom-404-pages)
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Learn More
|
|
449
|
+
|
|
450
|
+
Ready to dive deeper? Start with the [Complete Documentation](./DOCUMENTATION.md) or explore specific topics:
|
|
451
|
+
|
|
452
|
+
- New to Router-Kit? → [DOCUMENTATION.md](./DOCUMENTATION.md)
|
|
453
|
+
- Need API details? → [API_REFERENCE.md](./API_REFERENCE.md)
|
|
454
|
+
- Want examples? → [EXAMPLES.md](./EXAMPLES.md)
|
|
455
|
+
- Curious about internals? → [ARCHITECTURE.md](./ARCHITECTURE.md)
|
|
185
456
|
|
|
186
457
|
---
|
|
458
|
+
|
|
459
|
+
**Happy Routing! 🚀**
|
|
@@ -17,18 +17,6 @@ const RouterProvider = ({ routes }) => {
|
|
|
17
17
|
const [path, setPath] = useState("");
|
|
18
18
|
const [fullPathWithParams, setFullPathWithParams] = useState("");
|
|
19
19
|
let page404 = null;
|
|
20
|
-
const paths = routes.flatMap((route) => {
|
|
21
|
-
const collectPaths = (r, parentPath = "/") => {
|
|
22
|
-
const fullPath = join(parentPath, `/${r.path}`);
|
|
23
|
-
const currentPaths = [fullPath];
|
|
24
|
-
if (r.children) {
|
|
25
|
-
const childPaths = r.children.flatMap((child) => collectPaths(child, fullPath));
|
|
26
|
-
return [...currentPaths, ...childPaths];
|
|
27
|
-
}
|
|
28
|
-
return currentPaths;
|
|
29
|
-
};
|
|
30
|
-
return collectPaths(route);
|
|
31
|
-
});
|
|
32
20
|
useEffect(() => {
|
|
33
21
|
setPath(window.location.pathname);
|
|
34
22
|
const patchHistory = (method) => {
|
|
@@ -57,22 +45,7 @@ const RouterProvider = ({ routes }) => {
|
|
|
57
45
|
}, []);
|
|
58
46
|
const pathValidation = (routeFullPath, currentPath) => {
|
|
59
47
|
const routePaths = routeFullPath.split("|");
|
|
60
|
-
const staticPaths = [];
|
|
61
|
-
const dynamicPaths = [];
|
|
62
48
|
for (const routePath of routePaths) {
|
|
63
|
-
if (routePath.includes(":")) {
|
|
64
|
-
dynamicPaths.push(routePath);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
staticPaths.push(routePath);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
for (const routePath of staticPaths) {
|
|
71
|
-
if (routePath === currentPath) {
|
|
72
|
-
return routePath;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
for (const routePath of dynamicPaths) {
|
|
76
49
|
const routeParts = routePath.split("/").filter(Boolean);
|
|
77
50
|
const pathParts = currentPath.split("/").filter(Boolean);
|
|
78
51
|
if (routeParts.length !== pathParts.length)
|
|
@@ -94,12 +67,39 @@ const RouterProvider = ({ routes }) => {
|
|
|
94
67
|
return false;
|
|
95
68
|
};
|
|
96
69
|
const getComponent = (routesList, currentPath, parentPath = "/") => {
|
|
70
|
+
const staticRoutes = [];
|
|
71
|
+
const dynamicRoutes = [];
|
|
97
72
|
for (const route of routesList) {
|
|
98
73
|
const is404 = route.path === "404" || route.path === "/404";
|
|
99
74
|
if (is404) {
|
|
100
75
|
page404 = route.component;
|
|
101
76
|
continue;
|
|
102
77
|
}
|
|
78
|
+
const pathArray = Array.isArray(route.path) ? route.path : [route.path];
|
|
79
|
+
const hasDynamicParams = pathArray.some((p) => p.includes(":"));
|
|
80
|
+
if (hasDynamicParams) {
|
|
81
|
+
dynamicRoutes.push(route);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
staticRoutes.push(route);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
for (const route of staticRoutes) {
|
|
88
|
+
const fullPath = join(parentPath, `/${route.path}`);
|
|
89
|
+
const matchedPath = pathValidation(fullPath, currentPath);
|
|
90
|
+
if (matchedPath) {
|
|
91
|
+
if (matchedPath !== fullPathWithParams) {
|
|
92
|
+
setFullPathWithParams(matchedPath);
|
|
93
|
+
}
|
|
94
|
+
return route.component;
|
|
95
|
+
}
|
|
96
|
+
if (route.children) {
|
|
97
|
+
const childMatch = getComponent(route.children, currentPath, fullPath);
|
|
98
|
+
if (childMatch)
|
|
99
|
+
return childMatch;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const route of dynamicRoutes) {
|
|
103
103
|
const fullPath = join(parentPath, `/${route.path}`);
|
|
104
104
|
const matchedPath = pathValidation(fullPath, currentPath);
|
|
105
105
|
if (matchedPath) {
|
package/package.json
CHANGED