Files
sanderling/examples/folio-web/src/router.ts
T
pj af7b7e27b0 feat(folio-web): web sample app + CDP spec tests (#36)
* fix(runner): allow nil connection for web platform

* fix(testrun): skip SDK handshake for web platform

* feat(folio-web): add React/Vite web sample app

* feat(folio-web): add sanderling spec

* fix(chrome): use InsertText for multi-char text input

* feat(hierarchy): add Screen field populated from sanderling-screen attr

* fix(chrome): auto-detect viewport from CSS vars, fix InputText accumulation, expose route as screen

* fix(runner): fall back to hierarchy root screen when snapshot screen is empty

* fix(folio-web): broaden loggedIn extractor to all authenticated pages
2026-04-22 23:59:30 +07:00

57 lines
1.7 KiB
TypeScript

import { useEffect, useState } from 'react'
export type Route =
| { name: 'login' }
| { name: 'home' }
| { name: 'add-account' }
| { name: 'ledger'; accountId: string }
| { name: 'add-transaction'; accountId: string }
| { name: 'not-found' }
function readHash(): string {
const raw = window.location.hash.replace(/^#/, '')
return raw === '' ? '/' : raw
}
export function parseHash(hash: string): Route {
const path = hash.split('?')[0]
if (path === '/' || path === '') return { name: 'home' }
if (path === '/login') return { name: 'login' }
if (path === '/accounts/new') return { name: 'add-account' }
const ledgerMatch = /^\/accounts\/([^/]+)$/.exec(path)
if (ledgerMatch) return { name: 'ledger', accountId: ledgerMatch[1] }
const txnMatch = /^\/accounts\/([^/]+)\/transactions\/new$/.exec(path)
if (txnMatch)
return { name: 'add-transaction', accountId: txnMatch[1] }
return { name: 'not-found' }
}
export function useRoute(): Route {
const [hash, setHash] = useState<string>(() => readHash())
useEffect(() => {
function onChange() {
setHash(readHash())
}
window.addEventListener('hashchange', onChange)
return () => window.removeEventListener('hashchange', onChange)
}, [])
return parseHash(hash)
}
export function navigate(path: string, opts: { replace?: boolean } = {}) {
const target = '#' + (path.startsWith('/') ? path : '/' + path)
if (opts.replace) {
window.location.replace(target)
} else {
window.location.hash = target.slice(1)
}
}
export function back(fallback: string = '/') {
if (window.history.length > 1) {
window.history.back()
} else {
navigate(fallback, { replace: true })
}
}