project tile as web component

This commit is contained in:
lightling 2024-05-13 20:23:48 -04:00
parent 71adcff32b
commit a0367f8563
6 changed files with 61 additions and 24 deletions

View file

@ -0,0 +1,5 @@
import { registerProjectTile } from './project-tile'
export const register = () => {
registerProjectTile()
}

View file

@ -0,0 +1,9 @@
import { defineCustomElement } from 'vue'
import ProjectTileSFC from 'src/views/project/project-tile.vue'
export const ProjectTile = defineCustomElement(ProjectTileSFC)
export const registerProjectTile = () => {
customElements.define('project-tile', ProjectTile)
}

View file

@ -9,6 +9,7 @@ import './main.sass'
import { createRoutes, initializeRouteStore } from './routes' import { createRoutes, initializeRouteStore } from './routes'
import { headingSectionsExtension } from './utilities/marked' import { headingSectionsExtension } from './utilities/marked'
import { register } from './components/web-components'
marked marked
.use(headingSectionsExtension() as any) .use(headingSectionsExtension() as any)
@ -27,6 +28,7 @@ export const createApp = ViteSSG(
{ routes: createRoutes() }, { routes: createRoutes() },
// function to have custom setups // function to have custom setups
({ app, router, routes, isClient, initialState }) => { ({ app, router, routes, isClient, initialState }) => {
register()
app.use(createPinia()) app.use(createPinia())
initializeRouteStore(routes) initializeRouteStore(routes)
}, },

View file

@ -19,6 +19,15 @@ const domPurifyConfig = {
'src', 'src',
'style', 'style',
'title', 'title',
// project-tile
'info',
'view-path',
'thumbnail-background',
'thumbnail-position',
'caption',
'subtitle',
'summary',
], ],
ALLOWED_TAGS: [ ALLOWED_TAGS: [
'a', 'a',
@ -70,6 +79,8 @@ const domPurifyConfig = {
'dd', 'dd',
'dl', 'dl',
'dt', 'dt',
'project-tile',
], ],
} }

View file

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import type { import type {
ProjectList, ProjectList,
ProjectListingInfo, ProjectListingInfo,
@ -31,6 +31,7 @@ const currentRoute = getCurrentRoute()
const routeStore = useRouteStore() const routeStore = useRouteStore()
const routeConfig = routeStore._routes[currentRoute.path] as ProjectListDefinition const routeConfig = routeStore._routes[currentRoute.path] as ProjectListDefinition
const config = ref(null as ProjectList | null) const config = ref(null as ProjectList | null)
const projectViewPath = computed(() => `${currentRoute.path}/view`)
/** /**
* Handler for a tag being selected; * Handler for a tag being selected;
@ -71,9 +72,11 @@ onMounted(async () => {
) )
ProjectTile( ProjectTile(
v-if='!projects[id].hidden || !config.removeFromView' v-if='!projects[id].hidden || !config.removeFromView'
v-bind='projects[id]'
:class='{ hidden: projects[id].hidden && !config.removeFromView }' :class='{ hidden: projects[id].hidden && !config.removeFromView }'
:id='id' :id='id'
:info='projects[id]' :viewPath='projectViewPath'
:isInternal='true'
) )
FilterPanel( FilterPanel(
v-if='ready && !!config.tags' v-if='ready && !!config.tags'

View file

@ -5,28 +5,22 @@ import type {
ProjectListingInfo, ProjectListingInfo,
} from '@goldenwere/static-web-templates-types' } from '@goldenwere/static-web-templates-types'
import { getCurrentRoute } from 'src/utilities/vuetils'
const props = defineProps<{ const props = defineProps<{
id: string id: string,
info: ProjectListingInfo viewPath: string,
}>() isInternal: boolean,
} & ProjectListingInfo>()
const currentRoute = getCurrentRoute() const { thumbnailBackground, thumbnailBackgroundSize } = props
const caption = computed(() => marked.parse(props.caption || ''))
const { thumbnailBackground, thumbnailBackgroundSize } = props.info const summary = computed(() => marked.parse(props.summary || ''))
const caption = computed(() => marked.parse(props.info.caption || '')) const title = computed(() => marked.parse(props.title || ''))
const summary = computed(() => marked.parse(props.info.summary || '')) const subtitle = computed(() => marked.parse(props.subtitle || ''))
const title = computed(() => marked.parse(props.info.title || '')) const href = computed(() => `${props.viewPath}?id=${props.id}`)
const subtitle = computed(() => marked.parse(props.info.subtitle || ''))
</script> </script>
<template lang="pug"> <template lang="pug">
.project-embed mixin embedText
router-link.link(
:to='{ name: `${currentRoute.name}: View Project`, query: { id: id } }'
:style='{ background: thumbnailBackground, backgroundSize: thumbnailBackgroundSize }'
)
.text .text
.title( .title(
v-html='title' v-html='title'
@ -35,6 +29,19 @@ const subtitle = computed(() => marked.parse(props.info.subtitle || ''))
v-if='subtitle' v-if='subtitle'
v-html='subtitle' v-html='subtitle'
) )
.project-embed
router-link.router-link.link(
v-if='isInternal'
:to='{ path: viewPath, query: { id: id } }'
:style='{ background: thumbnailBackground, backgroundSize: thumbnailBackgroundSize }'
)
+embedText
a.link(
v-else
:href='href'
:style='{ background: thumbnailBackground, backgroundSize: thumbnailBackgroundSize }'
)
+embedText
.caption( .caption(
v-html='caption' v-html='caption'
) )