Skip to content

Commit

Permalink
feat: api return promise, refactor unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
hunterliu1003 committed Apr 23, 2021
1 parent 8de6d3f commit 3823be1
Show file tree
Hide file tree
Showing 16 changed files with 258 additions and 201 deletions.
2 changes: 1 addition & 1 deletion dist/VueFinalModal.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/VueFinalModal.esm.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/VueFinalModal.umd.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/VueFinalModal.umd.js.map

Large diffs are not rendered by default.

24 changes: 23 additions & 1 deletion docs/content/en/api.md
Expand Up @@ -31,13 +31,17 @@ export default {
- Arguments:
- name: `String` - Name of the modal
- params: `?: object` - Any data that you want to pass into the modal, checkout the guide [params](/guide/params).
- Returns: Promise<Object> | Promise<Array>

<show-code text="Example">

<v-api-show class="py-4"></v-api-show>

```js
this.$vfm.show('example', { userName: 'vue-final-modal' })
.then(() => {
// do something on modal opened
})
```

```html[Modal.vue]
Expand Down Expand Up @@ -67,6 +71,7 @@ this.$vfm.show('example', { userName: 'vue-final-modal' })
- Type: `Function`
- Arguments:
- names: `String` - The names to hide
- Returns: Promise<Object> | Promise<Array>

<show-code text="Example">

Expand All @@ -83,7 +88,9 @@ this.$vfm.show('example', { userName: 'vue-final-modal' })
show2: true
}),
mounted() {
this.$vfm.hide('example', 'example2')
this.$vfm.hide('example', 'example2').then(() => {
// do something on modal closed
})
}
}
</script>
Expand All @@ -93,18 +100,33 @@ this.$vfm.show('example', { userName: 'vue-final-modal' })

### `hideAll()`

- Returns: Promise<Object> | Promise<Array>

hide all modals.

```js
this.$vfm.hideAll().then(() => {
// do something on all modals closed
})
```

### `toggle(name, show, params)`

- Type: `Function`
- Arguments:
- name: [`String` | `Array`] - The names of the modal
- show: `?: Boolean` - Show modal or not
- params: `?: object` - Any data that you want to pass into the modal, checkout the guide [params](/guide/params).
- Returns: Promise<Object> | Promise<Array>

toggle modals by name.

```js
this.$vfm.toggle('myModal').then(() => {
// do something on modals opened or closed, it depends on params `show` is true or false
})
```

### `get([names])`

- Type: `Function`
Expand Down
1 change: 1 addition & 0 deletions docs/content/en/dynamic-modal.md
Expand Up @@ -42,6 +42,7 @@ To show dynamic modal you can use the API `$vfm.show` function.
- Arguments:
- dynamicModalOptions: `Object`
- params: same as [API $vfm.show](/api#showname-params)
- Returns: Promise<Object> | Promise<Array>

```ts
type dynamicModalOptions = {
Expand Down
24 changes: 23 additions & 1 deletion docs/content/zh-Hant/api.md
Expand Up @@ -31,13 +31,17 @@ export default {
- 參數:
- name: `String` - 指定 modal 的名字。
- params: `?: object` - Any data that you want to pass into the modal, checkout the guide [params](/zh-Hant/guide/params).
- 回傳: Promise<Object> | Promise<Array>

<show-code text="Example">

<v-api-show class="py-4"></v-api-show>

```js
this.$vfm.show('example', { userName: 'vue-final-modal' })
.then(() => {
// 當 modal 開啟後,做一些事
})
```

```html[Modal.vue]
Expand Down Expand Up @@ -67,6 +71,7 @@ this.$vfm.show('example', { userName: 'vue-final-modal' })
- 型別: `Function`
- 參數:
- names: `String` - 指定要隱藏 modal 名稱。
- 回傳: Promise<Object> | Promise<Array>

<show-code text="Example">

Expand All @@ -83,7 +88,9 @@ this.$vfm.show('example', { userName: 'vue-final-modal' })
show2: true
}),
mounted() {
this.$vfm.hide('example', 'example2')
this.$vfm.hide('example', 'example2').then(() => {
// 當 modal 關閉後,做一些事
})
}
}
</script>
Expand All @@ -93,18 +100,33 @@ this.$vfm.show('example', { userName: 'vue-final-modal' })

### `hideAll()`

- 回傳: Promise<Object> | Promise<Array>

關閉所有的 modal。

```js
this.$vfm.hideAll().then(() => {
// 當所有 modal 關閉後,做一些事
})
```

### `toggle(name, show, params)`

- 型別: `Function`
- 參數:
- name: [`String` | `Array`] - modal 的名稱。
- show: `?: Boolean` - 打開或隱藏這個 modal。
- params: `?: object` - 任何你想要傳入 modal 的資料,詳閱 [參數(params)](/zh-Hant/guide/params)
- 回傳: Promise<Object> | Promise<Array>

根據名字(name)切換 modals 的狀態。

```js
this.$vfm.toggle('myModal').then(() => {
// 當多個 modal 被開啟或被關閉時,做一些事,開啟或關閉取決於 show 參數給的是 true 或 false
})
```

### `get([names])`

- 型別: `Function`
Expand Down
1 change: 1 addition & 0 deletions docs/content/zh-Hant/dynamic-modal.md
Expand Up @@ -42,6 +42,7 @@ features:
- 參數:
- dynamicModalOptions: `Object`
- params: 與 [API $vfm.show](/zh-Hant/api#showname-params) 相同
- 回傳: Promise<Object> | Promise<Array>

```ts
type dynamicModalOptions = {
Expand Down
2 changes: 1 addition & 1 deletion example/src/components/basic/VDynamicModal.vue
@@ -1,6 +1,6 @@
<template>
<vue-final-modal v-bind="$attrs" classes="modal-container" content-class="modal-content">
<button class="modal__close" @click="$attrs['update:modalValue']">
<button class="modal__close" @click="$attrs['onUpdate:modelValue'](false)">
<mdi-close></mdi-close>
</button>
<span class="modal__title">Hello, vue-final-modal</span>
Expand Down
2 changes: 1 addition & 1 deletion example/src/components/hoc/VModal.vue
Expand Up @@ -25,7 +25,7 @@ export default {
emits: ['confirm', 'cancel'],
methods: {
close() {
$attrs['update:modalValue']()
this.$attrs['onUpdate:modelValue'](false)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion example/src/components/hoc/VTailwindModal.vue
Expand Up @@ -29,7 +29,7 @@ export default {
emits: ['cancel', 'confirm'],
methods: {
close() {
this.$attrs['update:modelValue']()
this.$attrs['onUpdate:modelValue'](false)
}
}
}
Expand Down
13 changes: 10 additions & 3 deletions lib/ModalsContainer.vue
Expand Up @@ -7,8 +7,9 @@
v-bind="modal.bind"
v-model="modal.value"
v-on="modal.on"
@closed="slice(index)"
@beforeOpen="e => beforeOpen(e, modal)"
@_closed="slice(index)"
@_beforeOpen="e => beforeOpen(e, modal)"
@_opened="modal.opened"
>
<template v-for="(slot, key) in modal.slots" #[key] :key="key">
<!-- eslint-disable vue/no-v-html -->
Expand All @@ -31,8 +32,14 @@ export default {
slice(index) {
this.api.dynamicModals.splice(index, 1)
},
beforeOpen(e, modal) {
async beforeOpen(e, modal, index) {
e.ref.params.value = modal.params
await this.$nextTick()
await this.$nextTick()
if (!modal.value) {
this.slice(index)
modal.reject('show')
}
},
isString(val) {
return typeof val === 'string'
Expand Down
45 changes: 24 additions & 21 deletions lib/PluginCore.js
Expand Up @@ -18,35 +18,38 @@ function createVfm(options) {
show(modal, ...args) {
switch (typeof modal) {
case 'string':
this.toggle(modal, true, ...args)
break
case 'object':
{
const defaultModal = {
value: true,
id: Symbol('dynamicModal'),
component: options.componentName,
bind: {},
slots: {},
on: {},
params: args[0]
}
this.dynamicModals.push(shallowReactive(Object.assign(defaultModal, modal)))
}
break
return this.toggle(modal, true, ...args)
case 'object': {
return Promise.allSettled([
new Promise((resolve, reject) => {
const defaultModal = {
value: true,
id: Symbol('dynamicModal'),
component: options.componentName,
bind: {},
slots: {},
on: {},
params: args[0],
reject,
opened() {
resolve('show')
}
}
this.dynamicModals.push(shallowReactive(Object.assign(defaultModal, modal)))
})
])
}
}
},
hide(...names) {
this.toggle(names, false)
return this.toggle(names, false)
},
hideAll() {
for (let i = this.openedModals.length - 1; i >= 0; i--) {
this.openedModals[i].emit('update:modelValue', false)
}
return this.hide(...this.openedModals.map(modal => modal.props.name))
},
toggle(name, ...args) {
const modals = Array.isArray(name) ? this.get(...name) : this.get(name)
modals.forEach(modal => modal.toggle(...args))
return Promise.allSettled(modals.map(modal => modal.toggle(...args)))
},
get(...names) {
return this.modals.filter(modal => names.includes(modal.props.name))
Expand Down
43 changes: 37 additions & 6 deletions lib/VueFinalModal.vue
Expand Up @@ -54,6 +54,8 @@ import { ref, reactive, onMounted, onBeforeUnmount, computed, nextTick, watch, i
import FocusTrap from './utils/focusTrap.js'
import { disableBodyScroll, enableBodyScroll } from './utils/bodyScrollLock'
const noop = () => {}
const TransitionState = {
Enter: 'enter',
Entering: 'entering',
Expand Down Expand Up @@ -96,7 +98,17 @@ export default {
focusRetain: { type: Boolean, default: true },
focusTrap: { type: Boolean, default: false }
},
emits: ['update:modelValue', 'click-outside', 'before-open', 'opened', 'before-close', 'closed'],
emits: [
'update:modelValue',
'click-outside',
'before-open',
'opened',
'before-close',
'closed',
'_before-open',
'_opened',
'_closed'
],
setup(props, { emit }) {
const uid = Symbol('vfm')
const root = ref(null)
Expand All @@ -118,6 +130,8 @@ export default {
const modalTransitionState = ref(null)
const _stopEvent = ref(false)
const params = ref({})
let resolveToggle = noop
let rejectToggle = noop
const computedOverlayTransition = computed(() => {
if (typeof props.overlayTransition === 'string') return { name: props.overlayTransition }
Expand Down Expand Up @@ -166,6 +180,7 @@ export default {
mounted()
if (!value) {
if (emitEvent('before-close', true)) {
rejectToggle('hide')
return
}
close()
Expand Down Expand Up @@ -227,7 +242,9 @@ export default {
}
function mounted() {
if (props.modelValue) {
emit('_before-open', createModalEvent({ type: '_before-open' }))
if (emitEvent('before-open', false)) {
rejectToggle('show')
return
}
Expand Down Expand Up @@ -345,7 +362,9 @@ export default {
if (props.focusTrap) {
$focusTrap.enable(vfmContainer.value)
}
emit('_opened')
emit('opened', createModalEvent({ type: 'opened' }))
resolveToggle('show')
}
function beforeModalLeave() {
modalTransitionState.value = TransitionState.Leaving
Expand All @@ -366,7 +385,9 @@ export default {
stopEvent = true
}
})
emit('_closed')
emit('closed', event)
resolveToggle('hide')
if (stopEvent) return
params.value = {}
}
Expand Down Expand Up @@ -404,11 +425,21 @@ export default {
return false
}
function toggle(show, _params) {
const value = typeof show === 'boolean' ? show : !props.modelValue
if (value && arguments.length === 2) {
params.value = _params
}
emit('update:modelValue', value)
return new Promise((resolve, reject) => {
resolveToggle = res => {
resolve(res)
resolveToggle = noop
}
rejectToggle = err => {
reject(err)
rejectToggle = noop
}
const value = typeof show === 'boolean' ? show : !props.modelValue
if (value && arguments.length === 2) {
params.value = _params
}
emit('update:modelValue', value)
})
}
return {
root,
Expand Down

0 comments on commit 3823be1

Please sign in to comment.