From c1a2ca718c8c781fcbe17ac63ac72c06041fe84d Mon Sep 17 00:00:00 2001 From: tristan Date: Wed, 27 May 2026 10:07:31 +0200 Subject: [PATCH] feat : composant TimeWheels deux molettes HH:MM avec bande centrale (MUI-39) Co-Authored-By: Claude Sonnet 4.6 --- .../malio/time/internal/TimeWheels.test.ts | 48 +++++++++++++++++ .../malio/time/internal/TimeWheels.vue | 54 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 app/components/malio/time/internal/TimeWheels.test.ts create mode 100644 app/components/malio/time/internal/TimeWheels.vue diff --git a/app/components/malio/time/internal/TimeWheels.test.ts b/app/components/malio/time/internal/TimeWheels.test.ts new file mode 100644 index 0000000..9134def --- /dev/null +++ b/app/components/malio/time/internal/TimeWheels.test.ts @@ -0,0 +1,48 @@ +import {describe, expect, it} from 'vitest' +import {mount} from '@vue/test-utils' +import TimeWheels from './TimeWheels.vue' +import TimeWheel from './TimeWheel.vue' + +const mountWheels = (modelValue = '09:30') => + mount(TimeWheels, {props: {modelValue}, attachTo: document.body}) + +describe('MalioTimeWheels', () => { + it('rend deux molettes (heures + minutes) et un séparateur', () => { + const wrapper = mountWheels('09:30') + const wheels = wrapper.findAllComponents(TimeWheel) + expect(wheels).toHaveLength(2) + expect(wheels[0].props('ariaLabel')).toBe('Heures') + expect(wheels[1].props('ariaLabel')).toBe('Minutes') + expect(wrapper.text()).toContain(':') + }) + + it('splitte modelValue vers les bonnes molettes', () => { + const wrapper = mountWheels('09:30') + const wheels = wrapper.findAllComponents(TimeWheel) + expect(wheels[0].props('modelValue')).toBe(9) + expect(wheels[1].props('modelValue')).toBe(30) + }) + + it('recompose et émet HH:MM quand l\'heure change', async () => { + const wrapper = mountWheels('09:30') + const wheels = wrapper.findAllComponents(TimeWheel) + wheels[0].vm.$emit('update:modelValue', 14) + await wrapper.vm.$nextTick() + expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['14:30']) + }) + + it('recompose et émet HH:MM quand la minute change', async () => { + const wrapper = mountWheels('09:30') + const wheels = wrapper.findAllComponents(TimeWheel) + wheels[1].vm.$emit('update:modelValue', 5) + await wrapper.vm.$nextTick() + expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['09:05']) + }) + + it('par défaut 00:00 quand modelValue est vide', () => { + const wrapper = mountWheels('') + const wheels = wrapper.findAllComponents(TimeWheel) + expect(wheels[0].props('modelValue')).toBe(0) + expect(wheels[1].props('modelValue')).toBe(0) + }) +}) diff --git a/app/components/malio/time/internal/TimeWheels.vue b/app/components/malio/time/internal/TimeWheels.vue new file mode 100644 index 0000000..b1112ab --- /dev/null +++ b/app/components/malio/time/internal/TimeWheels.vue @@ -0,0 +1,54 @@ + + +