<div class="modal " aria-hidden="true" id="modal-id">
<div class="modal__inner">
<div class="modal__box">
<div class="modal__header">
<button aria-controls="modal-id" aria-label="Stäng" class="modal__close-button">
<svg class="icon modal__close-button-icon" focusable="false">
<use xlink:href="#icon-close"></use>
</svg>
</button>
</div>
<div class="modal__content">
<h2>Example content</h2>
<p>EXAMPLE CONTENT: Pellentesque dapibus suscipit ligula. Donec posuere augue in quam. Etiam vel tortor
sodales tellus
ultricies commodo. Suspendisse potenti. Aenean in sem ac leo mollis blandit. Donec neque quam,
dignissim in, mollis
nec, sagittis eu, wisi. Phasellus lacus. Etiam laoreet quam sed arcu. Phasellus at dui in ligula
mollis ultricies.
Integer placerat tristique nisl. Praesent augue. Fusce commodo. Vestibulum convallis, lorem a tempus
semper, dui dui
euismod elit, vitae placerat urna tortor vitae lacus. Nullam libero mauris, consequat quis, varius
et, dictum id,
arcu. Mauris mollis tincidunt felis. Aliquam feugiat tellus ut neque. Nulla facilisis, risus a
rhoncus fermentum,
tellus tellus lacinia purus.</p>
</div>
</div>
</div>
</div>
<div class="modal {{getmodifiers modifiers "modal"}}" aria-hidden="true" id="{{ id }}">
<div class="modal__inner">
<div class="modal__box">
<div class="modal__header">
<button aria-controls="{{ id }}" aria-label="{{closeLabel}}" class="modal__close-button">
{{> @icon id="close" additionalClasses="modal__close-button-icon"}}
</button>
</div>
<div class="modal__content">
{{#>@partial-block}}
<h2>Example content</h2>
<p>EXAMPLE CONTENT: Pellentesque dapibus suscipit ligula. Donec posuere augue in quam. Etiam vel tortor
sodales tellus
ultricies commodo. Suspendisse potenti. Aenean in sem ac leo mollis blandit. Donec neque quam,
dignissim in, mollis
nec, sagittis eu, wisi. Phasellus lacus. Etiam laoreet quam sed arcu. Phasellus at dui in ligula
mollis ultricies.
Integer placerat tristique nisl. Praesent augue. Fusce commodo. Vestibulum convallis, lorem a tempus
semper, dui dui
euismod elit, vitae placerat urna tortor vitae lacus. Nullam libero mauris, consequat quis, varius
et, dictum id,
arcu. Mauris mollis tincidunt felis. Aliquam feugiat tellus ut neque. Nulla facilisis, risus a
rhoncus fermentum,
tellus tellus lacinia purus.</p>
{{/@partial-block}}
</div>
</div>
</div>
</div>
{
"modal": true,
"id": "modal-id",
"closeLabel": "Stäng"
}
import TabLoop from '../../functions/TabLoop';
class Modal {
constructor(modal) {
this.modal = modal;
this.state = 'hidden';
this.id = modal.getAttribute('id');
this.lastFocusedElement = undefined;
this.tabLoop = new TabLoop(this.modal);
this.ESCKEY = 27;
this.keyUpHandler = e => this.keyUp(e);
this.clickOutsideHandler = e => this.clickOutside(e);
this.setModalStateHandler = e => this.setModalState(e);
this.modal.modal = this;
this.publicOpen = (tabLoop) => this.open(tabLoop);
this.publicClose = () => this.close();
this.init();
}
init() {
this.attachTriggers();
}
attachTriggers() {
const triggers = document.querySelectorAll(`[aria-controls="${this.id}"]`);
for (let i = 0; i < triggers.length; i++) {
const trigger = triggers[i];
trigger.addEventListener('click', this.setModalStateHandler);
}
}
setModalState(e) {
e.preventDefault();
if (this.state === 'hidden') {
this.lastFocusedElement = e.target;
}
this.toggle();
}
addEventListeners() {
document.addEventListener('keyup', this.keyUpHandler);
document.addEventListener('click', this.clickOutsideHandler);
}
removeEventListeners() {
document.removeEventListener('keyup', this.keyUpHandler);
document.removeEventListener('click', this.clickOutsideHandler);
}
keyUp(e) {
if (e.which === this.ESCKEY) {
e.preventDefault();
this.close();
}
}
clickOutside(e) {
const target = e.target;
if (target === this.modal.children[0]) {
this.close();
}
}
open() {
this.modal.style.display = 'block';
this.modal.style.overflowX = 'hidden';
setTimeout(() => {
this.modal.setAttribute('aria-hidden', false);
this.state = 'visible';
document.body.style.overflow = 'hidden';
document.body.style.height = '100%';
this.tabLoop.start();
this.addEventListeners();
}, 30);
}
close() {
this.modal.setAttribute('aria-hidden', true);
this.state = 'hidden';
document.body.style.height = 'auto';
this.lastFocusedElement.focus();
this.tabLoop.stop();
this.removeEventListeners();
setTimeout(() => {
this.modal.style.display = 'none';
this.modal.style.overflowX = '';
document.body.style.overflow = '';
}, 250);
}
toggle() {
if (this.state === 'hidden') {
this.open();
} else {
this.close();
}
}
}
export default Modal;
import Modal from './Modal';
const els = document.querySelectorAll('.modal');
for (let el of els) {
new Modal(el);
}
.modal {
display: none;
position: fixed;
left: -9999px;
top: 0px;
width: 100%;
height: 100%;
background: rgba($color-black, 0);
overflow: scroll;
text-align: left;
-webkit-overflow-scrolling: touch;
transition-property: left, background-color;
transition-duration: 0ms, 200ms;
transition-delay: 200ms, 0ms;
z-index: $z-modal;
}
.modal__inner {
@include breakpoint($s) {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
&:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em;
}
}
}
.modal[aria-hidden='false'] {
left: 0;
transition-delay: 0ms, 0ms;
background-color: rgba($color-black, 0.5);
}
.modal__box {
position: relative;
width: 100%;
min-height: calc(100vh + size(10));
background: $color-white;
transform: translate3d(0, 400px, 0);
opacity: 0;
transition: all 200ms;
transition-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
@include breakpoint($s) {
width: percentage(10 / 12);
min-height: 0;
display: inline-block;
vertical-align: middle;
text-align: left;
}
@include breakpoint($m) {
max-width: $site-content-width;
}
@include breakpoint($l) {
max-width: $l;
}
.modal--form & {
width: auto;
margin: 40px 16px;
overflow: hidden;
@include breakpoint($s) {
width: percentage(10 / 12);
}
@include breakpoint($m) {
max-width: 764px;
margin: 40px 0;
}
h2 {
padding: 0 0 20px;
margin: 0 0 14px;
position: relative;
@include breakpoint($m) {
padding: 0 0 30px;
margin: 0 0 37px;
}
&:after {
position: absolute;
content: '';
left: -100px;
right: -100px;
top: -100px;
background: #E9F2E5;
z-index: -1;
bottom: 0;
}
}
}
}
.modal[aria-hidden='false'] .modal__box {
transform: translate3d(0, 0, 0);
opacity: 1;
}
.modal__header {
display: flex;
justify-content: center;
align-items: center;
padding: size(3) size(2);
padding-right: size(7);
color: $color-white;
position: relative;
min-height: size(8);
@include breakpoint($s) {
padding: size(2);
}
}
.modal__close-button {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: transparent;
border: none;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: size(2);
padding: 0;
color: $color-black;
@include breakpoint($s) {
right: size(3);
}
}
.modal__close-button-icon {
width: size(4);
height: size(4);
fill: currentColor;
}
.modal__content {
padding: 0 size(2) size(2);
padding-top: 0;
width: 100%;
vertical-align: top;
text-align: left;
min-height: calc(100vh - size(15));
@include breakpoint($s) {
min-height: 0;
padding: 0 size(4) size(4);
}
}
No notes defined.