<div id="dropdown-default" class="dropdown-list dropdown-list--buttons">
<ul class="dropdown-list__list">
<li class="
dropdown-list__item
dropdown-list__item--collapse
">
<button class="dropdown-list__label button button--icon" type="button" aria-expanded="false" aria-controls="dropdown-buttons-content">
<svg class="icon button__icon" aria-hidden="true" role="img">
<title>Heart</title>
<use href="/images/icons-sprite.svg#heart"></use>
</svg>
<span class="button__text dropdown-list__text margin-hz-s">
dropdown title
</span>
<svg class="icon dropdown-list__icon button__icon margin-0" aria-hidden="true" role="img">
<title>Arrow Down</title>
<use href="/images/icons-sprite.svg#angle-down"></use>
</svg>
</button>
<div id="dropdown-buttons-content" class="dropdown-list__content " aria-hidden="true">
<ul class="list ">
<li class="list__item ">
Lorem ipsum
</li>
<li class="list__item ">
Lorem ipsum
</li>
<li class="list__item ">
Lorem ipsum
</li>
<li class="list__item ">
Lorem ipsum
</li>
<li class="list__item ">
Lorem ipsum
</li>
</ul>
</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}}
>
{{#if iconBefore }}
{{ render '@icon' iconBefore}}
{{/if}}
<span class="button__text {{ textClass }}">
{{ title }}
</span>
{{#if collapse }}
{{ render '@icon' collapse }}
{{/if}}
</{{ itemTag }}>
{{#if contentElement}}
<div
id="{{ id }}"
class="dropdown-list__content {{ classContent }}"
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": "button",
"itemAttributes": "type=\"button\" aria-expanded=\"false\"",
"title": "dropdown title",
"textClass": "dropdown-list__text margin-hz-s",
"id": "dropdown-buttons-content",
"class": "button button--icon",
"iconBefore": {
"id": "heart",
"title": "Heart",
"class": "button__icon",
"attributes": "aria-hidden=\"true\""
},
"collapse": {
"id": "angle-down",
"title": "Arrow Down",
"class": "dropdown-list__icon button__icon margin-0",
"attributes": "aria-hidden=\"true\""
},
"contentElement": "list"
}
],
"class": "dropdown-list--buttons"
}
$dropdown-list__width : 100% !default;
$dropdown-list__bg-color : $white !default;
$dropdown-list__transition : $transition-base !default;
$dropdown-list__padding : 0 !default;
// List item
$dropdown-list__item-color : $gray-darker !default;
$dropdown-list__item-bg-color : $white !default;
$dropdown-list__item-border-bottom : $border-base !default;
$dropdown-list__item-width : 100% !default;
$dropdown-list__item-font-size : $font-size-base !default;
// List
$dropdown-list__list-width : 100% !default;
$dropdown-list__list-padding : 0 !default;
$dropdown-list__list-margin : 0 !default;
$dropdown-list__list-style-type : none !default;
// Label
$dropdown-list__label-font-size : $font-size-large !default;
$dropdown-list__label-text-transform : uppercase !default;
$dropdwon-list__label-font-famility : $font-family-base !default;
$dropdown-list__label-color : $color-primary !default;
$dropdown-list__label-margin : 0 !default;
$dropdown-list__label-padding-left : 0 !default;
$dropdown-list__label-padding-right : 48px !default;
$dropdown-list__label-border-radius : 0 !default;
$dropdown-list__label-width : 100% !default;
$dropdown-list__label-height : 64px !default;
$dropdown-list__label-bg-color : $white !default;
$dropdown-list__label-font-weight : $font-weight-bold !default;
$dropdown-list__label-color-hover : $gray-darker !default;
$dropdown-list__label-bg-color-hover : $white !default;
$dropdown-list__label-text-decoration : none !default;
$dropdown-list__label-text-decoration-hover : none !default;
$dropdown-list__label-text-align : left !default;
$dropdown-list__label-border : 0 !default;
$dropdown-list__label-cursor : pointer !default;
$dropdown-list__label-color--open : $color-primary !default;
$dropdown-list__label-bg-color--open : $white !default;
$dropdwon-list__label-line-height : $font-line-height !default;
// List icon
$dropdown-list__icon-width : 24px !default;
$dropdown-list__icon-height : 24px !default;
$dropdown-list__icon-fill : $color-secondary !default;
$dropdown-list__icon-fill-hover : $color-primary !default;
$dropdown-list__icon-fill--open : $color-primary !default;
$dropdown-list__icon-rotate--open : rotate(180deg) !default;
$dropdown-list__icon-margin : auto !default;
$dropdown-list__icon-right : $spacer--small !default;
// List content
$dropdown-list__content-transition : height 0.3s !default;
// Secondary variant
$dropdown-list__bg-color--secondary : $dropdown-list__bg-color !default;
$dropdown-list__label-font-size--secondary : $font-size-large !default;
$dropdown-list__label-height--secondary : 48px !default;
$dropdown-list__label-padding-right--secondary : 48px !default;
$dropdown-list__label-padding-left--secondary : 0 !default;
$dropdown-list__icon-width--secondary : 24px !default;
$dropdown-list__icon-height--secondary : 24px !default;
$dropdown-list__label-text-transform--secondary : uppercase !default;
$dropdown-list__icon-right--secondary : $dropdown-list__icon-right !default;
// With nested variant
$dropdown-list__label-font-size--with-nested : $font-size-base !default;
$dropdown-list__label-font-weight--with-nested : $font-weight-medium !default;
$dropdown-list__label-height--with-nested : 56px !default;
$dropdown-list__label-padding-left--with-nested : 0 !default;
$dropdown-list__label-padding-right--with-nested : 56px !default;
$dropdown-list__label-color--with-nested : $color-primary !default;
$dropdown-list__icon-fill--with-nested : $color-secondary !default;
$dropdown-list__icon-width--with-nested : 24px !default;
$dropdown-list__icon-height--with-nested : 24px !default;
$dropdown-list__icon-right--with-nested : $spacer--medium !default;
// Inner variant
$dropdown-list__padding--inner : 0 0 $spacer--medium $spacer--medium !default;
$dropdown-list__label-color--inner : $color-secondary !default;
$dropdown-list__label-text-transform--inner : capitalize !default;
$dropdown-list__label-font-weight--inner : $font-weight-base !default;
$dropdown-list__label-border-bottom--inner : 0 !default;
$dropdown-list__label-font-size--inner : $font-size-base !default;
$dropdown-list__label-height--inner : 48px !default;
$dropdown-list__label-padding-right--inner : 48px !default;
$dropdown-list__label-padding-left--inner : 0 !default;
// with-breakpoint list variables
$dropdown-list__screen--breakpoint : $screen-m !default;
$dropdown-list__content-margin--breakpoint : $spacer $spacer--medium !default;
$dropdown-list__item-bg-color--breakpoint : transparent !default;
// detailed-content list variables
$dropdown-list__width--detailed-content : auto !default;
$dropdown-list__label-text-transform--detailed-content : capitalize !default;
$dropdown-list__label-text-decoration--detailed-content: underline !default;
$dropdown-list__label-color--detailed-content : $color-primary !default;
$dropdown-list__label-font-size--detailed-content : $font-size-base !default;
$dropdown-list__label-font-weight--detailed-content : $font-weight-base !default;
$dropdown-list__label-height--detailed-content : 48px !default;
$dropdown-list__label-padding-right--detailed-content : 36px !default;
$dropdown-list__label-padding-left--detailed-content : 0 !default;
$dropdown-list__item-border-bottom--detailed-content : 0 !default;
$dropdown-list__icon-right--detailed-content : $spacer--small !default;
$dropdown-list__label-width--detailed-content : auto !default;
// buttons list variables
$dropdown-list__label-height--buttons : 56px !default;
$dropdown-list__label-padding--buttons : $spacer--extra-small $spacer !default;
$dropdown-list__label-background-color--buttons : $gray-lighter !default;
$dropdown-list__label-background-color-active--buttons : $gray-darkest !default;
$dropdown-list__label-text-color-active--buttons : $white !default;
$dropdown-list__icon-fill-active--buttons : $white !default;
$dropdown-list__icon-fill--buttons : $gray-darkest !default;
$dropdown-list__icon-fill-hover--buttons : $white !default;
$dropdown-list__text-font-size--buttons : $font-size-base !default;
$dropdown-list__text-color--buttons : $gray-darkest !default;
$dropdown-list__text-color-hover--buttons : $white !default;
$dropdown-list__content-left--buttons : 0 !default;
$dropdown-list__content-top--buttons : 100% !default;
$dropdown-list__content-width--buttons : 100% !default;
$dropdown-list__content-padding--buttons : $spacer 0 0 !default;
$dropdown-list__content-background-color--buttons : $white !default;
$dropdown-list__content-border--buttons : 1px solid $gray-dark !default;
$dropdown-list__item-padding--buttons : $spacer--small $spacer--semi-medium !default;
$dropdown-list__item-font-size--buttons : $font-size-medium !default;
$dropdown-list__item-font-line-height--buttons : 1.3 !default;
$dropdown-list__item-background-active--buttons : $gray-light !default;
@import 'dropdown-list-variables';
.dropdown-list {
position: relative;
width: $dropdown-list__width;
background-color: $dropdown-list__bg-color;
&--secondary {
background-color: $dropdown-list__bg-color--secondary;
.dropdown-list__label {
font-size: $dropdown-list__label-font-size--secondary;
text-transform: $dropdown-list__label-text-transform--secondary;
@include font-padding(
$dropdown-list__label-font-size--secondary,
$dropdown-list__label-height--secondary,
$dropdown-list__label-padding-right--secondary,
$dropdown-list__label-padding-left--secondary
);
}
.dropdown-list__icon {
width: $dropdown-list__icon-width--secondary;
height: $dropdown-list__icon-height--secondary;
right: $dropdown-list__icon-right--secondary;
}
}
&--with-nested {
.dropdown-list__label {
font-size: $dropdown-list__label-font-size--with-nested;
color: $dropdown-list__label-color--with-nested;
font-weight: $dropdown-list__label-font-weight--with-nested;
@include font-padding(
$dropdown-list__label-font-size--with-nested,
$dropdown-list__label-height--with-nested,
$dropdown-list__label-padding-right--with-nested,
$dropdown-list__label-padding-left--with-nested
);
}
.dropdown-list__icon {
fill: $dropdown-list__icon-fill--with-nested;
width: $dropdown-list__icon-width--with-nested;
height: $dropdown-list__icon-height--with-nested;
right: $dropdown-list__icon-right--with-nested;
}
}
&--inner {
padding: $dropdown-list__padding--inner;
.dropdown-list__label {
font-size: $dropdown-list__label-font-size--inner;
font-weight: $dropdown-list__label-font-weight--inner;
color: $dropdown-list__label-color--inner;
text-transform: $dropdown-list__label-text-transform--inner;
@include font-padding(
$dropdown-list__label-font-size--inner,
$dropdown-list__label-height--inner,
$dropdown-list__label-padding-right--inner,
$dropdown-list__label-padding-left--inner
);
}
.dropdown-list__item {
border-bottom: $dropdown-list__label-border-bottom--inner;
}
}
&--with-breakpoint {
@include mq($dropdown-list__screen--breakpoint) {
// from $dropdown-list__screen--breakpoint dropdown list displays inline and with opened list
.dropdown-list__list {
display: flex;
flex-flow: row nowrap;
}
.dropdown-list__item {
width: 25%;
cursor: default;
}
.dropdown-list__label {
cursor: default;
&:hover,
&.focus-visible {
color: $dropdown-list__item-color;
background-color: $dropdown-list__item-bg-color--breakpoint;
}
}
.dropdown-list__icon {
display: none;
}
.dropdown-list__content {
margin: $dropdown-list__content-margin--breakpoint;
height: auto;
}
}
}
&--detailed-content {
.dropdown-list {
&__list {
display: inline-block;
width: $dropdown-list__width--detailed-content;
}
&__label {
font-size: $dropdown-list__label-font-size--detailed-content;
font-weight: $dropdown-list__label-font-weight--detailed-content;
text-transform: $dropdown-list__label-text-transform--detailed-content;
text-decoration: $dropdown-list__label-text-decoration--detailed-content;
color: $dropdown-list__label-color--detailed-content;
width: $dropdown-list__label-width--detailed-content;
@include font-padding(
$dropdown-list__label-font-size--detailed-content,
$dropdown-list__label-height--detailed-content,
$dropdown-list__label-padding-right--detailed-content,
$dropdown-list__label-padding-left--detailed-content
);
}
&__item {
border-bottom: $dropdown-list__item-border-bottom--detailed-content;
}
&__icon {
right: $dropdown-list__icon-right--detailed-content;
}
}
}
&--buttons {
position: relative;
.dropdown-list {
&__item {
border: 0;
}
&__label {
display: flex;
height: $dropdown-list__label-height--buttons;
padding: $dropdown-list__label-padding--buttons;
background-color: $dropdown-list__label-background-color--buttons;
&:hover {
.icon {
fill: $dropdown-list__icon-fill-hover--buttons;
}
}
&[aria-expanded="true"] {
background-color: $dropdown-list__label-background-color-active--buttons;
&:before {
background-color: $dropdown-list__label-background-color-active--buttons;
}
.button__text {
color: $dropdown-list__label-text-color-active--buttons;
}
.icon {
fill: $dropdown-list__icon-fill-active--buttons;
}
}
}
&__icon {
position: static;
fill: $dropdown-list__icon-fill--buttons;
}
&__text {
font-size: $dropdown-list__text-font-size--buttons;
color: $dropdown-list__text-color--buttons;
&:hover,
&:focus {
color: $dropdown-list__text-color-hover--buttons;
}
}
&__content {
position: absolute;
top: $dropdown-list__content-top--buttons;
left: $dropdown-list__content-left--buttons;
width: $dropdown-list__content-width--buttons;
padding: $dropdown-list__content-padding--buttons;
background-color: $dropdown-list__content-background-color--buttons;
border: $dropdown-list__content-border--buttons;
z-index: 10;
&--right {
left: auto;
right: 0;
}
.button {
width: 100%;
}
}
}
.list {
&__item {
span {
display: block;
padding: $dropdown-list__item-padding--buttons;
font-size: $dropdown-list__item-font-size--buttons;
line-height: $dropdown-list__item-font-line-height--buttons;
cursor: pointer;
&:hover {
background-color: $dropdown-list__item-background-active--buttons;
}
}
}
}
}
&__list {
display: block;
width: $dropdown-list__list-width;
list-style-type: $dropdown-list__list-style-type;
padding: $dropdown-list__list-padding;
margin: $dropdown-list__list-margin;
}
&__icon {
position: absolute;
right: $dropdown-list__icon-right;
top: 0;
bottom: 0;
width: $dropdown-list__icon-width;
height: $dropdown-list__icon-height;
margin: $dropdown-list__icon-margin;
fill: $dropdown-list__icon-fill;
transition: $dropdown-list__transition;
}
&__item {
position: relative;
display: block;
width: $dropdown-list__item-width;
border-bottom: $dropdown-list__item-border-bottom;
font-size: $dropdown-list__item-font-size;
}
&__label {
display: block;
position: relative;
width: $dropdown-list__label-width;
background-color: $dropdown-list__label-bg-color;
margin: $dropdown-list__label-margin;
border: $dropdown-list__label-border;
border-radius: $dropdown-list__label-border-radius;
text-transform: $dropdown-list__label-text-transform;
text-decoration: $dropdown-list__label-text-decoration;
text-align: $dropdown-list__label-text-align;
cursor: $dropdown-list__label-cursor;
transition: $dropdown-list__transition;
color: $dropdown-list__label-color;
font-weight: $dropdown-list__label-font-weight;
font-size: $dropdown-list__label-font-size;
font-family: $dropdwon-list__label-font-famility;
line-height: $dropdwon-list__label-line-height;
@include font-padding(
$dropdown-list__label-font-size,
$dropdown-list__label-height,
$dropdown-list__label-padding-right,
$dropdown-list__label-padding-left
);
&:hover,
&.focus-visible {
color: $dropdown-list__label-color-hover;
background-color: $dropdown-list__label-bg-color-hover;
text-decoration: $dropdown-list__label-text-decoration-hover;
& > .dropdown-list__icon {
fill: $dropdown-list__icon-fill-hover;
}
}
&[aria-expanded="true"] {
color: $dropdown-list__label-color--open;
background-color: $dropdown-list__label-bg-color--open;
& > .dropdown-list__icon {
fill: $dropdown-list__icon-fill--open;
transform: $dropdown-list__icon-rotate--open;
}
&.button--icon-filled {
&:after {
background: $dropdown-list__label-bg-color--open;
}
}
}
}
&__content {
overflow: hidden;
transition: $dropdown-list__content-transition;
&[aria-hidden="true"] {
display: none;
}
}
}
'use strict';
class DropdownList { // eslint-disable-line
constructor(element) {
this.element = element;
this.dropdownCollapseLabel = '.dropdown-list__item--collapse > .dropdown-list__label, .dropdown-list__item--collapse > .dropdown-list__label-wrapper > .dropdown-list__label';
this.dropdownItem = [...this.element.querySelectorAll(this.dropdownCollapseLabel)];
this.contentClass = 'dropdown-list__content';
this.mq = '(min-width: 768px)';
this.mqClass = 'dropdown-list--with-breakpoint';
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(this.mqClass)) && window.matchMedia(this.mq).matches;
}
resetMqMediumOpen(item) {
const dropdownItem = item.parentNode;
const 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');
const 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');
const 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();
});
}
}
default
- Used as base for other dropdownswith-breakpoint
- Used in: Footersecondary
- Used in: Filterswith-nested
- Used in: Sidebarinner
- Used in: with-nesteddetailed-content
- Used in: Minicart (to do: name change?)aria-expanded
- set to true
if dropdown field is open, to false
when it’s closedaria-controls
where value it’s an id
of content dropdown elementaria-hidden
attribute set to true
of it’s closed and to false
when it’s open.