I was trying to pass a custom css class to tailwindCSS through a template literal. However, being the component rendered on Storybook, this doesn't seem to work due to some conflict. Instead, I'd like to pass a computed property, but I'm not sure how to write it in the most scalable way, since maybe there will be more css properties in the future.
This doesn't work:
const textSize = computed(() => { return `text-${props.textSize}`}
This works but it's pretty ugly:
const textSize = computed(() => {
return props.textSize === "xs"
? "text-xs"
: props.textSize === "sm"
? "text-sm"
: props.textSize === "base"
? "text-base"
: props.textSize === "lg"
? "text-lg"
: props.textSize === "xl"
? "text-xl"
: props.textSize === "2xl"
? "text-2xl"
: "text-3xl"
})
The whole component:
<template>
<div :class="[`h-full w-full p-2`, !props.isDisabled || `opacity-30`]">
<div
:class="[
'flex relative items-center h-full w-full',
props.checkBoxType === 'reverse-between' ? 'justify-between' : 'justify-start',
props.direction === 'vertical' ? 'flex-col justify-start gap-2' : 'items-center',
]"
>
<input
type="checkbox"
v-model="checked"
:class="[
'absolute z-50 order-1 w-6 h-6 opacity-0',
props.checkBoxType === 'reverse-between' && ' right-0',
props.checkBoxType === 'standard' ? 'order-0' : 'order-1',
props.direction === 'vertical' && 'top-0 right-4',
]"
:disabled="props.isDisabled"
/>
<div
:class="[
'bg-white w-6 h-6 flex flex-shrink-0 justify-center items-center p-1 border-2 border-gray',
props.checkBoxType === 'standard' && props.direction === 'horizontal' && 'order-0 mr-2',
props.checkBoxType === 'reverse-between' && props.direction === 'horizontal' && 'order-1 ml-2',
props.direction === 'vertical' && 'mr-0',
inputShape === 'square' ? 'rounded' : 'rounded-full',
props.isToggleEnabled || checked ? 'border-3' : 'border-1',
]"
>
<div
:class="[
'bg-gray w-3 h-3',
props.inputShape === 'circle' ? 'rounded-full' : 'rounded-sm',
props.isToggleEnabled || checked ? 'visible' : 'hidden',
]"
></div>
</div>
<div
:class="[
'select-none font-base flex justify-center items-center',
props.checkBoxType === 'standard' ? 'order-1' : 'order-0',
props.direction === 'vertical' && 'text-center',
]"
>
<span :class="[checked || isToggleEnabled ? 'font-bold' : 'font-normal', 'text-gray', textSize]">{{
props.label
}}</span>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { defineProps, ref, computed } from "vue"
const checked = ref(false)
const textSize = computed(() => {
return props.textSize === "xs"
? "text-xs"
: props.textSize === "sm"
? "text-sm"
: props.textSize === "base"
? "text-base"
: props.textSize === "lg"
? "text-lg"
: props.textSize === "xl"
? "text-xl"
: props.textSize === "2xl"
? "text-2xl"
: "text-3xl"
})
const props = defineProps({
/**
* Sets the label for the input element
*/
label: {
type: String,
default: "example",
},
/**
* Changes the layout between text and checkbox button
*/
checkBoxType: {
default: "standard",
},
/**
* Sets the shape of the checkbox as squared or circled
*/
inputShape: {
default: "square",
},
/**
* Sets the direction of the component as horizontal or vertical
*/
direction: {
default: "horizontal",
},
/**
* Sets the text size
*/
textSize: {
// type: String as PropType<FontSize>,
type: String,
default: "base",
},
/**
* Toggles or untoggles the checkbox
*/
isToggleEnabled: {
type: Boolean,
},
/**
* If false, the whole component is greyed out
*/
isDisabled: {
type: Boolean,
default: false,
},
})
</script>