69 lines
1.4 KiB
Vue
69 lines
1.4 KiB
Vue
<script setup lang="ts">
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
labelFor?: string
|
|
size?: 'default' | 'narrow' | 'wide' | 'fit'
|
|
height?: 'default' | 'compact'
|
|
position?: 'default' | 'dynamic'
|
|
stacked?: boolean
|
|
isRequired?: boolean
|
|
}>(),
|
|
{
|
|
size: 'default',
|
|
height: 'default',
|
|
position: 'default',
|
|
stacked: true,
|
|
isRequired: false,
|
|
},
|
|
)
|
|
|
|
const sizeMap = {
|
|
default: 'w-28 2xl:w-36',
|
|
narrow: 'w-24 2xl:w-28',
|
|
wide: 'w-44 2xl:w-48',
|
|
fit: 'w-fit',
|
|
} as const
|
|
|
|
const heightMap = {
|
|
default: 'pt-2 2xl:pt-2.5',
|
|
compact: 'leading-[14pt]',
|
|
} as const
|
|
|
|
const positionWrapMap = {
|
|
default: 'pe-2 text-start',
|
|
dynamic: 'md:text-end',
|
|
} as const
|
|
|
|
const positionChildMap = {
|
|
default: '',
|
|
dynamic: 'block pe-2.5',
|
|
} as const
|
|
|
|
const wrapperClass = computed(() => [
|
|
'block shrink-0',
|
|
props.stacked ? 'w-full mb-1 text-start' : sizeMap[props.size],
|
|
props.stacked ? '' : heightMap[props.height],
|
|
props.stacked ? '' : positionWrapMap[props.position],
|
|
])
|
|
|
|
const labelClass = computed(() => [props.stacked ? 'block mb-1 font-normal' : positionChildMap[props.position]])
|
|
</script>
|
|
|
|
<template>
|
|
<div :class="wrapperClass">
|
|
<label
|
|
class="block"
|
|
:class="labelClass"
|
|
:for="labelFor"
|
|
>
|
|
<slot />
|
|
<span
|
|
v-if="isRequired"
|
|
class="text-red-600"
|
|
>
|
|
*
|
|
</span>
|
|
</label>
|
|
</div>
|
|
</template>
|