support internal links with vue-router outside vue context

This commit is contained in:
lightling 2024-05-16 18:09:12 -04:00
parent 10dc4372c0
commit af5ec7a9dc
5 changed files with 30 additions and 3 deletions

View file

@ -1,7 +1,11 @@
import type { RoutedWindow } from '@goldenwere/static-web-templates-types'
import type { AttributeObserver } from './observer' import type { AttributeObserver } from './observer'
export type LinkEmbedAttributes = typeof LinkEmbed.observedAttributes[number] 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 * 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') const _link = ownerDocument.createElement('a')
_link.setAttribute('rel', 'noreferrer noopener') _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 = { this._observers.href = {
element: _link, element: _link,
observer: (oldVal, newVal) => { observer: (oldVal, newVal: string) => {
const { element } = this._observers.href const { element } = this._observers.href
element!.setAttribute('href', newVal) element!.setAttribute('href', newVal)
element!.dataset.href = newVal
}, },
} }
this._observers.target = { this._observers.target = {

View file

@ -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 { TemplateType } from '../content/templates/templateType'
import { WarningModal } from './warnings' import { WarningModal } from './warnings'
/** /**
* Defines the shared options for a route * Defines the shared options for a route
*/ */
@ -69,8 +71,16 @@ export type RouteDefinition =
*/ */
export type RouteCollection = { [key: string]: RouteDefinition } export type RouteCollection = { [key: string]: RouteDefinition }
/**
* Defines {@link Window} globals
*/
export interface RoutedWindow extends Window { 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 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 routeSubConfig: any
/** refers to content config for various view routes (e.g. {@link GalleryEntry}, {@link ProjectListingInfo}, etc.) */
routeContentConfig: any routeContentConfig: any
/** vue-router instance */
router?: Router
} }

View file

@ -4,6 +4,7 @@ import hljs from 'highlight.js'
import { marked } from 'marked' import { marked } from 'marked'
import { markedHighlight } from 'marked-highlight' import { markedHighlight } from 'marked-highlight'
import type { RoutedWindow } from '@goldenwere/static-web-templates-types'
import { registerLinkEmbed } from '@goldenwere/static-web-templates-embeds' import { registerLinkEmbed } from '@goldenwere/static-web-templates-embeds'
import main from './main.vue' import main from './main.vue'
@ -12,6 +13,8 @@ import './main.sass'
import { createRoutes, initializeRouteStore } from './routes' import { createRoutes, initializeRouteStore } from './routes'
import { headingSectionsExtension } from './utilities/marked' import { headingSectionsExtension } from './utilities/marked'
declare const window: RoutedWindow
marked marked
.use(headingSectionsExtension() as any) .use(headingSectionsExtension() as any)
.use(markedHighlight({ .use(markedHighlight({
@ -30,7 +33,7 @@ export const createApp = ViteSSG(
// function to have custom setups // function to have custom setups
({ app, router, routes, isClient, initialState }) => { ({ app, router, routes, isClient, initialState }) => {
registerLinkEmbed() registerLinkEmbed()
window.router = router
app.use(createPinia()) app.use(createPinia())
initializeRouteStore(routes) initializeRouteStore(routes)
}, },

View file

@ -52,6 +52,7 @@ onMounted(async () => {
title.value = getTitleFromEntryOrId(entry.value, id.value) title.value = getTitleFromEntryOrId(entry.value, id.value)
document.title = routeSubConfig.fullTitle?.replace('$ENTRY', title.value) document.title = routeSubConfig.fullTitle?.replace('$ENTRY', title.value)
routeStore.setBreadcrumbs(currentRoute, title.value) routeStore.setBreadcrumbs(currentRoute, title.value)
window.routeConfig = {...routeConfig}
window.routeSubConfig = {...routeSubConfig} window.routeSubConfig = {...routeSubConfig}
window.routeContentConfig = {...entry.value} window.routeContentConfig = {...entry.value}

View file

@ -34,6 +34,7 @@ onMounted(async () => {
content.value = md content.value = md
document.title = routeSubConfig.fullTitle?.replace('$PROJECT', info.value.title) document.title = routeSubConfig.fullTitle?.replace('$PROJECT', info.value.title)
routeStore.setBreadcrumbs(currentRoute, info.value.title) routeStore.setBreadcrumbs(currentRoute, info.value.title)
window.routeConfig = {...routeConfig}
window.routeSubConfig = {...routeSubConfig} window.routeSubConfig = {...routeSubConfig}
window.routeContentConfig = {...info.value} window.routeContentConfig = {...info.value}