@ereo/client 0.1.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.
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @ereo/client - Islands Architecture
3
+ *
4
+ * Selective hydration for interactive components.
5
+ * Static content stays static, only islands get hydrated.
6
+ */
7
+ import type { ComponentType } from 'react';
8
+ import type { HydrationStrategy } from '@ereo/core';
9
+ import { type HydrationProps } from './hydration';
10
+ /**
11
+ * Island registration.
12
+ */
13
+ export interface IslandRegistration {
14
+ id: string;
15
+ component: ComponentType<any>;
16
+ props: Record<string, unknown>;
17
+ strategy: HydrationStrategy;
18
+ media?: string;
19
+ element: Element;
20
+ hydrated: boolean;
21
+ }
22
+ /**
23
+ * Island registry - tracks all islands on the page.
24
+ */
25
+ declare class IslandRegistry {
26
+ private islands;
27
+ private cleanups;
28
+ /**
29
+ * Register an island for hydration.
30
+ */
31
+ register(id: string, component: ComponentType<any>, props: Record<string, unknown>, strategy: HydrationStrategy, element: Element, media?: string): void;
32
+ /**
33
+ * Get an island by ID.
34
+ */
35
+ get(id: string): IslandRegistration | undefined;
36
+ /**
37
+ * Mark an island as hydrated.
38
+ */
39
+ markHydrated(id: string): void;
40
+ /**
41
+ * Check if an island is hydrated.
42
+ */
43
+ isHydrated(id: string): boolean;
44
+ /**
45
+ * Set cleanup function for an island.
46
+ */
47
+ setCleanup(id: string, cleanup: () => void): void;
48
+ /**
49
+ * Cleanup an island.
50
+ */
51
+ cleanup(id: string): void;
52
+ /**
53
+ * Cleanup all islands.
54
+ */
55
+ cleanupAll(): void;
56
+ /**
57
+ * Get all islands.
58
+ */
59
+ getAll(): IslandRegistration[];
60
+ /**
61
+ * Get islands by strategy.
62
+ */
63
+ getByStrategy(strategy: HydrationStrategy): IslandRegistration[];
64
+ /**
65
+ * Get pending (not hydrated) islands.
66
+ */
67
+ getPending(): IslandRegistration[];
68
+ }
69
+ /**
70
+ * Global island registry.
71
+ */
72
+ export declare const islandRegistry: IslandRegistry;
73
+ /**
74
+ * Hydrate all islands on the page.
75
+ */
76
+ export declare function hydrateIslands(): Promise<void>;
77
+ /**
78
+ * Register an island component.
79
+ */
80
+ export declare function registerIslandComponent(name: string, component: ComponentType<any>): void;
81
+ /**
82
+ * Get an island component by name.
83
+ */
84
+ export declare function getIslandComponent(name: string): ComponentType<any> | undefined;
85
+ /**
86
+ * Register multiple island components.
87
+ */
88
+ export declare function registerIslandComponents(components: Record<string, ComponentType<any>>): void;
89
+ /**
90
+ * Create an island wrapper component.
91
+ * This is used during SSR to mark components for hydration.
92
+ */
93
+ export declare function createIsland<P extends Record<string, unknown>>(component: ComponentType<P>, name: string): ComponentType<P & HydrationProps>;
94
+ /**
95
+ * Auto-initialize islands on DOM ready.
96
+ */
97
+ export declare function initializeIslands(): void;
98
+ /**
99
+ * Cleanup all islands (for SPA navigation).
100
+ */
101
+ export declare function cleanupIslands(): void;
102
+ export {};
103
+ //# sourceMappingURL=islands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"islands.d.ts","sourceRoot":"","sources":["../src/islands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,cAAM,cAAc;IAClB,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,QAAQ,CAAiC;IAEjD;;OAEG;IACH,QAAQ,CACN,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,EAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,IAAI;IAYP;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI/C;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAO9B;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIjD;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IASzB;;OAEG;IACH,UAAU,IAAI,IAAI;IAMlB;;OAEG;IACH,MAAM,IAAI,kBAAkB,EAAE;IAI9B;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,iBAAiB,GAAG,kBAAkB,EAAE;IAIhE;;OAEG;IACH,UAAU,IAAI,kBAAkB,EAAE;CAGnC;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,gBAAuB,CAAC;AAEnD;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAiDpD;AAOD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI,CAEzF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,CAE/E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,GAC7C,IAAI,CAIN;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAC3B,IAAI,EAAE,MAAM,GACX,aAAa,CAAC,CAAC,GAAG,cAAc,CAAC,CA4BnC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAQxC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
package/dist/link.d.ts ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @ereo/client - Link Component
3
+ *
4
+ * Link and NavLink components with prefetch support for client-side navigation.
5
+ */
6
+ import * as React from 'react';
7
+ /**
8
+ * Prefetch strategy for links.
9
+ */
10
+ export type PrefetchStrategy = 'none' | 'intent' | 'render' | 'viewport';
11
+ /**
12
+ * Link component props.
13
+ */
14
+ export interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
15
+ /** URL to navigate to */
16
+ to: string;
17
+ /** Prefetch strategy (default: 'intent') */
18
+ prefetch?: PrefetchStrategy;
19
+ /** Replace history instead of push */
20
+ replace?: boolean;
21
+ /** Prevent scroll reset after navigation */
22
+ preventScrollReset?: boolean;
23
+ /** State to pass to the new location */
24
+ state?: unknown;
25
+ /** Reload the document instead of client navigation */
26
+ reloadDocument?: boolean;
27
+ /** Children elements */
28
+ children?: React.ReactNode;
29
+ }
30
+ /**
31
+ * Link component for client-side navigation with prefetch support.
32
+ *
33
+ * Renders an anchor tag for accessibility and SEO while intercepting
34
+ * clicks for client-side navigation.
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * <Link to="/about">About</Link>
39
+ * <Link to="/dashboard" prefetch="render">Dashboard</Link>
40
+ * <Link to="/external" reloadDocument>External</Link>
41
+ * ```
42
+ */
43
+ export declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
44
+ /**
45
+ * Active state props for NavLink.
46
+ */
47
+ export interface NavLinkActiveProps {
48
+ isActive: boolean;
49
+ isPending: boolean;
50
+ }
51
+ /**
52
+ * NavLink component props.
53
+ */
54
+ export interface NavLinkProps extends Omit<LinkProps, 'className' | 'style'> {
55
+ /** Class name - can be a function that receives active state */
56
+ className?: string | ((props: NavLinkActiveProps) => string);
57
+ /** Style - can be a function that receives active state */
58
+ style?: React.CSSProperties | ((props: NavLinkActiveProps) => React.CSSProperties);
59
+ /** Match exact path only (default: false) */
60
+ end?: boolean;
61
+ }
62
+ /**
63
+ * NavLink component - Link with active state styling.
64
+ *
65
+ * Automatically applies active styles/classes when the current
66
+ * location matches the link's destination.
67
+ *
68
+ * @example
69
+ * ```tsx
70
+ * <NavLink
71
+ * to="/dashboard"
72
+ * className={({ isActive }) => isActive ? 'active' : ''}
73
+ * >
74
+ * Dashboard
75
+ * </NavLink>
76
+ *
77
+ * <NavLink
78
+ * to="/settings"
79
+ * style={({ isActive }) => ({ fontWeight: isActive ? 'bold' : 'normal' })}
80
+ * >
81
+ * Settings
82
+ * </NavLink>
83
+ * ```
84
+ */
85
+ export declare const NavLink: React.ForwardRefExoticComponent<NavLinkProps & React.RefAttributes<HTMLAnchorElement>>;
86
+ /**
87
+ * Hook to get the active state for a given path.
88
+ * Useful for building custom navigation components.
89
+ */
90
+ export declare function useIsActive(path: string, end?: boolean): boolean;
91
+ //# sourceMappingURL=link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../src/link.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC5F,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,sCAAsC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4CAA4C;IAC5C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wCAAwC;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uDAAuD;IACvD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AA4CD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,IAAI,qFAuIf,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAAC;IAC1E,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,kBAAkB,KAAK,MAAM,CAAC,CAAC;IAC7D,2DAA2D;IAC3D,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,KAAK,EAAE,kBAAkB,KAAK,KAAK,CAAC,aAAa,CAAC,CAAC;IACnF,6CAA6C;IAC7C,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,OAAO,wFAuDlB,CAAC;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAQ,GAAG,OAAO,CAqB9D"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * @ereo/client - Client-side Navigation
3
+ *
4
+ * SPA-style navigation with loader data fetching.
5
+ */
6
+ import type { RouteParams } from '@ereo/core';
7
+ /**
8
+ * Navigation state.
9
+ */
10
+ export interface NavigationState {
11
+ pathname: string;
12
+ search: string;
13
+ hash: string;
14
+ state?: unknown;
15
+ }
16
+ /**
17
+ * Navigation event.
18
+ */
19
+ export interface NavigationEvent {
20
+ type: 'push' | 'replace' | 'pop';
21
+ from: NavigationState;
22
+ to: NavigationState;
23
+ }
24
+ /**
25
+ * Navigation listener.
26
+ */
27
+ export type NavigationListener = (event: NavigationEvent) => void;
28
+ /**
29
+ * Client router for SPA navigation.
30
+ */
31
+ declare class ClientRouter {
32
+ private listeners;
33
+ private currentState;
34
+ constructor();
35
+ /**
36
+ * Get current state from window.location.
37
+ */
38
+ private getStateFromLocation;
39
+ /**
40
+ * Setup popstate listener.
41
+ */
42
+ private setupPopState;
43
+ /**
44
+ * Navigate to a new URL.
45
+ */
46
+ navigate(to: string, options?: {
47
+ replace?: boolean;
48
+ state?: unknown;
49
+ }): Promise<void>;
50
+ /**
51
+ * Go back in history.
52
+ */
53
+ back(): void;
54
+ /**
55
+ * Go forward in history.
56
+ */
57
+ forward(): void;
58
+ /**
59
+ * Go to a specific history entry.
60
+ */
61
+ go(delta: number): void;
62
+ /**
63
+ * Subscribe to navigation events.
64
+ */
65
+ subscribe(listener: NavigationListener): () => void;
66
+ /**
67
+ * Notify all listeners.
68
+ */
69
+ private notify;
70
+ /**
71
+ * Get current navigation state.
72
+ */
73
+ getState(): NavigationState;
74
+ /**
75
+ * Check if a URL is the current location.
76
+ */
77
+ isActive(path: string, exact?: boolean): boolean;
78
+ }
79
+ /**
80
+ * Global client router instance.
81
+ */
82
+ export declare const router: ClientRouter;
83
+ /**
84
+ * Navigate to a new URL.
85
+ */
86
+ export declare function navigate(to: string, options?: {
87
+ replace?: boolean;
88
+ state?: unknown;
89
+ }): Promise<void>;
90
+ /**
91
+ * Go back in history.
92
+ */
93
+ export declare function goBack(): void;
94
+ /**
95
+ * Go forward in history.
96
+ */
97
+ export declare function goForward(): void;
98
+ /**
99
+ * Subscribe to navigation events.
100
+ */
101
+ export declare function onNavigate(listener: NavigationListener): () => void;
102
+ /**
103
+ * Get current navigation state.
104
+ */
105
+ export declare function getNavigationState(): NavigationState;
106
+ /**
107
+ * Fetch loader data for a route.
108
+ */
109
+ export declare function fetchLoaderData<T = unknown>(pathname: string, params?: RouteParams): Promise<T>;
110
+ /**
111
+ * Submit an action.
112
+ */
113
+ export declare function submitAction<T = unknown>(pathname: string, formData: FormData, options?: {
114
+ method?: string;
115
+ }): Promise<T>;
116
+ /**
117
+ * Scroll restoration helper.
118
+ */
119
+ export declare function setupScrollRestoration(): void;
120
+ export {};
121
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;IACjC,IAAI,EAAE,eAAe,CAAC;IACtB,EAAE,EAAE,eAAe,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AAElE;;GAEG;AACH,cAAM,YAAY;IAChB,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,YAAY,CAAkB;;IAOtC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;OAEG;IACG,QAAQ,CACZ,EAAE,EAAE,MAAM,EACV,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GACnD,OAAO,CAAC,IAAI,CAAC;IA8BhB;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,OAAO,IAAI,IAAI;IAMf;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMvB;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,IAAI;IAKnD;;OAEG;IACH,OAAO,CAAC,MAAM;IAMd;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,OAAO;CAM/C;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,cAAqB,CAAC;AAEzC;;GAEG;AACH,wBAAgB,QAAQ,CACtB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;GAEG;AACH,wBAAgB,MAAM,IAAI,IAAI,CAE7B;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAEhC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAEnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAEpD;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,CAAC,GAAG,OAAO,EAC/C,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,GAAG,OAAO,EAC5C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,CAAC,CAAC,CAcZ;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CA4B7C"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @ereo/client - Link Prefetching
3
+ *
4
+ * Intelligent prefetching for faster navigation.
5
+ */
6
+ /**
7
+ * Prefetch options.
8
+ */
9
+ export interface PrefetchOptions {
10
+ /** Prefetch strategy */
11
+ strategy?: 'hover' | 'viewport' | 'eager' | 'none';
12
+ /** Cache duration in milliseconds (default: 30000) */
13
+ cacheDuration?: number;
14
+ /** Intersection observer threshold */
15
+ threshold?: number;
16
+ }
17
+ /**
18
+ * Prefetch a URL.
19
+ */
20
+ export declare function prefetch(url: string): Promise<void>;
21
+ /**
22
+ * Get prefetched data.
23
+ */
24
+ export declare function getPrefetchedData<T>(url: string): T | undefined;
25
+ /**
26
+ * Clear prefetch cache.
27
+ */
28
+ export declare function clearPrefetchCache(): void;
29
+ /**
30
+ * Setup prefetch for a link element.
31
+ */
32
+ export declare function setupLinkPrefetch(element: HTMLAnchorElement, options?: PrefetchOptions): () => void;
33
+ /**
34
+ * Auto-setup prefetching for all links.
35
+ */
36
+ export declare function setupAutoPrefetch(options?: PrefetchOptions): () => void;
37
+ /**
38
+ * Prefetch multiple URLs.
39
+ */
40
+ export declare function prefetchAll(urls: string[]): Promise<void>;
41
+ /**
42
+ * Create a link prefetch directive for JSX.
43
+ */
44
+ export interface LinkPrefetchProps {
45
+ href: string;
46
+ prefetch?: PrefetchOptions['strategy'];
47
+ children: React.ReactNode;
48
+ }
49
+ /**
50
+ * Check if a URL is being prefetched.
51
+ */
52
+ export declare function isPrefetching(url: string): boolean;
53
+ /**
54
+ * Check if a URL has been prefetched.
55
+ */
56
+ export declare function isPrefetched(url: string): boolean;
57
+ //# sourceMappingURL=prefetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefetch.d.ts","sourceRoot":"","sources":["../src/prefetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;IACnD,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD;;GAEG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAM/D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,eAAoB,GAC5B,MAAM,IAAI,CAmDZ;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,eAAoB,GAAG,MAAM,IAAI,CAkC3E;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACvC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGjD"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * @ereo/client - Type-Safe Link Component
3
+ *
4
+ * Link component that validates routes exist and requires correct params
5
+ * per-route at compile time.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * // Valid - route exists and params match
10
+ * <TypedLink to="/users/[id]" params={{ id: "123" }}>User</TypedLink>
11
+ *
12
+ * // Error - missing required params
13
+ * <TypedLink to="/users/[id]">User</TypedLink>
14
+ *
15
+ * // Error - route doesn't exist
16
+ * <TypedLink to="/invalid">Invalid</TypedLink>
17
+ *
18
+ * // With search and hash params (Ereo exclusive)
19
+ * <TypedLink
20
+ * to="/posts/[slug]"
21
+ * params={{ slug: "hello-world" }}
22
+ * search={{ page: 1 }}
23
+ * hash={{ section: "comments" }}
24
+ * >
25
+ * Post
26
+ * </TypedLink>
27
+ * ```
28
+ */
29
+ import * as React from 'react';
30
+ import type { TypedRoutes, RouteParamsFor, SearchParamsFor, HashParamsFor } from '@ereo/core';
31
+ /**
32
+ * Check if params object is empty (no required params).
33
+ */
34
+ type IsEmptyObject<T> = keyof T extends never ? true : false;
35
+ /**
36
+ * Check if all properties in T are optional.
37
+ */
38
+ type AllOptional<T> = {
39
+ [K in keyof T]-?: {} extends Pick<T, K> ? true : false;
40
+ }[keyof T] extends true ? true : false;
41
+ /**
42
+ * Make params prop required only if the route has required params.
43
+ */
44
+ type ParamsProps<Path extends string, Params> = IsEmptyObject<Params> extends true ? {
45
+ params?: never;
46
+ } : AllOptional<Params> extends true ? {
47
+ params?: Params;
48
+ } : {
49
+ params: Params;
50
+ };
51
+ /**
52
+ * Make search prop optional, typed to route's search params.
53
+ */
54
+ type SearchProps<Path extends TypedRoutes> = {
55
+ search?: Partial<SearchParamsFor<Path>>;
56
+ };
57
+ /**
58
+ * Make hash prop optional, typed to route's hash params.
59
+ * This is UNIQUE to Ereo - TanStack has no hash param support.
60
+ */
61
+ type HashProps<Path extends TypedRoutes> = {
62
+ hash?: Partial<HashParamsFor<Path>>;
63
+ };
64
+ /**
65
+ * Prefetch strategy for links.
66
+ */
67
+ export type PrefetchStrategy = 'none' | 'intent' | 'render' | 'viewport';
68
+ /**
69
+ * Base props for TypedLink.
70
+ */
71
+ interface TypedLinkBaseProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
72
+ /** Prefetch strategy (default: 'intent') */
73
+ prefetch?: PrefetchStrategy;
74
+ /** Replace history instead of push */
75
+ replace?: boolean;
76
+ /** Prevent scroll reset after navigation */
77
+ preventScrollReset?: boolean;
78
+ /** State to pass to the new location */
79
+ state?: unknown;
80
+ /** Reload the document instead of client navigation */
81
+ reloadDocument?: boolean;
82
+ /** Children elements */
83
+ children?: React.ReactNode;
84
+ }
85
+ /**
86
+ * Full props for TypedLink with conditional params requirement.
87
+ */
88
+ export type TypedLinkProps<Path extends TypedRoutes = TypedRoutes> = TypedLinkBaseProps & {
89
+ /** Route path to navigate to */
90
+ to: Path;
91
+ } & ParamsProps<Path extends string ? Path : never, RouteParamsFor<Path>> & SearchProps<Path> & HashProps<Path>;
92
+ /**
93
+ * Build a complete URL from pattern, params, search, and hash.
94
+ */
95
+ export declare function buildUrl<Path extends TypedRoutes>(pattern: Path, options?: {
96
+ params?: RouteParamsFor<Path>;
97
+ search?: Partial<SearchParamsFor<Path>>;
98
+ hash?: Partial<HashParamsFor<Path>>;
99
+ }): string;
100
+ /**
101
+ * Type-safe Link component for client-side navigation.
102
+ *
103
+ * Validates that:
104
+ * 1. The route path exists in your route definitions
105
+ * 2. Required params are provided with correct types
106
+ * 3. Search params match the route's search schema
107
+ * 4. Hash params match the route's hash schema (Ereo exclusive)
108
+ *
109
+ * @example
110
+ * ```tsx
111
+ * // Basic usage
112
+ * <TypedLink to="/about">About</TypedLink>
113
+ *
114
+ * // With params
115
+ * <TypedLink to="/users/[id]" params={{ id: "123" }}>User Profile</TypedLink>
116
+ *
117
+ * // With search and hash params
118
+ * <TypedLink
119
+ * to="/posts/[slug]"
120
+ * params={{ slug: "hello" }}
121
+ * search={{ page: 1, sort: 'asc' }}
122
+ * hash={{ section: 'comments' }}
123
+ * >
124
+ * Post
125
+ * </TypedLink>
126
+ *
127
+ * // Prefetch on viewport
128
+ * <TypedLink to="/dashboard" prefetch="viewport">Dashboard</TypedLink>
129
+ * ```
130
+ */
131
+ export declare const TypedLink: <Path extends TypedRoutes>(props: TypedLinkProps<Path> & {
132
+ ref?: React.ForwardedRef<HTMLAnchorElement>;
133
+ }) => React.ReactElement | null;
134
+ /**
135
+ * Active state props for TypedNavLink.
136
+ */
137
+ export interface NavLinkActiveProps {
138
+ isActive: boolean;
139
+ isPending: boolean;
140
+ }
141
+ /**
142
+ * TypedNavLink props extending TypedLink with active state support.
143
+ */
144
+ export type TypedNavLinkProps<Path extends TypedRoutes = TypedRoutes> = Omit<TypedLinkProps<Path>, 'className' | 'style'> & {
145
+ /** Class name - can be a function that receives active state */
146
+ className?: string | ((props: NavLinkActiveProps) => string);
147
+ /** Style - can be a function that receives active state */
148
+ style?: React.CSSProperties | ((props: NavLinkActiveProps) => React.CSSProperties);
149
+ /** Match exact path only (default: false) */
150
+ end?: boolean;
151
+ };
152
+ /**
153
+ * Type-safe NavLink component with active state styling.
154
+ *
155
+ * @example
156
+ * ```tsx
157
+ * <TypedNavLink
158
+ * to="/dashboard"
159
+ * className={({ isActive }) => isActive ? 'active' : ''}
160
+ * >
161
+ * Dashboard
162
+ * </TypedNavLink>
163
+ *
164
+ * <TypedNavLink
165
+ * to="/users/[id]"
166
+ * params={{ id: "123" }}
167
+ * style={({ isActive }) => ({ fontWeight: isActive ? 'bold' : 'normal' })}
168
+ * >
169
+ * User
170
+ * </TypedNavLink>
171
+ * ```
172
+ */
173
+ export declare const TypedNavLink: <Path extends TypedRoutes>(props: TypedNavLinkProps<Path> & {
174
+ ref?: React.ForwardedRef<HTMLAnchorElement>;
175
+ }) => React.ReactElement | null;
176
+ /**
177
+ * Hook to check if a route is currently active.
178
+ *
179
+ * @example
180
+ * ```tsx
181
+ * const isActive = useIsRouteActive('/users/[id]', { params: { id: '123' } });
182
+ * ```
183
+ */
184
+ export declare function useIsRouteActive<Path extends TypedRoutes>(path: Path, options?: {
185
+ params?: RouteParamsFor<Path>;
186
+ end?: boolean;
187
+ }): boolean;
188
+ export {};
189
+ //# sourceMappingURL=typed-link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typed-link.d.ts","sourceRoot":"","sources":["../src/typed-link.tsx"],"names":[],"mappings":"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"}