<section class="overlay-modal" data-step="1" data-modal="cloud-email">
    <div class="overlay-modal__overlay">
        <span class="overlay-modal__bg overlay-modal__trigger--close"></span>

        <div class="overlay-modal__inner">
            <span class="overlay-modal__close overlay-modal__trigger--close"></span>

            <div class="overlay-modal__content">
                <h3 class="heading heading--4">
                    <span data-step="1">Update your email address here.</span>
                    <span data-step="2">Your email adress is succesfully updated.</span>
                </h3>

                <div class="overlay-modal__description">
                    Lorem ipsum dolor amet.
                </div>

                <form data-step="1" class="form form--modal form--email-modal" novalidate>
                    <div class="overlay-modal__form">
                        <div class="parent-class input-field is-required">
                            <div class="input-field__inner">
                                <input type="email" name="email" id="" value="" class="test" required>
                                <span class="input-field__placeholder">Email address</span>
                            </div>
                            <div class="input-field__error">
                                <p>This field is not filled in correctly or cannot be empty.</p>
                            </div>
                        </div>

                        <div class="overlay-modal__action">

                            <button type="submit" class="action action--normal action--on-light">
                                <span class="action__label">Update email address</span>
                                <span class="action__bg"></span>
                            </button>

                        </div>
                    </div>

                    <div class="overlay-modal__note">
                        We respect your privacy and don&#x27;t share you email with anybody.
                    </div>
                </form>
            </div>
        </div>
    </div>
