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
@@ -1,8 +1,45 @@
1
- import type { ReactNode } from "react";
2
- declare function NavLink({ to, children, className, activeClassName, }: {
3
- to: string;
4
- children: ReactNode;
5
- className?: string;
6
- activeClassName?: string;
7
- }): import("react/jsx-runtime").JSX.Element;
1
+ import type { NavLinkProps } from "../types";
2
+ /**
3
+ * NavLink component for navigation with active state styling
4
+ *
5
+ * Extends Link with automatic active state detection and styling.
6
+ * Perfect for navigation menus, tabs, and breadcrumbs.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * // Basic usage with activeClassName
11
+ * <NavLink to="/about" activeClassName="active">About</NavLink>
12
+ *
13
+ * // With activeStyle
14
+ * <NavLink
15
+ * to="/profile"
16
+ * activeStyle={{ fontWeight: 'bold', color: 'blue' }}
17
+ * >
18
+ * Profile
19
+ * </NavLink>
20
+ *
21
+ * // Exact matching with end prop
22
+ * <NavLink to="/" end activeClassName="active">Home</NavLink>
23
+ *
24
+ * // Custom active detection
25
+ * <NavLink
26
+ * to="/users"
27
+ * isActive={(match, location) => {
28
+ * return location.pathname.startsWith('/users');
29
+ * }}
30
+ * >
31
+ * Users
32
+ * </NavLink>
33
+ *
34
+ * // Render prop for full control
35
+ * <NavLink to="/dashboard">
36
+ * {({ isActive }) => (
37
+ * <span className={isActive ? 'active' : ''}>
38
+ * Dashboard {isActive && '✓'}
39
+ * </span>
40
+ * )}
41
+ * </NavLink>
42
+ * ```
43
+ */
44
+ declare const NavLink: import("react").ForwardRefExoticComponent<NavLinkProps & import("react").RefAttributes<HTMLAnchorElement>>;
8
45
  export default NavLink;
@@ -1,14 +1,115 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef, } from "react";
3
+ import { useLocation } from "../hooks/useLocation";
2
4
  import { useRouter } from "../hooks/useRouter";
