feat(frontend): add FormCheckbox primitive component
This commit is contained in:
parent
740546ee5a
commit
59e7c9bce3
|
|
@ -0,0 +1,42 @@
|
|||
import {describe, it, expect} from 'vitest'
|
||||
import {mount} from '@vue/test-utils'
|
||||
import FormCheckbox from './FormCheckbox.vue'
|
||||
|
||||
describe('FormCheckbox', () => {
|
||||
it('renders a Bulma-classed checkbox label', () => {
|
||||
const wrapper = mount(FormCheckbox, {props: {label: 'Enable thing'}})
|
||||
const label = wrapper.find('label.checkbox')
|
||||
expect(label.exists()).toBe(true)
|
||||
expect(label.text()).toContain('Enable thing')
|
||||
expect(label.find('input[type="checkbox"]').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('supports v-model (boolean)', async () => {
|
||||
const wrapper = mount(FormCheckbox, {
|
||||
props: {
|
||||
label: 'Toggle',
|
||||
modelValue: false,
|
||||
'onUpdate:modelValue': (val: boolean) => wrapper.setProps({modelValue: val}),
|
||||
},
|
||||
})
|
||||
const input = wrapper.find('input[type="checkbox"]')
|
||||
expect((input.element as HTMLInputElement).checked).toBe(false)
|
||||
|
||||
await input.setValue(true)
|
||||
expect(wrapper.props('modelValue')).toBe(true)
|
||||
})
|
||||
|
||||
it('applies disabled', () => {
|
||||
const wrapper = mount(FormCheckbox, {
|
||||
props: {label: 'X', disabled: true},
|
||||
})
|
||||
expect(wrapper.find('input').attributes('disabled')).toBe('')
|
||||
})
|
||||
|
||||
it('renders slot content instead of label prop when slot is provided', () => {
|
||||
const wrapper = mount(FormCheckbox, {
|
||||
slots: {default: '<span>Custom <b>content</b></span>'},
|
||||
})
|
||||
expect(wrapper.find('label.checkbox').html()).toContain('<b>content</b>')
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
modelValue?: boolean
|
||||
label?: string
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
}>()
|
||||
|
||||
function handleChange(event: Event) {
|
||||
emit('update:modelValue', (event.target as HTMLInputElement).checked)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<label class="checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="modelValue"
|
||||
:disabled="disabled || undefined"
|
||||
@change="handleChange"
|
||||
>
|
||||
<slot>{{ label }}</slot>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
label.checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .5rem;
|
||||
inline-size: fit-content;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-block-end: .75rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue