saagie-ui
Version:
Saagie UI from Saagie Design System
121 lines (96 loc) • 2.71 kB
JavaScript
import $ from 'domtastic';
import Popper from 'popper.js';
import ToggleComponent from '../_helpers/toggleComponent';
export default class Dropdown extends ToggleComponent {
constructor(element, customOptions) {
const $dropdown = $(element);
let options = {
target: `[data-sui-o-dropdown="${$dropdown.attr('id')}"]`,
dataAttrBase: 'data-sui-o-dropdown',
clickOutsideEnabled: true,
focusRecoverEnabled: true,
placement: 'bottom-start',
itemClass: 'sui-o-dropdown__link',
itemDisabledClass: 'as--disabled',
itemSelectedClass: 'as--selected',
};
// Merge custom options
if (customOptions) {
options = $.extend({}, options, customOptions);
}
super($dropdown, options);
}
_onDestroy() {
super._onDestroy();
if (this.popper) {
this.popper.destroy();
}
}
_onOpen(clickedElement) {
this.selectedItem = -1;
const $target = clickedElement ? $(clickedElement) : $(this.options.target);
const $dropdown = this.$component;
if (this.popper) {
this.popper.destroy();
}
if ($target && $target[0] && $dropdown && $dropdown[0]) {
this.popper = new Popper($target[0], $dropdown[0], {
placement: this.options.placement,
});
}
super._onOpen();
}
_onClose() {
super._onClose();
this._unselectItems();
}
_focusElement(element) {
const $target = $(element).first();
if ($target && $target[0]) {
$target[0].focus();
}
}
_keysMethods(event) {
super._keysMethods(event);
// Arrow up
if (event.which === 38) {
event.preventDefault();
this._prevItem();
}
// Arrow down
if (event.which === 40) {
event.preventDefault();
this._nextItem();
}
}
_getItems() {
return $(`.${this.options.itemClass}:not(:disabled):not(.${this.options.itemDisabledClass})`, this.$component);
}
_nextItem() {
const indexMax = this._getItems().length - 1;
if (this.selectedItem >= indexMax) {
this._selectItem(indexMax);
return;
}
this.selectedItem = parseInt(this.selectedItem, 10) + 1;
this._selectItem(this.selectedItem);
}
_prevItem() {
if (this.selectedItem <= 0) {
this._selectItem(0);
return;
}
this.selectedItem = parseInt(this.selectedItem, 10) - 1;
this._selectItem(this.selectedItem);
}
_selectItem(index) {
this._unselectItems();
const $item = $(this._getItems()[index]);
$item.addClass(this.options.itemSelectedClass);
this._focusElement($item);
}
_unselectItems() {
const $items = this._getItems();
$items.removeClass(this.options.itemSelectedClass);
}
}