feat(ui) : MalioDate/DateTime exposent update:valid + saisie clavier DateTime (#MUI-43)
- MalioDate : event update:valid (malforme/hors-plage => false), emis au montage - MalioDateTime : prop editable (saisie JJ/MM/AAAA HH:MM) + meme update:valid - CalendarField : masque maska configurable via prop mask - datetimeFormat : nouveau parseur parseDisplayToIsoDateTime - fix test Date « Entree » (key 'Enter' reel vs trigger keydown.enter) - doc COMPONENTS.md + CHANGELOG.md + champ editable dans le playground Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -338,7 +338,9 @@ describe('MalioDate', () => {
|
||||
await input.trigger('focus')
|
||||
expect(wrapper.find('[data-test="popover"]').exists()).toBe(true)
|
||||
await input.setValue('19/05/2026')
|
||||
await input.trigger('keydown.enter')
|
||||
// Valeur DOM réelle de la touche Entrée ('Enter') ; `trigger('keydown.enter')`
|
||||
// produirait `key: 'enter'`, qui ne matche pas le handler manuel `e.key === 'Enter'`.
|
||||
await input.trigger('keydown', {key: 'Enter'})
|
||||
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['2026-05-19'])
|
||||
expect(wrapper.find('[data-test="popover"]').exists()).toBe(false)
|
||||
})
|
||||
@@ -351,4 +353,73 @@ describe('MalioDate', () => {
|
||||
expect(wrapper.text()).toContain('Format incorrect')
|
||||
})
|
||||
})
|
||||
|
||||
describe('état de validité (update:valid)', () => {
|
||||
it('émet valid=true au montage avec une valeur valide', () => {
|
||||
const wrapper = mountDate({modelValue: '2026-05-19'})
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([true])
|
||||
})
|
||||
|
||||
it('émet valid=true au montage quand le champ est vide', () => {
|
||||
const wrapper = mountDate()
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([true])
|
||||
})
|
||||
|
||||
it('émet valid=true sur saisie clavier valide', async () => {
|
||||
const wrapper = mountDate({editable: true})
|
||||
const input = wrapper.get('[data-test="date-input"]')
|
||||
await input.setValue('19/05/2026')
|
||||
await input.trigger('blur')
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([true])
|
||||
})
|
||||
|
||||
it('émet valid=false sur saisie malformée sans émettre modelValue', async () => {
|
||||
const wrapper = mountDate({editable: true})
|
||||
const input = wrapper.get('[data-test="date-input"]')
|
||||
await input.setValue('32/13/2026')
|
||||
await input.trigger('blur')
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([false])
|
||||
expect(wrapper.emitted('update:modelValue')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('émet valid=false sur saisie hors min/max', async () => {
|
||||
const wrapper = mountDate({editable: true, min: '2026-05-10', max: '2026-05-20'})
|
||||
const input = wrapper.get('[data-test="date-input"]')
|
||||
await input.setValue('25/12/2026')
|
||||
await input.trigger('blur')
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([false])
|
||||
})
|
||||
|
||||
it('émet valid=true sur saisie vidée même si le champ est requis', async () => {
|
||||
const wrapper = mountDate({editable: true, required: true, modelValue: '2026-05-19'})
|
||||
const input = wrapper.get('[data-test="date-input"]')
|
||||
await input.setValue('')
|
||||
await input.trigger('blur')
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([true])
|
||||
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual([null])
|
||||
})
|
||||
|
||||
it('émet valid=true sur clear', async () => {
|
||||
const wrapper = mountDate({modelValue: '2026-05-19'})
|
||||
await wrapper.get('[data-test="clear"]').trigger('click')
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([true])
|
||||
})
|
||||
|
||||
it('émet valid=true quand on sélectionne une date au calendrier', async () => {
|
||||
const wrapper = mountDate()
|
||||
await wrapper.get('[data-test="date-input"]').trigger('click')
|
||||
await wrapper.get('[data-test="day"][data-iso="2026-05-19"]').trigger('click')
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([true])
|
||||
})
|
||||
|
||||
it('repasse valid=true quand modelValue change de l\'extérieur après une saisie invalide', async () => {
|
||||
const wrapper = mountDate({editable: true})
|
||||
const input = wrapper.get('[data-test="date-input"]')
|
||||
await input.setValue('32/13/2026')
|
||||
await input.trigger('blur')
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([false])
|
||||
await wrapper.setProps({modelValue: '2026-05-19'})
|
||||
expect(wrapper.emitted('update:valid')?.at(-1)).toEqual([true])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user