-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrouter.tsx
More file actions
100 lines (80 loc) · 2.44 KB
/
router.tsx
File metadata and controls
100 lines (80 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Simple Router implementation for our custom React
import { React, useState, initializeApp } from './app';
// Check if we're in a browser environment
const isBrowser = typeof window !== 'undefined';
// Route context to share current route
let currentRoute = isBrowser ? window.location.pathname : '/';
let routeListeners: Array<() => void> = [];
// Function to notify all route listeners
const notifyRouteChange = () => {
routeListeners.forEach(listener => listener());
};
// Navigation function
export const navigate = (path: string) => {
if (!isBrowser) return;
if (currentRoute !== path) {
currentRoute = path;
window.history.pushState({}, '', path);
notifyRouteChange();
initializeApp();
}
};
// Handle browser back/forward buttons
if (isBrowser) {
window.addEventListener('popstate', () => {
currentRoute = window.location.pathname;
notifyRouteChange();
initializeApp();
});
}
// useRoute hook to get current route
export const useRoute = () => {
const [route, setRoute] = useState(currentRoute);
// Define a stable listener function
const listener = () => setRoute(currentRoute);
// Subscribe to route changes
if (isBrowser && !routeListeners.includes(listener)) {
routeListeners.push(listener);
}
return route;
};
// Router component
export const Router = ({ children }: { children: any }) => {
return children;
};
// Route component
export const Route = ({ path, element }: { path: string; element: any }) => {
const currentPath = useRoute();
// Simple path matching (exact match for now)
if (currentPath === path) {
return element;
}
return null;
};
// Link component
export const Link = ({ to, children, component, ...props }: { to: string; children: any; component?: any; [key: string]: any }) => {
const handleClick = (e: Event) => {
e.preventDefault();
navigate(to);
};
// Use custom component if provided, otherwise default 'a'
const Component = component || 'a';
// If it's a custom component, we need to pass props differently
if (component) {
return React.createElement(Component, {
href: to,
onclick: handleClick,
...props
}, children);
}
return React.createElement('a', {
href: to,
onclick: handleClick,
...props
}, children);
};
// StaticRouter for SSR
export const StaticRouter = ({ location, children }: { location: string; children: any }) => {
currentRoute = location;
return children;
};