feat : réécriture du squelette MalioDrawer (slots, side, contrôlé/non-contrôlé)
This commit is contained in:
@@ -5,11 +5,18 @@ import { Icon as IconifyIcon } from '@iconify/vue'
|
||||
import Drawer from './Drawer.vue'
|
||||
|
||||
type DrawerProps = {
|
||||
modelValue?: boolean
|
||||
title?: string
|
||||
showClose?: boolean
|
||||
id?: string
|
||||
modelValue?: boolean
|
||||
side?: 'right' | 'left'
|
||||
showClose?: boolean
|
||||
dismissable?: boolean
|
||||
closeOnEscape?: boolean
|
||||
ariaLabel?: string
|
||||
drawerClass?: string
|
||||
overlayClass?: string
|
||||
headerClass?: string
|
||||
bodyClass?: string
|
||||
footerClass?: string
|
||||
}
|
||||
|
||||
const DrawerForTest = Drawer as DefineComponent<DrawerProps>
|
||||
@@ -18,11 +25,7 @@ function mountComponent(props: DrawerProps = {}, slots?: Record<string, string>)
|
||||
return mount(DrawerForTest, {
|
||||
props,
|
||||
slots,
|
||||
global: {
|
||||
stubs: {
|
||||
Teleport: true,
|
||||
},
|
||||
},
|
||||
global: { stubs: { Teleport: true } },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -32,50 +35,22 @@ describe('MalioDrawer', () => {
|
||||
expect(wrapper.find('[data-test="panel"]').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('renders when modelValue is true', () => {
|
||||
it('renders the panel when modelValue is true', () => {
|
||||
const wrapper = mountComponent({ modelValue: true })
|
||||
expect(wrapper.find('[data-test="panel"]').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('renders the title', () => {
|
||||
const wrapper = mountComponent({ modelValue: true, title: 'Mon tiroir' })
|
||||
expect(wrapper.find('h2').text()).toBe('Mon tiroir')
|
||||
})
|
||||
|
||||
it('renders slot content', () => {
|
||||
it('renders default slot in the body', () => {
|
||||
const wrapper = mountComponent(
|
||||
{ modelValue: true },
|
||||
{ default: '<p data-test="content">Contenu du drawer</p>' },
|
||||
{ default: '<p data-test="content">Contenu</p>' },
|
||||
)
|
||||
expect(wrapper.find('[data-test="content"]').text()).toBe('Contenu du drawer')
|
||||
expect(wrapper.find('[data-test="body"] [data-test="content"]').text()).toBe('Contenu')
|
||||
})
|
||||
|
||||
it('emits update:modelValue false on backdrop click', async () => {
|
||||
const wrapper = mountComponent({ modelValue: true })
|
||||
await wrapper.find('[data-test="backdrop"]').trigger('click')
|
||||
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([false])
|
||||
})
|
||||
|
||||
it('emits update:modelValue false 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])
|
||||
})
|
||||
|
||||
it('shows close button by default', () => {
|
||||
const wrapper = mountComponent({ modelValue: true })
|
||||
expect(wrapper.find('[data-test="close-button"]').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('hides close button when showClose is false', () => {
|
||||
const wrapper = mountComponent({ modelValue: true, showClose: false })
|
||||
expect(wrapper.find('[data-test="close-button"]').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('close button renders mdi:close icon', () => {
|
||||
const wrapper = mountComponent({ modelValue: true })
|
||||
const icon = wrapper.findComponent(IconifyIcon)
|
||||
expect(icon.props('icon')).toBe('mdi:close')
|
||||
it('works in uncontrolled mode (defaults closed)', () => {
|
||||
const wrapper = mountComponent()
|
||||
expect(wrapper.find('[data-test="panel"]').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('uses custom id when provided', () => {
|
||||
@@ -85,38 +60,18 @@ describe('MalioDrawer', () => {
|
||||
|
||||
it('generates an id when not provided', () => {
|
||||
const wrapper = mountComponent({ modelValue: true })
|
||||
const id = wrapper.find('.fixed').attributes('id')
|
||||
expect(id).toMatch(/^malio-drawer-/)
|
||||
expect(wrapper.find('.fixed').attributes('id')).toMatch(/^malio-drawer-/)
|
||||
})
|
||||
|
||||
it('has role="dialog" and aria-modal on panel', () => {
|
||||
it('has role="dialog" and aria-modal on the panel', () => {
|
||||
const wrapper = mountComponent({ modelValue: true })
|
||||
const panel = wrapper.find('[data-test="panel"]')
|
||||
expect(panel.attributes('role')).toBe('dialog')
|
||||
expect(panel.attributes('aria-modal')).toBe('true')
|
||||
})
|
||||
|
||||
it('aria-labelledby links to title id', () => {
|
||||
const wrapper = mountComponent({ modelValue: true, id: 'test-drawer' })
|
||||
const panel = wrapper.find('[data-test="panel"]')
|
||||
expect(panel.attributes('aria-labelledby')).toBe('test-drawer-title')
|
||||
expect(wrapper.find('h2').attributes('id')).toBe('test-drawer-title')
|
||||
})
|
||||
|
||||
it('applies drawerClass to the panel', () => {
|
||||
const wrapper = mountComponent({ modelValue: true, drawerClass: 'max-w-lg' })
|
||||
const panel = wrapper.find('[data-test="panel"]')
|
||||
expect(panel.classes()).toContain('max-w-lg')
|
||||
})
|
||||
|
||||
it('works in uncontrolled mode', () => {
|
||||
const wrapper = mountComponent()
|
||||
// Without modelValue, defaults to closed
|
||||
expect(wrapper.find('[data-test="panel"]').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('close button has aria-label "Fermer"', () => {
|
||||
const wrapper = mountComponent({ modelValue: true })
|
||||
expect(wrapper.find('[data-test="close-button"]').attributes('aria-label')).toBe('Fermer')
|
||||
const wrapper = mountComponent({ modelValue: true, drawerClass: 'max-w-2xl' })
|
||||
expect(wrapper.find('[data-test="panel"]').classes()).toContain('max-w-2xl')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user