<div id="dropdown-default" class="dropdown-list ">
    <ul class="dropdown-list__list">
        <li class="
                    dropdown-list__item
                ">
            <a class="dropdown-list__label " href="#">
                All

            </a>

        </li>
        <li class="
                    dropdown-list__item
                        dropdown-list__item--collapse
                ">
            <button class="dropdown-list__label " aria-expanded="false" aria-controls="dropdown-1">
                dropdown title

                <svg class="icon dropdown-list__icon" aria-hidden="true" role="img">
                    <title>Arrow down</title>
                    <use xlink:href="/images/icons-sprite.svg#angle-down"></use>
                </svg>

            </button>

            <div id="dropdown-1" class="dropdown-list__content " aria-hidden="true">
                <div class="lazyload-wrapper ">
                    <img class="image lazyload " src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw&#x3D;&#x3D;" data-src="/images/banner/banner-480_480.png" alt="image alt text">
                </div>

            </div>
        </li>
        <li class="
                    dropdown-list__item
                        dropdown-list__item--collapse
                ">
            <button class="dropdown-list__label " aria-expanded="false" aria-controls="dropdown-2">
                some longer longer and longer dropdown title

                <svg class="icon dropdown-list__icon" aria-hidden="true" role="img">
                    <title>Arrow down</title>
                    <use xlink:href="/images/icons-sprite.svg#angle-down"></use>
                </svg>

            </button>

            <div id="dropdown-2" class="dropdown-list__content " aria-hidden="true">
                <div class="paragraph">
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris

                        <a href="#">
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
                        </a>
                    </p>

                    <span>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
                    </span>

                    <pre>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</pre>

                    <blockquote>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
                    </blockquote>
                </div>

            </div>
        </li>
        <li class="
                    dropdown-list__item
                        dropdown-list__item--collapse
                ">
            <button class="dropdown-list__label " aria-expanded="false" aria-controls="dropdown-3">
                dropdown title

                <svg class="icon dropdown-list__icon" aria-hidden="true" role="img">
                    <title>Arrow down</title>
                    <use xlink:href="/images/icons-sprite.svg#angle-down"></use>
                </svg>

            </button>

            <div id="dropdown-3" class="dropdown-list__content " aria-hidden="true">
                <div class="lazyload-wrapper ">
                    <img class="image lazyload " src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw&#x3D;&#x3D;" data-src="/images/banner/banner-480_480.png" alt="image alt text">
                </div>

            </div>
        </li>
        <li class="
                    dropdown-list__item
                        dropdown-list__item--collapse
                ">
            <button class="dropdown-list__label " aria-expanded="false" aria-controls="dropdown-4">
                dropdown title

                <svg class="icon dropdown-list__icon" aria-hidden="true" role="img">
                    <title>Arrow down</title>
                    <use xlink:href="/images/icons-sprite.svg#angle-down"></use>
                </svg>

            </button>

            <div id="dropdown-4" class="dropdown-list__content " aria-hidden="true">
                <div class="paragraph">
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris

                        <a href="#">
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
                        </a>
                    </p>

                    <span>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
                    </span>

                    <pre>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris</pre>

                    <blockquote>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
                    </blockquote>
                </div>

            </div>
        </li>
    </ul>
</div>

<script type="text/javascript">
    new DropdownList(document.getElementById('dropdown-default'));
</script>
<div
    id="{{ id }}"
    class="dropdown-list {{ class }}" {{{ attributes }}}
