@aminnairi/react-router 2.2.0 → 3.0.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/README.md +283 -193
- package/index.tsx +416 -278
- package/package.json +4 -1
- package/.eslintrc.cjs +0 -13
- package/tsconfig.json +0 -16
package/README.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
Type-safe router for the React library
|
|
4
4
|
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- [Requirements](#requirements)
|
|
8
|
+
- [Usage](#usage)
|
|
9
|
+
- [Project initialization](#project-initialization)
|
|
10
|
+
- [Dependencies installation](#dependencies-installation)
|
|
11
|
+
- [Library installation](#library-installation)
|
|
12
|
+
- [Setup](#setup)
|
|
13
|
+
- [Startup](#startup)
|
|
14
|
+
- [API](#api)
|
|
15
|
+
- [createPage](#createpage)
|
|
16
|
+
- [useNavigateToPage](#usenavigatetopage)
|
|
17
|
+
- [createRouter](#createrouter)
|
|
18
|
+
- [useIsActivePage](#useisactivepage)
|
|
19
|
+
- [useLocale](#uselocale)
|
|
20
|
+
- [usePrefix](#useprefix)
|
|
21
|
+
- [usePath](#usepath)
|
|
22
|
+
- [Features](#features)
|
|
23
|
+
- [TypeScript](#typescript)
|
|
24
|
+
- [No codegen](#no-codegen)
|
|
25
|
+
- [Simplicity](#simplicity)
|
|
26
|
+
- [Transition](#transition)
|
|
27
|
+
- [Error handling](#error-handling)
|
|
28
|
+
- [License](#license)
|
|
29
|
+
- [Changelogs](#changelogs)
|
|
30
|
+
- [Versions](#versions)
|
|
31
|
+
- [3.0.0](#300)
|
|
32
|
+
- [2.1.0](#210)
|
|
33
|
+
- [2.0.1](#201)
|
|
34
|
+
- [2.0.0](#200)
|
|
35
|
+
- [1.1.0](#110)
|
|
36
|
+
- [1.0.1](#101)
|
|
37
|
+
- [1.0.0](#100)
|
|
38
|
+
- [0.1.1](#011)
|
|
39
|
+
- [0.1.0](#010)
|
|
40
|
+
|
|
5
41
|
## Requirements
|
|
6
42
|
|
|
7
43
|
- [Node](https://nodejs.org/)
|
|
@@ -52,13 +88,13 @@ touch src/router/fallback.tsx
|
|
|
52
88
|
```
|
|
53
89
|
|
|
54
90
|
```tsx
|
|
55
|
-
import { useNavigateToPage } from "
|
|
91
|
+
import { useNavigateToPage } from ".";
|
|
56
92
|
import { home } from "./pages/home";
|
|
57
93
|
|
|
58
94
|
export const Fallback = () => {
|
|
59
95
|
const navigateToHomePage = useNavigateToPage(home);
|
|
60
96
|
|
|
61
|
-
return <button onClick={
|
|
97
|
+
return <button onClick={navigateToHomePage}>Go back home</button>;
|
|
62
98
|
};
|
|
63
99
|
```
|
|
64
100
|
|
|
@@ -68,7 +104,7 @@ touch src/router/issue.tsx
|
|
|
68
104
|
|
|
69
105
|
```tsx
|
|
70
106
|
import { Fragment } from "react";
|
|
71
|
-
import { useNavigateToPage } from "
|
|
107
|
+
import { useNavigateToPage } from ".";
|
|
72
108
|
import { home } from "./pages/home";
|
|
73
109
|
|
|
74
110
|
export const Issue = () => {
|
|
@@ -77,7 +113,7 @@ export const Issue = () => {
|
|
|
77
113
|
return (
|
|
78
114
|
<Fragment>
|
|
79
115
|
<h1>An issue occurred</h1>
|
|
80
|
-
<button onClick={
|
|
116
|
+
<button onClick={navigateToHomePage}>Go back home</button>
|
|
81
117
|
</Fragment>
|
|
82
118
|
);
|
|
83
119
|
};
|
|
@@ -93,7 +129,7 @@ import { Fallback } from "./fallback";
|
|
|
93
129
|
import { Issue } from "./issue";
|
|
94
130
|
import { home } from "./pages/home";
|
|
95
131
|
|
|
96
|
-
export const
|
|
132
|
+
export const { RouterProvider, RouterView, useNavigateToPage } = createRouter({
|
|
97
133
|
fallback: Fallback,
|
|
98
134
|
issue: Issue,
|
|
99
135
|
pages: [home],
|
|
@@ -105,10 +141,10 @@ touch src/App.tsx
|
|
|
105
141
|
```
|
|
106
142
|
|
|
107
143
|
```tsx
|
|
108
|
-
import {
|
|
144
|
+
import { RouterView } from "./router";
|
|
109
145
|
|
|
110
146
|
export default function App() {
|
|
111
|
-
return <
|
|
147
|
+
return <RouterView />;
|
|
112
148
|
}
|
|
113
149
|
```
|
|
114
150
|
|
|
@@ -119,7 +155,7 @@ touch src/main.tsx
|
|
|
119
155
|
```tsx
|
|
120
156
|
import { StrictMode } from "react";
|
|
121
157
|
import { createRoot } from "react-dom/client";
|
|
122
|
-
import {
|
|
158
|
+
import { RouterProvider } from "./router";
|
|
123
159
|
import App from "./App";
|
|
124
160
|
|
|
125
161
|
const rootElement = document.getElementById("root");
|
|
@@ -130,9 +166,9 @@ if (!rootElement) {
|
|
|
130
166
|
|
|
131
167
|
createRoot(rootElement).render(
|
|
132
168
|
<StrictMode>
|
|
133
|
-
<
|
|
169
|
+
<RouterProvider>
|
|
134
170
|
<App />
|
|
135
|
-
</
|
|
171
|
+
</RouterProvider>
|
|
136
172
|
</StrictMode>,
|
|
137
173
|
);
|
|
138
174
|
```
|
|
@@ -213,9 +249,11 @@ createPage({
|
|
|
213
249
|
|
|
214
250
|
You can navigate from one page from another.
|
|
215
251
|
|
|
252
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
253
|
+
|
|
216
254
|
```tsx
|
|
217
255
|
import { Fragment } from "react";
|
|
218
|
-
import { createPage,
|
|
256
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
219
257
|
|
|
220
258
|
const login = createPage({
|
|
221
259
|
path: "/login",
|
|
@@ -232,12 +270,18 @@ const about = createPage({
|
|
|
232
270
|
return (
|
|
233
271
|
<Fragment>
|
|
234
272
|
<h1>About Us</h1>
|
|
235
|
-
<button onClick={
|
|
273
|
+
<button onClick={navigateToLoginPage}>Login</button>
|
|
236
274
|
</Fragment>
|
|
237
275
|
);
|
|
238
276
|
},
|
|
239
277
|
});
|
|
240
278
|
|
|
279
|
+
const { useNavigateToPage } = createRouter({
|
|
280
|
+
fallback: () => <h1>Not found</h1>,
|
|
281
|
+
issue: () => <h1>An error occurred</h1>,
|
|
282
|
+
pages: [login, about],
|
|
283
|
+
});
|
|
284
|
+
|
|
241
285
|
createPage({
|
|
242
286
|
path: "/",
|
|
243
287
|
element: function Home() {
|
|
@@ -246,7 +290,7 @@ createPage({
|
|
|
246
290
|
return (
|
|
247
291
|
<Fragment>
|
|
248
292
|
<h1>Home</h1>
|
|
249
|
-
<button onClick={
|
|
293
|
+
<button onClick={navigateToAboutPage}>About Us</button>
|
|
250
294
|
</Fragment>
|
|
251
295
|
);
|
|
252
296
|
},
|
|
@@ -257,7 +301,7 @@ And you can of course navigate to pages that have dynamic parameters as well.
|
|
|
257
301
|
|
|
258
302
|
```tsx
|
|
259
303
|
import { Fragment } from "react";
|
|
260
|
-
import { createPage,
|
|
304
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
261
305
|
|
|
262
306
|
const user = createPage({
|
|
263
307
|
path: "/users/:user",
|
|
@@ -266,6 +310,12 @@ const user = createPage({
|
|
|
266
310
|
},
|
|
267
311
|
});
|
|
268
312
|
|
|
313
|
+
const { useNavigateToPage } = createRouter({
|
|
314
|
+
fallback: () => <h1>Not found</h1>,
|
|
315
|
+
issue: () => <h1>An error occurred</h1>,
|
|
316
|
+
pages: [user],
|
|
317
|
+
});
|
|
318
|
+
|
|
269
319
|
createPage({
|
|
270
320
|
path: "/",
|
|
271
321
|
element: function Home() {
|
|
@@ -299,7 +349,7 @@ const home = createPage({
|
|
|
299
349
|
},
|
|
300
350
|
});
|
|
301
351
|
|
|
302
|
-
const
|
|
352
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
303
353
|
fallback: () => <h1>Not found</h1>,
|
|
304
354
|
issue: () => <h1>An error occurred</h1>,
|
|
305
355
|
pages: [home],
|
|
@@ -320,7 +370,7 @@ const App = () => {
|
|
|
320
370
|
<h1>App</h1>
|
|
321
371
|
</header>
|
|
322
372
|
<main>
|
|
323
|
-
<
|
|
373
|
+
<RouterView />
|
|
324
374
|
</main>
|
|
325
375
|
<footer>Credit © Yourself 2025</footer>
|
|
326
376
|
</Fragment>
|
|
@@ -329,18 +379,18 @@ const App = () => {
|
|
|
329
379
|
|
|
330
380
|
root.render(
|
|
331
381
|
<StrictMode>
|
|
332
|
-
<
|
|
382
|
+
<RouterProvider>
|
|
333
383
|
<App />
|
|
334
|
-
</
|
|
384
|
+
</RouterProvider>
|
|
335
385
|
</StrictMode>,
|
|
336
386
|
);
|
|
337
387
|
```
|
|
338
388
|
|
|
339
389
|
You can also activate the View Transition Web API if you want before each page renders. This is nice because by default, the browser already has some styling that allows for a smooth and simple transition between pages.
|
|
340
390
|
|
|
341
|
-
All you have to do is to provide a `transition` function in the arguments of the `createRouter` function. This function receives the navigation direction (`"
|
|
391
|
+
All you have to do is to provide a `transition` function in the arguments of the `createRouter` function. This function receives the navigation direction (`"forward"` or `"backward"`) and a `next` callback to render the next page.
|
|
342
392
|
|
|
343
|
-
This library also exports
|
|
393
|
+
This library also exports several transitions that you can use out-of-the-box: `slideHorizontalTransition`, `slideVerticalTransition`, `crossFadeTransition`, and `scaleFadeTransition`.
|
|
344
394
|
|
|
345
395
|
```tsx
|
|
346
396
|
import { Fragment, StrictMode } from "react";
|
|
@@ -348,7 +398,7 @@ import { createRoot } from "react-dom/client";
|
|
|
348
398
|
import {
|
|
349
399
|
createRouter,
|
|
350
400
|
createPage,
|
|
351
|
-
|
|
401
|
+
slideHorizontalTransition,
|
|
352
402
|
} from "@aminnairi/react-router";
|
|
353
403
|
|
|
354
404
|
const home = createPage({
|
|
@@ -358,8 +408,8 @@ const home = createPage({
|
|
|
358
408
|
},
|
|
359
409
|
});
|
|
360
410
|
|
|
361
|
-
const
|
|
362
|
-
transition:
|
|
411
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
412
|
+
transition: slideHorizontalTransition,
|
|
363
413
|
fallback: () => <h1>Not found</h1>,
|
|
364
414
|
issue: () => <h1>An error occurred</h1>,
|
|
365
415
|
pages: [home],
|
|
@@ -380,7 +430,7 @@ const App = () => {
|
|
|
380
430
|
<h1>App</h1>
|
|
381
431
|
</header>
|
|
382
432
|
<main>
|
|
383
|
-
<
|
|
433
|
+
<RouterView />
|
|
384
434
|
</main>
|
|
385
435
|
<footer>Credit © Yourself 2025</footer>
|
|
386
436
|
</Fragment>
|
|
@@ -389,9 +439,9 @@ const App = () => {
|
|
|
389
439
|
|
|
390
440
|
root.render(
|
|
391
441
|
<StrictMode>
|
|
392
|
-
<
|
|
442
|
+
<RouterProvider>
|
|
393
443
|
<App />
|
|
394
|
-
</
|
|
444
|
+
</RouterProvider>
|
|
395
445
|
</StrictMode>,
|
|
396
446
|
);
|
|
397
447
|
```
|
|
@@ -410,13 +460,13 @@ const home = createPage({
|
|
|
410
460
|
},
|
|
411
461
|
});
|
|
412
462
|
|
|
413
|
-
const
|
|
463
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
414
464
|
fallback: () => <h1>Not found</h1>,
|
|
415
|
-
issue: ({ error,
|
|
465
|
+
issue: ({ error, resetError }) => (
|
|
416
466
|
<Fragment>
|
|
417
467
|
<h1>Error</h1>
|
|
418
468
|
<p>{error.message}</p>
|
|
419
|
-
<button onClick={
|
|
469
|
+
<button onClick={resetError}>Reset</button>
|
|
420
470
|
</Fragment>
|
|
421
471
|
),
|
|
422
472
|
pages: [home],
|
|
@@ -437,7 +487,7 @@ const App = () => {
|
|
|
437
487
|
<h1>App</h1>
|
|
438
488
|
</header>
|
|
439
489
|
<main>
|
|
440
|
-
<
|
|
490
|
+
<RouterView />
|
|
441
491
|
</main>
|
|
442
492
|
<footer>Credit © Yourself 2025</footer>
|
|
443
493
|
</Fragment>
|
|
@@ -446,19 +496,19 @@ const App = () => {
|
|
|
446
496
|
|
|
447
497
|
root.render(
|
|
448
498
|
<StrictMode>
|
|
449
|
-
<
|
|
499
|
+
<RouterProvider>
|
|
450
500
|
<App />
|
|
451
|
-
</
|
|
501
|
+
</RouterProvider>
|
|
452
502
|
</StrictMode>,
|
|
453
503
|
);
|
|
454
504
|
```
|
|
455
505
|
|
|
456
|
-
You can also define
|
|
506
|
+
You can also define the issue component from the outside.
|
|
457
507
|
|
|
458
508
|
```tsx
|
|
459
509
|
import { Fragment, StrictMode } from "react";
|
|
460
510
|
import { createRoot } from "react-dom/client";
|
|
461
|
-
import { createRouter, createPage,
|
|
511
|
+
import { createRouter, createPage, IssueProps } from "@aminnairi/react-router";
|
|
462
512
|
|
|
463
513
|
const home = createPage({
|
|
464
514
|
path: "/",
|
|
@@ -471,15 +521,15 @@ const Fallback = () => {
|
|
|
471
521
|
return <h1>Not found</h1>;
|
|
472
522
|
};
|
|
473
523
|
|
|
474
|
-
const Issue =
|
|
524
|
+
const Issue = ({ error, resetError }: IssueProps) => (
|
|
475
525
|
<Fragment>
|
|
476
526
|
<h1>Error</h1>
|
|
477
527
|
<p>{error.message}</p>
|
|
478
|
-
<button onClick={
|
|
528
|
+
<button onClick={resetError}>Reset</button>
|
|
479
529
|
</Fragment>
|
|
480
|
-
)
|
|
530
|
+
);
|
|
481
531
|
|
|
482
|
-
const
|
|
532
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
483
533
|
fallback: Fallback,
|
|
484
534
|
issue: Issue,
|
|
485
535
|
pages: [home],
|
|
@@ -500,7 +550,7 @@ const App = () => {
|
|
|
500
550
|
<h1>App</h1>
|
|
501
551
|
</header>
|
|
502
552
|
<main>
|
|
503
|
-
<
|
|
553
|
+
<RouterView />
|
|
504
554
|
</main>
|
|
505
555
|
<footer>Credit © Yourself 2025</footer>
|
|
506
556
|
</Fragment>
|
|
@@ -509,9 +559,9 @@ const App = () => {
|
|
|
509
559
|
|
|
510
560
|
root.render(
|
|
511
561
|
<StrictMode>
|
|
512
|
-
<
|
|
562
|
+
<RouterProvider>
|
|
513
563
|
<App />
|
|
514
|
-
</
|
|
564
|
+
</RouterProvider>
|
|
515
565
|
</StrictMode>,
|
|
516
566
|
);
|
|
517
567
|
```
|
|
@@ -526,8 +576,7 @@ import { createRoot } from "react-dom/client";
|
|
|
526
576
|
import {
|
|
527
577
|
createRouter,
|
|
528
578
|
createPage,
|
|
529
|
-
|
|
530
|
-
useNavigateToPage,
|
|
579
|
+
IssueProps,
|
|
531
580
|
} from "@aminnairi/react-router";
|
|
532
581
|
|
|
533
582
|
const home = createPage({
|
|
@@ -543,20 +592,20 @@ const Fallback = () => {
|
|
|
543
592
|
return (
|
|
544
593
|
<Fragment>
|
|
545
594
|
<h1>Not found</h1>
|
|
546
|
-
<button onClick={
|
|
595
|
+
<button onClick={navigateToHomePage}>Go Back Home</button>
|
|
547
596
|
</Fragment>
|
|
548
597
|
);
|
|
549
598
|
};
|
|
550
599
|
|
|
551
|
-
const Issue =
|
|
600
|
+
const Issue = ({ error, resetError }: IssueProps) => (
|
|
552
601
|
<Fragment>
|
|
553
602
|
<h1>Error</h1>
|
|
554
603
|
<p>{error.message}</p>
|
|
555
|
-
<button onClick={
|
|
604
|
+
<button onClick={resetError}>Reset</button>
|
|
556
605
|
</Fragment>
|
|
557
|
-
)
|
|
606
|
+
);
|
|
558
607
|
|
|
559
|
-
const
|
|
608
|
+
const { RouterProvider, RouterView, useNavigateToPage } = createRouter({
|
|
560
609
|
prefix: "/portfolio",
|
|
561
610
|
fallback: Fallback,
|
|
562
611
|
issue: Issue,
|
|
@@ -578,7 +627,7 @@ const App = () => {
|
|
|
578
627
|
<h1>App</h1>
|
|
579
628
|
</header>
|
|
580
629
|
<main>
|
|
581
|
-
<
|
|
630
|
+
<RouterView />
|
|
582
631
|
</main>
|
|
583
632
|
<footer>Credit © Yourself 2025</footer>
|
|
584
633
|
</Fragment>
|
|
@@ -587,9 +636,9 @@ const App = () => {
|
|
|
587
636
|
|
|
588
637
|
root.render(
|
|
589
638
|
<StrictMode>
|
|
590
|
-
<
|
|
639
|
+
<RouterProvider>
|
|
591
640
|
<App />
|
|
592
|
-
</
|
|
641
|
+
</RouterProvider>
|
|
593
642
|
</StrictMode>,
|
|
594
643
|
);
|
|
595
644
|
```
|
|
@@ -600,9 +649,11 @@ Allow you to create a function that can then be called to navigate to another pa
|
|
|
600
649
|
|
|
601
650
|
It accepts a page that has been created using `createPage`.
|
|
602
651
|
|
|
652
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
653
|
+
|
|
603
654
|
```tsx
|
|
604
655
|
import { Fragment } from "react";
|
|
605
|
-
import { createPage,
|
|
656
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
606
657
|
|
|
607
658
|
const home = createPage({
|
|
608
659
|
path: "/",
|
|
@@ -611,6 +662,12 @@ const home = createPage({
|
|
|
611
662
|
},
|
|
612
663
|
});
|
|
613
664
|
|
|
665
|
+
const { useNavigateToPage } = createRouter({
|
|
666
|
+
fallback: () => <h1>Not found</h1>,
|
|
667
|
+
issue: () => <h1>An error occurred</h1>,
|
|
668
|
+
pages: [home],
|
|
669
|
+
});
|
|
670
|
+
|
|
614
671
|
createPage({
|
|
615
672
|
path: "/about",
|
|
616
673
|
element: function About() {
|
|
@@ -619,7 +676,7 @@ createPage({
|
|
|
619
676
|
return (
|
|
620
677
|
<Fragment>
|
|
621
678
|
<h1>About</h1>
|
|
622
|
-
<button onClick={
|
|
679
|
+
<button onClick={navigateToHomePage}>Home</button>
|
|
623
680
|
</Fragment>
|
|
624
681
|
);
|
|
625
682
|
},
|
|
@@ -632,7 +689,7 @@ The parameters should always be provided as string, as they are the only data ty
|
|
|
632
689
|
|
|
633
690
|
```tsx
|
|
634
691
|
import { Fragment } from "react";
|
|
635
|
-
import { createPage,
|
|
692
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
636
693
|
|
|
637
694
|
const user = createPage({
|
|
638
695
|
path: "/users/:user",
|
|
@@ -658,200 +715,190 @@ createPage({
|
|
|
658
715
|
});
|
|
659
716
|
```
|
|
660
717
|
|
|
661
|
-
###
|
|
718
|
+
### useIsActivePage
|
|
662
719
|
|
|
663
|
-
Allow you to
|
|
720
|
+
Allow you to check if a page is currently active.
|
|
664
721
|
|
|
665
|
-
|
|
722
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
666
723
|
|
|
667
724
|
```tsx
|
|
668
|
-
|
|
669
|
-
import { createPage,
|
|
725
|
+
// router/index.ts
|
|
726
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
670
727
|
|
|
671
|
-
const
|
|
672
|
-
path: "/
|
|
673
|
-
element: function
|
|
674
|
-
return <h1>
|
|
728
|
+
export const home = createPage({
|
|
729
|
+
path: "/",
|
|
730
|
+
element: function Home() {
|
|
731
|
+
return <h1>Home</h1>;
|
|
675
732
|
},
|
|
676
733
|
});
|
|
677
734
|
|
|
678
|
-
createPage({
|
|
735
|
+
export const about = createPage({
|
|
679
736
|
path: "/about",
|
|
680
737
|
element: function About() {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
return (
|
|
684
|
-
<Fragment>
|
|
685
|
-
<h1>About</h1>
|
|
686
|
-
<Link parameters={{ user: "123" }}>User#123</Link>
|
|
687
|
-
</Fragment>
|
|
688
|
-
);
|
|
738
|
+
return <h1>About</h1>;
|
|
689
739
|
},
|
|
690
740
|
});
|
|
691
|
-
```
|
|
692
741
|
|
|
693
|
-
|
|
742
|
+
export const { useIsActivePage } = createRouter({
|
|
743
|
+
fallback: () => <h1>Not found</h1>,
|
|
744
|
+
issue: () => <h1>An error occurred</h1>,
|
|
745
|
+
pages: [home, about],
|
|
746
|
+
});
|
|
747
|
+
```
|
|
694
748
|
|
|
695
749
|
```tsx
|
|
750
|
+
// components/layout.tsx
|
|
696
751
|
import { Fragment } from "react";
|
|
697
|
-
import {
|
|
752
|
+
import { useIsActivePage, useNavigateToPage } from "../router";
|
|
753
|
+
import { home, about } from "../router";
|
|
698
754
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
return <h1>User#{user}</h1>;
|
|
703
|
-
},
|
|
704
|
-
});
|
|
755
|
+
export default function Layout() {
|
|
756
|
+
const isHomeActive = useIsActivePage(home);
|
|
757
|
+
const isAboutActive = useIsActivePage(about);
|
|
705
758
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
<button className="nav-button" onClick={onClick}>
|
|
712
|
-
{children}
|
|
759
|
+
return (
|
|
760
|
+
<Fragment>
|
|
761
|
+
<nav>
|
|
762
|
+
<button style={{ fontWeight: isHomeActive ? "bold" : "normal" }}>
|
|
763
|
+
Home
|
|
713
764
|
</button>
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
</Fragment>
|
|
722
|
-
);
|
|
723
|
-
},
|
|
724
|
-
});
|
|
765
|
+
<button style={{ fontWeight: isAboutActive ? "bold" : "normal" }}>
|
|
766
|
+
About
|
|
767
|
+
</button>
|
|
768
|
+
</nav>
|
|
769
|
+
</Fragment>
|
|
770
|
+
);
|
|
771
|
+
}
|
|
725
772
|
```
|
|
726
773
|
|
|
727
|
-
|
|
728
|
-
- `path`: The computed URL path with parameters filled in
|
|
729
|
-
- `onClick`: The click event handler that prevents default navigation and handles routing
|
|
730
|
-
- `children`: The children passed to the link component
|
|
731
|
-
|
|
732
|
-
### useSearch
|
|
774
|
+
### useLocale
|
|
733
775
|
|
|
734
|
-
Allow you to get
|
|
776
|
+
Allow you to get and set the current locale for internationalization.
|
|
735
777
|
|
|
736
|
-
This
|
|
778
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
737
779
|
|
|
738
780
|
```tsx
|
|
739
|
-
|
|
740
|
-
import { createPage,
|
|
781
|
+
// router/index.ts
|
|
782
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
741
783
|
|
|
742
|
-
createPage({
|
|
743
|
-
path: "/
|
|
784
|
+
export const home = createPage({
|
|
785
|
+
path: "/",
|
|
744
786
|
element: function Home() {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
return (
|
|
749
|
-
<h1>Users</h1>
|
|
750
|
-
<p>Sorted by date: {sortedByDate ? "yes" : "no"}</p>
|
|
751
|
-
);
|
|
752
|
-
}
|
|
787
|
+
return <h1>Home</h1>;
|
|
788
|
+
},
|
|
753
789
|
});
|
|
754
|
-
```
|
|
755
|
-
|
|
756
|
-
You cannot set the search queries for now, this will be added in future release of this library.
|
|
757
|
-
|
|
758
|
-
### useHash
|
|
759
|
-
|
|
760
|
-
Allow you to get the hash, also called fragment, from the URL which is everything after the `#` symbol.
|
|
761
790
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
element: function OauthCallback() {
|
|
768
|
-
const token = useHash();
|
|
769
|
-
|
|
770
|
-
return <h1>You token is {token}</h1>;
|
|
771
|
-
},
|
|
791
|
+
export const { RouterProvider, RouterView, useLocale } = createRouter({
|
|
792
|
+
locales: ["en", "fr"],
|
|
793
|
+
fallback: () => <h1>Not found</h1>,
|
|
794
|
+
issue: () => <h1>An error occurred</h1>,
|
|
795
|
+
pages: [home],
|
|
772
796
|
});
|
|
773
797
|
```
|
|
774
798
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
Return a boolean in case a route matches a path. A route is a URI that looks something like `/users/:user/articles` and a path is the browser's location pathname that looks something like `/users/123/articles`.
|
|
780
|
-
|
|
781
|
-
This function is mainly used in the internals of the `createRouter` and in most case should not be necessary.
|
|
782
|
-
|
|
783
|
-
```typescript
|
|
784
|
-
import { doesRouteMatchPath } from "@aminnairi/react-router";
|
|
785
|
-
|
|
786
|
-
doesRouteMatchPath("/", "/"); // true
|
|
787
|
-
|
|
788
|
-
doesRouteMatchPath("/", "/about"); // false
|
|
799
|
+
```tsx
|
|
800
|
+
// components/layout.tsx
|
|
801
|
+
import { Fragment } from "react";
|
|
802
|
+
import { useLocale } from "../router";
|
|
789
803
|
|
|
790
|
-
|
|
804
|
+
export default function Layout() {
|
|
805
|
+
const { locale, setLocale } = useLocale();
|
|
791
806
|
|
|
792
|
-
|
|
807
|
+
return (
|
|
808
|
+
<Fragment>
|
|
809
|
+
<nav>
|
|
810
|
+
<p>Current locale: {locale ?? "none"}</p>
|
|
811
|
+
<button onClick={() => setLocale("en")}>English</button>
|
|
812
|
+
<button onClick={() => setLocale("fr")}>Français</button>
|
|
813
|
+
</nav>
|
|
814
|
+
</Fragment>
|
|
815
|
+
);
|
|
816
|
+
}
|
|
793
817
|
```
|
|
794
818
|
|
|
795
|
-
|
|
819
|
+
### usePrefix
|
|
796
820
|
|
|
797
|
-
|
|
798
|
-
import { doesRouteMatchPath } from "@aminnairi/react-router";
|
|
821
|
+
Allow you to get the current route prefix.
|
|
799
822
|
|
|
800
|
-
|
|
823
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
801
824
|
|
|
802
|
-
|
|
825
|
+
```tsx
|
|
826
|
+
// router/index.ts
|
|
827
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
803
828
|
|
|
804
|
-
|
|
829
|
+
export const home = createPage({
|
|
830
|
+
path: "/",
|
|
831
|
+
element: function Home() {
|
|
832
|
+
return <h1>Home</h1>;
|
|
833
|
+
},
|
|
834
|
+
});
|
|
805
835
|
|
|
806
|
-
|
|
836
|
+
export const { RouterProvider, RouterView, usePrefix } = createRouter({
|
|
837
|
+
prefix: "/portfolio",
|
|
838
|
+
fallback: () => <h1>Not found</h1>,
|
|
839
|
+
issue: () => <h1>An error occurred</h1>,
|
|
840
|
+
pages: [home],
|
|
841
|
+
});
|
|
807
842
|
```
|
|
808
843
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
This function is mainly used in the internals of the `createRouter` and in most case should not be necessary.
|
|
814
|
-
|
|
815
|
-
```typescript
|
|
816
|
-
import { getParameters } from "@aminnairi/react-router";
|
|
817
|
-
|
|
818
|
-
getParameters("/", "/"); // {}
|
|
819
|
-
|
|
820
|
-
getParameters("/", "/about"); // {}
|
|
844
|
+
```tsx
|
|
845
|
+
// components/layout.tsx
|
|
846
|
+
import { Fragment } from "react";
|
|
847
|
+
import { usePrefix } from "../router";
|
|
821
848
|
|
|
822
|
-
|
|
849
|
+
export default function Layout() {
|
|
850
|
+
const { prefix } = usePrefix();
|
|
823
851
|
|
|
824
|
-
|
|
852
|
+
return (
|
|
853
|
+
<Fragment>
|
|
854
|
+
<nav>
|
|
855
|
+
<p>Current prefix: {prefix ?? "none"}</p>
|
|
856
|
+
</nav>
|
|
857
|
+
</Fragment>
|
|
858
|
+
);
|
|
859
|
+
}
|
|
825
860
|
```
|
|
826
861
|
|
|
827
|
-
|
|
862
|
+
### usePath
|
|
828
863
|
|
|
829
|
-
|
|
830
|
-
import { getParameters } from "@aminnairi/react-router";
|
|
864
|
+
Allow you to get the current path.
|
|
831
865
|
|
|
832
|
-
|
|
866
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
833
867
|
|
|
834
|
-
|
|
868
|
+
```tsx
|
|
869
|
+
// router/index.ts
|
|
870
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
835
871
|
|
|
836
|
-
|
|
872
|
+
export const home = createPage({
|
|
873
|
+
path: "/",
|
|
874
|
+
element: function Home() {
|
|
875
|
+
return <h1>Home</h1>;
|
|
876
|
+
},
|
|
877
|
+
});
|
|
837
878
|
|
|
838
|
-
|
|
879
|
+
export const { RouterProvider, RouterView, usePath } = createRouter({
|
|
880
|
+
fallback: () => <h1>Not found</h1>,
|
|
881
|
+
issue: () => <h1>An error occurred</h1>,
|
|
882
|
+
pages: [home],
|
|
883
|
+
});
|
|
839
884
|
```
|
|
840
885
|
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
```ts
|
|
846
|
-
import { sanitizePath } from "@aminnairi/react-router";
|
|
847
|
-
|
|
848
|
-
sanitizePath("/"); // "/"
|
|
849
|
-
|
|
850
|
-
sanitizePath("users"); // "/users"
|
|
886
|
+
```tsx
|
|
887
|
+
// components/layout.tsx
|
|
888
|
+
import { Fragment } from "react";
|
|
889
|
+
import { usePath } from "../router";
|
|
851
890
|
|
|
852
|
-
|
|
891
|
+
export default function Layout() {
|
|
892
|
+
const { path } = usePath();
|
|
853
893
|
|
|
854
|
-
|
|
894
|
+
return (
|
|
895
|
+
<Fragment>
|
|
896
|
+
<nav>
|
|
897
|
+
<p>Current path: {path}</p>
|
|
898
|
+
</nav>
|
|
899
|
+
</Fragment>
|
|
900
|
+
);
|
|
901
|
+
}
|
|
855
902
|
```
|
|
856
903
|
|
|
857
904
|
## Features
|
|
@@ -874,7 +921,7 @@ This means that you can use this library with other popular solutions for handli
|
|
|
874
921
|
|
|
875
922
|
### Transition
|
|
876
923
|
|
|
877
|
-
Support for the View Transition API is built-in and allows for painless and smooth view transition out-of-the-box. You can create your own transition animation, and the library also exports
|
|
924
|
+
Support for the View Transition API is built-in and allows for painless and smooth view transition out-of-the-box. You can create your own transition animation, and the library also exports several transitions ready to be used: `slideHorizontalTransition`, `slideVerticalTransition`, `crossFadeTransition`, and `scaleFadeTransition`.
|
|
878
925
|
|
|
879
926
|
### Error handling
|
|
880
927
|
|
|
@@ -888,6 +935,8 @@ See [`LICENSE`](./LICENSE).
|
|
|
888
935
|
|
|
889
936
|
### Versions
|
|
890
937
|
|
|
938
|
+
- [`3.0.1`](#301)
|
|
939
|
+
- [`3.0.0`](#300)
|
|
891
940
|
- [`2.1.0`](#210)
|
|
892
941
|
- [`2.0.1`](#201)
|
|
893
942
|
- [`2.0.0`](#200)
|
|
@@ -897,6 +946,47 @@ See [`LICENSE`](./LICENSE).
|
|
|
897
946
|
- [`0.1.1`](#011)
|
|
898
947
|
- [`0.1.0`](#010)
|
|
899
948
|
|
|
949
|
+
### 3.0.1
|
|
950
|
+
|
|
951
|
+
#### Major changes
|
|
952
|
+
|
|
953
|
+
None.
|
|
954
|
+
|
|
955
|
+
#### Minor changes
|
|
956
|
+
|
|
957
|
+
None.
|
|
958
|
+
|
|
959
|
+
#### Bug & security fixes
|
|
960
|
+
|
|
961
|
+
- Fixed incorrect imports in documentation - hooks like `useNavigateToPage`, `useIsActivePage`, `useLocale`, `usePrefix`, and `usePath` are returned from `createRouter` and should not be imported directly from the package
|
|
962
|
+
- Fixed file structure in documentation setup guide to properly separate files and avoid duplicate code definitions
|
|
963
|
+
- Updated issue component examples to use exported `IssueProps` type instead of inline type definitions
|
|
964
|
+
|
|
965
|
+
### 3.0.0
|
|
966
|
+
|
|
967
|
+
#### Major changes
|
|
968
|
+
|
|
969
|
+
- Full rewrite of the library implementation
|
|
970
|
+
- Added `locales` support for internationalization
|
|
971
|
+
- Added `useLocale` hook for locale management
|
|
972
|
+
- Added `usePrefix` and `usePath` hooks
|
|
973
|
+
- Renamed `slideFadeTransition` to `slideHorizontalTransition` and added new transitions: `scaleFadeTransition`, `crossFadeTransition`, `slideVerticalTransition`
|
|
974
|
+
- Changed API structure: `router.View` → `router.RouterView` and `router.Provider` → `RouterProvider`
|
|
975
|
+
- Renamed `reset` to `resetError` in `IssueProps`
|
|
976
|
+
- Renamed internal functions: `doesRouteMatchPath` → `matchPath`, `getParameters` → `matchParameters`
|
|
977
|
+
- Added `Uri` class for URL parsing
|
|
978
|
+
- Changed `createRouter` return value structure
|
|
979
|
+
- Removed `useLink`, `useSearch`, and `useHash` hooks and `UseLinkRenderFunction` type
|
|
980
|
+
|
|
981
|
+
#### Minor changes
|
|
982
|
+
|
|
983
|
+
- Added better URL normalization with `normalize` function
|
|
984
|
+
- Improved error handling with `ErrorBoundary` component
|
|
985
|
+
|
|
986
|
+
#### Bug & security fixes
|
|
987
|
+
|
|
988
|
+
- None.
|
|
989
|
+
|
|
900
990
|
### 2.1.0
|
|
901
991
|
|
|
902
992
|
#### Major changes
|