</section>
{{#if visible}}<div class="overlay-modal-is-visible">{{/if}}
<section class="overlay-modal" data-step="1"{{#if modal}} data-modal="{{modal}}"{{/if}}>
  <div class="overlay-modal__overlay">
    <span class="overlay-modal__bg overlay-modal__trigger--close"></span>

    <div class="overlay-modal__inner">
      <span class="overlay-modal__close overlay-modal__trigger--close">{{ @icon-cross }}</span>

      <div class="overlay-modal__content">
        <h3 class="heading heading--4">
          <span data-step="1">{{ heading }}</span>
          <span data-step="2">{{ thanks }}</span>
        </h3>

        <div class="overlay-modal__description">
          {{ description }}
        </div>

        <form data-step="1" class="form form--modal{{#if formModifier }} form--{{ formModifier }}{{/if}}" novalidate>
          <div class="overlay-modal__form">
            {{render '@input-field' input merge=true }}

            <div class="overlay-modal__action">
              {{render '@action' action merge=true }}
            </div>
          </div>

          <div class="overlay-modal__note">
            {{ note }}
          </div>
        </form>
      </div>
    </div>
  </div>
</section>
{{#if visible}}</div>{{/if}}
visible: false
heading: Update your email address here.
description: Lorem ipsum dolor amet.
thanks: Your email adress is succesfully updated.
note: We respect your privacy and don't share you email with anybody.
formModifier: email-modal
input:
  placeholder: Email address
  name: email
  required: true
  type: email
action:
  label: Update email address
  buttonType: submit
modal: cloud-email
  • Content:
    const MODALFORM = ((window, undefined) => {
      const SETTINGS = {
        debug: true,
      };
      const SELECTORS = {
        form: '.form--modal',
        inputWrapper: '.input-field',
        select: 'select',
        modal: '.overlay-modal'
      };
      const CLASSES = {
        formError: 'form--error',
        error: 'has-error',
      };
    
      function resetField(element) {
        if (SETTINGS.debug) { console.log('MODALFORM reset field', element); }
    
        element.closest(SELECTORS.inputWrapper).classList.remove(CLASSES.error);
      }
    
      function isHidden(el) {
        return (!el || el.offsetParent === null);
      }
    
      function onFieldChange (e) {
        resetField(e.target);
      }
    
      function validate(form) {
        if (!form) { return; }
    
        let valid = true;
    
        if (SETTINGS.debug) { console.log('MODALFORM validate', form); }
    
        [...form.elements].forEach(element => {
          if (isHidden(element)) {
            resetField(element);
            return;
          }
    
          element.classList.remove(CLASSES.error);
    
          try {
            if (!element.checkValidity()) {
              valid = false;
    
              if (SETTINGS.debug) { console.warn('MODALFORM validate element error', element, element.checkValidity()); }
    
              element.closest(SELECTORS.inputWrapper).classList.add(CLASSES.error);
    
              element.removeEventListener('input', onFieldChange);
              element.addEventListener('input', onFieldChange);
            }
          } catch(e) {
            if (SETTINGS.debug) { console.error(e); }
          }
        });
    
        return valid;
      }
    
      function submit(e) {
        const form = e.target;
    
        form.classList.remove(CLASSES.formError);
    
        if (!validate(form)) {
          e.preventDefault();
          form.classList.add(CLASSES.formError);
          return;
        }
    
        if (SETTINGS.debug) {
          const modal = form.closest(SELECTORS.modal);
          if (!modal) { return; }
    
          if (modal.dataset.step) {
            e.preventDefault();
            modal.setAttribute('data-step', 2);
            return;
          }
        }
      }
    
      function init() {
        const forms = document.querySelectorAll(SELECTORS.form);
    
        if (!forms || forms.length <= 0) { return; }
    
        if (SETTINGS.debug) { console.log('MODALFORM init', forms); }
    
        forms.forEach(form => form.addEventListener('submit', submit));
      }
    
      document.addEventListener('DOMContentLoaded', init);
    })(window);
    
  • URL: /components/raw/overlay-modal/modal-form.js
  • Filesystem Path: ../src/04_organisms/overlay-modal/modal-form.js
  • Size: 2.3 KB
  • Content:
    const OVERLAYModal = ((w, d, undefined) => {
    
      'use strict';
    
      const selectors = {
        theWrap: '.overlay-modal',
        theTrigger: '.overlay-modal__trigger,.action[data-modal], .action--modal',
        theCloser: '.overlay-modal__trigger--close',
      };
    
      const classes = {
        isVisible: 'is-visible',
        overlayModalIsVisible: 'overlay-modal-is-visible',
      };
    
      const els = {};
    
      const init = () => {
        els.theWraps = d.querySelectorAll(selectors.theWrap);
        els.theTriggers = d.querySelectorAll(selectors.theTrigger);
        els.theClosers = d.querySelectorAll(selectors.theCloser);
    
        // [...els.theWraps].forEach((theWrap) => {
        //   const theClose = theWrap.querySelector(selectors.theClose);
    
        // });
    
        [...els.theClosers].forEach((theClose) => {
          theClose && theClose.addEventListener('click', (e) => {
            e.preventDefault();
            d.body.classList.remove(classes.overlayModalIsVisible);
            d.removeEventListener('keyup', keyTabbed);
          });
        });
    
        [...els.theTriggers].forEach((theTrigger) => {
          theTrigger && theTrigger.addEventListener('click', (e) => {
            e.preventDefault();
    
            const trigger = e.currentTarget;
    
            // if (trigger.getAttribute('href') && trigger.dataset.modal) {
            //  e.preventDefault();
            // }
    
            d.body.classList.add(classes.overlayModalIsVisible);
            d.addEventListener('keyup', keyTabbed);
    
            const modal = trigger.dataset['modal'];
    
            if (modal) {
              const wrongWrappers = document.querySelectorAll(`${selectors.theWrap}:not([data-modal="${trigger.dataset['modal']}"])`);
              [...wrongWrappers].forEach(wrapper => wrapper.classList.add('hidden'));
    
              const wrapper = document.querySelector(`${selectors.theWrap}[data-modal="${trigger.dataset['modal']}"]`);
              if (wrapper) {
                wrapper.classList.remove('hidden');
              }
            } else {
              const wrongWrappers = document.querySelectorAll(`${selectors.theWrap}[data-modal]`);
              [...wrongWrappers].forEach(wrapper => wrapper.classList.add('hidden'));
    
              const wrapper = document.querySelector(`${selectors.theWrap}:not([data-modal])`);
              if (wrapper) {
                wrapper.classList.remove('hidden');
              }
            }
    
            MAIN.resize(true);
            return false;
          });
        });
      };
    
      const keyTabbed = (event) => {
        if(!event || event.key !== 'Escape') { return; }
    
        [...els.theWraps].forEach((theWrap) => {
          theWrap.classList.contains(classes.isVisible) && theWrap.classList.remove(classes.isVisible);
          d.body.classList.contains(classes.overlayModalIsVisible) && d.body.classList.remove(classes.overlayModalIsVisible);
        });
      };
    
      d.addEventListener('DOMContentLoaded', init);
    
    })(window, window.document);
    
  • URL: /components/raw/overlay-modal/overlay-modal.js
  • Filesystem Path: ../src/04_organisms/overlay-modal/overlay-modal.js
  • Size: 2.8 KB
  • Content:
    .overlay-modal-is-visible {
      overflow: hidden;
    }
    
    .overlay-modal {
      overflow: hidden;
    
      .overlay-modal-is-visible & {
        overflow: visible;
      }
    }
    
    .overlay-modal__overlay {
      transition: opacity 500ms, left 0s 500ms;
      position: fixed;
      top: 0;
      left: 100%;
      z-index: 99999;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100vw;
      height: 100vh;
      height: calc(var(--vh, 1vh) * 100);
      padding: var(--gutter--bucket);
      opacity: 0;
      pointer-events: none;
      background-color: rgba(#161616, .4);
    
      .overlay-modal-is-visible & {
        transition: opacity 500ms;
        left: 0;
        opacity: 1;
        pointer-events: all;
      }
    }
    
    .overlay-modal .g-recaptcha {
      position: relative;
      display: block;
      width: 100%;
      height: 0;
      padding-top: (78 / 304) * 100%;
    
      & > div {
        position: absolute;
        top: 0;
        left: 0;
        display: block;
        width: 100%;
        height: 100%;
      }
    
      iframe {
        @media (max-width: 360px) {
          transform-origin: 0 0;
          transform: scale(.844);
        }
      }
    }
    
    .overlay-modal__bg {
      position: absolute;
      top: 0;
      left: 0;
      display: block;
      width: 100%;
      height: 100%;
      background-color: var(--color--neutrals-9);
      opacity: 0.4;
    }
    
    .overlay-modal__inner {
      position: relative;
      display: block;
      flex: 1 1 auto;
      max-width: var(--section--3);
      padding: var(--gap--10) var(--gap--3);
      background-color: var(--color--neutrals-0);
      max-height: 90vh;
      overflow: auto;
    
      @media (min-width: 750px) {
        padding: var(--gap--10) var(--gap--16);
      }
    }
    
    .overlay-modal__close {
      transition: transform 250ms;
      position: absolute;
      top: var(--gap--3);
      right: var(--gap--3);
      display: block;
      width: 14px;
      color: inherit;
      text-decoration: none;
      cursor: pointer;
    
      @media (min-width: 750px) {
        top: var(--gap--5);
        right: var(--gap--5);
      }
    
      &:hover,
      &:focus,
      &:active {
        transform: rotate(90deg);
        color: inherit;
        text-decoration: none;
      }
    
      &:after {
        transform: translate(-50%, -50%);
        position: absolute;
        top: 50%;
        left: 50%;
        display: block;
        width: 30px;
        height: 30px;
        border-radius: 50%;
        content: '';
      }
    }
    
    .overlay-modal__description {
      margin-top: var(--gap--2);
    }
    
    .overlay-modal__form {
      margin-top: var(--gap--4);
    }
    
    .overlay-modal__action {
      margin-top: var(--gap--4);
    }
    
    .overlay-modal__note {
      margin-top: var(--gap--4);
      font-size: var(--p--2);
    }
    
    [data-step="1"] {
      [data-step]:not([data-step="1"]) & {
        display: none;
      }
    }
    
    [data-step="2"] {
      [data-step]:not([data-step="2"]) & {
        display: none;
      }
    }
    
  • URL: /components/raw/overlay-modal/overlay-modal.scss
  • Filesystem Path: ../src/04_organisms/overlay-modal/overlay-modal.scss
  • Size: 2.6 KB

No notes defined.