docs: add JSDoc documentation to core modules (directus, i18n, router, helpers)
This commit is contained in:
62
js/router.js
62
js/router.js
@@ -1,23 +1,59 @@
|
||||
/**
|
||||
* Hash-based Client-Side Router
|
||||
* @module router
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Route
|
||||
* @property {string} path - Current path
|
||||
* @property {Object<string, string>} params - Route and query params
|
||||
* @property {string} componentTag - Web component tag name
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hash-based router for SPA navigation
|
||||
* @class
|
||||
*/
|
||||
class Router {
|
||||
constructor() {
|
||||
/** @type {Map<string, string>} */
|
||||
this.routes = new Map()
|
||||
/** @type {Route|null} */
|
||||
this.currentRoute = null
|
||||
/** @type {HTMLElement|null} */
|
||||
this.outlet = null
|
||||
/** @type {Function|null} */
|
||||
this.beforeNavigate = null
|
||||
/** @type {Function|null} */
|
||||
this.afterNavigate = null
|
||||
|
||||
window.addEventListener('hashchange', () => this.handleRouteChange())
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the outlet element where components will be rendered
|
||||
* @param {HTMLElement} element - Container element
|
||||
*/
|
||||
setOutlet(element) {
|
||||
this.outlet = element
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a route
|
||||
* @param {string} path - Route path (e.g., '/listing/:id')
|
||||
* @param {string} componentTag - Web component tag name
|
||||
* @returns {Router} this for chaining
|
||||
*/
|
||||
register(path, componentTag) {
|
||||
this.routes.set(path, componentTag)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse current hash into path and query params
|
||||
* @private
|
||||
* @returns {{path: string, params: Object}}
|
||||
*/
|
||||
parseHash() {
|
||||
const hash = window.location.hash.slice(1) || '/'
|
||||
const [path, queryString] = hash.split('?')
|
||||
@@ -26,6 +62,12 @@ class Router {
|
||||
return { path, params: Object.fromEntries(params) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a path to a registered route
|
||||
* @private
|
||||
* @param {string} path - Path to match
|
||||
* @returns {{componentTag: string, params: Object}|null}
|
||||
*/
|
||||
matchRoute(path) {
|
||||
if (this.routes.has(path)) {
|
||||
return { componentTag: this.routes.get(path), params: {} }
|
||||
@@ -57,6 +99,10 @@ class Router {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle hash change event
|
||||
* @private
|
||||
*/
|
||||
async handleRouteChange() {
|
||||
const { path, params: queryParams } = this.parseHash()
|
||||
const match = this.matchRoute(path)
|
||||
@@ -86,6 +132,10 @@ class Router {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render current route's component into outlet
|
||||
* @private
|
||||
*/
|
||||
render() {
|
||||
if (!this.outlet || !this.currentRoute) return
|
||||
|
||||
@@ -120,6 +170,7 @@ class Router {
|
||||
}, { once: true })
|
||||
}
|
||||
|
||||
/** @private */
|
||||
renderNotFound() {
|
||||
if (!this.outlet) return
|
||||
|
||||
@@ -128,6 +179,11 @@ class Router {
|
||||
this.outlet.appendChild(notFound)
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to a path
|
||||
* @param {string} path - Target path
|
||||
* @param {Object<string, string>} [params={}] - Query parameters
|
||||
*/
|
||||
navigate(path, params = {}) {
|
||||
let url = `#${path}`
|
||||
|
||||
@@ -139,14 +195,20 @@ class Router {
|
||||
window.location.hash = url.slice(1)
|
||||
}
|
||||
|
||||
/** Navigate back in history */
|
||||
back() {
|
||||
window.history.back()
|
||||
}
|
||||
|
||||
/** Navigate forward in history */
|
||||
forward() {
|
||||
window.history.forward()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current route info
|
||||
* @returns {Route|null}
|
||||
*/
|
||||
getCurrentRoute() {
|
||||
return this.currentRoute
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user