router-kit 1.3.3 → 2.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.
Files changed (49) hide show
  1. package/README.md +123 -373
  2. package/dist/components/Link.d.ts +23 -6
  3. package/dist/components/Link.js +51 -6
  4. package/dist/components/NavLink.d.ts +44 -7
  5. package/dist/components/NavLink.js +111 -10
  6. package/dist/components/Outlet.d.ts +66 -0
  7. package/dist/components/Outlet.js +69 -0
  8. package/dist/components/Router.d.ts +69 -0
  9. package/dist/components/Router.js +109 -0
  10. package/dist/components/route.d.ts +77 -0
  11. package/dist/components/route.js +51 -0
  12. package/dist/context/OutletContext.d.ts +41 -0
  13. package/dist/context/OutletContext.js +31 -0
  14. package/dist/context/RouterContext.d.ts +9 -0
  15. package/dist/context/RouterContext.js +21 -1
  16. package/dist/context/RouterProvider.d.ts +15 -4
  17. package/dist/context/RouterProvider.js +321 -84
  18. package/dist/core/createRouter.d.ts +65 -0
  19. package/dist/core/createRouter.js +126 -7
  20. package/dist/hooks/useBlocker.d.ts +65 -0
  21. package/dist/hooks/useBlocker.js +152 -0
  22. package/dist/hooks/useDynamicComponents.d.ts +61 -2
  23. package/dist/hooks/useDynamicComponents.js +89 -17
  24. package/dist/hooks/useLoaderData.d.ts +98 -0
  25. package/dist/hooks/useLoaderData.js +107 -0
  26. package/dist/hooks/useLocation.d.ts +37 -0
  27. package/dist/hooks/useLocation.js +106 -1
  28. package/dist/hooks/useMatches.d.ts +99 -0
  29. package/dist/hooks/useMatches.js +114 -0
  30. package/dist/hooks/useNavigate.d.ts +59 -0
  31. package/dist/hooks/useNavigate.js +70 -0
  32. package/dist/hooks/useParams.d.ts +57 -2
  33. package/dist/hooks/useParams.js +60 -14
  34. package/dist/hooks/useQuery.d.ts +53 -3
  35. package/dist/hooks/useQuery.js +107 -8
  36. package/dist/hooks/useRouter.d.ts +34 -0
  37. package/dist/hooks/useRouter.js +35 -1
  38. package/dist/index.d.ts +19 -5
  39. package/dist/index.js +23 -4
  40. package/dist/ssr/StaticRouter.d.ts +65 -0
  41. package/dist/ssr/StaticRouter.js +292 -0
  42. package/dist/ssr/hydrateRouter.d.ts +44 -0
  43. package/dist/ssr/hydrateRouter.js +60 -0
  44. package/dist/ssr/index.d.ts +92 -0
  45. package/dist/ssr/index.js +92 -0
  46. package/dist/ssr/serverUtils.d.ts +107 -0
  47. package/dist/ssr/serverUtils.js +263 -0
  48. package/dist/types/index.d.ts +201 -2
  49. package/package.json +14 -2
package/README.md CHANGED
@@ -1,459 +1,209 @@
1
- # Documentation Index
1
+ # Router-Kit
2
2
 
3
- Complete documentation for Router-Kit v1.3.1
3
+ A professional React routing library with guards, loaders, and navigation blocking.
4
4
 