3
- function NavLink({ to, children, className, activeClassName = "active", }) {
4
- const { navigate, path } = useRouter();
5
- const isActive = path === to;
6
- const combinedClass = [className, isActive ? activeClassName : null]
5
+ /**
6
+ * Checks if a link should trigger navigation or default browser behavior
7
+ */
8
+ const shouldNavigate = (event, target) => {
9
+ return (!event.defaultPrevented &&
10
+ event.button === 0 &&
11
+ (!target || target === "_self") &&
12
+ !event.metaKey &&
13
+ !event.altKey &&
14
+ !event.ctrlKey &&
15
+ !event.shiftKey);
16
+ };
17
+ /**
18
+ * Default active matching logic
19
+ */
20
+ const defaultIsActive = (pathname, to, end, caseSensitive) => {
21
+ const toPath = caseSensitive ? to : to.toLowerCase();
22
+ const currentPath = caseSensitive ? pathname : pathname.toLowerCase();
23
+ if (end) {
24
+ // Exact match (including trailing slash variations)
25
+ return currentPath === toPath || currentPath === `${toPath}/`;
26
+ }
27
+ // Partial match - pathname starts with to
28
+ return (currentPath.startsWith(toPath) &&
29
+ (currentPath.length === toPath.length || currentPath[toPath.length] === "/"));
30
+ };
31
+ /**
32
+ * NavLink component for navigation with active state styling
33
+ *
34
+ * Extends Link with automatic active state detection and styling.
35
+ * Perfect for navigation menus, tabs, and breadcrumbs.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * // Basic usage with activeClassName
40
+ * <NavLink to="/about" activeClassName="active">About</NavLink>
41
+ *
42
+ * // With activeStyle
43
+ * <NavLink
44
+ * to="/profile"
45
+ * activeStyle={{ fontWeight: 'bold', color: 'blue' }}
46
+ * >
47
+ * Profile
48
+ * </NavLink>
49
+ *
50
+ * // Exact matching with end prop
51
+ * <NavLink to="/" end activeClassName="active">Home</NavLink>
52
+ *
53
+ * // Custom active detection
54
+ * <NavLink
55
+ * to="/users"
56
+ * isActive={(match, location) => {
57
+ * return location.pathname.startsWith('/users');
58
+ * }}
59
+ * >
60
+ * Users
61
+ * </NavLink>
62
+ *
63
+ * // Render prop for full control
64
+ * <NavLink to="/dashboard">
65
+ * {({ isActive }) => (
66
+ * <span className={isActive ? 'active' : ''}>
67
+ * Dashboard {isActive && '✓'}
68
+ * </span>
69
+ * )}
70
+ * </NavLink>
71
+ * ```
72
+ */
73
+ const NavLink = forwardRef(({ to, children, className, activeClassName = "active", activeStyle, isActive: customIsActive, end = false, caseSensitive = false, replace = false, state, preventScrollReset = false, target, rel, title, onClick, ...rest }, ref) => {
74
+ const { navigate, pathname, matches } = useRouter();
75
+ const location = useLocation();
76
+ // Determine active state
77
+ let isActive;
78
+ if (customIsActive) {
79
+ // Use custom isActive function
80
+ const currentMatch = matches.length > 0 ? matches[matches.length - 1] : null;
81
+ isActive = customIsActive(currentMatch, location);
82
+ }
83
+ else {
84
+ // Use default matching
85
+ isActive = defaultIsActive(pathname, to, end, caseSensitive);
86
+ }
87
+ // Compute class names
88
+ const computedClassName = [className, isActive ? activeClassName : null]
7
89
  .filter(Boolean)
8
- .join(" ");
9
- return (_jsx("a", { onClick: (e) => {
10
- e.preventDefault();
11
- navigate(to);
12
- }, className: combinedClass, href: to, children: children }));
13
- }
90
+ .join(" ") || undefined;
91
+ // Compute styles
92
+ const computedStyle = isActive
93
+ ? activeStyle
94
+ : undefined;
95
+ // External link check
96
+ const isExternal = /^https?:\/\//i.test(to);
97
+ const handleClick = (event) => {
98
+ onClick === null || onClick === void 0 ? void 0 : onClick(event);
99
+ if (!isExternal && shouldNavigate(event, target)) {
100
+ event.preventDefault();
101
+ navigate(to, { replace, state, preventScrollReset });
102
+ }
103
+ };
104
+ // Security for external links
105
+ const computedRel = isExternal && target === "_blank" ? rel || "noopener noreferrer" : rel;
106
+ // Support render prop pattern
107
+ const renderChildren = typeof children === "function"
108
+ ? children({
109
+ isActive,
110
+ })
111
+ : children;
112
+ return (_jsx("a", { ref: ref, href: to, onClick: handleClick, className: computedClassName, style: computedStyle, target: target, rel: computedRel, title: title, "aria-current": isActive ? "page" : undefined, ...rest, children: renderChildren }));
113
+ });
114
+ NavLink.displayName = "NavLink";
14
115
  export default NavLink;
