0

I'm trying to make a custom checkbox in Vue. I stored the checked state in a variable, and with a function I'm trying to invert this status, calling it on click. But it doesn't work and I can't get why.

If I manually change checked to true, the checkbox behave correctly showing the custom div i used as a tick.

Here's the code:

<template>
    <div
        class="cursor-pointer"
        :class="[
            'flex relative items-center h-full w-full p-2',
            props.isEnabled || `opacity-30`,
            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"
            @click="toggleCheckbox"
            class="absolute order-1 w-8 h-8 opacity-0"
            :class="[
                props.checkBoxType === 'reverse-between' && ' right-0',
                props.checkBoxType === 'standard' ? 'order-0' : 'order-1',
                props.direction === 'vertical' && 'top-0 right-4',
            ]"
            :disabled="!props.isEnabled"
        />
        <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.isToggled && 'border-1',
            ]"
        >
            <div
                v-if="checked"
                :class="[
                    'bg-gray w-3 h-3',
                    props.inputShape === 'circle' ? 'rounded-full' : 'rounded-sm',
                    !props.isToggled && '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="[
                    props.textSize ? `text-${props.textSize}` : 'text-base',
                    props.isToggled ? 'font-bold' : 'font-normal',
                    'text-gray',
                ]"
                >{{ props.label }}</span
            >
        </div>
    </div>
</template>

<script lang="ts" setup>
    import { defineProps, ref } from "vue"

    const checked = ref(false)

    const toggleCheckbox = () => {
        checked.value = !checked.value
    }
1
  • 1
    Is the native input element visible and clickable? Do you click on the inputelement? I'm asking because there is a class opacity-0, and because the component as shown seems to work fine in SFC playground when clicking on input. Commented Jun 23, 2022 at 20:25

1 Answer 1

1

I think, you need to remove the click event, as v-model handles input change out of the box.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.