[#MUI-31] Création d'un composant téléphone (#45)

| Numéro du ticket | Titre du ticket |
|------------------|-----------------|
|                  |                 |

## Description de la PR

## Modification du .env

## Check list

- [ ] Pas de régression
- [ ] TU/TI/TF rédigée
- [ ] TU/TI/TF OK
- [ ] CHANGELOG modifié

Reviewed-on: #45
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #45.
This commit is contained in:
2026-05-12 06:54:35 +00:00
committed by Autin
parent 1ffe63827d
commit 9ed094ba86
22 changed files with 1201 additions and 155 deletions

View File

@@ -114,7 +114,7 @@ describe('MalioCheckbox', () => {
})
expect(wrapper.get('input').attributes('aria-invalid')).toBe('true')
expect(wrapper.get('label').classes()).toContain('text-m-error')
expect(wrapper.get('label').classes()).toContain('text-m-danger')
expect(wrapper.get('p').text()).toBe('You must accept')
})
@@ -125,7 +125,7 @@ describe('MalioCheckbox', () => {
})
expect(wrapper.get('p').text()).toBe('Invalid')
expect(wrapper.get('p').classes()).toContain('text-m-error')
expect(wrapper.get('p').classes()).toContain('text-m-danger')
})
it('shows success styles and message when there is no error', () => {
@@ -151,4 +151,14 @@ describe('MalioCheckbox', () => {
expect(wrapper.get('label').classes()).toContain('text-black')
})
it('updates label color when toggled without v-model (uncontrolled)', async () => {
const wrapper = mountCheckbox({label: 'Accept terms'})
expect(wrapper.get('label').classes()).toContain('text-m-muted')
await wrapper.get('input').setValue(true)
expect(wrapper.get('label').classes()).toContain('text-black')
})
})

View File

@@ -40,7 +40,7 @@
</template>
<script setup lang="ts">
import {computed, useAttrs, useId} from 'vue'
import {computed, ref, useAttrs, useId} from 'vue'
import {twMerge} from 'tailwind-merge'
defineOptions({name: 'MalioCheckbox', inheritAttrs: false})
@@ -80,9 +80,11 @@ const props = withDefaults(
const attrs = useAttrs()
const generatedId = useId()
const localChecked = ref(false)
const inputId = computed(() => props.id?.toString() || `malio-checkbox-${generatedId}`)
const isChecked = computed(() => !!props.modelValue)
const isControlled = computed(() => props.modelValue !== undefined)
const isChecked = computed(() => (isControlled.value ? !!props.modelValue : localChecked.value))
const hasError = computed(() => !!props.error)
const hasSuccess = computed(() => !!props.success && !hasError.value)
const disabled = computed(() => props.disabled)
@@ -111,7 +113,7 @@ const mergedLabelClass = computed(() =>
'cbx text-lg',
isChecked.value ? 'text-black' : 'text-m-muted',
disabled.value ? 'cursor-not-allowed text-black/60' : '',
hasError.value ? 'text-m-error' : '',
hasError.value ? 'text-m-danger' : '',
hasSuccess.value ? 'text-m-success' : '',
props.labelClass,
),
@@ -121,7 +123,7 @@ const mergedMessageClass = computed(() =>
twMerge(
'text-xs',
hasError.value
? 'text-m-error'
? 'text-m-danger'
: hasSuccess.value
? 'text-m-success'
: 'text-m-muted',
@@ -140,6 +142,10 @@ const onChange = (event: Event) => {
return
}
if (!isControlled.value) {
localChecked.value = target.checked
}
emit('update:modelValue', target.checked)
}
</script>
@@ -205,14 +211,14 @@ const onChange = (event: Event) => {
stroke-dashoffset: 0;
}
.inp-cbx + .cbx.text-m-error span:first-child {
border-color: rgb(var(--m-error) / 1);
.inp-cbx + .cbx.text-m-danger span:first-child {
border-color: rgb(var(--m-danger) / 1);
}
.cbx.text-m-error span:first-child svg {
stroke: rgb(var(--m-error) / 1);
.cbx.text-m-danger span:first-child svg {
stroke: rgb(var(--m-danger) / 1);
}
.inp-cbx:checked + .cbx.text-m-error span:first-child {
border-color: rgb(var(--m-error) / 1);
.inp-cbx:checked + .cbx.text-m-danger span:first-child {
border-color: rgb(var(--m-danger) / 1);
}
.inp-cbx + .cbx.text-m-success span:first-child {