>
    <ul class="dropdown-list__list">
        {{#each dropdowns as |dropdown|}}
            <li class="
                    dropdown-list__item
                    {{#if collapse }}
                        dropdown-list__item--collapse
                    {{/if}}
                "
            >
                <{{ itemTag }}
                   class="dropdown-list__label {{ class }}"
                   {{{ itemAttributes }}}
                    {{#if collapse }}
                        aria-controls="{{ id }}"
                    {{/if}}
                >
                    {{ title }}

                    {{#if collapse }}
                        {{ render '@icon' collapse }}
                    {{/if}}
                </{{ itemTag }}>

                {{#if contentElement}}
                    <div
                        id="{{ id }}"
                        class="dropdown-list__content {{ class }}"
                        aria-hidden="true"
                    >
                        {{ render (component contentElement) contentContext }}
                    </div>
                {{/if}}
            </li>
        {{/each}}
    </ul>
</div>

{{#if id}}
    <script type="text/javascript">
        new DropdownList(document.getElementById('{{ id }}'));
    </script>
{{/if}}
{
  "id": "dropdown-default",
  "dropdowns": [
    {
      "itemTag": "a",
      "title": "All",
      "itemAttributes": "href=\"#\""
    },
    {
      "itemTag": "button",
      "itemAttributes": "aria-expanded=\"false\"",
      "title": "dropdown title",
      "id": "dropdown-1",
      "collapse": {
        "id": "angle-down",
        "title": "Arrow down",
        "class": "dropdown-list__icon",
        "attributes": "aria-hidden=\"true\""
      },
      "contentElement": "image"
    },
    {
      "itemTag": "button",
      "itemAttributes": "aria-expanded=\"false\"",
      "title": "some longer longer and longer dropdown title",
      "id": "dropdown-2",
      "collapse": {
        "id": "angle-down",
        "title": "Arrow down",
        "class": "dropdown-list__icon",
        "attributes": "aria-hidden=\"true\""
      },
      "contentElement": "paragraph"
    },
    {
      "itemTag": "button",
      "itemAttributes": "aria-expanded=\"false\"",
      "title": "dropdown title",
      "id": "dropdown-3",
      "collapse": {
        "id": "angle-down",
        "title": "Arrow down",
        "class": "dropdown-list__icon",
        "attributes": "aria-hidden=\"true\""
      },
      "contentElement": "image"
    },
    {
      "itemTag": "button",
      "itemAttributes": "aria-expanded=\"false\"",
      "title": "dropdown title",
      "id": "dropdown-4",
      "collapse": {
        "id": "angle-down",
        "title": "Arrow down",
        "class": "dropdown-list__icon",
        "attributes": "aria-hidden=\"true\""
      },
      "contentElement": "paragraph"
    }
  ]
}
  • Content:
    $dropdown-list__width                     : 100% !default;
    $dropdown-list__bg-color                  : $white !default;
    $dropdown-list__border-radius             : 0 !default;
    $dropdown-list__outline                   : none !default;
    $dropdown-list__font-size                 : $font-size-base !default;
    $dropdown-list__transition-height         : height 0.3s !default;
    $dropdown-list__transition                : $transition-base !default;
    
    // List item
    $dropdown-list__item-padding              : $spacer--medium !default;
    $dropdown-list__item-color                : $font-color-base !default;
    $dropdown-list__item-color--open          : $font-color-base !default;
    $dropdown-list__item-color-hover          : $font-color-base !default;
    $dropdown-list__item-bg-color             : $white !default;
    $dropdown-list__item-bg-color--open       : $bg-color-base !default;
    $dropdown-list__item-bg-color-hover       : $color-primary !default;
    $dropdown-list__item-font-weight          : $font-weight-base !default;
    
    // List icon
    $dropdown-list__icon-width                : 16px !default;
    $dropdown-list__icon-height               : 16px !default;
    $dropdown-list__icon-fill                 : $black !default;
    $dropdown-list__icon-fill-hover           : $color-primary !default;
    $dropdown-list__icon-fill--open           : $white !default;
    
    // Secondary list variant
    $dropdown-list__font-weight--secondary    : $font-weight-bold !default;
    $dropdown-list__bg-color--secondary       : $dropdown-list__bg-color !default;
    $dropdown-list__item-color--secondary     : $dropdown-list__item-color !default;
    $dropdown-list__item-color--secondary-open: $color-primary !default;
    $dropdown-list__icon-size---secondary     : 24px !default;
    $dropdown-list__icon-padding--secondary   : 0 5px !default;
    $dropdown-list__icon-margin--secondary    : 0 0 0 5px !default;
    $dropdown-list__icon-rotate--open         : rotate(180deg) !default;
    $dropdown-list__icon-fill--secondary      : $dropdown-list__icon-fill !default;
    $dropdown-list__icon-fill-hover--secondary: $gray !default;
    $dropdown-list__icon-fill---secondary-open: $color-primary !default;
    
    // Dark list variant
    $dropdown-list__bg-color--dark            : $gray-darker !default;
    $dropdown-list__list-padding--dark        : $spacer--medium !default;
    $dropdown-list__item-border--dark         : 2px solid $gray-darkest !default;
    $dropdown-list__icon-fill--dark           : $white !default;
    $dropdown-list__icon-fill-hover--dark     : $color-primary !default;
    $dropdown-list__item-color--dark          : $color-primary !default;
    $dropdown-list__item-color-hover--dark    : $color-primary !default;
    $dropdown-list__item-bg-color-hover--dark : $color-tertiary !default;
    
    // Light list variant
    $dropdown-list__bg-color--light           : $color-tertiary !default;
    $dropdown-list__list-padding--light       : $spacer--medium !default;
    $dropdown-list__item-border--light        : 2px solid $gray-darkest !default;
    $dropdown-list__icon-fill--light          : $color-primary !default;
    $dropdown-list__icon-fill-hover--light    : $color-primary !default;
    $dropdown-list__item-color--light         : $color-primary !default;
    $dropdown-list__item-color-hover--light   : $color-primary !default;
    $dropdown-list__item-bg-color-hover--light : $color-tertiary !default;
    
    // Inner list variables
    $dropdown-list__item-bg-color--inner      : $gray-lightest !default;
    $dropdown-list__item-color--inner         : $gray-font !default;
    $dropdown-list__item-color-hover--inner   : $font-color-base !default;
    $dropdown-list__icon-fill--inner          : $color-primary !default;
    $dropdown-list__item-border--inner        : 1px solid $gray-lightest !default;
    $dropdown-list__item-border--inner-level2 : 1px solid $gray !default;
    $dropdown-list__item-font-weight--inner   : $font-weight-base !default;
    
    // screen-m list variables
    $dropdown-list__content-margin--screen-m  : $spacer $spacer--medium !default;
    
    .dropdown-list {
        width: $dropdown-list__width;
        position: relative;
        background-color: $dropdown-list__bg-color;
    
        &--secondary {
            background-color: $dropdown-list__bg-color--secondary;
    
            .dropdown-list__label {
                display: flex;
                justify-content: flex-start;
                align-items: center;
                flex-direction: row;
                text-transform: uppercase;
                font-size: $dropdown-list__font-size;
                font-weight: $dropdown-list__font-weight--secondary;
                background-color: $dropdown-list__bg-color--secondary;
                color: $dropdown-list__item-color--secondary;
    
                .dropdown-list__icon {
                    position: relative;
                    top: 0;
                    bottom: 0;
                    left: 0;
                    right: 0;
                    width: $dropdown-list__icon-size---secondary;
                    height: $dropdown-list__icon-size---secondary;
                    padding: $dropdown-list__icon-padding--secondary;
                    margin: $dropdown-list__icon-margin--secondary;
                    backface-visibility: hidden;
                    fill: $dropdown-list__icon-fill--secondary;
                }
    
                &:hover,
                &:focus {
                    background-color: $dropdown-list__bg-color--secondary;
                    color: $dropdown-list__item-color--secondary;
                    & > .dropdown-list__icon {
                        fill: $dropdown-list__icon-fill-hover--secondary;
                    }
                }
                &[aria-expanded="true"] {
                    background-color: $dropdown-list__bg-color--secondary;
                    color: $dropdown-list__item-color--secondary-open;
                    & > .dropdown-list__icon {
                        fill: $dropdown-list__icon-fill---secondary-open;
                    }
                }
            }
        }
    
        &--light {
            background-color: $dropdown-list__bg-color--light;
            padding: 0 $dropdown-list__list-padding--light;
    
            .dropdown-list__item {
                border-bottom: $dropdown-list__item-border--light;
            }
    
            .dropdown-list__label {
                background-color: $dropdown-list__bg-color--light;
                color: $dropdown-list__item-color--light;
                font-weight: $font-weight-bold;
    
                &:hover,
                &:focus {
                    color: $dropdown-list__item-color-hover--light;
                    background-color: $dropdown-list__item-bg-color-hover--light;
    
                    & .dropdown-list__icon {
                        fill: $dropdown-list__icon-fill-hover--light;
                    }
                }
    
                & .dropdown-list__icon {
                    fill: $dropdown-list__icon-fill--light;
                }
            }
    
            .dropdown-list__content {
                background-color: $dropdown-list__bg-color--light;
            }
        }
    
        &--inner {
            .dropdown-list__item {
                border-bottom: $dropdown-list__item-border--inner;
            }
            .dropdown-list__label {
                color: $dropdown-list__item-color--inner;
                background-color: $dropdown-list__item-bg-color--inner;
                font-weight: $dropdown-list__item-font-weight--inner;
                &:hover,
                &:focus {
                    color: $dropdown-list__item-color-hover--inner;
                }
                &[aria-expanded="true"] {
                    border-bottom: none;
                }
                & > .dropdown-list__icon {
                    fill: $dropdown-list__icon-fill--inner;
                }
            }
            .dropdown-list--inner {
                .dropdown-list__item {
                    border-bottom: $dropdown-list__item-border--inner-level2;
                    &:last-child {
                        border-bottom: none;
                    }
                }
            }
        }
    
        &--dark {
            background-color: $dropdown-list__bg-color--dark;
            padding: 0 $dropdown-list__list-padding--dark;
    
            .dropdown-list__item {
                border-bottom: $dropdown-list__item-border--dark;
            }
    
            .dropdown-list__label {
                background-color: $dropdown-list__bg-color--dark;
                color: $dropdown-list__item-color--dark;
                font-weight: $font-weight-bold;
    
                &:hover,
                &:focus {
                    color: $dropdown-list__item-color-hover--dark;
                    background-color: $dropdown-list__item-bg-color-hover--dark;
    
                    & .dropdown-list__icon {
                        fill: $dropdown-list__icon-fill-hover--dark;
                    }
                }
    
                & .dropdown-list__icon {
                    fill: $dropdown-list__icon-fill--dark;
                }
            }
    
            .dropdown-list__content {
                background-color: $dropdown-list__bg-color--dark;
            }
        }
    
        &--inner {
            .dropdown-list__item {
                border-bottom: $dropdown-list__item-border--inner;
            }
            .dropdown-list__label {
                color: $dropdown-list__item-color--inner;
                background-color: $dropdown-list__item-bg-color--inner;
                font-weight: $dropdown-list__item-font-weight--inner;
                &:hover,
                &:focus {
                    color: $dropdown-list__item-color-hover--inner;
                }
                &[aria-expanded="true"] {
                    border-bottom: none;
                }
                & > .dropdown-list__icon {
                    fill: $dropdown-list__icon-fill--inner;
                }
            }
            .dropdown-list--inner {
                .dropdown-list__item {
                    border-bottom: $dropdown-list__item-border--inner-level2;
                    &:last-child {
                        border-bottom: none;
                    }
                }
            }
        }
    
        &__list {
            display: block;
            width: $dropdown-list__width;
            list-style-type: none;
            padding: 0;
            margin: 0;
        }
    
        &__icon {
            position: absolute;
            right: 10px;
            top: 0;
            bottom: 0;
            width: $dropdown-list__icon-width;
            height: $dropdown-list__icon-height;
            margin: auto;
            fill: $dropdown-list__icon-fill;
            transition: $dropdown-list__transition;
        }
    
        &__item {
            position: relative;
            display: block;
            width: 100%;
            padding: 0;
            font-size: $dropdown-list__font-size;
    
            &--collapse {
                .dropdown-list__label {
                    padding-right: 30px;
                }
            }
        }
    
        &__label {
            display: block;
            position: relative;
            width: 100%;
            background-color: $dropdown-list__item-bg-color;
            padding: $dropdown-list__item-padding;
            margin: 0;
            border: 0;
            border-radius: $dropdown-list__border-radius;
            text-decoration: none;
            text-align: left;
            cursor: pointer;
            transition: $dropdown-list__transition;
            color: $dropdown-list__item-color;
            font-weight: $dropdown-list__item-font-weight;
    
            &:hover,
            &:focus {
                color: $dropdown-list__item-color-hover;
                background-color: $dropdown-list__item-bg-color-hover--light;
                outline: $dropdown-list__outline;
    
                & > .dropdown-list__icon {
                    fill: $dropdown-list__icon-fill-hover;
                }
            }
    
            &[aria-expanded="true"] {
                color: $dropdown-list__item-color--open;
                background-color: $dropdown-list__item-bg-color--open;
    
                & > .dropdown-list__icon {
                    fill: $dropdown-list__icon-fill--open;
                    transform: $dropdown-list__icon-rotate--open;
                }
            }
    
            .dropdown-list--inner .dropdown-list--inner & {
                padding-left: $dropdown-list__item-padding * 2;
            }
            .dropdown-list--inner .dropdown-list--inner .dropdown-list--inner & {
                padding-left: $dropdown-list__item-padding * 3;
            }
        }
    
        &__content {
            overflow: hidden;
            transition: $dropdown-list__transition-height;
            &[aria-hidden="true"] {
                display: none;
            }
        }
    
        @include mq($screen-m) {
            // from $screen-m drpdown list displays inline and with opened list
            &--is-open\@screen-m {
                .dropdown-list__list {
                    display: flex;
                    flex-flow: row nowrap;
                }
    
                .dropdown-list__item {
                    width: 25%;
                    cursor: default;
                }
    
                .dropdown-list__label {
                    cursor: default;
                    &:hover,
                    &:focus {
                        color: $dropdown-list__item-color;
                        background-color: $dropdown-list__item-bg-color;
                    }
                }
                .dropdown-list__icon {
                    display: none;
                }
                .dropdown-list__content {
                    margin: $dropdown-list__content-margin--screen-m;
                    height: auto;
                }
    
                &.dropdown-list--dark {
                    .dropdown-list__label {
                        &:hover,
                        &:focus {
                            color: $dropdown-list__item-color--dark;
                            background-color: $dropdown-list__item-bg-color-hover--dark;
                        }
                    }
                }
            }
        }
    }
    
  • URL: /components/raw/dropdown-list/_dropdown-list.scss
  • Filesystem Path: build/components/02-elements/dropdown-list/_dropdown-list.scss
  • Size: 13.2 KB
  • Content:
    'use strict';
    
    class DropdownList {  // eslint-disable-line
      constructor(element) {
        this.element = element;
        this.dropdownCollapseLabel = '.dropdown-list__item--collapse > .dropdown-list__label';
        this.dropdownItem = [...this.element.querySelectorAll(this.dropdownCollapseLabel)];
        this.contentClass = 'dropdown-list__content';
        this.mq = '(min-width: 768px)';
        this.mqClass = 'dropdown-list--is-open@screen-m';
        this.dropdownMediumOpen = this.element.classList.contains(this.mqClass);
        this.init();
      }
    
      setAriaAttributes(label, content, expanded) {
        if (expanded) {
          label.setAttribute('aria-expanded', 'false');
          content.setAttribute('aria-hidden', 'true');
        }
        else {
          label.setAttribute('aria-expanded', 'true');
          content.setAttribute('aria-hidden', 'false');
        }
      }
    
      removeAriaAttributes(label, content) {
        label.removeAttribute('aria-expanded');
        content.setAttribute('aria-hidden', 'false');
        label.disabled = true;
      }
    
      isMediumOpen(dropdownBlock) {
        return (dropdownBlock.classList.contains('dropdown-list--is-open@screen-m')) && window.matchMedia(this.mq).matches;
      }
    
      resetMqMediumOpen(item) {
        const dropdownItem    = item.parentNode,
              dropdownContent = dropdownItem.querySelector(`.${this.contentClass}`);
    
        if (window.matchMedia(this.mq).matches) {
          this.removeAriaAttributes(item, dropdownContent);
        }
        else {
          this.setAriaAttributes(item, dropdownContent, true);
          item.disabled = false;
        }
      }
    
      toggleContent(trigger, dropdownContent, opening) {
        const dropdownBlock = trigger.closest('.dropdown-list'),
              focusableElements = dropdownContent.querySelectorAll('button:not([disabled]), a[href], area[href] input:not([disabled]), select:not([disabled]), textarea:not([disabled]), *[tabindex]:not([tabindex="-1"]), object, embed, *[contenteditable]');
    
        if (!this.isMediumOpen(dropdownBlock)) {
          if (dropdownContent.clientHeight > 0) {
            this.setAriaAttributes(trigger, dropdownContent, true);
            trigger.focus();
          }
          else if (opening) {
            this.setAriaAttributes(trigger, dropdownContent, false);
            if (focusableElements[0]) {
              focusableElements[0].focus();
            }
          }
        }
      }
    
      setMediumOpen() {
        if (this.dropdownMediumOpen) {
          let dropdownItems = [...this.element.querySelectorAll(this.dropdownCollapseLabel)];
          dropdownItems.forEach(key => this.resetMqMediumOpen(key));
        }
      }
    
      init() {
        this.dropdownItem.forEach(key => {
          const dropdownId = key.getAttribute('aria-controls'),
                dropdownContent = document.getElementById(dropdownId);
    
          key.addEventListener('click', e => {
            e.preventDefault();
            this.toggleContent(key, dropdownContent, true);
          }, false);
    
          [key, dropdownContent].forEach(el => el.addEventListener('keydown', e => {
            if (e.key === 'Escape') {
              this.toggleContent(key, dropdownContent, false);
            }
          }));
        });
    
        this.setMediumOpen();
    
        window.addEventListener('resize', () => {
          this.setMediumOpen();
        });
      }
    }
    
  • URL: /components/raw/dropdown-list/dropdown-list.js
  • Filesystem Path: build/components/02-elements/dropdown-list/dropdown-list.js
  • Size: 3.1 KB

Dropdown list

Accessibility:

  • Buttons (reactive elements, which open dropdown) should have following aria attributes:
    • aria-expanded - set to true if dropdown field is open, to false when it’s closed
    • aria-controls where value it’s an id of content dropdown element
  • Dropdown content should have aria-hidden attribute set to true of it’s closed and to false when it’s open.
  • focus management and keyboard support should be implemented