clear-react-router 1.0.5 → 1.0.6

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.
Files changed (2) hide show
  1. package/README.md +168 -0
  2. package/package.json +49 -49
package/README.md ADDED
@@ -0,0 +1,168 @@
1
+ [![npm version](https://badge.fury.io/js/clear-react-router.svg)](https://www.npmjs.com/package/clear-react-router)
2
+
3
+ A lightweight, type-safe routing library for React applications with nested routes, data loading, navigation blocking, and prefetching.
4
+
5
+ ## Features
6
+
7
+ - 🧩 **Nested Routes** - Organize your UI with nested layouts and routes
8
+ - ⚡ **Data Loading** - Built-in loaders with caching and stale-while-revalidate strategy
9
+ - 🔒 **Navigation Blocking** - Prevent accidental navigation with `useBlocker`
10
+ - 🎯 **Type-safe Redirects** - Redirect from loaders and beforeLoad hooks
11
+ - 📦 **Prefetching** - Preload data on hover for instant navigation
12
+ - 🚀 **Lazy Loading** - Code-split your routes with dynamic imports for optimal performance
13
+ - 🎨 **Flexible API** - Use components or hooks as you prefer
14
+ - 📱 **Browser History** - Full support for browser back/forward buttons
15
+ - 🧠 **Context-aware** - Pass and update context through routes
16
+
17
+ ## API
18
+
19
+ ### `createRouter(routes)`
20
+
21
+ Normalizes route configuration. Handles wildcard `*` routes, extracts dynamic params, builds nested paths.
22
+
23
+ | Property | Type | Description |
24
+ |----------|------|-------------|
25
+ | `path` | `string` | Route path, e.g., `/user/:userId` |
26
+ | `element` | `ReactElement \| () => ReactElement \| LazyComponent` | Component to render |
27
+ | `loader` | `() => Promise<unknown>` | Fetch data |
28
+ | `beforeLoad` | `(context) => Promise<void>` | Auth checks, redirects |
29
+ | `afterLoad` | `(context) => Promise<void>` | Analytics, side effects |
30
+ | `fallback` | `ReactElement \| () => ReactElement` | Loading fallback (for lazy loading) |
31
+ | `loaderFallback` | `ReactElement \| () => ReactElement` | Loading fallback (for loader) |
32
+ | `errorElement` | `ReactElement \| () => ReactElement` | Error fallback |
33
+ | `staleTime` | `number` | Cache duration in ms for loader data |
34
+ | `children` | `RouteItem[]` | Nested routes |
35
+
36
+ ### `Router`
37
+
38
+ Main component that renders the application based on current URL.
39
+
40
+ | Prop | Type | Description |
41
+ |------|------|-------------|
42
+ | `routeList` | `RouteItem[]` | Array of route configurations |
43
+ | `context` | `object` | Optional initial context (user, theme, etc.) |
44
+
45
+ ### `Link`
46
+
47
+ Component for client-side navigation with prefetch support.
48
+
49
+ | Prop | Type | Default |
50
+ |------|------|---------|
51
+ | `to` | `string` | required |
52
+ | `prefetch` | `boolean` | `true` |
53
+ | `children` | `ReactElement` | required |
54
+
55
+ ### `redirect(url, search?)`
56
+
57
+ Redirects from `beforeLoad`.
58
+ ```
59
+ beforeLoad: context => {
60
+ if (!context.isAuthorized) return redirect('/');
61
+ }
62
+ ```
63
+
64
+ ## Hooks
65
+
66
+ ### `useNavigate()`
67
+
68
+ Returns function to navigate programmatically:
69
+
70
+ - `navigate({ pathname: '/about' })` - navigate to path
71
+ - `navigate({ pathname: '/user/123', state: { fromDashboard: true } })` - navigate with state
72
+ - `navigate(-1)` - go back
73
+
74
+ **Note:** Navigation state can be accessed via `useLocation()`:
75
+
76
+ ```
77
+ const navigate = useNavigate();
78
+ navigate({ pathname: '/profile', state: { userId: 123 } });
79
+
80
+ // In Profile component
81
+ const { state } = useLocation();
82
+ console.log(state); // { userId: 123 }
83
+ ```
84
+
85
+ ### `useParams<T>()`
86
+
87
+ Returns route parameters object.
88
+
89
+ const params = useParams<{ userId: string }>();
90
+ // URL: /user/123 → params.userId === '123'
91
+
92
+ ### `useLocation()`
93
+
94
+ Returns current location `{ pathname, search, state }`.
95
+ ```
96
+ const { pathname, search, state } = useLocation();
97
+ ```
98
+
99
+ ### `useLoaderState()`
100
+
101
+ Returns loaderState from current route's loader.
102
+
103
+ ### `useBlocker(callback)`
104
+
105
+ Blocks navigation when callback returns `true`.
106
+
107
+ **Returns:**
108
+
109
+ | Property | Type | Description |
110
+ |----------|------|-------------|
111
+ | `state` | `'unblocked' \| 'charged' \| 'blocked'` | Current blocker state |
112
+ | `process()` | `() => void` | Confirm navigation and proceed |
113
+ | `reset()` | `() => void` | Cancel navigation |
114
+
115
+ ```
116
+ const { state, process, reset } = useBlocker(() => hasUnsavedChanges);
117
+
118
+ useEffect(() => {
119
+ if (state === 'blocked') {
120
+ // Show your custom modal
121
+ if (confirm('Leave without saving?')) {
122
+ process();
123
+ } else {
124
+ reset();
125
+ }
126
+ }
127
+ }, [state, process, reset]);
128
+ ```
129
+
130
+ ### `useBeforeUnload(callback?)`
131
+
132
+ Executes a callback when the page is about to be closed or reloaded. Perfect for auto-saving data at the last moment.
133
+
134
+ **Parameters:**
135
+
136
+ | Parameter | Type | Description |
137
+ |-----------|------|-------------|
138
+ | `callback` | `() => void \| undefined` | Function to execute before page unload (e.g., auto-save) |
139
+
140
+ **Note:** This hook does not show a browser confirmation dialog. It silently executes the callback, allowing you to save user data in the background before the page closes.
141
+
142
+ ```
143
+ const [text, setText] = useState('');
144
+ const onSave = useCallback(() => {
145
+ localStorage.setItem('draft', text);
146
+ }, [text]);
147
+
148
+ // Auto-save when user tries to close/reload the page
149
+ useBeforeUnload(text ? onSave : undefined);
150
+ ```
151
+
152
+ ## Lazy Loading
153
+
154
+ Clear Router supports code-splitting out of the box. Simply pass a function that returns a dynamic import:
155
+ ```
156
+ {
157
+ path: '/heavy-page',
158
+ element: () => import('./pages/HeavyComponent'),
159
+ fallback: () => <div>Loading...</div>,
160
+ }
161
+ ```
162
+
163
+ ## Requirements
164
+ - React 16.6+ (for React.lazy and Suspense)
165
+ - Use `default` export for your lazy-loaded components
166
+
167
+ ## License
168
+ MIT
package/package.json CHANGED
@@ -1,49 +1,49 @@
1
- {
2
- "name": "clear-react-router",
3
- "version": "1.0.5",
4
- "description": "A lightweight, type-safe routing library for React applications",
5
- "author": "Andrew Bubnov",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "scripts": {
10
- "build": "vite build && tsc --emitDeclarationOnly"
11
- },
12
- "keywords": [
13
- "react",
14
- "router",
15
- "routing",
16
- "typescript",
17
- "spa",
18
- "nested-routes"
19
- ],
20
- "repository": {
21
- "type": "git",
22
- "url": "https://github.com/AndrewBubnov/clear-react-router"
23
- },
24
- "sideEffects": false,
25
- "peerDependencies": {
26
- "react": ">=16.8.0",
27
- "react-dom": ">=16.8.0"
28
- },
29
- "files": [
30
- "dist"
31
- ],
32
- "license": "MIT",
33
- "type": "module",
34
- "exports": {
35
- ".": {
36
- "types": "./dist/index.d.ts",
37
- "import": "./dist/index.js",
38
- "require": "./dist/index.js"
39
- }
40
- },
41
- "devDependencies": {
42
- "@types/react": "^19.2.17",
43
- "@vitejs/plugin-react": "^6.0.2",
44
- "react": "^19.2.7",
45
- "react-dom": "^19.2.7",
46
- "typescript": "^6.0.3",
47
- "vite": "^8.0.16"
48
- }
49
- }
1
+ {
2
+ "name": "clear-react-router",
3
+ "version": "1.0.6",
4
+ "description": "A lightweight, type-safe routing library for React applications",
5
+ "author": "Andrew Bubnov",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "scripts": {
10
+ "build": "vite build && tsc --emitDeclarationOnly"
11
+ },
12
+ "keywords": [
13
+ "react",
14
+ "router",
15
+ "routing",
16
+ "typescript",
17
+ "spa",
18
+ "nested-routes"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/AndrewBubnov/clear-react-router"
23
+ },
24
+ "sideEffects": false,
25
+ "peerDependencies": {
26
+ "react": ">=16.8.0",
27
+ "react-dom": ">=16.8.0"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "license": "MIT",
33
+ "type": "module",
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "import": "./dist/index.js",
38
+ "require": "./dist/index.js"
39
+ }
40
+ },
41
+ "devDependencies": {
42
+ "@types/react": "^19.2.17",
43
+ "@vitejs/plugin-react": "^6.0.2",
44
+ "react": "^19.2.7",
45
+ "react-dom": "^19.2.7",
46
+ "typescript": "^6.0.3",
47
+ "vite": "^8.0.16"
48
+ }
49
+ }