@@ -0,0 +1,66 @@
1
+ import { ReactNode } from "react";
2
+ import { useOutletContext } from "../context/OutletContext";
3
+ /**
4
+ * Outlet component props
5
+ */
6
+ export interface OutletProps {
7
+ /** Custom context to pass to child routes */
8
+ context?: unknown;
9
+ }
10
+ /**
11
+ * Outlet Component
12
+ *
13
+ * Renders the child route's element when nested routes are used.
14
+ * This is the React Router-style component for rendering nested route content.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * // Parent route component
19
+ * function Dashboard() {
20
+ * return (
21
+ * <div className="dashboard">
22
+ * <Sidebar />
23
+ * <main>
24
+ * <Outlet /> {/* Renders child route content *\/}
25
+ * </main>
26
+ * </div>
27
+ * );
28
+ * }
29
+ *
30
+ * // Routes configuration
31
+ * const routes = createRouter([
32
+ * {
33
+ * path: "dashboard",
34
+ * component: <Dashboard />,
35
+ * children: [
36
+ * { path: "", component: <DashboardHome /> },
37
+ * { path: "settings", component: <Settings /> },
38
+ * { path: "profile", component: <Profile /> },
39
+ * ],
40
+ * },
41
+ * ]);
42
+ * ```
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * // Passing context to child routes
47
+ * function Layout() {
48
+ * const user = useUser();
49
+ * return (
50
+ * <div>
51
+ * <Header user={user} />
52
+ * <Outlet context={{ user }} />
53
+ * </div>
54
+ * );
55
+ * }
56
+ *
57
+ * // Accessing context in child route
58
+ * function Profile() {
59
+ * const { user } = useOutletContext<{ user: User }>();
60
+ * return <h1>Welcome, {user.name}</h1>;
61
+ * }
62
+ * ```
63
+ */
64
+ export declare function Outlet({ context }: OutletProps): ReactNode;
65
+ export { useOutletContext };
66
+ export default Outlet;
@@ -0,0 +1,69 @@
1
+ import { useOutlet, useOutletContext } from "../context/OutletContext";
2
+ /**
3
+ * Outlet Component
4
+ *
5
+ * Renders the child route's element when nested routes are used.
6
+ * This is the React Router-style component for rendering nested route content.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * // Parent route component
11
+ * function Dashboard() {
12
+ * return (
13
+ * <div className="dashboard">
14
+ * <Sidebar />
15
+ * <main>
16
+ * <Outlet /> {/* Renders child route content *\/}
17
+ * </main>
18
+ * </div>
19
+ * );
20
+ * }
21
+ *
22
+ * // Routes configuration
23
+ * const routes = createRouter([
24
+ * {
25
+ * path: "dashboard",
26
+ * component: <Dashboard />,
27
+ * children: [
28
+ * { path: "", component: <DashboardHome /> },
29
+ * { path: "settings", component: <Settings /> },
30
+ * { path: "profile", component: <Profile /> },
31
+ * ],
32
+ * },
33
+ * ]);
34
+ * ```
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * // Passing context to child routes
39
+ * function Layout() {
40
+ * const user = useUser();
41
+ * return (
42
+ * <div>
43
+ * <Header user={user} />
44
+ * <Outlet context={{ user }} />
45
+ * </div>
46
+ * );
47
+ * }
48
+ *
49
+ * // Accessing context in child route
50
+ * function Profile() {
51
+ * const { user } = useOutletContext<{ user: User }>();
52
+ * return <h1>Welcome, {user.name}</h1>;
53
+ * }
54
+ * ```
55
+ */
56
+ export function Outlet({ context }) {
57
+ const outlet = useOutlet();
58
+ // If context is provided, we could wrap outlet with context
59
+ // For now, just return the outlet content
60
+ if (context !== undefined) {
61
+ // Context is passed through OutletProvider in RouterProvider
62
+ console.warn("Outlet context prop is for documentation purposes. " +
63
+ "Use useOutletContext() in child components to access parent context.");
64
+ }
65
+ return outlet;
66
+ }
67
+ // Re-export useOutletContext for convenience
68
+ export { useOutletContext };
69
+ export default Outlet;
@@ -0,0 +1,69 @@
1
+ import { type ReactNode } from "react";
2
+ /**
3
+ * Router props
4
+ */
5
+ interface RouterProps {
6
+ /** Route children as JSX */
7
+ children: ReactNode;
8
+ /** Base path for all routes */
9
+ basename?: string;
10
+ /** Fallback element shown during lazy loading */
11
+ fallback?: ReactNode;
12
+ }
13
+ /**
14
+ * Router component for declarative routing
15
+ *
16
+ * Provides an alternative JSX-based approach to defining routes.
17
+ * Supports all route configuration options through props.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * // Basic usage
22
+ * <Router>
23
+ * <Route path="/" component={<Home />} />
24
+ * <Route path="/about" component={<About />} />
25
+ * <Route path="/users/:id" component={<UserProfile />} />
26
+ * <Route path="/dashboard" component={<Dashboard />}>
27
+ * <Route path="settings" component={<Settings />} />
28
+ * <Route path="profile" component={<Profile />} />
29
+ * </Route>
30
+ * <Route path="/404" component={<NotFound />} />
31
+ * </Router>
32
+ * ```
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * // With basename
37
+ * <Router basename="/app">
38
+ * <Route path="/" component={<Home />} />
39
+ * </Router>
40
+ * ```
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * // With lazy loading
45
+ * const LazyAbout = lazy(() => import('./pages/About'));
46
+ *
47
+ * <Router fallback={<Loading />}>
48
+ * <Route path="/about" component={<LazyAbout />} />
49
+ * </Router>
50
+ * ```
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * // With guards and loaders
55
+ * <Router>
56
+ * <Route
57
+ * path="/admin"
58
+ * component={<Admin />}
59
+ * guard={() => isAdmin() || '/login'}
60
+ * loader={async () => fetchAdminData()}
61
+ * />
62
+ * </Router>
63
+ * ```
64
+ */
65
+ declare const Router: {
66
+ ({ children, basename, fallback }: RouterProps): import("react/jsx-runtime").JSX.Element;
67
+ displayName: string;
68
+ };
69
+ export default Router;
@@ -0,0 +1,109 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Children, isValidElement, Suspense } from "react";
3
+ import RouterProvider from "../context/RouterProvider";
4
+ import createRouter from "../core/createRouter";
5
+ import { Route } from "./route";
6
+ /**
7
+ * Extracts route configurations from JSX Route elements
8
+ * @param children React children containing Route elements
9
+ * @returns Array of route configurations
10
+ */
11
+ function extractRoutesFromJSX(children) {
12
+ const routes = [];
13
+ Children.forEach(children, (child) => {
14
+ var _a;
15
+ if (isValidElement(child)) {
16
+ // Check if this is a Route component
17
+ const isRouteComponent = child.type === Route ||
18
+ ((_a = child.type) === null || _a === void 0 ? void 0 : _a.displayName) === "Route" ||
19
+ (typeof child.type === "function" && child.type.name === "Route");
20
+ if (isRouteComponent) {
21
+ const props = child.props;
22
+ const route = {
23
+ path: props.path,
24
+ component: props.component,
25
+ // Pass through all route configuration options
26
+ index: props.index,
27
+ lazy: props.lazy,
28
+ loader: props.loader,
29
+ errorElement: props.errorElement,
30
+ redirectTo: props.redirectTo,
31
+ guard: props.guard,
32
+ meta: props.meta,
33
+ };
34
+ // Handle nested routes
35
+ if (props.children) {
36
+ const childRoutes = extractRoutesFromJSX(props.children);
37
+ if (childRoutes.length > 0) {
38
+ route.children = childRoutes;
39
+ }
40
+ }
41
+ routes.push(route);
42
+ }
43
+ }
44
+ });
45
+ return routes;
46
+ }
47
+ /**
48
+ * Router component for declarative routing
49
+ *
50
+ * Provides an alternative JSX-based approach to defining routes.
51
+ * Supports all route configuration options through props.
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * // Basic usage
56
+ * <Router>
57
+ * <Route path="/" component={<Home />} />
58
+ * <Route path="/about" component={<About />} />
59
+ * <Route path="/users/:id" component={<UserProfile />} />
60
+ * <Route path="/dashboard" component={<Dashboard />}>
61
+ * <Route path="settings" component={<Settings />} />
62
+ * <Route path="profile" component={<Profile />} />
63
+ * </Route>
64
+ * <Route path="/404" component={<NotFound />} />
65
+ * </Router>
66
+ * ```
67
+ *
68
+ * @example
69
+ * ```tsx
70
+ * // With basename
71
+ * <Router basename="/app">
72
+ * <Route path="/" component={<Home />} />
73
+ * </Router>
74
+ * ```
75
+ *
76
+ * @example
77
+ * ```tsx
78
+ * // With lazy loading
79
+ * const LazyAbout = lazy(() => import('./pages/About'));
80
+ *
81
+ * <Router fallback={<Loading />}>
82
+ * <Route path="/about" component={<LazyAbout />} />
83
+ * </Router>
84
+ * ```
85
+ *
86
+ * @example
87
+ * ```tsx
88
+ * // With guards and loaders
89
+ * <Router>
90
+ * <Route
91
+ * path="/admin"
92
+ * component={<Admin />}
93
+ * guard={() => isAdmin() || '/login'}
94
+ * loader={async () => fetchAdminData()}
95
+ * />
96
+ * </Router>
97
+ * ```
98
+ */
99
+ const Router = ({ children, basename, fallback }) => {
100
+ const routes = extractRoutesFromJSX(children);
101
+ const content = (_jsx(RouterProvider, { routes: createRouter(routes), basename: basename, fallbackElement: fallback }));
102
+ // Wrap in Suspense if fallback is provided
103
+ if (fallback) {
104
+ return _jsx(Suspense, { fallback: fallback, children: content });
105
+ }
106
+ return content;
107
+ };
108
+ Router.displayName = "Router";
109
+ export default Router;
@@ -0,0 +1,77 @@
1
+ import { ComponentType, LazyExoticComponent, ReactElement } from "react";
2
+ import type { RouteGuard, RouteLoader, RouteMeta } from "../types";
3
+ /**
4
+ * Route component props for declarative routing
5
+ */
6
+ export interface RouteProps {
7
+ /** Path pattern(s) for the route */
8
+ path: string | string[];
9
+ /** Component to render when route matches */
10
+ component: ReactElement;
11
+ /** Nested route children */
12
+ children?: ReactElement<RouteProps> | ReactElement<RouteProps>[];
13
+ /** Index route - renders when parent path matches exactly */
14
+ index?: boolean;
15
+ /** Lazy-loaded component */
16
+ lazy?: LazyExoticComponent<ComponentType<any>>;
17
+ /** Route loader for data fetching */
18
+ loader?: RouteLoader;
19
+ /** Error boundary element */
20
+ errorElement?: ReactElement;
21
+ /** Redirect to another path */
22
+ redirectTo?: string;
23
+ /** Route guard function */
24
+ guard?: RouteGuard;
25
+ /** Route metadata */
26
+ meta?: RouteMeta;
27
+ /** Case-sensitive matching */
28
+ caseSensitive?: boolean;
29
+ }
30
+ /**
31
+ * Route component - used for declarative route definitions
32
+ * This is a placeholder component that will be processed by the Router
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * // Basic route
37
+ * <Route path="/users/:id" component={<UserProfile />} />
38
+ *
39
+ * // Multiple paths
40
+ * <Route path={["/about", "/about-us"]} component={<About />} />
41
+ *
42
+ * // Nested routes
43
+ * <Route path="/dashboard" component={<Dashboard />}>
44
+ * <Route path="settings" component={<Settings />} />
45
+ * <Route path="profile" component={<Profile />} />
46
+ * </Route>
47
+ *
48
+ * // With loader
49
+ * <Route
50
+ * path="/user/:id"
51
+ * component={<UserPage />}
52
+ * loader={async ({ params }) => fetchUser(params.id)}
53
+ * />
54
+ *
55
+ * // With guard
56
+ * <Route
57
+ * path="/admin"
58
+ * component={<AdminPanel />}
59
+ * guard={() => isAdmin() || '/login'}
60
+ * />
61
+ *
62
+ * // With metadata
63
+ * <Route
64
+ * path="/about"
65
+ * component={<About />}
66
+ * meta={{ title: 'About Us', description: 'Learn about us' }}
67
+ * />
68
+ *
69
+ * // Catch-all route
70
+ * <Route path="*" component={<NotFound />} />
71
+ * ```
72
+ */
73
+ export declare function Route(_props: RouteProps): null;
74
+ export declare namespace Route {
75
+ var displayName: string;
76
+ }
77
+ export default Route;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Route component - used for declarative route definitions
3
+ * This is a placeholder component that will be processed by the Router
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * // Basic route
8
+ * <Route path="/users/:id" component={<UserProfile />} />
9
+ *
10
+ * // Multiple paths
11
+ * <Route path={["/about", "/about-us"]} component={<About />} />
12
+ *
13
+ * // Nested routes
14
+ * <Route path="/dashboard" component={<Dashboard />}>
15
+ * <Route path="settings" component={<Settings />} />
16
+ * <Route path="profile" component={<Profile />} />
17
+ * </Route>
18
+ *
19
+ * // With loader
20
+ * <Route
21
+ * path="/user/:id"
22
+ * component={<UserPage />}
23
+ * loader={async ({ params }) => fetchUser(params.id)}
24
+ * />
25
+ *
26
+ * // With guard
27
+ * <Route
28
+ * path="/admin"
29
+ * component={<AdminPanel />}
30
+ * guard={() => isAdmin() || '/login'}
31
+ * />
32
+ *
33
+ * // With metadata
34
+ * <Route
35
+ * path="/about"
36
+ * component={<About />}
37
+ * meta={{ title: 'About Us', description: 'Learn about us' }}
38
+ * />
39
+ *
40
+ * // Catch-all route
41
+ * <Route path="*" component={<NotFound />} />
42
+ * ```
43
+ */
44
+ export function Route(_props) {
45
+ // This component doesn't render anything directly
46
+ // It's used as a declarative way to define routes that will be processed by Router
47
+ return null;
48
+ }
49
+ // Add displayName for better debugging and component recognition
50
+ Route.displayName = "Route";
51
+ export default Route;
@@ -0,0 +1,41 @@
1
+ import { ReactNode } from "react";
2
+ import type { Route, RouteMatch } from "../types";
3
+ /**
4
+ * Outlet context for nested route rendering
5
+ */
6
+ export interface OutletContextType {
7
+ /** Current outlet content to render */
8
+ outlet: ReactNode;
9
+ /** Remaining child routes */
10
+ childRoutes: Route[];
11
+ /** Current route matches */
12
+ matches: RouteMatch[];
13
+ /** Current depth in route tree */
14
+ depth: number;
15
+ /** Custom context data passed to outlet */
16
+ context?: unknown;
17
+ }
18
+ /**
19
+ * Context for outlet data
20
+ */
21
+ export declare const OutletDataContext: import("react").Context<OutletContextType | null>;
22
+ /**
23
+ * Hook to access outlet context
24
+ */
25
+ export declare function useOutletContext<T = unknown>(): T;
26
+ /**
27
+ * Hook to check if there's an outlet available
28
+ */
29
+ export declare function useOutlet(): ReactNode;
30
+ /**
31
+ * Provider for outlet context
32
+ */
33
+ export declare function OutletProvider({ children, outlet, childRoutes, matches, depth, context, }: {
34
+ children: ReactNode;
35
+ outlet: ReactNode;
36
+ childRoutes?: Route[];
37
+ matches?: RouteMatch[];
38
+ depth?: number;
39
+ context?: unknown;
40
+ }): import("react/jsx-runtime").JSX.Element;
41
+ export default OutletDataContext;