diff --git a/packages/components/drawer/__tests__/drawer.test.ts b/packages/components/drawer/__tests__/drawer.test.ts
deleted file mode 100644
index 6b52168fcc980..0000000000000
--- a/packages/components/drawer/__tests__/drawer.test.ts
+++ /dev/null
@@ -1,467 +0,0 @@
-// @ts-nocheck
-import { nextTick } from 'vue'
-import { mount } from '@vue/test-utils'
-import { describe, expect, test, vi } from 'vitest'
-import { rAF } from '@element-plus/test-utils/tick'
-import Drawer from '../src/drawer.vue'
-import Button from '../../button/src/button.vue'
-
-const _mount = (template: string, data, otherObj?) =>
- mount({
- components: {
- [Drawer.name]: Drawer,
- [Button.name]: Button,
- },
- template,
- data,
- ...otherObj,
- })
-const title = 'Drawer Title'
-const content = 'content'
-
-describe('Drawer', () => {
- test('create', async () => {
- const wrapper = _mount(
- `
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
- await nextTick()
- await rAF()
- await nextTick()
- const wrapperEl = wrapper.find('.el-overlay').element as HTMLDivElement
- const headerEl = wrapper.find('.el-drawer__header').element
-
- await nextTick()
- expect(wrapperEl.style.display).not.toEqual('none')
- expect(headerEl.textContent).toEqual(title)
- })
-
- test('render correct content', async () => {
- const wrapper = _mount(
- `
-
- this is a sentence
- cancel
- confirm
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
-
- await nextTick()
- await rAF()
- await nextTick()
- expect(wrapper.find('.el-drawer__body span').element.textContent).toEqual(
- 'this is a sentence'
- )
- const footerBtns = wrapper.findAll('.el-button')
- expect(footerBtns.length).toEqual(2)
- expect(footerBtns[0].find('span').element.textContent).toEqual('cancel')
- expect(footerBtns[1].find('span').element.textContent).toEqual('confirm')
- })
-
- test('should append to body, when append-to-body flag is true', async () => {
- const wrapper = _mount(
- `
-
- content
-
- `,
- () => ({
- title,
- visible: false,
- })
- )
- const vm = wrapper.vm as any
-
- vm.visible = true
- await nextTick()
- await rAF()
- await nextTick()
- expect(document.querySelector('.el-overlay')?.parentNode).toEqual(
- document.body
- )
- })
-
- test('should open and close drawer properly', async () => {
- const onClose = vi.fn()
- const onClosed = vi.fn()
- const onOpened = vi.fn()
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: false,
- }),
- {
- methods: {
- onOpened,
- onClose,
- onClosed,
- },
- }
- )
- const vm = wrapper.vm as any
- await nextTick()
- await rAF()
- await nextTick()
- expect(onOpened).not.toHaveBeenCalled()
-
- const drawerEl = wrapper.find('.el-overlay').element as HTMLDivElement
- expect(drawerEl.style.display).toEqual('none')
-
- vm.visible = true
- await nextTick()
- await rAF()
- expect(drawerEl.style.display).not.toEqual('none')
- expect(onOpened).toHaveBeenCalled()
-
- // vm.visible = false
- // await nextTick()
- // await rAF()
- // await nextTick()
- // expect(onClose).toHaveBeenCalled()
- })
-
- test('should destroy every child after drawer was closed when destroy-on-close flag is true', async () => {
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
- const vm = wrapper.vm as any
-
- await nextTick()
- await rAF()
- await nextTick()
- expect(wrapper.find('.el-drawer__body span').element.textContent).toEqual(
- content
- )
- vm.$refs.drawer.handleClose()
- await nextTick()
- await rAF()
- await nextTick()
- expect(wrapper.find('.el-drawer__body').exists()).toBe(false)
- })
-
- test('should close dialog by clicking the close button', async () => {
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
- await nextTick()
- await rAF()
- await nextTick()
- const vm = wrapper.vm as any
-
- await wrapper.find('.el-drawer__close-btn').trigger('click')
- await nextTick()
- await rAF()
- await nextTick()
- expect(vm.visible).toEqual(false)
- })
-
- test('should invoke before-close', async () => {
- const beforeClose = vi.fn()
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: true,
- beforeClose,
- })
- )
- const vm = wrapper.vm as any
- vm.$refs.drawer.handleClose()
-
- expect(beforeClose).toHaveBeenCalled()
- })
-
- test('should not show close button when show-close flag is false', async () => {
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
-
- expect(wrapper.find('.el-drawer__close-btn').exists()).toBe(false)
- })
-
- test('should have custom classes when custom classes were given', async () => {
- const classes = 'some-custom-class'
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
-
- expect(wrapper.find(`.${classes}`).exists()).toBe(true)
- })
-
- test('drawer header should have slot props', async () => {
- const wrapper = _mount(
- `
-
-
-
-
-
- `,
- () => ({
- visible: true,
- })
- )
- await nextTick()
- const drawer = wrapper.findComponent({ ref: 'drawer' })
- const headerButton = wrapper.find('button')
- expect(headerButton.attributes()['data-title-id']).toBeTruthy()
- expect(headerButton.attributes()['data-title-class']).toBe(
- 'el-drawer__title'
- )
- expect(drawer.emitted().close).toBeFalsy()
- headerButton.trigger('click')
- await nextTick()
- expect(drawer.emitted()).toHaveProperty('close')
- })
-
- test('should not render header when withHeader attribute is false', async () => {
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
-
- expect(wrapper.find('.el-drawer__header').exists()).toBe(false)
- })
-
- describe('directions', () => {
- const renderer = (direction: string) => {
- return _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
- }
- test('should render from left to right', async () => {
- expect(renderer('ltr').find('.ltr').exists()).toBe(true)
- })
-
- test('should render from right to left', async () => {
- expect(renderer('rtl').find('.rtl').exists()).toBe(true)
- })
-
- test('should render from top to bottom', async () => {
- expect(renderer('ttb').find('.ttb').exists()).toBe(true)
- })
-
- test('should render from bottom to top', async () => {
- expect(renderer('btt').find('.btt').exists()).toBe(true)
- })
- })
-
- test('events', async () => {
- const open = vi.fn()
- const opened = vi.fn()
- const close = vi.fn()
- const closed = vi.fn()
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- title,
- visible: false,
- }),
- {
- methods: {
- close,
- closed,
- open,
- opened,
- },
- }
- )
- const vm = wrapper.vm as any
- const drawer = wrapper.vm.$refs.drawer as any
-
- vm.visible = true
- await nextTick()
- await nextTick()
- expect(open).toHaveBeenCalled()
- drawer.afterEnter()
- expect(opened).toHaveBeenCalled()
- expect(close).not.toHaveBeenCalled()
- expect(closed).not.toHaveBeenCalled()
-
- vm.visible = false
- await nextTick()
- expect(close).toHaveBeenCalled()
- drawer.afterLeave()
- expect(closed).toHaveBeenCalled()
- })
-
- describe('size', () => {
- const renderer = (size: string, isVertical: boolean) =>
- _mount(
- `
-
- ${content}
-
- `,
- () => ({
- visible: true,
- title,
- })
- )
-
- test('should effect height when drawer is vertical', async () => {
- const drawerEl = renderer('50%', true).find('.el-drawer')
- .element as HTMLDivElement
- expect(drawerEl.style.width).toEqual('50%')
- })
-
- test('should effect width when drawer is horizontal', async () => {
- const drawerEl = renderer('50%', false).find('.el-drawer')
- .element as HTMLDivElement
- expect(drawerEl.style.height).toEqual('50%')
- })
- })
-
- describe('accessibility', () => {
- test('title attribute should set aria-label', async () => {
- const wrapper = _mount(
- `
-
-
- `,
- () => ({
- title,
- visible: true,
- })
- )
- await nextTick()
- const drawerDialog = wrapper.find('[role="dialog"]')
- expect(drawerDialog.attributes()['aria-label']).toBe(title)
- expect(drawerDialog.attributes()['aria-labelledby']).toBeFalsy()
- })
-
- test('missing title attribute should point to header slot content', async () => {
- const wrapper = _mount(
- `
-
-
-
-
-
- `,
- () => ({
- visible: true,
- })
- )
- await nextTick()
- const drawerDialog = wrapper.find('[role="dialog"]')
- const drawerTitle = wrapper.find('.el-drawer__title')
- expect(drawerDialog.attributes()['aria-label']).toBeFalsy()
- expect(drawerDialog.attributes()['aria-labelledby']).toBe(
- drawerTitle.attributes().id
- )
- })
-
- test('aria-describedby should point to modal body', async () => {
- const wrapper = _mount(
- `
-
- ${content}
-
- `,
- () => ({
- visible: true,
- })
- )
- await nextTick()
- const drawerDialog = wrapper.find('[role="dialog"]')
- const drawerBody = wrapper.find('.el-drawer__body')
- expect(drawerDialog.attributes()['aria-describedby']).toBe(
- drawerBody.attributes().id
- )
- })
- })
-})
diff --git a/packages/components/drawer/__tests__/drawer.test.tsx b/packages/components/drawer/__tests__/drawer.test.tsx
new file mode 100644
index 0000000000000..89c558fe7e5a3
--- /dev/null
+++ b/packages/components/drawer/__tests__/drawer.test.tsx
@@ -0,0 +1,356 @@
+// @ts-nocheck
+import { nextTick } from 'vue'
+import { mount } from '@vue/test-utils'
+import { describe, expect, test, vi } from 'vitest'
+import { rAF } from '@element-plus/test-utils/tick'
+import Drawer from '../src/drawer.vue'
+import Button from '../../button/src/button.vue'
+
+const title = 'Drawer Title'
+const content = 'content'
+
+describe('Drawer', () => {
+ test('create', async () => {
+ const wrapper = mount(() => )
+
+ await nextTick()
+ const wrapperEl = wrapper.find('.el-overlay').element as HTMLDivElement
+ const headerEl = wrapper.find('.el-drawer__header').element
+
+ expect(wrapperEl.style.display).not.toEqual('none')
+ expect(headerEl.textContent).toEqual(title)
+ })
+
+ test('render correct content', async () => {
+ const wrapper = mount(() => (
+
+ {content}
+
+
+
+ ))
+
+ await nextTick()
+ expect(wrapper.find('.el-drawer__body span').element.textContent).toEqual(
+ content
+ )
+ const footerBtns = wrapper.findAll('.el-button')
+ expect(footerBtns.length).toEqual(2)
+ expect(footerBtns[0].find('span').element.textContent).toEqual('cancel')
+ expect(footerBtns[1].find('span').element.textContent).toEqual('confirm')
+ })
+
+ test('should append to body, when append-to-body flag is true', async () => {
+ const wrapper = mount({
+ data: () => ({ visible: false }),
+ render() {
+ return (
+
+ )
+ },
+ })
+
+ const vm = wrapper.vm as any
+
+ vm.visible = true
+ await nextTick()
+ await rAF()
+ await nextTick()
+ expect(document.querySelector('.el-overlay')?.parentNode).toEqual(
+ document.body
+ )
+ })
+
+ test('should open and close drawer properly', async () => {
+ const onClose = vi.fn()
+ const onClosed = vi.fn()
+ const onOpened = vi.fn()
+
+ const wrapper = mount({
+ data: () => ({ visible: false }),
+ render() {
+ return (
+
+ )
+ },
+ })
+
+ const vm = wrapper.vm as any
+ await nextTick()
+ await rAF()
+ await nextTick()
+ expect(onOpened).not.toHaveBeenCalled()
+
+ const drawerEl = wrapper.find('.el-overlay').element as HTMLDivElement
+ expect(drawerEl.style.display).toEqual('none')
+
+ vm.visible = true
+ await nextTick()
+ await rAF()
+ expect(drawerEl.style.display).not.toEqual('none')
+ expect(onOpened).toHaveBeenCalled()
+ })
+
+ test('should destroy every child after drawer was closed when destroy-on-close flag is true', async () => {
+ const wrapper = mount(() => (
+
+ {content}
+
+ ))
+ await nextTick()
+ await rAF()
+ await nextTick()
+ expect(wrapper.find('.el-drawer__body span').element.textContent).toEqual(
+ content
+ )
+
+ await wrapper.find('.el-drawer__close-btn').trigger('click')
+ await nextTick()
+ await rAF()
+ await nextTick()
+ expect(wrapper.find('.el-drawer__body').exists()).toBe(false)
+ })
+
+ test('should close dialog by clicking the close button', async () => {
+ const wrapper = mount({
+ data: () => ({ visible: false }),
+ render() {
+ return (
+ (this.visible = val)}
+ />
+ )
+ },
+ })
+ await nextTick()
+ await rAF()
+ await nextTick()
+ const vm = wrapper.vm as any
+
+ await wrapper.find('.el-drawer__close-btn').trigger('click')
+ await nextTick()
+ await rAF()
+ await nextTick()
+ expect(vm.visible).toEqual(false)
+ })
+
+ test('should invoke before-close', async () => {
+ const beforeClose = vi.fn()
+
+ const wrapper = mount({
+ data: () => ({ visible: false }),
+ render() {
+ return (
+
+ )
+ },
+ })
+
+ await wrapper.find('.el-drawer__close-btn').trigger('click')
+ expect(beforeClose).toHaveBeenCalled()
+ })
+
+ test('should not show close button when show-close flag is false', async () => {
+ const wrapper = mount(() => (
+
+ ))
+
+ expect(wrapper.find('.el-drawer__close-btn').exists()).toBe(false)
+ })
+
+ test('should have custom classes when custom classes were given', async () => {
+ const classes = 'some-custom-class'
+ const wrapper = mount(() => (
+
+ ))
+
+ expect(wrapper.find(`.${classes}`).exists()).toBe(true)
+ })
+
+ test('drawer header should have slot props', async () => {
+ const wrapper = mount(
+ (
+
+ ),
+ }}
+ />
+ )
+
+ await nextTick()
+ const headerButton = wrapper.find('button')
+ expect(headerButton.attributes()['data-title-id']).toBeTruthy()
+ expect(headerButton.attributes()['data-title-class']).toBe(
+ 'el-drawer__title'
+ )
+ expect(wrapper.emitted().close).toBeFalsy()
+ headerButton.trigger('click')
+ await nextTick()
+ expect(wrapper.emitted()).toHaveProperty('close')
+ })
+
+ test('should not render header when withHeader attribute is false', async () => {
+ const wrapper = mount(() => (
+
+ ))
+ expect(wrapper.find('.el-drawer__header').exists()).toBe(false)
+ })
+
+ describe('directions', () => {
+ const renderer = (direction: string) => {
+ return mount(() => (
+
+ ))
+ }
+ test('should render from left to right', () => {
+ expect(renderer('ltr').find('.ltr').exists()).toBe(true)
+ })
+
+ test('should render from right to left', () => {
+ expect(renderer('rtl').find('.rtl').exists()).toBe(true)
+ })
+
+ test('should render from top to bottom', () => {
+ expect(renderer('ttb').find('.ttb').exists()).toBe(true)
+ })
+
+ test('should render from bottom to top', () => {
+ expect(renderer('btt').find('.btt').exists()).toBe(true)
+ })
+ })
+
+ test('events', async () => {
+ const onOpen = vi.fn()
+ const onOpened = vi.fn()
+ const onClose = vi.fn()
+ const onClosed = vi.fn()
+
+ const wrapper = mount({
+ data: () => ({ visible: false }),
+ render() {
+ return (
+
+ )
+ },
+ })
+
+ const vm = wrapper.vm as any
+
+ vm.visible = true
+ await nextTick()
+ await nextTick()
+ expect(onOpen).toHaveBeenCalled()
+ await nextTick()
+ await rAF()
+ await nextTick()
+ expect(onOpened).toHaveBeenCalled()
+ expect(onClose).not.toHaveBeenCalled()
+ expect(onClosed).not.toHaveBeenCalled()
+
+ vm.visible = false
+ await nextTick()
+ expect(onClose).toHaveBeenCalled()
+ await nextTick()
+ await rAF()
+ await nextTick()
+ expect(onOpened).toHaveBeenCalled()
+ })
+
+ describe('size', () => {
+ const renderer = (size: string, isVertical: boolean) =>
+ mount(() => (
+
+ ))
+
+ test('should effect height when drawer is vertical', async () => {
+ const drawerEl = renderer('50%', true).find('.el-drawer')
+ .element as HTMLDivElement
+ expect(drawerEl.style.width).toEqual('50%')
+ })
+
+ test('should effect width when drawer is horizontal', async () => {
+ const drawerEl = renderer('50%', false).find('.el-drawer')
+ .element as HTMLDivElement
+ expect(drawerEl.style.height).toEqual('50%')
+ })
+ })
+
+ describe('accessibility', () => {
+ test('title attribute should set aria-label', async () => {
+ const wrapper = mount(() => )
+
+ const drawerDialog = wrapper.find('[role="dialog"]')
+ expect(drawerDialog.attributes()['aria-label']).toBe(title)
+ expect(drawerDialog.attributes()['aria-labelledby']).toBeFalsy()
+ })
+
+ test('missing title attribute should point to header slot content', async () => {
+ const wrapper = mount(() => (
+ (
+
+ ),
+ }}
+ />
+ ))
+ const drawerDialog = wrapper.find('[role="dialog"]')
+ const drawerTitle = wrapper.find('.el-drawer__title')
+ expect(drawerDialog.attributes()['aria-label']).toBeFalsy()
+ expect(drawerDialog.attributes()['aria-labelledby']).toBe(
+ drawerTitle.attributes().id
+ )
+ })
+
+ test('aria-describedby should point to modal body', async () => {
+ const wrapper = mount(() => )
+ await nextTick()
+ const drawerDialog = wrapper.find('[role="dialog"]')
+ const drawerBody = wrapper.find('.el-drawer__body')
+ expect(drawerDialog.attributes()['aria-describedby']).toBe(
+ drawerBody.attributes().id
+ )
+ })
+ })
+})