40 lines
966 B
TypeScript
40 lines
966 B
TypeScript
type RouteHandler = (params: Record<string, string>) => void
|
|
|
|
interface Route {
|
|
pattern: RegExp
|
|
keys: string[]
|
|
handler: RouteHandler
|
|
}
|
|
|
|
const routes: Route[] = []
|
|
|
|
export function route(path: string, handler: RouteHandler): void {
|
|
const keys: string[] = []
|
|
const pattern = new RegExp(
|
|
'^' + path.replace(/:([^/]+)/g, (_: string, k: string) => { keys.push(k); return '([^/]+)' }) + '$'
|
|
)
|
|
routes.push({ pattern, keys, handler })
|
|
}
|
|
|
|
export function navigate(path: string): void {
|
|
history.pushState(null, '', path)
|
|
dispatch(path)
|
|
}
|
|
|
|
function dispatch(path: string): void {
|
|
for (const r of routes) {
|
|
const m = path.match(r.pattern)
|
|
if (m) {
|
|
const params: Record<string, string> = {}
|
|
r.keys.forEach((k, i) => { params[k] = m[i + 1] })
|
|
r.handler(params)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
export function startRouter(): void {
|
|
window.addEventListener('popstate', () => dispatch(location.pathname))
|
|
dispatch(location.pathname)
|
|
}
|