UNPKG

@shaun/alpinejs-router

Version:

A lightweight client-side router for Alpine.js that adds declarative routes, link navigation, dynamic params, external templates, and hash or HTML5 history modes without turning your app into a larger framework.

100 lines (79 loc) • 2.08 kB
export class RouterURL { #url #path constructor(url, opts = {}) { this.#url = new URL(url) this.mode = opts.mode ?? 'web' this.base = opts.base ?? '' } set url (val) { this.#url = new URL(val) this.#path = undefined } get url () { return this.#url.href } get path () { this.#path ??= this.#resolvePath() return this.#path } #hashContent () { return this.#url.hash.slice(1).split('#').shift() } #resolvePath () { if (this.mode === 'hash' && this.#url.hash) { return this.#hashContent().split('?').shift() || '/' } const pathname = this.#url.pathname const base = this.base && this.base !== '/' ? this.base.replace(/\/$/, '') : '' if (!base) { return pathname } if (pathname === base) { return '/' } if (pathname.startsWith(base + '/')) { return pathname.slice(base.length) || '/' } return pathname } get query () { const search = this.mode === 'hash' && this.#url.hash ? this.#hashContent().split('?').slice(1).join('?') : this.#url.search return Object.fromEntries(new URLSearchParams(search)) } resolve (path, params, replace = false) { const l = this.#url.origin + this.base + (this.mode === 'hash' ? '#' : '') + path const r = replace ? new URLSearchParams(params).toString() : new URLSearchParams({ ...this.query, ...params }).toString() this.url = l + (r ? '?' + r : '') return this } static resolveTemplatePath (pathname, tpl) { if (!tpl) return tpl if (tpl.startsWith('/')) { return tpl } const dir = pathname.slice(0, pathname.lastIndexOf('/')) if (tpl.startsWith('./')) { return dir + tpl.slice(1) } if (tpl.startsWith('../')) { const re = /\.\.\//g let i = tpl.match(re).length let arr = dir.split('/') while (i--) { arr.pop() } if (arr.length === 0) { arr = [''] } return [...arr, tpl.replace(re, '')].join('/') } return tpl } }