<div class="message--error " role="alert">
      <div class="message__container">
          <div class="message__icon-container">
              <span class="visually-hidden">Error message</span>
              <ul class="message__list">
                  <li class="message__list-item">E-mail <a href="#">field</a> is required.</li>
                  <li class="message__list-item">Message field is required.<br>New line</li>
              </ul>
              <span class="message__close-button" tabindex="0" role="button">
                  <span class="visually-hidden">Close</span>
              </span>
          </div>
      </div>
  </div>
{{#ifCond _self.name "===" "error"}}
  <div class="message--error {{#if isHidden}}is-hidden{{/if}}" role="alert">
    <div class="message__container">
      <div class="message__icon-container">
        <span class="visually-hidden">Error message</span>
        {{#if message}}
          {{{message}}}
        {{else}}
          <ul class="message__list">
            <li class="message__list-item">E-mail <a href="#">field</a> is required.</li>
            <li class="message__list-item">Message field is required.<br>New line</li>
          </ul>
        {{/if}}
        <span class="message__close-button" tabindex="{{#if isHidden}}-1{{else}}0{{/if}}" role="button">
          <span class="visually-hidden">Close</span>
        </span>
      </div>
    </div>
  </div>
{{/ifCond}}
{{#ifCond _self.name "===" "warning"}}
  <div class="message--warning {{#if isHidden}}is-hidden{{/if}}" role="alert">
    <div class="message__container">
      <div class="message__icon-container">
        <span class="visually-hidden">Warning message</span>
        {{#if message}}
          {{{message}}}
        {{else}}
          <p class="message__text">Please <a href="#">mind</a> the gap.<br>There might be a problem.</p>
        {{/if}}
        <span class="message__close-button" tabindex="{{#if isHidden}}-1{{else}}0{{/if}}" role="button">
          <span class="visually-hidden">Close</span>
        </span>
      </div>
    </div>
  </div>
{{/ifCond}}
{{#ifCond _self.name "===" "status"}}
  <div class="message--status {{#if isHidden}}is-hidden{{/if}}" role="alert">
    <div class="message__container">
      <div class="message__icon-container">
        <span class="visually-hidden">Status message</span>
        {{#if message}}
          {{{message}}}
        {{else}}
          <p class="message__text">Yip. That <a href="#">action</a> worked! Updated Page <em>Test Title</em> successfully</p>
        {{/if}}
        <span class="message__close-button" tabindex="{{#if isHidden}}-1{{else}}0{{/if}}" role="button">
          <span class="visually-hidden">Close</span>
        </span>
      </div>
    </div>
  </div>
{{/ifCond}}
{
  "isHidden": false,
  "message": ""
}
  • Content:
    import MoveTo from 'moveto';
    
    export class Message {
      constructor(context, options) {
        this.options = Object.assign({}, {
          focusOnStart: true,
          debug: true
        }, options);
        this.message = context;
        this.messages = [...document.querySelectorAll(selector)];
        this.closeButton = context.querySelector('.message__close-button');
        this.determineInlineMessage();
        this.initCloseButton();
        this.focusFirstMessage();
        if (this.options.debug) {
          console.debug('Message initialized');
        }
      }
    
      determineInlineMessage() {
        // check if the parent element of the message (or the parents parent in case
        // one div is wrapped our) is matching the <main> tag. Otherwise we can
        // assume it's an inline message
        const parent = this.message.parentElement;
        if (parent) {
          if (parent.nodeName !== 'MAIN' && parent.nodeName !== 'BODY') {
            const parentParent = parent.parentElement;
            if (parentParent && parentParent.nodeName !== 'MAIN') {
              if (parentParent.nodeName !== 'BODY') {
                this.message.classList.add('is-inline');
              }
            }
          }
        }
      }
    
      initCloseButton() {
        if (this.closeButton) {
          // set role button if not available already
          if (!this.closeButton.hasAttribute('role')) {
            this.closeButton.setAttribute('role', 'button');
          }
          this.closeButton.addEventListener('click', () => this.hide());
          this.closeButton.addEventListener('keydown', event => {
            if (event.keyCode === 13) {
              event.preventDefault(); // in case message is located in a <form>
              this.hide();
            }
          });
          if (this.message.classList.contains('is-hidden')) {
            this.hide(); // make sure tabindex is correctly
          }
        }
      }
    
      focusFirstMessage() {
        if (this.messages[0] === this.message && this.options.focusOnStart) {
          if (!this.message.classList.contains('is-hidden')) {
            // the browser focuses the document on init by default. Wait for it
            // with setTimeout and focus the message instead. Also, remove and add
            // the class otherwise the browser won't focus the message since it's
            // not focusable by default (has no tabindex)
            this.message.classList.add('is-hidden');
            setTimeout(() => {
              this.message.classList.remove('is-hidden');
              this.message.focus();
              new MoveTo({
                duration: 400,
                tolerance: 10
              }).move(this.message);
            }, 100);
          }
        }
      }
    
      hide() {
        this.message.classList.add('is-hidden');
        this.closeButton.setAttribute('tabindex', '-1');
        // in case it was focused and there's a custom focus library like flying
        // focus that still highlights the now hidden button
        this.closeButton.blur();
      }
    }
    
    export const selector = '[class^="message--"]';
    
  • URL: /components/raw/message-material-like/message-material-like.js
  • Filesystem Path: src/components/message/message-material-like/message-material-like.js
  • Size: 2.9 KB
  • Content:
    @import "~shared/base";
    
    $fontFamily: inherit;
    $fontSize: 1.125rem;
    $lineHeight: 1.33;
    $iconSize: 20px;
    $closeButtonIconSize: 13px;
    
    $statusBackgroundColor: #e0ede5;
    $statusColor: #257340;
    $statusLinkHoverColor: $statusColor;
    
    $warningBackgroundColor: #fffbd4;
    $warningColor: #bd8300;
    $warningLinkHoverColor: $warningColor;
    
    $errorBackgroundColor: #fdd9d9;
    $errorColor: #920005;
    $errorLinkHoverColor: $errorColor;
    
    $closeButtonIconColor: #4a4a4a;
    
    /*******************************************************************************
     * General
     ******************************************************************************/
    .message {
    
      &--error,
      &--warning,
      &--status {
        padding: 15px 0;
        font-family: $fontFamily;
        font-size: $fontSize;
        line-height: $lineHeight;
    
        // in high contrast mode, no background color is displayed, therefore
        // use border as an alternative design pattern
        @media screen and (-ms-high-contrast: white-on-black) {
          border: 1px solid $a11yNonTextColorWhiteOnBlack;
        }
        @media screen and (-ms-high-contrast: black-on-white) {
          border: 1px solid $a11yNonTextColorBlackOnWhite;
        }
    
        &.is-inline {
          margin: 10px 0;
        }
        &.is-hidden {
          display: none;
        }
    
        em {
          // em is used to indicate a title quote
          font-style: normal;
          &:before {
            content: "\00BB";
          }
          &:after {
            content: "\00AB";
          }
        }
    
        span.visually-hidden {
          @include visually-hidden;
        }
      }
    
      &--error {
        background: $errorBackgroundColor;
        color: $errorColor;
    
        a {
          @include link-underline-small($errorColor, $errorLinkHoverColor);
        }
      }
      &--warning {
        background: $warningBackgroundColor;
        color: $warningColor;
    
        a {
          @include link-underline-small($warningColor, $warningLinkHoverColor);
        }
      }
      &--status {
        background: $statusBackgroundColor;
        color: $statusColor;
    
        a {
          @include link-underline-small($statusColor, $statusLinkHoverColor);
        }
      }
    
      &__container {
        @include container;
        position: relative;
      }
    
      /*****************************************************************************
       * Icon
       ****************************************************************************/
      &__icon-container {
        position: relative;
        padding: 0 #{$closeButtonIconSize + 15} 0 #{$iconSize + 15};
    
        &:before {
          position: absolute;
          top: 3px; // optical alignment
          left: 0;
          font-size: $iconSize;
          line-height: $iconSize;
          color: inherit;
        }
      }
      &--error &__icon-container {
        @include form-components-icons-before("error");
      }
      &--warning &__icon-container {
        @include form-components-icons-before("warning");
      }
      &--status &__icon-container {
        @include form-components-icons-before("status");
      }
    
      /*****************************************************************************
       * List
       ****************************************************************************/
      &__list {
        margin: 0;
        padding: 0;
        list-style-type: none;
    
        &-item {
          position: relative;
          margin: 0;
          padding: 0 0 0 20px;
    
          &:before {
            position: absolute;
            top: 0;
            left: 0;
            content: "–";
          }
        }
      }
    
      /*****************************************************************************
       * Text
       ****************************************************************************/
      &__text {
        margin: 0;
        padding: 0;
      }
    
      /*****************************************************************************
       * Close Button
       ****************************************************************************/
      &__close-button {
        position: absolute;
        top: -4px; // optical alignment with icon on the left side
        right: 0;
        cursor: pointer;
        border: 0;
        outline: 0;
        @include form-components-icons-after("close");
    
        // hide dotted outline in Firefox
        &:-moz-focusring {
          color: transparent;
          text-shadow: 0 0 0 $closeButtonIconColor;
        }
    
        &:after {
          color: $closeButtonIconColor;
          font-size: $closeButtonIconSize;
          line-height: $closeButtonIconSize;
        }
      }
    }
    
  • URL: /components/raw/message-material-like/message-material-like.scss
  • Filesystem Path: src/components/message/message-material-like/message-material-like.scss
  • Size: 4.2 KB

No notes defined.