@aminnairi/react-router 2.0.1 → 3.0.0
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 +235 -157
- package/index.tsx +417 -271
- package/package.json +6 -2
- 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/)
|
|
@@ -58,7 +94,7 @@ import { home } from "./pages/home";
|
|
|
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
|
|
|
@@ -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 } = 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
|
},
|
|
@@ -299,7 +343,7 @@ const home = createPage({
|
|
|
299
343
|
},
|
|
300
344
|
});
|
|
301
345
|
|
|
302
|
-
const
|
|
346
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
303
347
|
fallback: () => <h1>Not found</h1>,
|
|
304
348
|
issue: () => <h1>An error occurred</h1>,
|
|
305
349
|
pages: [home],
|
|
@@ -320,7 +364,7 @@ const App = () => {
|
|
|
320
364
|
<h1>App</h1>
|
|
321
365
|
</header>
|
|
322
366
|
<main>
|
|
323
|
-
<
|
|
367
|
+
<RouterView />
|
|
324
368
|
</main>
|
|
325
369
|
<footer>Credit © Yourself 2025</footer>
|
|
326
370
|
</Fragment>
|
|
@@ -329,18 +373,18 @@ const App = () => {
|
|
|
329
373
|
|
|
330
374
|
root.render(
|
|
331
375
|
<StrictMode>
|
|
332
|
-
<
|
|
376
|
+
<RouterProvider>
|
|
333
377
|
<App />
|
|
334
|
-
</
|
|
378
|
+
</RouterProvider>
|
|
335
379
|
</StrictMode>,
|
|
336
380
|
);
|
|
337
381
|
```
|
|
338
382
|
|
|
339
383
|
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
384
|
|
|
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 (`"
|
|
385
|
+
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
386
|
|
|
343
|
-
This library also exports
|
|
387
|
+
This library also exports several transitions that you can use out-of-the-box: `slideHorizontalTransition`, `slideVerticalTransition`, `crossFadeTransition`, and `scaleFadeTransition`.
|
|
344
388
|
|
|
345
389
|
```tsx
|
|
346
390
|
import { Fragment, StrictMode } from "react";
|
|
@@ -348,7 +392,7 @@ import { createRoot } from "react-dom/client";
|
|
|
348
392
|
import {
|
|
349
393
|
createRouter,
|
|
350
394
|
createPage,
|
|
351
|
-
|
|
395
|
+
slideHorizontalTransition,
|
|
352
396
|
} from "@aminnairi/react-router";
|
|
353
397
|
|
|
354
398
|
const home = createPage({
|
|
@@ -358,8 +402,8 @@ const home = createPage({
|
|
|
358
402
|
},
|
|
359
403
|
});
|
|
360
404
|
|
|
361
|
-
const
|
|
362
|
-
transition:
|
|
405
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
406
|
+
transition: slideHorizontalTransition,
|
|
363
407
|
fallback: () => <h1>Not found</h1>,
|
|
364
408
|
issue: () => <h1>An error occurred</h1>,
|
|
365
409
|
pages: [home],
|
|
@@ -380,7 +424,7 @@ const App = () => {
|
|
|
380
424
|
<h1>App</h1>
|
|
381
425
|
</header>
|
|
382
426
|
<main>
|
|
383
|
-
<
|
|
427
|
+
<RouterView />
|
|
384
428
|
</main>
|
|
385
429
|
<footer>Credit © Yourself 2025</footer>
|
|
386
430
|
</Fragment>
|
|
@@ -389,9 +433,9 @@ const App = () => {
|
|
|
389
433
|
|
|
390
434
|
root.render(
|
|
391
435
|
<StrictMode>
|
|
392
|
-
<
|
|
436
|
+
<RouterProvider>
|
|
393
437
|
<App />
|
|
394
|
-
</
|
|
438
|
+
</RouterProvider>
|
|
395
439
|
</StrictMode>,
|
|
396
440
|
);
|
|
397
441
|
```
|
|
@@ -410,13 +454,13 @@ const home = createPage({
|
|
|
410
454
|
},
|
|
411
455
|
});
|
|
412
456
|
|
|
413
|
-
const
|
|
457
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
414
458
|
fallback: () => <h1>Not found</h1>,
|
|
415
|
-
issue: ({ error,
|
|
459
|
+
issue: ({ error, resetError }) => (
|
|
416
460
|
<Fragment>
|
|
417
461
|
<h1>Error</h1>
|
|
418
462
|
<p>{error.message}</p>
|
|
419
|
-
<button onClick={
|
|
463
|
+
<button onClick={resetError}>Reset</button>
|
|
420
464
|
</Fragment>
|
|
421
465
|
),
|
|
422
466
|
pages: [home],
|
|
@@ -437,7 +481,7 @@ const App = () => {
|
|
|
437
481
|
<h1>App</h1>
|
|
438
482
|
</header>
|
|
439
483
|
<main>
|
|
440
|
-
<
|
|
484
|
+
<RouterView />
|
|
441
485
|
</main>
|
|
442
486
|
<footer>Credit © Yourself 2025</footer>
|
|
443
487
|
</Fragment>
|
|
@@ -446,19 +490,19 @@ const App = () => {
|
|
|
446
490
|
|
|
447
491
|
root.render(
|
|
448
492
|
<StrictMode>
|
|
449
|
-
<
|
|
493
|
+
<RouterProvider>
|
|
450
494
|
<App />
|
|
451
|
-
</
|
|
495
|
+
</RouterProvider>
|
|
452
496
|
</StrictMode>,
|
|
453
497
|
);
|
|
454
498
|
```
|
|
455
499
|
|
|
456
|
-
You can also define
|
|
500
|
+
You can also define the issue component from the outside.
|
|
457
501
|
|
|
458
502
|
```tsx
|
|
459
503
|
import { Fragment, StrictMode } from "react";
|
|
460
504
|
import { createRoot } from "react-dom/client";
|
|
461
|
-
import { createRouter, createPage
|
|
505
|
+
import { createRouter, createPage } from "@aminnairi/react-router";
|
|
462
506
|
|
|
463
507
|
const home = createPage({
|
|
464
508
|
path: "/",
|
|
@@ -471,15 +515,15 @@ const Fallback = () => {
|
|
|
471
515
|
return <h1>Not found</h1>;
|
|
472
516
|
};
|
|
473
517
|
|
|
474
|
-
const Issue =
|
|
518
|
+
const Issue = ({ error, resetError }: { error: Error; resetError: () => void }) => (
|
|
475
519
|
<Fragment>
|
|
476
520
|
<h1>Error</h1>
|
|
477
521
|
<p>{error.message}</p>
|
|
478
|
-
<button onClick={
|
|
522
|
+
<button onClick={resetError}>Reset</button>
|
|
479
523
|
</Fragment>
|
|
480
|
-
)
|
|
524
|
+
);
|
|
481
525
|
|
|
482
|
-
const
|
|
526
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
483
527
|
fallback: Fallback,
|
|
484
528
|
issue: Issue,
|
|
485
529
|
pages: [home],
|
|
@@ -500,7 +544,7 @@ const App = () => {
|
|
|
500
544
|
<h1>App</h1>
|
|
501
545
|
</header>
|
|
502
546
|
<main>
|
|
503
|
-
<
|
|
547
|
+
<RouterView />
|
|
504
548
|
</main>
|
|
505
549
|
<footer>Credit © Yourself 2025</footer>
|
|
506
550
|
</Fragment>
|
|
@@ -509,9 +553,9 @@ const App = () => {
|
|
|
509
553
|
|
|
510
554
|
root.render(
|
|
511
555
|
<StrictMode>
|
|
512
|
-
<
|
|
556
|
+
<RouterProvider>
|
|
513
557
|
<App />
|
|
514
|
-
</
|
|
558
|
+
</RouterProvider>
|
|
515
559
|
</StrictMode>,
|
|
516
560
|
);
|
|
517
561
|
```
|
|
@@ -526,7 +570,6 @@ import { createRoot } from "react-dom/client";
|
|
|
526
570
|
import {
|
|
527
571
|
createRouter,
|
|
528
572
|
createPage,
|
|
529
|
-
createIssue,
|
|
530
573
|
useNavigateToPage,
|
|
531
574
|
} from "@aminnairi/react-router";
|
|
532
575
|
|
|
@@ -543,20 +586,20 @@ const Fallback = () => {
|
|
|
543
586
|
return (
|
|
544
587
|
<Fragment>
|
|
545
588
|
<h1>Not found</h1>
|
|
546
|
-
<button onClick={
|
|
589
|
+
<button onClick={navigateToHomePage}>Go Back Home</button>
|
|
547
590
|
</Fragment>
|
|
548
591
|
);
|
|
549
592
|
};
|
|
550
593
|
|
|
551
|
-
const Issue =
|
|
594
|
+
const Issue = ({ error, resetError }: { error: Error; resetError: () => void }) => (
|
|
552
595
|
<Fragment>
|
|
553
596
|
<h1>Error</h1>
|
|
554
597
|
<p>{error.message}</p>
|
|
555
|
-
<button onClick={
|
|
598
|
+
<button onClick={resetError}>Reset</button>
|
|
556
599
|
</Fragment>
|
|
557
|
-
)
|
|
600
|
+
);
|
|
558
601
|
|
|
559
|
-
const
|
|
602
|
+
const { RouterProvider, RouterView } = createRouter({
|
|
560
603
|
prefix: "/portfolio",
|
|
561
604
|
fallback: Fallback,
|
|
562
605
|
issue: Issue,
|
|
@@ -578,7 +621,7 @@ const App = () => {
|
|
|
578
621
|
<h1>App</h1>
|
|
579
622
|
</header>
|
|
580
623
|
<main>
|
|
581
|
-
<
|
|
624
|
+
<RouterView />
|
|
582
625
|
</main>
|
|
583
626
|
<footer>Credit © Yourself 2025</footer>
|
|
584
627
|
</Fragment>
|
|
@@ -587,9 +630,9 @@ const App = () => {
|
|
|
587
630
|
|
|
588
631
|
root.render(
|
|
589
632
|
<StrictMode>
|
|
590
|
-
<
|
|
633
|
+
<RouterProvider>
|
|
591
634
|
<App />
|
|
592
|
-
</
|
|
635
|
+
</RouterProvider>
|
|
593
636
|
</StrictMode>,
|
|
594
637
|
);
|
|
595
638
|
```
|
|
@@ -600,9 +643,11 @@ Allow you to create a function that can then be called to navigate to another pa
|
|
|
600
643
|
|
|
601
644
|
It accepts a page that has been created using `createPage`.
|
|
602
645
|
|
|
646
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
647
|
+
|
|
603
648
|
```tsx
|
|
604
649
|
import { Fragment } from "react";
|
|
605
|
-
import { createPage,
|
|
650
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
606
651
|
|
|
607
652
|
const home = createPage({
|
|
608
653
|
path: "/",
|
|
@@ -611,6 +656,12 @@ const home = createPage({
|
|
|
611
656
|
},
|
|
612
657
|
});
|
|
613
658
|
|
|
659
|
+
const { useNavigateToPage } = createRouter({
|
|
660
|
+
fallback: () => <h1>Not found</h1>,
|
|
661
|
+
issue: () => <h1>An error occurred</h1>,
|
|
662
|
+
pages: [home],
|
|
663
|
+
});
|
|
664
|
+
|
|
614
665
|
createPage({
|
|
615
666
|
path: "/about",
|
|
616
667
|
element: function About() {
|
|
@@ -619,7 +670,7 @@ createPage({
|
|
|
619
670
|
return (
|
|
620
671
|
<Fragment>
|
|
621
672
|
<h1>About</h1>
|
|
622
|
-
<button onClick={
|
|
673
|
+
<button onClick={navigateToHomePage}>Home</button>
|
|
623
674
|
</Fragment>
|
|
624
675
|
);
|
|
625
676
|
},
|
|
@@ -632,7 +683,7 @@ The parameters should always be provided as string, as they are the only data ty
|
|
|
632
683
|
|
|
633
684
|
```tsx
|
|
634
685
|
import { Fragment } from "react";
|
|
635
|
-
import { createPage,
|
|
686
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
636
687
|
|
|
637
688
|
const user = createPage({
|
|
638
689
|
path: "/users/:user",
|
|
@@ -658,161 +709,146 @@ createPage({
|
|
|
658
709
|
});
|
|
659
710
|
```
|
|
660
711
|
|
|
661
|
-
###
|
|
712
|
+
### useIsActivePage
|
|
662
713
|
|
|
663
|
-
Allow you to
|
|
714
|
+
Allow you to check if a page is currently active.
|
|
664
715
|
|
|
665
|
-
|
|
716
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
666
717
|
|
|
667
718
|
```tsx
|
|
668
719
|
import { Fragment } from "react";
|
|
669
|
-
import { createPage,
|
|
720
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
670
721
|
|
|
671
|
-
const
|
|
672
|
-
path: "/
|
|
673
|
-
element: function
|
|
674
|
-
return <h1>
|
|
722
|
+
const home = createPage({
|
|
723
|
+
path: "/",
|
|
724
|
+
element: function Home() {
|
|
725
|
+
return <h1>Home</h1>;
|
|
675
726
|
},
|
|
676
727
|
});
|
|
677
728
|
|
|
678
|
-
createPage({
|
|
729
|
+
const about = createPage({
|
|
679
730
|
path: "/about",
|
|
680
731
|
element: function About() {
|
|
681
|
-
|
|
732
|
+
return <h1>About</h1>;
|
|
733
|
+
},
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
const { useIsActivePage } = createRouter({
|
|
737
|
+
fallback: () => <h1>Not found</h1>,
|
|
738
|
+
issue: () => <h1>An error occurred</h1>,
|
|
739
|
+
pages: [home, about],
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
createPage({
|
|
743
|
+
path: "/",
|
|
744
|
+
element: function Home() {
|
|
745
|
+
const isAboutActive = useIsActivePage(about);
|
|
682
746
|
|
|
683
747
|
return (
|
|
684
748
|
<Fragment>
|
|
685
|
-
<h1>
|
|
686
|
-
<
|
|
749
|
+
<h1>Home</h1>
|
|
750
|
+
<p>About page is {isAboutActive ? "active" : "not active"}</p>
|
|
687
751
|
</Fragment>
|
|
688
752
|
);
|
|
689
753
|
},
|
|
690
754
|
});
|
|
691
755
|
```
|
|
692
756
|
|
|
693
|
-
###
|
|
757
|
+
### useLocale
|
|
694
758
|
|
|
695
|
-
Allow you to get
|
|
759
|
+
Allow you to get and set the current locale for internationalization.
|
|
696
760
|
|
|
697
|
-
This
|
|
761
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
698
762
|
|
|
699
763
|
```tsx
|
|
700
|
-
import {
|
|
701
|
-
import { createPage,
|
|
764
|
+
import { Fragment } from "react";
|
|
765
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
702
766
|
|
|
703
|
-
createPage({
|
|
704
|
-
path: "/
|
|
767
|
+
const home = createPage({
|
|
768
|
+
path: "/",
|
|
705
769
|
element: function Home() {
|
|
706
|
-
const
|
|
707
|
-
const sortedByDate = useMemo(() => search.get("sort-by") === "date", [search]);
|
|
770
|
+
const { locale, setLocale } = useLocale();
|
|
708
771
|
|
|
709
772
|
return (
|
|
710
|
-
<
|
|
711
|
-
|
|
773
|
+
<Fragment>
|
|
774
|
+
<h1>Home</h1>
|
|
775
|
+
<p>Current locale: {locale ?? "none"}</p>
|
|
776
|
+
<button onClick={() => setLocale("en")}>English</button>
|
|
777
|
+
<button onClick={() => setLocale("fr")}>Français</button>
|
|
778
|
+
</Fragment>
|
|
712
779
|
);
|
|
713
|
-
}
|
|
780
|
+
},
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
const { RouterProvider, RouterView, useLocale } = createRouter({
|
|
784
|
+
locales: ["en", "fr"],
|
|
785
|
+
fallback: () => <h1>Not found</h1>,
|
|
786
|
+
issue: () => <h1>An error occurred</h1>,
|
|
787
|
+
pages: [home],
|
|
714
788
|
});
|
|
715
789
|
```
|
|
716
790
|
|
|
717
|
-
|
|
791
|
+
### usePrefix
|
|
718
792
|
|
|
719
|
-
|
|
793
|
+
Allow you to get the current route prefix.
|
|
720
794
|
|
|
721
|
-
|
|
795
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
722
796
|
|
|
723
797
|
```tsx
|
|
724
|
-
import {
|
|
798
|
+
import { Fragment } from "react";
|
|
799
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
725
800
|
|
|
726
|
-
createPage({
|
|
727
|
-
path: "/
|
|
728
|
-
element: function
|
|
729
|
-
const
|
|
801
|
+
const home = createPage({
|
|
802
|
+
path: "/",
|
|
803
|
+
element: function Home() {
|
|
804
|
+
const { prefix } = usePrefix();
|
|
730
805
|
|
|
731
|
-
return
|
|
806
|
+
return (
|
|
807
|
+
<Fragment>
|
|
808
|
+
<h1>Home</h1>
|
|
809
|
+
<p>Current prefix: {prefix ?? "none"}</p>
|
|
810
|
+
</Fragment>
|
|
811
|
+
);
|
|
732
812
|
},
|
|
733
813
|
});
|
|
734
|
-
```
|
|
735
|
-
|
|
736
|
-
## Internal API
|
|
737
|
-
|
|
738
|
-
### doesRouteMatchPath
|
|
739
|
-
|
|
740
|
-
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`.
|
|
741
814
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
doesRouteMatchPath("/", "/about"); // false
|
|
750
|
-
|
|
751
|
-
doesRouteMatchPath("/users/:user", "/users/123"); // true
|
|
752
|
-
|
|
753
|
-
doesRouteMatchPath("/users/:user", "/users/123/articles"); // false
|
|
754
|
-
```
|
|
755
|
-
|
|
756
|
-
You can also optionally provide a prefix.
|
|
757
|
-
|
|
758
|
-
```typescript
|
|
759
|
-
import { doesRouteMatchPath } from "@aminnairi/react-router";
|
|
760
|
-
|
|
761
|
-
doesRouteMatchPath("/", "/github", "/github"); // true
|
|
762
|
-
|
|
763
|
-
doesRouteMatchPath("/", "/github/about", "/github"); // false
|
|
764
|
-
|
|
765
|
-
doesRouteMatchPath("/users/:user", "/github/users/123", "/github"); // true
|
|
766
|
-
|
|
767
|
-
doesRouteMatchPath("/users/:user", "/github/users/123/articles", "/github"); // false
|
|
768
|
-
```
|
|
769
|
-
|
|
770
|
-
### getParameters
|
|
771
|
-
|
|
772
|
-
Return an object in case a route matches a path, with its dynamic parameters as output. It returns a generic `object` type in case no dynamic parameters are found in the URI. Note that the parameters are always strings, if you need to, convert them to other types explicitely.
|
|
773
|
-
|
|
774
|
-
This function is mainly used in the internals of the `createRouter` and in most case should not be necessary.
|
|
775
|
-
|
|
776
|
-
```typescript
|
|
777
|
-
import { getParameters } from "@aminnairi/react-router";
|
|
778
|
-
|
|
779
|
-
getParameters("/", "/"); // {}
|
|
780
|
-
|
|
781
|
-
getParameters("/", "/about"); // {}
|
|
782
|
-
|
|
783
|
-
getParameters("/users/:user", "/users/123"); // { user: "123" }
|
|
784
|
-
|
|
785
|
-
getParameters("/users/:user", "/users/123/articles"); // {}
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
You can also provide an optional prefix.
|
|
789
|
-
|
|
790
|
-
```typescript
|
|
791
|
-
import { getParameters } from "@aminnairi/react-router";
|
|
792
|
-
|
|
793
|
-
getParameters("/", "/github", "/github"); // {}
|
|
794
|
-
|
|
795
|
-
getParameters("/", "/github/about", "/github"); // {}
|
|
796
|
-
|
|
797
|
-
getParameters("/users/:user", "/github/users/123", "/github"); // { user: "123" }
|
|
798
|
-
|
|
799
|
-
getParameters("/users/:user", "/github/users/123/articles", "/github"); // {}
|
|
815
|
+
const { RouterProvider, RouterView, usePrefix } = createRouter({
|
|
816
|
+
prefix: "/portfolio",
|
|
817
|
+
fallback: () => <h1>Not found</h1>,
|
|
818
|
+
issue: () => <h1>An error occurred</h1>,
|
|
819
|
+
pages: [home],
|
|
820
|
+
});
|
|
800
821
|
```
|
|
801
822
|
|
|
802
|
-
###
|
|
823
|
+
### usePath
|
|
803
824
|
|
|
804
|
-
|
|
825
|
+
Allow you to get the current path.
|
|
805
826
|
|
|
806
|
-
|
|
807
|
-
import { sanitizePath } from "@aminnairi/react-router";
|
|
827
|
+
Note: This hook is returned from `createRouter`, not imported directly from the library.
|
|
808
828
|
|
|
809
|
-
|
|
829
|
+
```tsx
|
|
830
|
+
import { Fragment } from "react";
|
|
831
|
+
import { createPage, createRouter } from "@aminnairi/react-router";
|
|
810
832
|
|
|
811
|
-
|
|
833
|
+
const home = createPage({
|
|
834
|
+
path: "/",
|
|
835
|
+
element: function Home() {
|
|
836
|
+
const { path } = usePath();
|
|
812
837
|
|
|
813
|
-
|
|
838
|
+
return (
|
|
839
|
+
<Fragment>
|
|
840
|
+
<h1>Home</h1>
|
|
841
|
+
<p>Current path: {path}</p>
|
|
842
|
+
</Fragment>
|
|
843
|
+
);
|
|
844
|
+
},
|
|
845
|
+
});
|
|
814
846
|
|
|
815
|
-
|
|
847
|
+
const { RouterProvider, RouterView, usePath } = createRouter({
|
|
848
|
+
fallback: () => <h1>Not found</h1>,
|
|
849
|
+
issue: () => <h1>An error occurred</h1>,
|
|
850
|
+
pages: [home],
|
|
851
|
+
});
|
|
816
852
|
```
|
|
817
853
|
|
|
818
854
|
## Features
|
|
@@ -835,7 +871,7 @@ This means that you can use this library with other popular solutions for handli
|
|
|
835
871
|
|
|
836
872
|
### Transition
|
|
837
873
|
|
|
838
|
-
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
|
|
874
|
+
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`.
|
|
839
875
|
|
|
840
876
|
### Error handling
|
|
841
877
|
|
|
@@ -849,6 +885,8 @@ See [`LICENSE`](./LICENSE).
|
|
|
849
885
|
|
|
850
886
|
### Versions
|
|
851
887
|
|
|
888
|
+
- [`3.0.0`](#300)
|
|
889
|
+
- [`2.1.0`](#210)
|
|
852
890
|
- [`2.0.1`](#201)
|
|
853
891
|
- [`2.0.0`](#200)
|
|
854
892
|
- [`1.1.0`](#110)
|
|
@@ -857,6 +895,46 @@ See [`LICENSE`](./LICENSE).
|
|
|
857
895
|
- [`0.1.1`](#011)
|
|
858
896
|
- [`0.1.0`](#010)
|
|
859
897
|
|
|
898
|
+
### 3.0.0
|
|
899
|
+
|
|
900
|
+
#### Major changes
|
|
901
|
+
|
|
902
|
+
- Full rewrite of the library implementation
|
|
903
|
+
- Added `locales` support for internationalization
|
|
904
|
+
- Added `useLocale` hook for locale management
|
|
905
|
+
- Added `usePrefix` and `usePath` hooks
|
|
906
|
+
- Renamed `slideFadeTransition` to `slideHorizontalTransition` and added new transitions: `scaleFadeTransition`, `crossFadeTransition`, `slideVerticalTransition`
|
|
907
|
+
- Changed API structure: `router.View` → `router.RouterView` and `router.Provider` → `RouterProvider`
|
|
908
|
+
- Renamed `reset` to `resetError` in `IssueProps`
|
|
909
|
+
- Renamed internal functions: `doesRouteMatchPath` → `matchPath`, `getParameters` → `matchParameters`
|
|
910
|
+
- Added `Uri` class for URL parsing
|
|
911
|
+
- Changed `createRouter` return value structure
|
|
912
|
+
- Removed `useLink`, `useSearch`, and `useHash` hooks and `UseLinkRenderFunction` type
|
|
913
|
+
|
|
914
|
+
#### Minor changes
|
|
915
|
+
|
|
916
|
+
- Added better URL normalization with `normalize` function
|
|
917
|
+
- Improved error handling with `ErrorBoundary` component
|
|
918
|
+
|
|
919
|
+
#### Bug & security fixes
|
|
920
|
+
|
|
921
|
+
- None.
|
|
922
|
+
|
|
923
|
+
### 2.1.0
|
|
924
|
+
|
|
925
|
+
#### Major changes
|
|
926
|
+
|
|
927
|
+
None.
|
|
928
|
+
|
|
929
|
+
#### Minor changes
|
|
930
|
+
|
|
931
|
+
- Added optional `render` parameter to `useLink` hook for custom render functions
|
|
932
|
+
- Added `UseLinkRenderFunction` type for custom render function signatures
|
|
933
|
+
|
|
934
|
+
#### Bug & security fixes
|
|
935
|
+
|
|
936
|
+
None.
|
|
937
|
+
|
|
860
938
|
### 2.0.1
|
|
861
939
|
|
|
862
940
|
#### Major changes
|