<component is="modal-btn">Try Me</component>
<component is="modal">
<component class="video" v-slot="video" id="86jwyC1kFDk" is="video">
<div class="video__overlay" :class="{'video__overlay--active': video.active == true}">
<div class="video__btn">
<svg class="video__svg" viewBox="0 0 12 18">
<path d="M0 18V0l12 9.5L0 18Z" />
</svg>
</div>
<picture>
<source media="(min-width:768px)" srcset="https://via.placeholder.com/960x540">
<img class="video__image object-cover" src="https://via.placeholder.com/960x540" alt="Test alt" />
</picture>
</div>
<div class="video__iframe"></div>
</component>
</component>
<component is="modal-btn">Try Me</component>
<component
is="modal"
>
{% include '@video' with {
image: {
srcset: 'https://via.placeholder.com/960x540',
src: 'https://via.placeholder.com/960x540',
alt: 'Test alt',
},
video: {
id: '86jwyC1kFDk',
},
} %}
</component>
{
"in_component_library": true
}
<template >
<div
class="modal"
ref="modal"
>
<button
class="modal__button"
@click="closeModal()"
>
<span class="sr-only" v-text="'Close modal'" />
<svg class="icon-x" viewBox="0 0 51.9 51.1">
<path d="m2.4 1.7 48.1 48M1.4 49.4l48-48" />
</svg>
</button>
<div class="modal__main">
<slot />
</div>
</div>
</template>
<script>
// The trick with this simple modal
// is that it is completely controlled by
// the active state of it's sibling button
// IE the modal.previousSibling
export default {
methods: {
closeModal() {
const modal = this.$refs.modal;
modal.previousSibling.click();
console.log(this);
}
}
}
</script>
<template>
<button
ref="btn"
class="modal-btn"
@click="toggleActive()"
>
<slot />
</button>
</template>
<script>
export default {
data() {
return {
active: false,
}
},
methods: {
toggleActive() {
const modal = this.$refs.btn.nextSibling;
const video = modal.querySelector('.video');
this.active = !this.active;
this.active ?
modal.classList.add('modal--active') :
modal.classList.remove('modal--active');
// If theres a Video in the slot of
// this components sibling IE the modal itself
// click it. That will toggle the pause and play.
if (video) {
video.click();
}
}
}
}
</script>
.modal {
position: fixed;
z-index: 100;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
color: $black;
background-color: rgba(0, 0, 0, 0.9);
opacity: 0;
visibility: hidden;
transition: $transition-default;
&--active {
opacity: 1;
visibility: visible;
}
.media-context__image img {
object-fit: contain;
object-position: center;
}
.media-context__caption {
display: none;
}
&__button {
position: absolute;
z-index: 10;
top: 2.080vw;
right: 4.167vw;
display: flex;
justify-content: center;
align-items: center;
width: 44px;
height: 44px;
padding: 0;
background-color: transparent;
border: 0;
appearance: none;
cursor: pointer;
@include breakpoint(medium) {
width: 4.861vw;
height: 4.861vw;
}
&:hover {
background-color: $red;
svg {
stroke: $black;
}
}
.icon-x {
width: 80%;
fill: none;
stroke: $red;
stroke-width: 4;
}
}
&__main {
background-color: $white;
width: 70%;
}
}
.modal-btn {
position: relative;
font-size: 0;
padding: 0;
background: transparent;
border: 0;
appearance: none;
cursor: pointer;
}
No notes defined.