Some checks failed
Build and deploy updated apps / Build & deploy (push) Failing after 50s
116 lines
2.9 KiB
Vue
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>
|