Files
Aether/frontend/src/components/ui/checkbox.vue
T

59 lines
1.3 KiB
Vue
Raw Normal View History

2025-12-10 20:52:44 +08:00
<template>
<input
ref="inputRef"
2025-12-10 20:52:44 +08:00
type="checkbox"
:class="checkboxClass"
v-bind="$attrs"
:checked="isChecked"
:aria-checked="indeterminate ? 'mixed' : isChecked"
2025-12-10 20:52:44 +08:00
@change="handleChange"
2025-12-12 16:15:07 +08:00
>
2025-12-10 20:52:44 +08:00
</template>
<script setup lang="ts">
import { computed, ref, watchEffect } from 'vue'
2025-12-10 20:52:44 +08:00
import { cn } from '@/lib/utils'
interface Props {
modelValue?: boolean
checked?: boolean
indeterminate?: boolean
2025-12-10 20:52:44 +08:00
class?: string
}
const props = defineProps<Props>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
'update:checked': [value: boolean]
}>()
const checkboxClass = computed(() =>
cn(
'h-4 w-4 rounded border-border/60 bg-card/80 text-primary shadow-sm focus:ring-2 focus:ring-primary/40 focus:ring-offset-1 accent-primary',
props.class
)
)
const isChecked = computed<boolean>(() => {
if (typeof props.checked === 'boolean') {
return props.checked
}
return props.modelValue ?? false
})
const inputRef = ref<HTMLInputElement | null>(null)
watchEffect(() => {
if (inputRef.value) {
inputRef.value.indeterminate = props.indeterminate ?? false
}
}, { flush: 'post' })
2025-12-10 20:52:44 +08:00
function handleChange(event: Event) {
const target = event.target as HTMLInputElement
const value = target.checked
emit('update:modelValue', value)
emit('update:checked', value)
}
</script>