5
- 🌐 **Website:** [https://routerkit.com/](https://routerkit.com/)
5
+ **Version:** 2.0.0 | **License:** MIT
6
6
 
7
7
  ---
8
8
 
9
- ## 📚 Documentation Structure
9
+ ## Features
10
10
 
11
- This directory contains comprehensive documentation for Router-Kit. Choose the documentation that best fits your needs:
12
-
13
- ### For Users
14
-
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
19
-
20
- ### For Developers
21
-
22
- - **[Architecture](./ARCHITECTURE.md)** - Internal implementation details
23
- - **[Contributing Guide](#contributing)** - How to contribute to Router-Kit
11
+ - 🛡️ **Route Guards** - Authentication & authorization
12
+ - 📦 **Data Loaders** - Pre-fetch route data
13
+ - 🚫 **Navigation Blocking** - Protect unsaved changes
14
+ - 📜 **Scroll Restoration** - Auto scroll management
15
+ - **Lazy Loading** - Code splitting support
16
+ - 🎯 **TypeScript** - Full type safety
17
+ - 🎭 **Outlet** - Professional nested layouts
18
+ - 🪝 **10 Hooks** - Complete routing control
24
19
 
25
20
  ---
26
21
 
27
- ## Quick Start Guide
28
-
29
- ### Installation
22
+ ## 📦 Installation
30
23
 
31
24
  ```bash
32
25
  npm install router-kit
33
26
  ```
34
27
 
35
- ### Basic Setup
28
+ ---
29
+
30
+ ## 🚀 Quick Start
31
+
32
+ ### Programmatic Approach
36
33
 
37
34
  ```tsx
38
- import React from "react";
39
- import { createRouter, RouterProvider, Link } from "router-kit";
35
+ import {
36
+ createRouter,
37
+ RouterProvider,
38
+ Link,
39
+ useNavigate,
40
+ useParams,
41
+ } from "router-kit";
40
42
 
41
- // 1. Define your components
42
- const Home = () => <h1>Home Page</h1>;
43
- const About = () => <h1>About Page</h1>;
43
+ const Home = () => <h1>Home</h1>;
44
+ const User = () => {
45
+ const { id } = useParams();
46
+ return <h1>User {id}</h1>;
47
+ };
44
48
 
45
- // 2. Create routes
46
49
  const routes = createRouter([
47
- { path: "/", component: <Home /> },
48
- { path: "about", component: <About /> },
50
+ { path: "/", component: <Home />, meta: { title: "Home" } },
51
+ { path: "users/:id", component: <User /> },
52
+ { path: "/404", component: <h1>Not Found</h1> },
49
53
  ]);
50
54
 
51
- // 3. Wrap your app with RouterProvider
52
55
  function App() {
53
56
  return <RouterProvider routes={routes} />;
54
57
  }
55
-
56
- export default App;
57
58
  ```
58
59
 
59
- ### Navigation
60
+ ### Declarative Approach
60
61
 
61
62
  ```tsx
62
- import { Link, NavLink } from "router-kit";
63
+ import { Router, Route, Link } from "router-kit";
63
64
 
64
- function Navigation() {
65
+ function App() {
65
66
  return (
66
- <nav>
67
- <Link to="/">Home</Link>
68
- <NavLink to="/about" activeClassName="active">
69
- About
70
- </NavLink>
71
- </nav>
67
+ <Router>
68
+ <Route path="/" component={<Home />} />
69
+ <Route path="/users/:id" component={<User />} />
70
+ <Route path="/404" component={<NotFound />} />
71
+ </Router>
72
72
  );
73
73
  }
74
74
  ```
75
75
 
76
- ### Dynamic Routes
76
+ ---
77
+
78
+ ## 🛡️ Route Guards
77
79
 
78
80
  ```tsx
79
- import { useParams } from "router-kit";
81
+ const authGuard = async () => {
82
+ const isAuth = await checkAuth();
83
+ return isAuth || { redirect: "/login" };
84
+ };
80
85
 
81
- // Route: /users/:id
82
86
  const routes = createRouter([
83
- { path: "users/:id", component: <UserProfile /> },
87
+ {
88
+ path: "dashboard",
89
+ component: <Dashboard />,
90
+ guard: authGuard,
91
+ },
84
92
  ]);
85
-
86
- function UserProfile() {
87
- const { id } = useParams();
88
- return <h1>User {id}</h1>;
89
- }
90
- ```
91
-
92
- ### Programmatic Navigation
93
-
94
- ```tsx
95
- import { useRouter } from "router-kit";
96
-
97
- function LoginForm() {
98
- const { navigate } = useRouter();
99
-
100
- const handleLogin = () => {
101
- // After successful login
102
- navigate("/dashboard");
103
- };
104
-
105
- return <button onClick={handleLogin}>Login</button>;
106
- }
107
93
  ```
108
94
 
109
95
  ---
110
96
 
111
- ## Documentation Files
112
-
113
- ### [DOCUMENTATION.md](./DOCUMENTATION.md)
114
-
115
- **Complete user guide covering:**
116
-
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
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
97
+ ## 📦 Data Loaders
182
98
 
183
99
  ```tsx
184
100
  const routes = createRouter([
185
- { path: "/", component: <Home /> },
186
- { path: "about", component: <About /> },
187
- { path: "contact", component: <Contact /> },
188
- { path: "/404", component: <NotFound /> },
101
+ {
102
+ path: "users/:id",
103
+ component: <UserProfile />,
104
+ loader: async ({ params }) => {
105
+ return fetch(`/api/users/${params.id}`).then((r) => r.json());
106
+ },
107
+ },
189
108
  ]);
109
+
110
+ function UserProfile() {
111
+ const user = useLoaderData();
112
+ return <h1>{user.name}</h1>;
113
+ }
190
114
  ```
191
115
 
192
- 📖 **See:** [Basic Examples in EXAMPLES.md](./EXAMPLES.md#basic-examples)
116
+ ---
193
117
 
194
- ### Blog or CMS
118
+ ## 🪝 Hooks
195
119
 
196
120
  ```tsx
197
- const routes = createRouter([
198
- { path: "/", component: <BlogHome /> },
199
- { path: "posts/:category/:slug", component: <BlogPost /> },
200
- { path: "author/:username", component: <AuthorProfile /> },
201
- ]);
121
+ const navigate = useNavigate(); // Navigation
122
+ const { id } = useParams(); // Route params
123
+ const { page } = useQuery(); // Query params
124
+ const location = useLocation(); // Location object
125
+ const matches = useMatches(); // Route matches
126
+ const data = useLoaderData(); // Loader data
127
+ const blocker = useBlocker(isDirty); // Block navigation
128
+ const outlet = useOutlet(); // Child route element
129
+ const ctx = useOutletContext(); // Outlet context
202
130
  ```
203
131
 
204
- 📖 **See:** [Blog Platform in EXAMPLES.md](./EXAMPLES.md#blog-platform)
132
+ ---
205
133
 
206
- ### Dashboard Application
134
+ ## 🎭 Outlet (Nested Layouts)
207
135
 
208
136
  ```tsx
209
- const routes = createRouter([
210
- { path: "dashboard/:view", component: <Dashboard /> },
211
- ]);
137
+ import { Outlet, useOutletContext } from "router-kit";
212
138
 
213
- function Dashboard() {
214
- const views = {
215
- overview: <OverviewView />,
216
- analytics: <AnalyticsView />,
217
- settings: <SettingsView />,
218
- };
139
+ // Parent layout with Outlet
140
+ function DashboardLayout() {
141
+ const [user] = useState({ name: "John" });
219
142
 
220
- return useDynamicComponents(views, "view");
143
+ return (
144
+ <div className="dashboard">
145
+ <Sidebar />
146
+ <main>
147
+ <Outlet context={{ user, theme: "dark" }} />
148
+ </main>
149
+ </div>
150
+ );
221
151
  }
222
- ```
223
-
224
- 📖 **See:** [Dashboard Application in EXAMPLES.md](./EXAMPLES.md#dashboard-application)
225
152
 
226
- ### E-commerce Site
227
-
228
- ```tsx
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
- ]);
153
+ // Child route accesses context
154
+ function Settings() {
155
+ const { user, theme } = useOutletContext<{ user: User; theme: string }>();
156
+ return <div className={theme}>Settings for {user.name}</div>;
157
+ }
236
158
  ```
237
159
 
238
- 📖 **See:** [E-commerce Application in EXAMPLES.md](./EXAMPLES.md#e-commerce-application)
239
-
240
- ### Protected Routes
160
+ ### Programmatic Config
241
161
 
242
162
  ```tsx
243
163
  const routes = createRouter([
244
- { path: "/", component: <PublicHome /> },
245
164
  {
246
165
  path: "dashboard",
247
- component: (
248
- <ProtectedRoute>
249
- <Dashboard />
250
- </ProtectedRoute>
251
- ),
166
+ component: <DashboardLayout />,
167
+ children: [
168
+ { index: true, component: <Overview /> },
169
+ { path: "settings", component: <Settings /> },
170
+ { path: "profile", component: <Profile /> },
171
+ ],
252
172
  },
253
173
  ]);
254
174
  ```
255
175
 
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
282
-
283
- ```tsx
284
- // Core
285
- import { createRouter, RouterProvider } from "router-kit";
286
-
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
- ```
311
-
312
- ### Route Patterns
313
-
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
- ]
334
- }
335
-
336
- // 404 page
337
- { path: "/404", component: <NotFound /> }
338
- ```
339
-
340
- ### Hook Usage
176
+ ### Declarative Config
341
177
 
342
178
  ```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");
179
+ <Router>
180
+ <Route path="dashboard" component={<DashboardLayout />}>
181
+ <Route index component={<Overview />} />
182
+ <Route path="settings" component={<Settings />} />
183
+ <Route path="profile" component={<Profile />} />
184
+ </Route>
185
+ </Router>
357
186
  ```
358
187
 
359
188
  ---
360
189
 
361
- ## Version Information
190
+ ## 📚 Documentation
362
191
 
363
- - **Current Version:** 1.3.1
364
- - **React Version:** >=16 <20
365
- - **TypeScript:** >=5.2.0
366
- - **License:** MIT
192
+ | Document | Description |
193
+ | ---------------------------------------- | ----------------- |
194
+ | [Documentation](./docs/DOCUMENTATION.md) | Complete guide |
195
+ | [API Reference](./docs/API_REFERENCE.md) | Full API docs |
196
+ | [Examples](./docs/EXAMPLES.md) | Code examples |
197
+ | [Architecture](./docs/ARCHITECTURE.md) | Technical details |
198
+ | [Changelog](./docs/CHANGELOG.md) | Version history |
367
199
 
368
200
  ---
369
201
 
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
- ---
413
-
414
- ## FAQ
415
-
416
- ### How does Router-Kit compare to React Router?
417
-
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.
419
-
420
- 📖 **See:** [Migration Guide in DOCUMENTATION.md](./DOCUMENTATION.md#migration-guide)
421
-
422
- ### Can I use Router-Kit with TypeScript?
423
-
424
- Yes! Router-Kit is written in TypeScript and provides full type definitions.
425
-
426
- 📖 **See:** [TypeScript Support in DOCUMENTATION.md](./DOCUMENTATION.md#typescript-support)
427
-
428
- ### How do I handle authentication?
429
-
430
- Use the ProtectedRoute pattern with useRouter and useLocation hooks.
431
-
432
- 📖 **See:** [Authentication Flow in EXAMPLES.md](./EXAMPLES.md#authentication-flow)
433
-
434
- ### How do I create nested routes?
435
-
436
- Use the `children` property in route configuration.
437
-
438
- 📖 **See:** [Nested Routes in DOCUMENTATION.md](./DOCUMENTATION.md#nested-routes)
439
-
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:
202
+ ## 🔗 Links
451
203
 
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)
204
+ - **GitHub:** [github.com/Mohammed-Ben-Cheikh/router-kit](https://github.com/Mohammed-Ben-Cheikh/router-kit)
205
+ - **Author:** [Mohammed Ben Cheikh](https://mohammedbencheikh.com/)
456
206
 
457
207
  ---
458
208
 
459
- **Happy Routing! 🚀**
209
+ Made with ❤️ by Mohammed Ben Cheikh
@@ -1,7 +1,24 @@
1
- import type { ReactNode } from "react";
2
- declare function Link({ to, children, className, }: {
3
- to: string;
4
- children: ReactNode;
5
- className?: string;
6
- }): import("react/jsx-runtime").JSX.Element;
1
+ import type { LinkProps } from "../types";
2
+ /**
3
+ * Link component for client-side navigation
4
+ *
5
+ * Provides seamless navigation without full page reloads.
6
+ * Supports all standard anchor attributes and navigation options.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * // Basic usage
11
+ * <Link to="/about">About Us</Link>
12
+ *
13
+ * // With state
14
+ * <Link to="/profile" state={{ from: 'dashboard' }}>Profile</Link>
15
+ *
16
+ * // Replace history entry
17
+ * <Link to="/login" replace>Login</Link>
18
+ *
19
+ * // External link (opens normally)
20
+ * <Link to="https://example.com" target="_blank">External</Link>
21
+ * ```
22
+ */
23
+ declare const Link: import("react").ForwardRefExoticComponent<LinkProps & import("react").RefAttributes<HTMLAnchorElement>>;
7
24
  export default Link;
@@ -1,10 +1,55 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
2
3
  import { useRouter } from "../hooks/useRouter";
3
- function Link({ to, children, className, }) {
4
+ /**
5
+ * Checks if a link should trigger navigation or default browser behavior
6
+ */
7
+ const shouldNavigate = (event, target) => {
8
+ return (!event.defaultPrevented &&
9
+ event.button === 0 && // Left click
10
+ (!target || target === "_self") &&
11
+ !event.metaKey &&
12
+ !event.altKey &&
13
+ !event.ctrlKey &&
14
+ !event.shiftKey);
15
+ };
16
+ /**
17
+ * Link component for client-side navigation
18
+ *
19
+ * Provides seamless navigation without full page reloads.
20
+ * Supports all standard anchor attributes and navigation options.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * // Basic usage
25
+ * <Link to="/about">About Us</Link>
26
+ *
27
+ * // With state
28
+ * <Link to="/profile" state={{ from: 'dashboard' }}>Profile</Link>
29
+ *
30
+ * // Replace history entry
31
+ * <Link to="/login" replace>Login</Link>
32
+ *
33
+ * // External link (opens normally)
34
+ * <Link to="https://example.com" target="_blank">External</Link>
35
+ * ```
36
+ */
37
+ const Link = forwardRef(({ to, children, className, replace = false, state, preventScrollReset = false, target, rel, title, onClick, ...rest }, ref) => {
4
38
  const { navigate } = useRouter();
5
- return (_jsx("a", { onClick: (e) => {
6
- e.preventDefault();
7
- navigate(to);
8
- }, className: className, href: to, children: children }));
9
- }
39
+ // Determine if link is external
40
+ const isExternal = /^https?:\/\//i.test(to);
41
+ const handleClick = (event) => {
42
+ // Call user's onClick handler first
43
+ onClick === null || onClick === void 0 ? void 0 : onClick(event);
44
+ // Handle internal navigation
45
+ if (!isExternal && shouldNavigate(event, target)) {
46
+ event.preventDefault();
47
+ navigate(to, { replace, state, preventScrollReset });
48
+ }
49
+ };
50
+ // Auto-add security attributes for external links
51
+ const computedRel = isExternal && target === "_blank" ? rel || "noopener noreferrer" : rel;
52
+ return (_jsx("a", { ref: ref, href: to, onClick: handleClick, className: className, target: target, rel: computedRel, title: title, ...rest, children: children }));
53
+ });
54
+ Link.displayName = "Link";
10
55
  export default Link;