46 lines
1.0 KiB
Vue
46 lines
1.0 KiB
Vue
<template>
|
|
<component :is="tag" :class="headingClass">
|
|
<slot />
|
|
</component>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const props = defineProps({
|
|
level: {
|
|
type: Number,
|
|
default: 1,
|
|
},
|
|
weight: {
|
|
type: String,
|
|
default: 'bold',
|
|
},
|
|
tone: {
|
|
type: String,
|
|
default: 'default', // default | inverse | muted
|
|
},
|
|
})
|
|
|
|
const tag = computed(() => {
|
|
const n = Math.min(Math.max(props.level, 1), 4)
|
|
return `h${n}`
|
|
})
|
|
|
|
const headingClass = computed(() => {
|
|
const sizeMap: Record<number, string> = {
|
|
1: 'text-3xl lg:text-4xl',
|
|
2: 'text-2xl lg:text-3xl',
|
|
3: 'text-xl lg:text-2xl',
|
|
4: 'text-lg',
|
|
}
|
|
const sizeClass = sizeMap[Math.min(Math.max(props.level, 1), 4)]
|
|
const weightClass = props.weight === 'semibold' ? 'font-semibold' : 'font-bold'
|
|
const toneMap: Record<string, string> = {
|
|
default: 'text-base-content',
|
|
inverse: 'text-primary-content',
|
|
muted: 'text-base-content/80',
|
|
}
|
|
const toneClass = toneMap[props.tone] || toneMap.default
|
|
return [sizeClass, weightClass, toneClass].join(' ')
|
|
})
|
|
</script>
|