Skip to content

Commit

Permalink
modal: possibility to open more modals in one component
Browse files Browse the repository at this point in the history
  • Loading branch information
zraly committed Nov 30, 2022
1 parent a241877 commit 2749fe1
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 107 deletions.
208 changes: 110 additions & 98 deletions components/modal/modal.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,111 @@
export default () => ({
open: false,
originalBodyPaddingRight: null,
originalBodyOverflow: null,
style: {
background: "fixed top-0 left-0 flex w-screen h-screen max-w-full bg-neutral-500/50 z-50 overflow-y-auto p-3",
dialog: "h-auto p-6 m-auto relative w-full max-w-md bg-white rounded-lg shadow-xl",
},
init() {
const style = this.style;
const templateContent = this.$el.querySelector("template").content;
const backgroundElement = templateContent.querySelector("[x-bind=background]");
const dialogElement = templateContent.querySelector("[x-bind=dialog]");
backgroundElement.className = style.background;
dialogElement.className = style.dialog;

this.$watch('open', value => {
if (value === true) {
this.originalBodyOverfow = window.getComputedStyle(document.body).overflow;
this.originalPaddingRight = document.body.style.paddingRight;
const originalComputedPaddingRight = window.getComputedStyle(document.body).paddingRight;
const scrollBarWidth = window.innerWidth - document.documentElement.clientWidth;
document.body.classList.add('overflow-hidden')
document.body.style.paddingRight = `${scrollBarWidth + parseFloat(originalComputedPaddingRight || 0)}px`;

} else {
setTimeout(() => {
document.body.classList.remove('overflow-hidden')
document.body.style.paddingRight = this.originalBodyPaddingRight || null;
document.body.style.overflow = this.originalBodyOverflow;
}, 300);
}
});
},
trigger: {
['@click']() {
this.open = ! this.open
},
},
background: {
['x-show']() {
return this.open
},
['x-transition:enter']() {
return 'transition duration-300';
},
['x-transition:enter-start']() {
return 'opacity-0';
},
['x-transition:enter-end']() {
return 'opacity-1';
},
['x-transition:leave']() {
return 'transition duration-300';
},
['x-transition:leave-start']() {
return 'opacity-1';
},
['x-transition:leave-end']() {
return 'opacity-0';
}
},
dialog: {
['@mistral-close-modals.window']() {
return this.open = false;
},
['x-show']() {
return this.open
},
["x-trap"]() {
return this.open;
},
['@keydown.escape.window']() {
this.open = false;
},
['@click.away']() {
this.open = false;
},
['x-transition:enter']() {
return 'transition ease-[cubic-bezier(.46,1.56,.8,1)] duration-300';
},
['x-transition:enter-start']() {
return 'opacity-0 -translate-y-12';
},
['x-transition:enter-end']() {
return 'opacity-1 translate-y-0';
},
['x-transition:leave']() {
return 'transition ease-out duration-300';
},
['x-transition:leave-start']() {
return 'opacity-1 translate-y-0';
},
['x-transition:leave-end']() {
return 'opacity-0 -translate-y-12';
}

}
})
openedModalId: null,
originalBodyPaddingRight: null,
originalBodyOverflow: null,
style: {
background:
'fixed top-0 left-0 flex w-screen h-screen max-w-full bg-neutral-500/50 z-50 overflow-y-auto p-3',
dialog:
'h-auto p-6 m-auto relative w-full max-w-md bg-white rounded-lg shadow-xl',
},
init() {
const style = this.style;
const templateContent = this.$el.querySelector('template').content;
const backgroundElement = templateContent.querySelector(
'[x-bind=background]'
);
const dialogElements = templateContent.querySelectorAll('[x-bind=dialog]');
dialogElements.forEach(dialogElement => {
backgroundElement.className = style.background;
dialogElement.className = style.dialog;
});

this.$watch('open', (value) => {
if (value !== null) {
this.originalBodyOverfow = window.getComputedStyle(
document.body
).overflow;
this.originalPaddingRight = document.body.style.paddingRight;
const originalComputedPaddingRight = window.getComputedStyle(
document.body
).paddingRight;
const scrollBarWidth =
window.innerWidth - document.documentElement.clientWidth;
document.body.classList.add('overflow-hidden');
document.body.style.paddingRight = `${
scrollBarWidth + parseFloat(originalComputedPaddingRight || 0)
}px`;
} else {
setTimeout(() => {
document.body.classList.remove('overflow-hidden');
document.body.style.paddingRight =
this.originalBodyPaddingRight || null;
document.body.style.overflow = this.originalBodyOverflow;
}, 300);
}
});
},
trigger: {
['@click']() {
this.openedModalId = this.$el.dataset.mistralModalId;
},
},
background: {
['x-show']() {
return this.openedModalId !== null;
},
['x-transition:enter']() {
return 'transition duration-300';
},
['x-transition:enter-start']() {
return 'opacity-0';
},
['x-transition:enter-end']() {
return 'opacity-1';
},
['x-transition:leave']() {
return 'transition duration-300';
},
['x-transition:leave-start']() {
return 'opacity-1';
},
['x-transition:leave-end']() {
return 'opacity-0';
},
},
dialog: {
['@mistral-close-modals.window']() {
return (this.openedModalId === null);
},
['x-show']() {
return this.openedModalId === this.$el.id;
},
['x-trap']() {
return this.openedModalId === this.$el.id;
},
['@keydown.escape.window']() {
this.openedModalId = null;
},
['@click.away']() {
this.openedModalId = null;
},
['x-transition:enter']() {
return 'transition ease-[cubic-bezier(.46,1.56,.8,1)] duration-300';
},
['x-transition:enter-start']() {
return 'opacity-0 -translate-y-12';
},
['x-transition:enter-end']() {
return 'opacity-1 translate-y-0';
},
['x-transition:leave']() {
return 'transition ease-out duration-300';
},
['x-transition:leave-start']() {
return 'opacity-1 translate-y-0';
},
['x-transition:leave-end']() {
return 'opacity-0 -translate-y-12';
},
},
});
35 changes: 31 additions & 4 deletions components/modal/variations/default/demo.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
<div x-data="modal">
<button
class="bg-blue-400 text-white px-4 py-2 rounded-lg font-semibold hover:brightness-110"
x-bind="trigger"
x-bind="trigger" data-mistral-modal-id="modal-1"
>
Show modal
Show modal 1
</button>
<button
class="bg-blue-400 text-white px-4 py-2 rounded-lg font-semibold hover:brightness-110"
x-bind="trigger" data-mistral-modal-id="modal-2"
>
Show modal 2
</button>
<template x-teleport="body">
<div x-bind="background">
<div x-bind="dialog" role="dialog" aria-hidden="true">
<h3 class="text-lg font-bold">Modal title</h3>
<div x-bind="dialog" role="dialog" aria-hidden="true" id="modal-1">
<h3 class="text-lg font-bold">Modal 1 title</h3>
<div class="mt-6 gap-3 flex flex-wrap">
<div class="flex gap-3 flex-wrap">
<div class="bg-neutral-300 rounded w-28 h-4"></div>
Expand All @@ -28,6 +34,27 @@ <h3 class="text-lg font-bold">Modal title</h3>
</button>
</div>
</div>
<div x-bind="dialog" role="dialog" aria-hidden="true" id="modal-2">
<h3 class="text-lg font-bold">Modal 2 title</h3>
<div class="mt-6 gap-3 flex flex-wrap">
<div class="flex gap-3 flex-wrap">
<div class="bg-neutral-300 rounded w-28 h-4"></div>
<div class="bg-neutral-300 rounded w-16 h-4 flex-auto"></div>
<div class="bg-neutral-300 rounded w-20 h-4"></div>
<div class="bg-neutral-300 rounded w-36 h-4 flex-auto"></div>
<div class="bg-neutral-300 rounded w-24 h-4"></div>
<div class="bg-neutral-300 rounded w-12 h-4 flex-auto"></div>
<div class="bg-neutral-300 rounded w-12 h-4"></div>
</div>

<button
class="bg-blue-400 text-white px-4 py-2 rounded-lg font-semibold hover:brightness-110 mt-6 mx-auto"
@click="$data.open = false"
>
Close
</button>
</div>
</div>
</div>
</template>
</div>
11 changes: 8 additions & 3 deletions components/modal/variations/default/html.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<div x-data="modal">
<button class="btn" x-bind="trigger">Show modal</button>
<button class="btn" x-bind="trigger" data-mistral-modal-id="modal-1">Show modal 1</button>
<button class="btn" x-bind="trigger" data-mistral-modal-id="modal-2">Show modal 2</button>
<template x-teleport="body">
<div x-bind="background">
<div x-bind="dialog" role="dialog" aria-hidden="true">
<h3 class="text-lg font-bold">Modal title</h3>
<div x-bind="dialog" role="dialog" aria-hidden="true" id="modal-1">
<h3 class="text-lg font-bold">Modal 1 title</h3>
<div class="mt-6">Content</div>
</div>
<div x-bind="dialog" role="dialog" aria-hidden="true" id="modal-2">
<h3 class="text-lg font-bold">Modal 2 title</h3>
<div class="mt-6">Content</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 2749fe1

Please sign in to comment.