add modal and clickoutside
This commit is contained in:
16019
package-lock.json
generated
16019
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"v-click-outside": "^3.2.0",
|
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-router": "^4.1.5",
|
"vue-router": "^4.1.5",
|
||||||
"vuex": "^4.0.2"
|
"vuex": "^4.0.2"
|
||||||
|
|||||||
78
src/components/base/BaseModal.vue
Normal file
78
src/components/base/BaseModal.vue
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
teleport(:to="appContainer", v-if="value")
|
||||||
|
.base-overlay(:class="{'base-overlay-bg': !hideOverlay}", :style="styleOverlay")
|
||||||
|
.base-content(v-click-outside="clickOutside")
|
||||||
|
.base-header
|
||||||
|
.header-title.text {{ title }}
|
||||||
|
.icon-cancel(@click="value = false")
|
||||||
|
slot
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "BaseModal",
|
||||||
|
props: {
|
||||||
|
hideOverlay: Boolean,
|
||||||
|
styleOverlay: Object,
|
||||||
|
title: String,
|
||||||
|
modelValue: Boolean,
|
||||||
|
},
|
||||||
|
emits: ["update:modelValue"],
|
||||||
|
methods: {
|
||||||
|
clickOutside() {
|
||||||
|
this.value = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
appContainer() {
|
||||||
|
return this.$.appContext.app._container;
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
get() {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit("update:modelValue", value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="sass">
|
||||||
|
.base-overlay
|
||||||
|
z-index: 10000
|
||||||
|
position: absolute
|
||||||
|
left: 0
|
||||||
|
top: 0
|
||||||
|
display: flex
|
||||||
|
justify-content: center
|
||||||
|
align-items: center
|
||||||
|
|
||||||
|
.base-overlay-bg
|
||||||
|
background: rgba(37, 40, 80, 0.2)
|
||||||
|
backdrop-filter: blur(4px)
|
||||||
|
width: 100vw
|
||||||
|
height: 100vh
|
||||||
|
.base-content
|
||||||
|
padding: 32px
|
||||||
|
background-color: var(--default-white)
|
||||||
|
box-shadow: 4px 4px 8px rgba(9, 10, 21, 0.1), -4px -4px 8px rgba(9, 10, 21, 0.1)
|
||||||
|
border-radius: 4px
|
||||||
|
|
||||||
|
.header-title
|
||||||
|
font-weight: 700
|
||||||
|
font-size: 20px
|
||||||
|
line-height: 23px
|
||||||
|
|
||||||
|
.base-header
|
||||||
|
display: flex
|
||||||
|
justify-content: space-between
|
||||||
|
gap: 16px
|
||||||
|
.icon-cancel
|
||||||
|
margin-top: -11px
|
||||||
|
margin-right: -11px
|
||||||
|
cursor: pointer
|
||||||
|
color: var(--font-grey-color)
|
||||||
|
</style>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
.select-form-separator.cursor-pointer.mr-4(v-if="separator")
|
.select-form-separator.cursor-pointer.mr-4(v-if="separator")
|
||||||
span.icon-down-arrow.open-icon(:class="{'open': open }")
|
span.icon-down-arrow.open-icon(:class="{'open': open }")
|
||||||
base-menu(v-if="open")
|
base-menu(v-if="open")
|
||||||
.items-container(@click="open = false", @mouseleave="leaveSelect")
|
.items-container(@click="open = false", v-click-outside="leaveSelect")
|
||||||
.item(v-for="item in items", :key="item.id" @click="clickItem(item.label)") {{ item.label }}
|
.item(v-for="item in items", :key="item.id" @click="clickItem(item.label)") {{ item.label }}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { createApp } from "vue";
|
|||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import vClickOutside from "v-click-outside";
|
|
||||||
import "./assets/sass/fonts.sass";
|
import "./assets/sass/fonts.sass";
|
||||||
import "./assets/sass/tailwind.sass";
|
import "./assets/sass/tailwind.sass";
|
||||||
import "./assets/sass/variables.sass";
|
import "./assets/sass/variables.sass";
|
||||||
import "./assets/css/iconfonts.css";
|
import "./assets/css/iconfonts.css";
|
||||||
import { clientsServer } from "../server.js";
|
import { clientsServer } from "../server.js";
|
||||||
|
import { clickOutside } from "@/shared/clickOutside";
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "development") {
|
if (process.env.NODE_ENV === "development") {
|
||||||
clientsServer({ environment: "development" });
|
clientsServer({ environment: "development" });
|
||||||
@@ -15,4 +15,7 @@ if (process.env.NODE_ENV === "development") {
|
|||||||
|
|
||||||
moment.locale("ru");
|
moment.locale("ru");
|
||||||
|
|
||||||
createApp(App).use(router, vClickOutside, moment).mount("#app");
|
createApp(App)
|
||||||
|
.directive("click-outside", clickOutside)
|
||||||
|
.use(router, moment)
|
||||||
|
.mount("#app");
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
div
|
div
|
||||||
v-select(:items="items", placeholder="Выберите значение", v-model="value" )
|
v-select(:items="items", placeholder="Выберите значение", v-model="value" )
|
||||||
|
BaseButton(@click="showModal = true") Открыть модалку
|
||||||
|
base-modal(v-model="showModal", title="Тестовый заголовок окна" )
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import VSelect from "@/components/base/BaseSelect";
|
import VSelect from "@/components/base/BaseSelect";
|
||||||
|
import BaseModal from "@/components/base/BaseModal";
|
||||||
|
import BaseButton from "@/components/base/BaseButton";
|
||||||
export default {
|
export default {
|
||||||
name: "TheSettings",
|
name: "TheSettings",
|
||||||
components: { VSelect },
|
components: { BaseButton, BaseModal, VSelect },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
items: [
|
items: [
|
||||||
@@ -25,6 +29,7 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
value: "",
|
value: "",
|
||||||
|
showModal: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
15
src/shared/clickOutside.js
Normal file
15
src/shared/clickOutside.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
export const clickOutside = {
|
||||||
|
mounted: (el, binding) => {
|
||||||
|
el.clickOutsideEvent = (event) => {
|
||||||
|
if (!(el === event.target || el.contains(event.target))) {
|
||||||
|
binding.value();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener("click", el.clickOutsideEvent, { capture: true });
|
||||||
|
},
|
||||||
|
unmounted: (el) => {
|
||||||
|
document.removeEventListener("click", el.clickOutsideEvent, {
|
||||||
|
capture: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user