webapps/packages/layers/ux/app/components/XScaffold/HeaderHeroMainFooter.vue
Dominik Milacher 0dc24c4db7
Some checks failed
Build and deploy updated apps / Build & deploy (push) Failing after 50s
Extend ux layer and overhaul panoramablick-saalbach.at
2025-11-21 21:17:52 +01:00

116 lines
2.9 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue'
const props = defineProps<{
class?: string
ux?: any
fillHero?: boolean
overlapHero?: boolean
}>()
const classes = useStyling(
'scaffoldHeaderHeroMainFooter',
{
slots: {
base: 'grid isolate w-full',
header: 'sticky top-0 z-150 w-full min-w-0 col-start-1',
hero: 'z-100 w-full min-w-0 col-start-1',
heroBackground: 'z-50 w-full min-w-0 col-start-1',
main: 'w-full min-w-0 col-start-1',
footer: 'w-full min-w-0 col-start-1',
},
},
props
)
const route = useRoute()
const slots = useSlots()
const config = computed(() => {
const meta = (route.meta.scaffoldHeaderHeroMainFooter as Record<string, any>) ?? {}
const enabled = (n: string) => slots[n] && (meta[n] ?? true)
const result: Record<string, any> = {}
let row = 1
for (const name of ['header', 'hero', 'main', 'footer']) {
if (enabled(name)) {
result[name] = { from: row, to: row + 1 }
row += 1
}
}
if (result.hero) {
result.hero.fill = meta.fillHero ?? props.fillHero
result.hero.overlap = meta.overlapHero ?? props.overlapHero
if (enabled('hero-background')) {
const offset = result.header && result.hero.overlap ? 1 : 0
result['hero-background'] = {
from: result.hero.from - offset,
to: result.hero.to,
}
}
}
result.spacer = {
from: 1,
to: result.hero?.fill ? result.hero.to : -1,
}
for (const item of Object.values(result)) {
item.style = { 'grid-row': `${item.from} / ${item.to}` }
}
const spacing: Record<string, string> = {
header: 'min-content',
hero: result.hero?.fill ? '1fr' : 'auto',
main: result.hero?.fill ? 'auto' : '1fr',
footer: 'auto',
}
const spacings = Object.keys(result)
.filter((n) => n in spacing)
.map((n) => spacing[n])
result.base = { style: { gridTemplateRows: `${spacings.join(' ')}` } }
return result
})
</script>
<template>
<div :class="classes.base" :style="config.base.style">
<div class="h-[100vh] col-span-full" :style="config.spacer.style" />
<div :class="classes.header" :style="config.header.style" v-if="config.header">
<slot name="header" />
</div>
<div :class="classes.hero" :style="config.hero.style" v-if="config.hero">
<slot name="hero" />
</div>
<div
:class="classes.heroBackground"
:style="config['hero-background'].style"
v-if="config['hero-background']"
>
<div class="relative w-full h-full">
<div class="absolute inset-0 pointer-events-none">
<slot name="hero-background" />
</div>
</div>
</div>
<div :class="classes.main" :style="config.main.style" v-if="config.main">
<slot name="main" />
</div>
<div :class="classes.footer" :style="config.footer.style" v-if="config.footer">
<slot name="footer" />
</div>
</div>
</template>