Skip to content

Instantly share code, notes, and snippets.

@guiseek
Last active January 15, 2023 12:10
Show Gist options
  • Save guiseek/c07ac2396365f2461dd654f0e3c03b31 to your computer and use it in GitHub Desktop.
Save guiseek/c07ac2396365f2461dd654f0e3c03b31 to your computer and use it in GitHub Desktop.
Router
export class ErrorPage extends HTMLElement {
innerHTML = `<h1>Error</h1>`
}
customElements.define('error-page', ErrorPage)
export class HomePage extends HTMLElement {
innerHTML = `<h1>Home</h1>`
}
customElements.define('home-page', HomePage)
router.bootstrap(
document.querySelector('main#outlet')
)
export class ProfilePage extends HTMLElement {
innerHTML = `<h1>Profile</h1>`
}
customElements.define('profile-page', ProfilePage)
export const router = new Router(
[
{
path: '/',
element: HomePage,
},
{
path: '/profile',
element: ProfilePage,
}
],
{}
)
interface Route {
path: string
element: CustomElementConstructor
}
interface RouteExtras {
outlet?: HTMLElement
initOnLoad?: boolean
}
export class Router {
readonly extras: RouteExtras
constructor(readonly routes: Route[], extras: RouteExtras) {
this.extras = {...{initOnLoad: true}, ...extras}
}
getParams() {
const [, query] = location.hash.split('?')
const params = new URLSearchParams(query)
return Object.fromEntries(params.entries())
}
getPath() {
const [path] = location.hash.slice(1).split('?')
return path ? path.toLowerCase() : '/'
}
findByPath(path: string) {
const regExp = new RegExp(`^\\${path}$`, 'gm')
const route = this.routes.find(({path}) => {
console.log(path.match(regExp))
return path.match(regExp)
})
return route ? route : {element: ErrorPage}
}
handle(outlet: HTMLElement) {
return () => {
const path = this.getPath()
const {element} = this.findByPath(path)
outlet.childNodes.forEach((node) => node.remove())
outlet.appendChild(new element())
}
}
bootstrap(outlet: HTMLElement) {
onhashchange = this.handle(outlet)
if (this.extras.initOnLoad) {
onload = this.handle(outlet)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment