Skip to content

Commit

Permalink
Merge pull request #122 from Jenesius/issue_121
Browse files Browse the repository at this point in the history
Issue 121
  • Loading branch information
Jenesius authored Jul 5, 2024
2 parents 3e9515d + 3159227 commit 0da09c7
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 8 deletions.
8 changes: 7 additions & 1 deletion docs/guide/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ you need to take care of the closure yourself.

- **`store`** Default value is `{}`. Used for storage
modal windows and opening them by key. You can read more in detail
on [here](./store).
on [here](./store).

- **`singleShow`** The default value is `false`. Used in case
if you need to show only the last modal window when using several
windows (via `pushModal`). In such a case, if the value is set to true,
When you open a fashion window, all voices will be closed (through the mechanism
`v-show`).
8 changes: 7 additions & 1 deletion docs/ru/guide/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,10 @@ config({

- **`store`** Значение по умолчанию `{}`. Используется для хранения
модальных окон и открытия их по ключу. Более подробно можно прочитать
на [здесь](./store).
на [здесь](./store).

- **`singleShow`** Значение по умолчанию `false`. Используется в случае,
если нужно показывать лишь последнее модальное окно при использовании нескольких
окон (через `pushModal`). В таком случае, если значение установлено как `true`,
при открытии модального окна, все предыдущие будут скрываться (через механизм
`v-show`).
1 change: 1 addition & 0 deletions examples/multi-modal/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {createApp} from "vue"
import App from "./App.vue";


createApp(App)
.mount("#app")
7 changes: 4 additions & 3 deletions src/components/WidgetModalContainer.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import WidgetContainerModalItem from "./WidgetModalContainerItem.vue";
import initialize from "../utils/initialize";
import {h, onMounted, TransitionGroup} from "vue";
import {h, onMounted, TransitionGroup, vShow} from "vue";
import {getNamespace, configuration} from "../utils/state";
export default {
Expand All @@ -17,10 +17,11 @@
const namespaceState = getNamespace(props.namespace);
return h(TransitionGroup, {name: configuration.animation, tag: "div", appear: configuration.appear}, {
default: () => namespaceState.queue.map(modalObject => {
default: () => namespaceState.queue.map((modalObject, index, arr) => {
return h(WidgetContainerModalItem, {
key: modalObject.id,
id: modalObject.id
id: modalObject.id,
show: configuration.singleShow === true ? index === arr.length - 1 : true
});
})
})
Expand Down
5 changes: 3 additions & 2 deletions src/components/WidgetModalContainerItem.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="widget__modal-container__item modal-container" @pointerdown.self.stop="handelClick" ref = "modalContainerRef">
<div class="widget__modal-container__item modal-container" @pointerdown.self.stop="handelClick" ref = "modalContainerRef" v-show = "show">
<component
:is="modal.component"
v-bind="modal.props.value"
Expand All @@ -18,7 +18,8 @@ import createDebug from "../utils/create-debug";
const debug = createDebug('modal-item')
const props = defineProps<{
id: number
id: number,
show: boolean
}>()
const modal = getModalById(props.id) as Modal;
Expand Down
6 changes: 6 additions & 0 deletions src/utils/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const modalState = (function () {
skipInitCheck: false,
draggable: false,
appear: true,
singleShow: false,
beforeEach: () => {}
}

Expand Down Expand Up @@ -89,6 +90,11 @@ export interface ConfigInterface{
* passing the value false.
*/
beforeEach: () => any,
/**
* @description If the value is set to true, then only one modal window will be shown. If several are opened
* (using pushModal), only the last one will be shown, and the rest will be hidden using `v-show`.
*/
singleShow: boolean,
store: Record<string, Component>
}

1 change: 1 addition & 0 deletions tests/IntegrationRouter/router.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe("Integration with VueRouter", () => {
await router.push("/simple-modal");
await router.isReady();

// @ts-ignore
const wrapper = await mount(App, { stubs: {
transition: false
}, global: {plugins: [router]}});
Expand Down
23 changes: 22 additions & 1 deletion tests/configuration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {mount} from "@vue/test-utils";
import {closeModal, config, container, getQueueByNamespace, openModal, popModal} from "../src/index";
import {closeModal, config, container, getQueueByNamespace, openModal, popModal, pushModal} from "../src/index";
import wait from "./wait";
import ModalTitle from "./components/modal-title.vue";
import NamespaceStore from "../src/utils/NamespaceStore";
import ModalError from "../src/utils/ModalError";
import triggerClickClose from "./assets/trigger-click-close";
import WidgetModalContainerItem from "../src/components/WidgetModalContainerItem.vue";

const modalQueue = getQueueByNamespace();
beforeEach(async () => {
Expand Down Expand Up @@ -138,5 +139,25 @@ describe("Configuration function", () => {
await expect(openModal(ModalTitle)).resolves.not.toThrow();
})

test("SingleShow in configuration", async () => {
const app = await mount(container);
config({
singleShow: true
})

await pushModal(ModalTitle)
await pushModal(ModalTitle)
await pushModal(ModalTitle)
await pushModal(ModalTitle)

expect(modalQueue.length).toBe(4);


const arrayModalContainer = app.findAllComponents(WidgetModalContainerItem);

arrayModalContainer.map(item => item.props('show'))
.forEach((value, index, arr) => expect(value).toBe(index === arr.length - 1))

})

})

0 comments on commit 0da09c7

Please sign in to comment.