mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-03 19:47:10 +00:00
* 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
57 lines
1.7 KiB
TypeScript
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 })
|
|
}
|
|
}
|