Skip to content

Commit 86216b3

Browse files
feat: update z-index after state changes (#334)
* feat: update `z-index` after state changes * fix: only refresh zIndex if the modal is visible * fix: watch zIndexFn and index.value * fix: refreshZIndex after moveToLastOpenedModals * test: add useZIndex test cases and simplify tests * test: add test cases for focusTrap * test: add events test cases * test: add test video * fix: do not need to execute refreshZIndex in CoreModal * refactor: tests --------- Co-authored-by: Hunter <hunterliu1003@gmail.com>
1 parent 61d2604 commit 86216b3

File tree

14 files changed

+271
-64
lines changed

14 files changed

+271
-64
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script setup lang="ts">
2+
import { ModalsContainer } from '~/index'
3+
</script>
4+
5+
<template>
6+
<div>
7+
<div v-for="i in 1000" :key="i">
8+
id: {{ i }}
9+
</div>
10+
<slot />
11+
12+
<ModalsContainer />
13+
</div>
14+
</template>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script setup lang="ts">
2+
import { ref } from 'vue'
3+
4+
const emit = defineEmits<{
5+
(e: 'submit', payload: {
6+
account: string
7+
password: string
8+
}): void
9+
}>()
10+
11+
const account = ref('')
12+
const password = ref('')
13+
</script>
14+
15+
<template>
16+
<form @submit.prevent="() => emit('submit', { account, password })">
17+
<label>Account:<input v-model="account" class="form-account" type="text"></label>
18+
<label>Password:<input v-model="password" class="form-password" type="password"></label>
19+
20+
<button class="form-submit" type="submit">
21+
Submit
22+
</button>
23+
</form>
24+
</template>

packages/vue-final-modal/cypress/components/TestUseModal.spec.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

packages/vue-final-modal/cypress/components/TestUseModal.vue

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import App from './App.vue'
2+
import Form from './Form.vue'
3+
import { VueFinalModal, createVfm, useModal } from '~/index'
4+
5+
describe('Test focusTrap', () => {
6+
it('Props: focusTrap', () => {
7+
const vfm = createVfm()
8+
9+
const firstModal = useModal({
10+
context: vfm,
11+
component: VueFinalModal,
12+
attrs: { contentClass: 'first-modal-content' },
13+
slots: {
14+
default: Form,
15+
},
16+
})
17+
18+
const secondModal = useModal({
19+
context: vfm,
20+
component: VueFinalModal,
21+
attrs: { contentClass: 'second-modal-content' },
22+
slots: {
23+
default: '<p>Hello world!</p>',
24+
},
25+
})
26+
27+
cy.mount(App, {
28+
global: {
29+
plugins: [vfm],
30+
stubs: { transition: false },
31+
},
32+
})
33+
.then(async () => {
34+
await firstModal.open()
35+
cy.focused().as('firstModalFocus')
36+
cy.get('@firstModalFocus').should('have.class', 'first-modal-content')
37+
})
38+
.then(async () => {
39+
cy.get('.form-submit').focus()
40+
cy.focused().as('formSubmitFocus')
41+
cy.get('@formSubmitFocus').should('have.class', 'form-submit')
42+
})
43+
.then(async () => {
44+
await secondModal.open()
45+
cy.focused().as('secondModalFocus')
46+
cy.get('@secondModalFocus').should('have.class', 'second-modal-content')
47+
})
48+
.then(async () => {
49+
await secondModal.close()
50+
cy.focused().as('formSubmitFocus')
51+
cy.get('@formSubmitFocus').should('have.class', 'form-submit')
52+
})
53+
.then(async () => {
54+
await firstModal.close()
55+
await firstModal.open()
56+
cy.focused().as('firstModalFocus')
57+
cy.get('@firstModalFocus').should('have.class', 'first-modal-content')
58+
})
59+
})
60+
})
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import App from './App.vue'
2+
import Form from './Form.vue'
3+
import { createVfm, useModal } from '~/index'
4+
5+
describe('Test useModal()', () => {
6+
it('Should be closed by default', () => {
7+
const vfm = createVfm()
8+
const modal = useModal({
9+
context: vfm,
10+
slots: { default: 'Hello World!' },
11+
})
12+
13+
cy.mount(App, {
14+
global: {
15+
plugins: [vfm],
16+
stubs: { transition: false },
17+
},
18+
}).as('app')
19+
20+
cy.contains('Hello World!').should('not.exist')
21+
cy.get('@app').then(() => modal.open())
22+
cy.contains('Hello World!').should('exist')
23+
})
24+
25+
it('Should be opened by given defaultModelValue: true', () => {
26+
const vfm = createVfm()
27+
useModal({
28+
context: vfm,
29+
defaultModelValue: true,
30+
slots: {
31+
default: 'Hello World!',
32+
},
33+
})
34+
35+
cy.mount(App, {
36+
global: {
37+
plugins: [vfm],
38+
stubs: { transition: false },
39+
},
40+
})
41+
42+
cy.contains('Hello World!')
43+
})
44+
45+
it('Events', () => {
46+
const vfm = createVfm()
47+
48+
const onBeforeOpen = cy.spy().as('onBeforeOpen')
49+
const onOpened = cy.spy().as('onOpened')
50+
const onBeforeClose = cy.spy().as('onBeforeClose')
51+
const onClosed = cy.spy().as('onClosed')
52+
53+
const modal = useModal({
54+
context: vfm,
55+
attrs: {
56+
onBeforeOpen,
57+
onOpened,
58+
onBeforeClose,
59+
onClosed,
60+
},
61+
slots: { default: Form },
62+
})
63+
64+
cy.mount(App, {
65+
global: {
66+
plugins: [vfm],
67+
stubs: { transition: false },
68+
},
69+
}).as('app')
70+
71+
cy.get('@onBeforeOpen').should('have.callCount', 0)
72+
cy.get('@onOpened').should('have.callCount', 0)
73+
cy.get('@app').then(() => modal.open())
74+
cy.get('@onBeforeOpen').should('have.callCount', 1)
75+
cy.get('@onOpened').should('have.callCount', 1)
76+
77+
cy.get('@onBeforeClose').should('have.callCount', 0)
78+
cy.get('@onClosed').should('have.callCount', 0)
79+
cy.get('@app').then(() => modal.close())
80+
cy.get('@onBeforeClose').should('have.callCount', 1)
81+
cy.get('@onClosed').should('have.callCount', 1)
82+
})
83+
})
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import App from './App.vue'
2+
import { VueFinalModal, createVfm, useModal } from '~/index'
3+
4+
describe('Test useZIndex()', () => {
5+
it('Props: zIndexFn()', () => {
6+
const vfm = createVfm()
7+
const firstModal = useModal({
8+
context: vfm,
9+
component: VueFinalModal,
10+
attrs: { class: 'first-modal' },
11+
})
12+
13+
const secondModal = useModal({
14+
context: vfm,
15+
component: VueFinalModal,
16+
attrs: { class: 'second-modal' },
17+
})
18+
19+
const thirdModal = useModal({
20+
context: vfm,
21+
component: VueFinalModal,
22+
attrs: { class: 'third-modal' },
23+
})
24+
25+
cy.mount(App, {
26+
global: {
27+
plugins: [vfm],
28+
stubs: { transition: false },
29+
},
30+
}).as('app')
31+
cy.get('@app').then(() => {
32+
firstModal.open()
33+
})
34+
cy.get('.first-modal').should(($el) => {
35+
expect($el).to.have.css('zIndex', '1000')
36+
})
37+
cy.get('@app').then(() => {
38+
secondModal.open()
39+
})
40+
cy.get('.second-modal').should(($el) => {
41+
expect($el).to.have.css('zIndex', '1002')
42+
})
43+
cy.get('@app').then(() => {
44+
thirdModal.open()
45+
})
46+
cy.get('.third-modal').should(($el) => {
47+
expect($el).to.have.css('zIndex', '1004')
48+
})
49+
cy.get('@app').then(() => {
50+
thirdModal.patchOptions({
51+
attrs: {
52+
zIndexFn: ({ index }) => 1234 + 2 * index,
53+
},
54+
})
55+
})
56+
cy.get('.third-modal').should(($el) => {
57+
expect($el).to.have.css('zIndex', '1238')
58+
})
59+
cy.get('@app').then(() => {
60+
firstModal.close()
61+
})
62+
cy.get('.second-modal').should(($el) => {
63+
expect($el).to.have.css('zIndex', '1000')
64+
})
65+
cy.get('.third-modal').should(($el) => {
66+
expect($el).to.have.css('zIndex', '1236')
67+
})
68+
})
69+
})
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)