diff --git a/libs/embeds/src/link.ts b/libs/embeds/src/link.ts index 342731e..41a49f8 100644 --- a/libs/embeds/src/link.ts +++ b/libs/embeds/src/link.ts @@ -1,7 +1,11 @@ +import type { RoutedWindow } from '@goldenwere/static-web-templates-types' + import type { AttributeObserver } from './observer' export type LinkEmbedAttributes = typeof LinkEmbed.observedAttributes[number] +declare const window: RoutedWindow + /** * A link embed is a link with a title and an optional icon + subtitle */ @@ -23,11 +27,19 @@ export class LinkEmbed extends HTMLElement { const _link = ownerDocument.createElement('a') _link.setAttribute('rel', 'noreferrer noopener') + _link.addEventListener('click', (e) => { + if (_link.dataset?.href?.startsWith('/') && !!window.router) { + e.preventDefault() + const route = window.router.resolve({ path: _link.dataset.href }) + window.router.push(route) + } + }) this._observers.href = { element: _link, - observer: (oldVal, newVal) => { + observer: (oldVal, newVal: string) => { const { element } = this._observers.href element!.setAttribute('href', newVal) + element!.dataset.href = newVal }, } this._observers.target = { diff --git a/libs/types/src/config/routing.d.ts b/libs/types/src/config/routing.d.ts index 52bfd2b..61ebde4 100644 --- a/libs/types/src/config/routing.d.ts +++ b/libs/types/src/config/routing.d.ts @@ -1,7 +1,9 @@ +import { Router } from 'vue-router' +import { GalleryEntry } from '../content/templates/gallery-list' +import { ProjectListingInfo } from '../content/templates/project-list' import { TemplateType } from '../content/templates/templateType' import { WarningModal } from './warnings' - /** * Defines the shared options for a route */ @@ -69,8 +71,16 @@ export type RouteDefinition = */ export type RouteCollection = { [key: string]: RouteDefinition } +/** + * Defines {@link Window} globals + */ export interface RoutedWindow extends Window { + /** refers to a template's primary route config; may briefly refer to sub config until a view is fully resolved */ routeConfig: RouteDefinition + /** refers to a template's sub config in the case of child routes under a template (e.g. project-view under project-list) */ routeSubConfig: any + /** refers to content config for various view routes (e.g. {@link GalleryEntry}, {@link ProjectListingInfo}, etc.) */ routeContentConfig: any + /** vue-router instance */ + router?: Router } diff --git a/projects/frontend/src/main.ts b/projects/frontend/src/main.ts index 43fb38c..3a7436d 100644 --- a/projects/frontend/src/main.ts +++ b/projects/frontend/src/main.ts @@ -4,6 +4,7 @@ import hljs from 'highlight.js' import { marked } from 'marked' import { markedHighlight } from 'marked-highlight' +import type { RoutedWindow } from '@goldenwere/static-web-templates-types' import { registerLinkEmbed } from '@goldenwere/static-web-templates-embeds' import main from './main.vue' @@ -12,6 +13,8 @@ import './main.sass' import { createRoutes, initializeRouteStore } from './routes' import { headingSectionsExtension } from './utilities/marked' +declare const window: RoutedWindow + marked .use(headingSectionsExtension() as any) .use(markedHighlight({ @@ -30,7 +33,7 @@ export const createApp = ViteSSG( // function to have custom setups ({ app, router, routes, isClient, initialState }) => { registerLinkEmbed() - + window.router = router app.use(createPinia()) initializeRouteStore(routes) }, diff --git a/projects/frontend/src/views/gallery/gallery-view.vue b/projects/frontend/src/views/gallery/gallery-view.vue index 6e9a664..dfd879f 100644 --- a/projects/frontend/src/views/gallery/gallery-view.vue +++ b/projects/frontend/src/views/gallery/gallery-view.vue @@ -52,6 +52,7 @@ onMounted(async () => { title.value = getTitleFromEntryOrId(entry.value, id.value) document.title = routeSubConfig.fullTitle?.replace('$ENTRY', title.value) routeStore.setBreadcrumbs(currentRoute, title.value) + window.routeConfig = {...routeConfig} window.routeSubConfig = {...routeSubConfig} window.routeContentConfig = {...entry.value} diff --git a/projects/frontend/src/views/project/project-view.vue b/projects/frontend/src/views/project/project-view.vue index 02c3f36..ed710ed 100644 --- a/projects/frontend/src/views/project/project-view.vue +++ b/projects/frontend/src/views/project/project-view.vue @@ -34,6 +34,7 @@ onMounted(async () => { content.value = md document.title = routeSubConfig.fullTitle?.replace('$PROJECT', info.value.title) routeStore.setBreadcrumbs(currentRoute, info.value.title) + window.routeConfig = {...routeConfig} window.routeSubConfig = {...routeSubConfig} window.routeContentConfig = {...info.value}