Skip to content

Instantly share code, notes, and snippets.

@clw8
Last active March 3, 2020 16:15
Show Gist options
  • Save clw8/711c3f72f771874b81cabc57abdf8239 to your computer and use it in GitHub Desktop.
Save clw8/711c3f72f771874b81cabc57abdf8239 to your computer and use it in GitHub Desktop.
simple dropdown
<div class="dropdown js__dropdown">
<div class="dropdown__toggle js__dropdown-toggle">
<span class="dropdown__selected js__dropdown-selected">Selected</span>
<span class="caret" id="js__dropdown-cart"></span>
</div>
<ul class="dropdown__menu js__dropdown-menu">
<li class="dropdown__item js__dropdown-item">
// dropdown label here
</li>
</ul>
</div>
import delegate from 'delegate';
let dropdownOpen = false, dropdowns, destroyDelegations = [];
export default {
init: function () {
dropdowns = document.querySelectorAll('.js__dropdown');
dropdowns.forEach(dropdown => {
let dropdownSelected = dropdown.querySelector('.js__dropdown-selected');
let activeDropdownItem;
let toggleDelegation = delegate(dropdown, '.js__dropdown-toggle', 'click', function (e) {
if (dropdownOpen) {
e.delegateTarget.nextElementSibling.classList.remove('dropdown__menu--show');
} else {
e.delegateTarget.nextElementSibling.classList.add('dropdown__menu--show');
}
dropdownOpen = !dropdownOpen;
});
let itemDelegation = delegate(dropdown, '.js__dropdown-item', 'click', function (e) {
console.log(dropdownSelected, e.delegateTarget.textContent);
if (!e.delegateTarget.classList.contains('dropdown__item--active')) {
if (activeDropdownItem) activeDropdownItem.classList.remove('dropdown__item--active');
e.delegateTarget.classList.add('dropdown__item--active');
dropdownSelected.textContent = e.delegateTarget.textContent;
activeDropdownItem = e.delegateTarget;
}
});
destroyDelegations.push(toggleDelegation);
destroyDelegations.push(itemDelegation);
})
},
destroy: function () {
destroyDelegations.forEach(delegation => delegation.destroy());
}
}
$dropdown-selected-height: 38px;
.dropdown {
position: relative;
border-radius: 2px;
font-size: 1rem;
background-color: $color-primary;
&__toggle {
@include type-small;
position: relative;
display: flex;
box-sizing: border-box;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 1rem 2rem;
color: $white;
&:hover {
cursor: pointer;
}
}
&__menu {
position: absolute;
visibility: hidden;
z-index: 1000;
pointer-events: none;
overflow-y: auto;
top: 100%;
left: 0;
width: 100%;
max-height: 350px;
margin: -2px 0 0;
list-style: none;
opacity: 0;
transition: opacity .2s ease;
&:hover {
cursor: pointer;
}
&--show {
visibility: visible;
pointer-events: all;
opacity: 1;
}
}
&__item {
position: relative;
display: block;
box-sizing: border-box;
user-select: none;
overflow: hidden;
width: 100%;
margin: 0;
padding: 1rem 2rem;
white-space: nowrap;
text-decoration: none;
color: $white;
background-color: $color-bg-light-black;
clear: both;
&:hover {
background-color: $color-pink;
}
&--active {
// to set if needed
}
}
&__selected {
z-index: 2;
line-height: 1.1rem;
white-space: nowrap;
text-overflow: ellipsis;
margin-block-end: 0;
}
.caret {
position: relative;
z-index: 2;
top: -4px;
left: 1px;
transform: rotate(-45deg);
transform-origin: 3px 8px;
width: 8px;
height: 8px;
margin-left: 10px;
border-bottom: 1px solid $white;
border-left: 1px solid $white;
vertical-align: middle;
transition: transform .5s ease;
margin-block-end: 0;
&--active {
transform: rotate(135deg);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment