forked from element-plus/element-plus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
### feat: add dialog (element-plus#197)
* Add overlay component; Dialog component almost done * feat(dialog): add use-lockscreen * feat(dialog): coding completed awaiting tests * feat(dialog): finish writing test cases * fix test failures * Address PR comments * fallback some changes
- Loading branch information
Showing
31 changed files
with
1,005 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,4 @@ yarn-error.log | |
storybook-static | ||
coverage/ | ||
website-dist | ||
website/play/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
import { nextTick } from 'vue' | ||
import { mount } from '@vue/test-utils' | ||
import Dialog from '../src/index' | ||
|
||
const AXIOM = 'Rem is the best girl' | ||
|
||
const _mount = ({ | ||
slots, | ||
...rest | ||
}: Indexable<any>) => { | ||
return mount(Dialog, { | ||
slots: { | ||
default: AXIOM, | ||
...slots, | ||
}, | ||
...rest, | ||
}) | ||
} | ||
|
||
jest.useFakeTimers() | ||
|
||
describe('Dialog.vue', () => { | ||
test('render test', () => { | ||
const wrapper = _mount({ | ||
slots: { | ||
default: AXIOM, | ||
}, | ||
}) | ||
expect(wrapper.text()).toEqual(AXIOM) | ||
}) | ||
|
||
test('dialog should have a title when title has been given', () => { | ||
const HEADER = 'I am header' | ||
let wrapper = _mount({ | ||
slots: { | ||
header: HEADER, | ||
}, | ||
}) | ||
expect(wrapper.find('.el-dialog__header').text()).toBe(HEADER) | ||
|
||
wrapper = _mount({ | ||
props: { | ||
title: HEADER, | ||
}, | ||
}) | ||
|
||
expect(wrapper.find('.el-dialog__header').text()).toBe(HEADER) | ||
}) | ||
|
||
test('dialog should have a footer when footer has been given', () => { | ||
const wrapper = _mount({ | ||
slots: { | ||
footer: AXIOM, | ||
}, | ||
}) | ||
|
||
expect(wrapper.find('.el-dialog__footer').exists()).toBe(true) | ||
expect(wrapper.find('.el-dialog__footer').text()).toBe(AXIOM) | ||
}) | ||
|
||
test('should append dialog to body when appendToBody is true', () => { | ||
const wrapper = _mount({ | ||
props: { | ||
appendToBody: true, | ||
}, | ||
}) | ||
expect(document.body.firstElementChild.classList.contains('el-overlay')).toBe(true) | ||
wrapper.unmount() | ||
}) | ||
|
||
test('should center dialog', () => { | ||
const wrapper = _mount({ | ||
props: { | ||
center: true, | ||
}, | ||
}) | ||
expect(wrapper.find('.el-dialog--center').exists()).toBe(true) | ||
}) | ||
|
||
test('should show close button', () => { | ||
const wrapper = _mount({}) | ||
expect(wrapper.find('.el-dialog__close').exists()).toBe(true) | ||
}) | ||
|
||
test('should close dialog when click on close button', async () => { | ||
const wrapper = _mount({ | ||
props: { | ||
modelValue: true, | ||
}, | ||
}) | ||
|
||
await wrapper.find('.el-dialog__headerbtn').trigger('click') | ||
expect(wrapper.vm.visible).toBe(false) | ||
}) | ||
|
||
describe('mask related', () => { | ||
test('should not have overlay mask when mask is false', () => { | ||
const wrapper = _mount({ | ||
props: { | ||
mask: false, | ||
}, | ||
}) | ||
|
||
expect(wrapper.find('.el-overlay').exists()).toBe(false) | ||
}) | ||
|
||
test('should close the modal when clicking on mask when `closeOnClickModal` is true', async () => { | ||
const wrapper = _mount({}) | ||
|
||
expect(wrapper.find('.el-overlay').exists()).toBe(true) | ||
|
||
await wrapper.find('.el-overlay').trigger('click') | ||
expect(wrapper.vm.visible).toBe(false) | ||
}) | ||
}) | ||
|
||
describe('life cycles', () => { | ||
test('should call before close', async () => { | ||
const beforeClose = jest.fn() | ||
const wrapper = _mount({ | ||
props: { | ||
beforeClose, | ||
}, | ||
}) | ||
|
||
wrapper.vm.handleClose() | ||
expect(beforeClose).toHaveBeenCalled() | ||
}) | ||
|
||
test('should not close dialog when user cancelled', () => { | ||
const beforeClose = jest.fn().mockImplementation((hide: (cancel: boolean) => void) => hide(true)) | ||
|
||
const wrapper = _mount({ | ||
props: { | ||
beforeClose, | ||
modelValue: true, | ||
}, | ||
}) | ||
|
||
wrapper.vm.handleClose() | ||
expect(beforeClose).toHaveBeenCalled() | ||
expect(wrapper.vm.visible).toBe(true) | ||
}) | ||
|
||
test('should open and close with delay', async () => { | ||
const wrapper = _mount({ | ||
props: { | ||
openDelay: 200, | ||
closeDelay: 200, | ||
modelValue: false, | ||
}, | ||
}) | ||
|
||
expect(wrapper.vm.visible).toBe(false) | ||
|
||
await wrapper.setProps({ | ||
modelValue: true, | ||
}) | ||
|
||
expect(wrapper.vm.visible).toBe(false) | ||
|
||
jest.runOnlyPendingTimers() | ||
|
||
expect(wrapper.vm.visible).toBe(true) | ||
}) | ||
|
||
test('should destroy on close', async () => { | ||
const wrapper = _mount({ | ||
props: { | ||
modelValue: true, | ||
destroyOnClose: true, | ||
}, | ||
}) | ||
|
||
expect(wrapper.vm.visible).toBe(true) | ||
|
||
wrapper.vm.handleClose() | ||
await wrapper.setProps({ | ||
// manually setting this prop because that Transition is not available in testing, | ||
// updating model value event was emitted via transition hooks. | ||
modelValue: false, | ||
}) | ||
await nextTick() | ||
expect(wrapper.html()).toBe('<!---->') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default { | ||
title: 'Dialog', | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { App } from 'vue' | ||
import Dialog from './src/index.vue' | ||
export default (app: App): void => { | ||
app.component(Dialog.name, Dialog) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "@element-plus/dialog", | ||
"version": "0.0.0", | ||
"main": "dist/index.js", | ||
"license": "MIT", | ||
"peerDependencies": { | ||
"vue": "^3.0.0-rc.7" | ||
}, | ||
"devDependencies": { | ||
"@vue/test-utils": "^2.0.0-beta.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export interface UseDialogProps { | ||
beforeClose?: (close: (shouldCancel: boolean) => void) => void | ||
closeOnClickModal: boolean | ||
closeOnPressEscape: boolean | ||
closeDelay: number | ||
destroyOnClose: boolean | ||
fullscreen: boolean | ||
lockScroll: boolean | ||
modelValue: boolean | ||
openDelay: number | ||
top: string | ||
width: string | ||
zIndex?: number | ||
} |
Oops, something went wrong.