diff --git a/app/components/malio/drawer/Drawer.test.ts b/app/components/malio/drawer/Drawer.test.ts index 8d05cf5..5be7684 100644 --- a/app/components/malio/drawer/Drawer.test.ts +++ b/app/components/malio/drawer/Drawer.test.ts @@ -74,4 +74,75 @@ describe('MalioDrawer', () => { const wrapper = mountComponent({ modelValue: true, drawerClass: 'max-w-2xl' }) expect(wrapper.find('[data-test="panel"]').classes()).toContain('max-w-2xl') }) + + it('renders the #header slot inside the header bar', () => { + const wrapper = mountComponent( + { modelValue: true }, + { header: '

Titre

' }, + ) + expect(wrapper.find('[data-test="header"] [data-test="title"]').text()).toBe('Titre') + }) + + it('renders the header bar when showClose is true even without #header', () => { + const wrapper = mountComponent({ modelValue: true }) + expect(wrapper.find('[data-test="header"]').exists()).toBe(true) + }) + + it('does not render the header bar when no #header and showClose is false', () => { + const wrapper = mountComponent({ modelValue: true, showClose: false }) + expect(wrapper.find('[data-test="header"]').exists()).toBe(false) + }) + + it('shows the close button by default', () => { + const wrapper = mountComponent({ modelValue: true }) + expect(wrapper.find('[data-test="close-button"]').exists()).toBe(true) + }) + + it('hides the close button when showClose is false', () => { + const wrapper = mountComponent( + { modelValue: true, showClose: false }, + { header: '

Titre

' }, + ) + expect(wrapper.find('[data-test="close-button"]').exists()).toBe(false) + }) + + it('close button renders mdi:cancel-bold icon', () => { + const wrapper = mountComponent({ modelValue: true }) + const icon = wrapper.findComponent(IconifyIcon) + expect(icon.props('icon')).toBe('mdi:cancel-bold') + }) + + it('close button has aria-label "Fermer"', () => { + const wrapper = mountComponent({ modelValue: true }) + expect(wrapper.find('[data-test="close-button"]').attributes('aria-label')).toBe('Fermer') + }) + + it('emits update:modelValue false and close on close button click', async () => { + const wrapper = mountComponent({ modelValue: true }) + await wrapper.find('[data-test="close-button"]').trigger('click') + expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([false]) + expect(wrapper.emitted('close')).toHaveLength(1) + }) + + it('sets aria-labelledby to the header id when #header is provided', () => { + const wrapper = mountComponent( + { modelValue: true, id: 'test-drawer' }, + { header: '

Titre

' }, + ) + const panel = wrapper.find('[data-test="panel"]') + expect(panel.attributes('aria-labelledby')).toBe('test-drawer-header') + expect(wrapper.find('[data-test="header-content"]').attributes('id')).toBe('test-drawer-header') + }) + + it('sets aria-label from ariaLabel when no #header is provided', () => { + const wrapper = mountComponent({ modelValue: true, ariaLabel: 'Panneau latéral' }) + const panel = wrapper.find('[data-test="panel"]') + expect(panel.attributes('aria-label')).toBe('Panneau latéral') + expect(panel.attributes('aria-labelledby')).toBeUndefined() + }) + + it('applies headerClass to the header bar', () => { + const wrapper = mountComponent({ modelValue: true, headerClass: 'bg-m-primary' }) + expect(wrapper.find('[data-test="header"]').classes()).toContain('bg-m-primary') + }) }) diff --git a/app/components/malio/drawer/Drawer.vue b/app/components/malio/drawer/Drawer.vue index cc4870c..2a712af 100644 --- a/app/components/malio/drawer/Drawer.vue +++ b/app/components/malio/drawer/Drawer.vue @@ -25,9 +25,38 @@ )" role="dialog" aria-modal="true" + :aria-labelledby="hasHeader ? headerId : undefined" + :aria-label="hasHeader ? undefined : (ariaLabel || undefined)" tabindex="-1" data-test="panel" > +
+
+ +
+ +