Skip to content

Instantly share code, notes, and snippets.

@YuraKolesnikov
Created March 2, 2021 14:42
Show Gist options
  • Save YuraKolesnikov/5083c75614b2fedc0abd0fef8bdb2a66 to your computer and use it in GitHub Desktop.
Save YuraKolesnikov/5083c75614b2fedc0abd0fef8bdb2a66 to your computer and use it in GitHub Desktop.
<template>
<transition
:enter-class="$style.Modal_slide_enter"
:enter-active-class="$style.Modal_slide_active"
:leave-active-class="$style.Modal_slide_leaveActive"
:leave-to-class="$style.Modal_slide_leaveTo"
>
<div
:class="modalClassList"
v-if="isOpen"
@click.self="close"
>
<div :class="$style.Modal__main">
<VIcon
:class="$style.Modal__close"
@click.native="$emit('close')"
size="m"
name="cross.circle"
/>
<div :class="$style.Modal__content">
<slot name="content" />
</div>
</div>
</div>
</transition>
</template>
<script>
import VIcon from '../VIcon/VIcon'
export default {
components: {
VIcon
},
props: {
isOpen: {
type: Boolean,
default: false
},
fullscreen: {
type: Boolean,
default: false
}
},
computed: {
modalClassList () {
return [
this.$style.Modal,
{ [this.$style.Modal_type_fullscreen]: this.fullscreen }
]
}
},
mounted () {
document.addEventListener('keydown', this.closeOnKey)
},
beforeDestroy () {
document.removeEventListener('keydown', this.closeOnKey)
},
methods: {
close () {
this.$emit('close')
},
closeOnKey (event) {
if (event.key === 'Escape') {
this.close()
}
}
}
}
</script>
<style lang="scss" module>
@import "../../assets/scss/variables";
$local-animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
.Modal__main {
background-color: #fff;
border-radius: 12px;
padding: 40px;
position: absolute;
left: 50%;
top: 50%;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
max-width: 808px;
transform: translate(-50%, -50%);
}
.Modal__content {
max-height: 80vh;
width: 100%;
overflow-y: auto;
}
.Modal {
background-color: rgba($base-05, 0.2);
display: flex;
align-items: center;
justify-content: center;
position: fixed;
z-index: 2;
left: 0;
top: 0;
right: 0;
bottom: 0;
& > * {
box-sizing: border-box;
}
}
.Modal_type_fullscreen {
background-color: #fff;
.Modal__main {
max-width: 100%;
width: 100%;
height: 100%;
}
}
.Modal_slide_active {
transition: opacity 0.4s $local-animation-timing-function;
.Modal__main {
transition: opacity 0.4s $local-animation-timing-function, transform 0.4s $local-animation-timing-function;
}
}
.Modal_slide_leaveActive {
transition: opacity 0.2s $local-animation-timing-function;
.Modal__main {
transition: opacity 0.2s $local-animation-timing-function, transform 0.2s $local-animation-timing-function;
}
}
.Modal_slide_enter,
.Modal_slide_leaveTo {
opacity: 0;
.Modal__main {
opacity: 0;
transform: translate(-50%, 50%);
}
}
.Modal__close {
cursor: pointer;
position: absolute;
top: 12px;
right: 12px;
}
@media screen and (max-width: 992px) {
.Modal__main {
width: 80vw;
padding: 20px;
}
}
@media (max-width: 834px) and (min-width: 569px) {
.Modal {
padding: 0 40px;
}
}
@media screen and (max-width: 568px) {
.Modal__main {
position: static;
left: auto;
top: auto;
transform: translate(0, 0);
width: 100%;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
padding: 40px 16px;
max-height: 95vh;
}
.Modal {
align-items: flex-end;
}
.Modal_type_fullscreen .Modal__main {
max-height: 100vh;
}
.Modal_slide_enter,
.Modal_slide_leaveTo {
opacity: 0;
.Modal__main {
opacity: 0;
transform: translate(0, 500px);
}
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment