Socket
Socket
Sign inDemoInstall

@odopod/odo-dropdown

Package Overview
Dependencies
5
Maintainers
3
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.1.0 to 2.1.1

18

dist/odo-dropdown.esm.js

@@ -29,10 +29,2 @@ import OdoDevice from '@odopod/odo-device';

var inherits = function (subClass, superClass) {

@@ -54,12 +46,2 @@ if (typeof superClass !== "function" && superClass !== null) {

var possibleConstructorReturn = function (self, call) {

@@ -66,0 +48,0 @@ if (!self) {

1172

dist/odo-dropdown.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@odopod/odo-device'), require('@odopod/odo-helpers'), require('@odopod/odo-base-component')) :
typeof define === 'function' && define.amd ? define(['@odopod/odo-device', '@odopod/odo-helpers', '@odopod/odo-base-component'], factory) :
(global.OdoDropdown = factory(global.OdoDevice,global.OdoHelpers,global.OdoBaseComponent));
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@odopod/odo-device'), require('@odopod/odo-helpers'), require('@odopod/odo-base-component')) :
typeof define === 'function' && define.amd ? define(['@odopod/odo-device', '@odopod/odo-helpers', '@odopod/odo-base-component'], factory) :
(global.OdoDropdown = factory(global.OdoDevice,global.OdoHelpers,global.OdoBaseComponent));
}(this, (function (OdoDevice,odoHelpers,OdoBaseComponent) { 'use strict';
OdoDevice = OdoDevice && OdoDevice.hasOwnProperty('default') ? OdoDevice['default'] : OdoDevice;
OdoBaseComponent = OdoBaseComponent && OdoBaseComponent.hasOwnProperty('default') ? OdoBaseComponent['default'] : OdoBaseComponent;
OdoDevice = OdoDevice && OdoDevice.hasOwnProperty('default') ? OdoDevice['default'] : OdoDevice;
OdoBaseComponent = OdoBaseComponent && OdoBaseComponent.hasOwnProperty('default') ? OdoBaseComponent['default'] : OdoBaseComponent;
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
var id = 0;
function uniqueId() {
id += 1;
return 'ododropdown-' + id;
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var Dropdown = function (_OdoBaseComponent) {
inherits(Dropdown, _OdoBaseComponent);
function Dropdown(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
classCallCheck(this, Dropdown);
/**
* Override any defaults with the given options.
* @type {Object}
*/
var _this = possibleConstructorReturn(this, _OdoBaseComponent.call(this, element));
_this.options = Object.assign({}, Dropdown.Defaults, options);
/**
* Unique id for this instance.
* @type {string}
*/
_this.id = uniqueId();
/**
* Whether the dropdown is currently open.
* @type {boolean}
*/
_this._isOpen = false;
/**
* The <select> element.
* @type {HTMLSelectElement}
*/
_this._select = _this.getElementByClass(Dropdown.Classes.SELECT);
// Give the select an id if it doesn't have one.
odoHelpers.giveId(_this._select, _this.id);
/**
* The <label> for the <select>.
* @type {?HTMLLabelElement}
*/
_this._label = document.querySelector('label[for="' + _this._select.id + '"]');
// Generate the custom markup for options.
if (_this.options.insertMarkup) {
_this._insertMarkup();
}
// Save Element references.
_this._optionsContainer = _this.getElementByClass(Dropdown.Classes.OPTIONS_CONTAINER);
_this._button = _this.getElementByClass(Dropdown.Classes.BUTTON);
_this._placeholder = _this.getElementByClass(Dropdown.Classes.DEFAULT);
_this._valueContainer = _this.getElementByClass(Dropdown.Classes.VALUE);
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
// Set the selected option.
_this._selectedOption = _this._getCustomSelectedOption();
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
_this._onSelectChange = _this._handleSelectChange.bind(_this);
_this._onPageClick = _this._handlePageClick.bind(_this);
_this._onButtonClick = _this._showOptions.bind(_this);
_this._onKey = _this._handleKey.bind(_this);
var id = 0;
function uniqueId() {
id += 1;
return 'ododropdown-' + id;
}
_this._transitionId = null;
var Dropdown = function (_OdoBaseComponent) {
inherits(Dropdown, _OdoBaseComponent);
_this._initialize();
return _this;
}
function Dropdown(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
classCallCheck(this, Dropdown);
/**
* Override any defaults with the given options.
* @type {Object}
* Determines whether to create custom dropdown module,
* or use native select element
*/
var _this = possibleConstructorReturn(this, _OdoBaseComponent.call(this, element));
_this.options = Object.assign({}, Dropdown.Defaults, options);
/**
* Unique id for this instance.
* @type {string}
*/
_this.id = uniqueId();
Dropdown.prototype._initialize = function _initialize() {
this._valueContainer.setAttribute('aria-hidden', true);
/**
* Whether the dropdown is currently open.
* @type {boolean}
*/
_this._isOpen = false;
if (this.options.useNative) {
this._initializeNativeDropdown();
} else {
this._initializeCustomDropdown();
}
};
/**
* The <select> element.
* @type {HTMLSelectElement}
* Return the selected custom option element.
* @return {Element}
*/
_this._select = _this.getElementByClass(Dropdown.Classes.SELECT);
// Give the select an id if it doesn't have one.
odoHelpers.giveId(_this._select, _this.id);
Dropdown.prototype._getCustomSelectedOption = function _getCustomSelectedOption() {
return this.getCustomOptions()[this._select.selectedIndex];
};
/**
* The <label> for the <select>.
* @type {?HTMLLabelElement}
* Insert the custom option html markup before the <select> element.
*/
_this._label = document.querySelector('label[for="' + _this._select.id + '"]');
// Generate the custom markup for options.
if (_this.options.insertMarkup) {
_this._insertMarkup();
}
// Save Element references.
_this._optionsContainer = _this.getElementByClass(Dropdown.Classes.OPTIONS_CONTAINER);
_this._button = _this.getElementByClass(Dropdown.Classes.BUTTON);
_this._placeholder = _this.getElementByClass(Dropdown.Classes.DEFAULT);
_this._valueContainer = _this.getElementByClass(Dropdown.Classes.VALUE);
Dropdown.prototype._insertMarkup = function _insertMarkup() {
var markup = this.getCustomOptionsHtml();
this._select.insertAdjacentHTML('beforebegin', markup);
};
// Set the selected option.
_this._selectedOption = _this._getCustomSelectedOption();
/**
* Listen for change events on the <select>.
*/
_this._onSelectChange = _this._handleSelectChange.bind(_this);
_this._onPageClick = _this._handlePageClick.bind(_this);
_this._onButtonClick = _this._showOptions.bind(_this);
_this._onKey = _this._handleKey.bind(_this);
_this._transitionId = null;
Dropdown.prototype._initializeNativeDropdown = function _initializeNativeDropdown() {
this.element.classList.add(Dropdown.Classes.BASE_NATIVE);
this._select.addEventListener('change', this._onSelectChange);
_this._initialize();
return _this;
}
// Hide the <button> from the screen reader so that it only reads the
// <select> element. The <select> is actually positioned on top of the
// <button> with zero opacity.
this._button.setAttribute('aria-hidden', true);
this._button.tabIndex = -1;
};
/**
* Determines whether to create custom dropdown module,
* or use native select element
*/
/**
* Listen for clicks to trigger the menu and keyboard input.
*/
Dropdown.prototype._initialize = function _initialize() {
this._valueContainer.setAttribute('aria-hidden', true);
Dropdown.prototype._initializeCustomDropdown = function _initializeCustomDropdown() {
if (this._label) {
odoHelpers.giveId(this._label, this.id + '-label');
var _id = this._label.id;
if (this.options.useNative) {
this._initializeNativeDropdown();
} else {
this._initializeCustomDropdown();
}
};
this._optionsContainer.setAttribute('aria-labelledby', _id);
}
/**
* Return the selected custom option element.
* @return {Element}
*/
this._select.tabIndex = -1;
this._select.setAttribute('aria-hidden', true);
this._button.setAttribute('aria-haspopup', 'true');
this._button.setAttribute('aria-controls', this._select.id);
this._button.setAttribute('aria-expanded', false);
this._toggleButtonListener(true);
this.element.addEventListener('keydown', this._onKey);
};
Dropdown.prototype._getCustomSelectedOption = function _getCustomSelectedOption() {
return this.getCustomOptions()[this._select.selectedIndex];
};
/**
* Key down event occured.
* @param {KeyboardEvent} e Event object.
*/
/**
* Insert the custom option html markup before the <select> element.
*/
Dropdown.prototype._handleKey = function _handleKey(e) {
var code = e.which;
Dropdown.prototype._insertMarkup = function _insertMarkup() {
var markup = this.getCustomOptionsHtml();
this._select.insertAdjacentHTML('beforebegin', markup);
};
if (this._isOpen) {
switch (code) {
case Dropdown.Key.ESC:
case Dropdown.Key.TAB:
this._hideOptions();
break;
/**
* Listen for change events on the <select>.
*/
case Dropdown.Key.DOWN:
case Dropdown.Key.UP:
e.preventDefault();
Dropdown._moveFocus(code === Dropdown.Key.DOWN);
break;
case Dropdown.Key.SPACE:
case Dropdown.Key.ENTER:
e.preventDefault();
this._selectOption(e.target);
break;
// no default
}
} else {
switch (code) {
case Dropdown.Key.SPACE:
case Dropdown.Key.DOWN:
case Dropdown.Key.UP:
case Dropdown.Key.ENTER:
e.preventDefault();
this._showOptions();
break;
// no default
}
}
};
Dropdown.prototype._initializeNativeDropdown = function _initializeNativeDropdown() {
this.element.classList.add(Dropdown.Classes.BASE_NATIVE);
this._select.addEventListener('change', this._onSelectChange);
/**
* Transer focus from one option to the next or prev enabled option.
* @param {boolean} isNext Whether to focus on the next or previous option.
*/
// Hide the <button> from the screen reader so that it only reads the
// <select> element. The <select> is actually positioned on top of the
// <button> with zero opacity.
this._button.setAttribute('aria-hidden', true);
this._button.tabIndex = -1;
};
/**
* Listen for clicks to trigger the menu and keyboard input.
*/
Dropdown._moveFocus = function _moveFocus(isNext) {
var selector = Dropdown.Selector.ENABLED_OPTION;
var enabledOption = isNext ? Dropdown._nextMatch(document.activeElement, selector) : Dropdown._prevMatch(document.activeElement, selector);
if (enabledOption) {
enabledOption.focus();
}
};
Dropdown.prototype._initializeCustomDropdown = function _initializeCustomDropdown() {
if (this._label) {
odoHelpers.giveId(this._label, this.id + '-label');
var _id = this._label.id;
/**
* Find the next sibling which matches a selector.
* @param {Element} element Element to test.
* @param {string} selector Selector to match.
* @return {?Element} The element or null if there isn't one.
*/
this._optionsContainer.setAttribute('aria-labelledby', _id);
}
this._select.tabIndex = -1;
this._select.setAttribute('aria-hidden', true);
this._button.setAttribute('aria-haspopup', 'true');
this._button.setAttribute('aria-controls', this._select.id);
this._button.setAttribute('aria-expanded', false);
Dropdown._nextMatch = function _nextMatch(element, selector) {
while (element = element.nextElementSibling) {
// eslint-disable-line
if (element.matches(selector)) {
return element;
}
}
this._toggleButtonListener(true);
this.element.addEventListener('keydown', this._onKey);
};
return null;
};
/**
* Key down event occured.
* @param {KeyboardEvent} e Event object.
*/
/**
* Find the previous sibling which matches a selector.
* @param {Element} element Element to test.
* @param {string} selector Selector to match.
* @return {?Element} The element or null if there isn't one.
*/
Dropdown.prototype._handleKey = function _handleKey(e) {
var code = e.which;
if (this._isOpen) {
switch (code) {
case Dropdown.Key.ESC:
case Dropdown.Key.TAB:
this._hideOptions();
break;
case Dropdown.Key.DOWN:
case Dropdown.Key.UP:
e.preventDefault();
Dropdown._moveFocus(code === Dropdown.Key.DOWN);
break;
case Dropdown.Key.SPACE:
case Dropdown.Key.ENTER:
e.preventDefault();
this._selectOption(e.target);
break;
// no default
Dropdown._prevMatch = function _prevMatch(element, selector) {
while (element = element.previousElementSibling) {
// eslint-disable-line
if (element.matches(selector)) {
return element;
}
}
} else {
switch (code) {
case Dropdown.Key.SPACE:
case Dropdown.Key.DOWN:
case Dropdown.Key.UP:
case Dropdown.Key.ENTER:
e.preventDefault();
this._showOptions();
break;
// no default
}
}
};
/**
* Transer focus from one option to the next or prev enabled option.
* @param {boolean} isNext Whether to focus on the next or previous option.
*/
return null;
};
/**
* Delegated click event on the document. Check to see if it was an option,
* otherwise hide the dropdown menu.
* @param {MouseEvent} e Event object.
*/
Dropdown._moveFocus = function _moveFocus(isNext) {
var selector = Dropdown.Selector.ENABLED_OPTION;
var enabledOption = isNext ? Dropdown._nextMatch(document.activeElement, selector) : Dropdown._prevMatch(document.activeElement, selector);
if (enabledOption) {
enabledOption.focus();
}
};
/**
* Find the next sibling which matches a selector.
* @param {Element} element Element to test.
* @param {string} selector Selector to match.
* @return {?Element} The element or null if there isn't one.
*/
Dropdown._nextMatch = function _nextMatch(element, selector) {
while (element = element.nextElementSibling) {
// eslint-disable-line
if (element.matches(selector)) {
return element;
Dropdown.prototype._handlePageClick = function _handlePageClick(e) {
var option = e.target.closest('.' + Dropdown.Classes.OPTION);
if (option) {
this._selectOption(option);
} else {
this._hideOptions();
}
}
};
return null;
};
/**
* Set the current value from an option element.
* @param {Element} option Custom option element.
*/
/**
* Find the previous sibling which matches a selector.
* @param {Element} element Element to test.
* @param {string} selector Selector to match.
* @return {?Element} The element or null if there isn't one.
*/
Dropdown._prevMatch = function _prevMatch(element, selector) {
while (element = element.previousElementSibling) {
// eslint-disable-line
if (element.matches(selector)) {
return element;
Dropdown.prototype._selectOption = function _selectOption(option) {
// Avoid selecting disabled options or a target which is not an option (if
// the user rapidly presses space|enter, this method could be called with
// an event target which is not an option element because the transition
// hasn't finished).
if (option.classList.contains(Dropdown.Classes.OPTION_DISABLED) || !option.classList.contains(Dropdown.Classes.OPTION)) {
return;
}
}
return null;
};
var value = option.getAttribute('data-value');
this.value = value;
this._hideOptions();
/**
* Delegated click event on the document. Check to see if it was an option,
* otherwise hide the dropdown menu.
* @param {MouseEvent} e Event object.
*/
// Emit event to notify watchers that this has changed.
this.emit(Dropdown.EventType.CHANGE, {
name: this.select.name,
value: this.value
});
};
/**
* The native <select> input changed. Update the display.
*/
Dropdown.prototype._handlePageClick = function _handlePageClick(e) {
var option = e.target.closest('.' + Dropdown.Classes.OPTION);
if (option) {
this._selectOption(option);
} else {
this._hideOptions();
}
};
/**
* Set the current value from an option element.
* @param {Element} option Custom option element.
*/
Dropdown.prototype._handleSelectChange = function _handleSelectChange() {
this.value = this._select.value;
// Emit event to notify watchers that this has changed.
this.emit(Dropdown.EventType.CHANGE, {
name: this.select.name,
value: this.value
});
};
Dropdown.prototype._selectOption = function _selectOption(option) {
// Avoid selecting disabled options or a target which is not an option (if
// the user rapidly presses space|enter, this method could be called with
// an event target which is not an option element because the transition
// hasn't finished).
if (option.classList.contains(Dropdown.Classes.OPTION_DISABLED) || !option.classList.contains(Dropdown.Classes.OPTION)) {
return;
}
/**
* Add or remove click listener for custom select display element
* @params {boolean} add Whether to add or remove click listener
*/
var value = option.getAttribute('data-value');
this.value = value;
this._hideOptions();
// Emit event to notify watchers that this has changed.
this.emit(Dropdown.EventType.CHANGE, {
name: this.select.name,
value: this.value
});
};
Dropdown.prototype._toggleButtonListener = function _toggleButtonListener(add) {
if (add) {
this._button.addEventListener('click', this._onButtonClick);
} else {
this._button.removeEventListener('click', this._onButtonClick);
}
};
/**
* The native <select> input changed. Update the display.
*/
/**
* Show the options dropdown menu.
*/
Dropdown.prototype._handleSelectChange = function _handleSelectChange() {
this.value = this._select.value;
Dropdown.prototype._showOptions = function _showOptions() {
this._isOpen = true;
// Emit event to notify watchers that this has changed.
this.emit(Dropdown.EventType.CHANGE, {
name: this.select.name,
value: this.value
});
};
// Clear any pending transition ends.
odoHelpers.cancelTransitionEnd(this._transitionId);
/**
* Add or remove click listener for custom select display element
* @params {boolean} add Whether to add or remove click listener
*/
// Remove click listener on button.
this._toggleButtonListener(false);
this.element.classList.add(Dropdown.Classes.OPEN);
this._optionsContainer.setAttribute('aria-hidden', false);
this._button.setAttribute('aria-expanded', true);
this._button.tabIndex = -1;
odoHelpers.causeLayout(this._optionsContainer);
this._optionsContainer.classList.add(Dropdown.Classes.OPTIONS_CONTAINER_OPEN);
this._transitionId = odoHelpers.onTransitionEnd(this._optionsContainer, this._handleOptionsShown, this);
};
Dropdown.prototype._toggleButtonListener = function _toggleButtonListener(add) {
if (add) {
this._button.addEventListener('click', this._onButtonClick);
} else {
this._button.removeEventListener('click', this._onButtonClick);
}
};
/**
* Options dropdown finished show animation.
*/
/**
* Show the options dropdown menu.
*/
Dropdown.prototype._handleOptionsShown = function _handleOptionsShown() {
document.body.addEventListener('click', this._onPageClick);
Dropdown.prototype._showOptions = function _showOptions() {
this._isOpen = true;
// If all the options are disabled, a selected option doesn't exist.
if (this._selectedOption) {
this._selectedOption.focus();
}
};
// Clear any pending transition ends.
odoHelpers.cancelTransitionEnd(this._transitionId);
/**
* Hide the options dropdown.
*/
// Remove click listener on button.
this._toggleButtonListener(false);
this.element.classList.add(Dropdown.Classes.OPEN);
this._optionsContainer.setAttribute('aria-hidden', false);
this._button.setAttribute('aria-expanded', true);
this._button.tabIndex = -1;
odoHelpers.causeLayout(this._optionsContainer);
this._optionsContainer.classList.add(Dropdown.Classes.OPTIONS_CONTAINER_OPEN);
this._transitionId = odoHelpers.onTransitionEnd(this._optionsContainer, this._handleOptionsShown, this);
};
Dropdown.prototype._hideOptions = function _hideOptions() {
this._isOpen = false;
/**
* Options dropdown finished show animation.
*/
// Clear any pending transition ends.
odoHelpers.cancelTransitionEnd(this._transitionId);
document.body.removeEventListener('click', this._onPageClick);
this._optionsContainer.setAttribute('aria-hidden', true);
this._button.tabIndex = 0;
this._button.setAttribute('aria-expanded', false);
this._optionsContainer.classList.remove(Dropdown.Classes.OPTIONS_CONTAINER_OPEN);
this._transitionId = odoHelpers.onTransitionEnd(this._optionsContainer, this._handleOptionsHidden, this);
};
Dropdown.prototype._handleOptionsShown = function _handleOptionsShown() {
document.body.addEventListener('click', this._onPageClick);
/**
* Options dropdown finished hiding.
*/
// If all the options are disabled, a selected option doesn't exist.
if (this._selectedOption) {
this._selectedOption.focus();
}
};
/**
* Hide the options dropdown.
*/
Dropdown.prototype._handleOptionsHidden = function _handleOptionsHidden() {
this.element.classList.remove(Dropdown.Classes.OPEN);
this._button.focus();
this._toggleButtonListener(true);
};
/**
* Generate the HTML to show on non-touch devices.
* @return {string} A string of HTML.
* @protected
*/
Dropdown.prototype._hideOptions = function _hideOptions() {
this._isOpen = false;
// Clear any pending transition ends.
odoHelpers.cancelTransitionEnd(this._transitionId);
Dropdown.prototype.getCustomOptionsHtml = function getCustomOptionsHtml() {
return '<div class="' + Dropdown.Classes.OPTIONS_CONTAINER + '" role="menu" aria-hidden="true">' + this.getOptionsMarkup() + '</div>';
};
document.body.removeEventListener('click', this._onPageClick);
this._optionsContainer.setAttribute('aria-hidden', true);
this._button.tabIndex = 0;
this._button.setAttribute('aria-expanded', false);
this._optionsContainer.classList.remove(Dropdown.Classes.OPTIONS_CONTAINER_OPEN);
this._transitionId = odoHelpers.onTransitionEnd(this._optionsContainer, this._handleOptionsHidden, this);
};
/**
* Generate an HTML string for custom options based on the current options
* in the <select>
* @return {string} Markup.
* @protected
*/
/**
* Options dropdown finished hiding.
*/
Dropdown.prototype.getOptionsMarkup = function getOptionsMarkup() {
var _this2 = this;
Dropdown.prototype._handleOptionsHidden = function _handleOptionsHidden() {
this.element.classList.remove(Dropdown.Classes.OPEN);
this._button.focus();
this._toggleButtonListener(true);
};
return this.getNativeOptions().reduce(function (str, option) {
return str + _this2.getOptionMarkup(option);
}, '');
};
/**
* Generate the HTML to show on non-touch devices.
* @return {string} A string of HTML.
* @protected
*/
/**
* Create an HTML string to be used for a custom option.
* @param {HTMLOptionElement} option Native option element.
* @return {string} Markup.
* @protected
*/
Dropdown.prototype.getCustomOptionsHtml = function getCustomOptionsHtml() {
return '<div class="' + Dropdown.Classes.OPTIONS_CONTAINER + '" role="menu" aria-hidden="true">' + this.getOptionsMarkup() + '</div>';
};
Dropdown.prototype.getOptionMarkup = function getOptionMarkup(option) {
var selected = option.selected ? ' ' + Dropdown.Classes.OPTION_SELECTED : '';
var disabled = option.disabled ? ' ' + Dropdown.Classes.OPTION_DISABLED : '';
var className = Dropdown.Classes.OPTION + selected + disabled;
return '<div class="' + className + '" data-value="' + option.value + '" tabindex="-1" role="menuitem">' + option.text + '</div>';
};
/**
* Generate an HTML string for custom options based on the current options
* in the <select>
* @return {string} Markup.
* @protected
*/
/**
* Return an array of custom option elements.
* @return {Array.<HTMLDivElement>}
*/
Dropdown.prototype.getOptionsMarkup = function getOptionsMarkup() {
var _this2 = this;
Dropdown.prototype.getCustomOptions = function getCustomOptions() {
return this.getElementsByClass(Dropdown.Classes.OPTION);
};
return this.getNativeOptions().reduce(function (str, option) {
return str + _this2.getOptionMarkup(option);
}, '');
};
/**
* Return an array of option elements.
* @return {Array.<HTMLOptionElement>}
*/
/**
* Create an HTML string to be used for a custom option.
* @param {HTMLOptionElement} option Native option element.
* @return {string} Markup.
* @protected
*/
Dropdown.prototype.getNativeOptions = function getNativeOptions() {
return Array.from(this.select.options);
};
Dropdown.prototype.getOptionMarkup = function getOptionMarkup(option) {
var selected = option.selected ? ' ' + Dropdown.Classes.OPTION_SELECTED : '';
var disabled = option.disabled ? ' ' + Dropdown.Classes.OPTION_DISABLED : '';
var className = Dropdown.Classes.OPTION + selected + disabled;
return '<div class="' + className + '" data-value="' + option.value + '" tabindex="-1" role="menuitem">' + option.text + '</div>';
};
/**
* Retrieve the text to display inside the button.
* @param {number} selectedIndex Index of the selected option.
* @return {string} Text to display.
* @protected
*/
/**
* Return an array of custom option elements.
* @return {Array.<HTMLDivElement>}
*/
Dropdown.prototype.getDisplayText = function getDisplayText(selectedIndex) {
return this.select.options[selectedIndex].text;
};
Dropdown.prototype.getCustomOptions = function getCustomOptions() {
return this.getElementsByClass(Dropdown.Classes.OPTION);
};
/**
* Retrieve the selected index of the <select>
* @return {number}
*/
/**
* Return an array of option elements.
* @return {Array.<HTMLOptionElement>}
*/
/**
* Toggle the state of an option.
* @param {string} value Value of the option to toggle.
* @param {boolean} isDisabled Whether to disable it or not.
* @return {Dropdown} This instance for chaining.
*/
Dropdown.prototype.toggleOptionByValue = function toggleOptionByValue(value, isDisabled) {
var customOption = this._optionsContainer.querySelector('[data-value="' + value + '"]');
var nativeOption = this._select.querySelector('[value="' + value + '"]');
Dropdown.prototype.getNativeOptions = function getNativeOptions() {
return Array.from(this.select.options);
};
customOption.classList.toggle(Dropdown.Classes.OPTION_DISABLED, isDisabled);
if (isDisabled) {
customOption.setAttribute('aria-disabled', true);
} else {
customOption.removeAttribute('aria-disabled');
}
/**
* Retrieve the text to display inside the button.
* @param {number} selectedIndex Index of the selected option.
* @return {string} Text to display.
* @protected
*/
nativeOption.disabled = isDisabled;
return this;
};
Dropdown.prototype.getDisplayText = function getDisplayText(selectedIndex) {
return this.select.options[selectedIndex].text;
};
/**
* Disable an option.
* @param {string} value Value of the option to disable.
* @return {Dropdown} This instance.
*/
/**
* Retrieve the selected index of the <select>
* @return {number}
*/
Dropdown.prototype.disableOptionByValue = function disableOptionByValue(value) {
return this.toggleOptionByValue(value, true);
};
/**
* Toggle the state of an option.
* @param {string} value Value of the option to toggle.
* @param {boolean} isDisabled Whether to disable it or not.
* @return {Dropdown} This instance for chaining.
*/
Dropdown.prototype.toggleOptionByValue = function toggleOptionByValue(value, isDisabled) {
var customOption = this._optionsContainer.querySelector('[data-value="' + value + '"]');
var nativeOption = this._select.querySelector('[value="' + value + '"]');
/**
* Enable an option.
* @param {string} value Value of the option to enable.
* @return {Dropdown} This instance.
*/
customOption.classList.toggle(Dropdown.Classes.OPTION_DISABLED, isDisabled);
if (isDisabled) {
customOption.setAttribute('aria-disabled', true);
} else {
customOption.removeAttribute('aria-disabled');
}
nativeOption.disabled = isDisabled;
Dropdown.prototype.enableOptionByValue = function enableOptionByValue(value) {
return this.toggleOptionByValue(value, false);
};
return this;
};
Dropdown.prototype.dispose = function dispose() {
this._select.removeEventListener('change', this._onSelectChange);
this._button.removeEventListener('click', this._onButtonClick);
document.body.removeEventListener('click', this._onPageClick);
this._optionsContainer.parentNode.removeChild(this._optionsContainer);
/**
* Disable an option.
* @param {string} value Value of the option to disable.
* @return {Dropdown} This instance.
*/
// Prefer resetting the tabIndex property by using removeAttribute to lets the
// browser decide if it should go back to 0 (like if it was a button) or to
// -1 if it wasn't originally focusable.
this._select.removeAttribute('tabindex');
this._select.removeAttribute('aria-hidden');
this._button.removeAttribute('tabindex');
this._button.removeAttribute('aria-hidden');
this._button.removeAttribute('aria-haspopup');
this._button.removeAttribute('aria-controls');
this._button.removeAttribute('aria-expanded');
this._selectedOption = null;
this._optionsContainer = null;
this._button = null;
this._placeholder = null;
this._valueContainer = null;
this._select = null;
_OdoBaseComponent.prototype.dispose.call(this);
};
Dropdown.prototype.disableOptionByValue = function disableOptionByValue(value) {
return this.toggleOptionByValue(value, true);
};
createClass(Dropdown, [{
key: 'selectedIndex',
get: function get$$1() {
return this._select.selectedIndex;
}
/**
* Enable an option.
* @param {string} value Value of the option to enable.
* @return {Dropdown} This instance.
*/
/**
* Set the selected option by index.
* @param {number} index Index to select.
*/
,
set: function set$$1(index) {
this.value = this._select.options[index].value;
}
/**
* Returns the <select>.
* @return {HTMLSelectElement}
*/
Dropdown.prototype.enableOptionByValue = function enableOptionByValue(value) {
return this.toggleOptionByValue(value, false);
};
}, {
key: 'select',
get: function get$$1() {
return this._select;
}
Dropdown.prototype.dispose = function dispose() {
this._select.removeEventListener('change', this._onSelectChange);
this._button.removeEventListener('click', this._onButtonClick);
document.body.removeEventListener('click', this._onPageClick);
this._optionsContainer.parentNode.removeChild(this._optionsContainer);
/**
* Returns the button to open the select menu.
* @return {HTMLButtonElement}
*/
// Prefer resetting the tabIndex property by using removeAttribute to lets the
// browser decide if it should go back to 0 (like if it was a button) or to
// -1 if it wasn't originally focusable.
this._select.removeAttribute('tabindex');
this._select.removeAttribute('aria-hidden');
this._button.removeAttribute('tabindex');
this._button.removeAttribute('aria-hidden');
this._button.removeAttribute('aria-haspopup');
this._button.removeAttribute('aria-controls');
this._button.removeAttribute('aria-expanded');
}, {
key: 'button',
get: function get$$1() {
return this._button;
}
this._selectedOption = null;
this._optionsContainer = null;
this._button = null;
this._placeholder = null;
this._valueContainer = null;
this._select = null;
_OdoBaseComponent.prototype.dispose.call(this);
};
/**
* Return the display text for the currently selected option.
* @returns {string}
*/
createClass(Dropdown, [{
key: 'selectedIndex',
get: function get$$1() {
return this._select.selectedIndex;
}
}, {
key: 'selectedText',
get: function get$$1() {
return this._select.options[this._select.selectedIndex].text;
}
/**
* Set the selected option by index.
* @param {number} index Index to select.
*/
,
set: function set$$1(index) {
this.value = this._select.options[index].value;
}
/**
* Retrieve the selected value.
* @return {string}
*/
/**
* Returns the <select>.
* @return {HTMLSelectElement}
*/
}, {
key: 'value',
get: function get$$1() {
return this._select.value;
}
}, {
key: 'select',
get: function get$$1() {
return this._select;
}
/**
* Set the value of the <select> and the custom menu.
* @param {string} value Value which matches one of the options.
*/
,
set: function set$$1(value) {
// Remove the old selected class.
if (this._selectedOption) {
this._selectedOption.classList.remove(Dropdown.Classes.OPTION_SELECTED);
}
/**
* Returns the button to open the select menu.
* @return {HTMLButtonElement}
*/
// Set new value.
this._select.value = value;
}, {
key: 'button',
get: function get$$1() {
return this._button;
}
// Update currently selected option.
this._selectedOption = this._getCustomSelectedOption();
/**
* Return the display text for the currently selected option.
* @returns {string}
*/
if (this._selectedOption) {
// Read the text for the new value.
var text = this.getDisplayText(this.selectedIndex);
}, {
key: 'selectedText',
get: function get$$1() {
return this._select.options[this._select.selectedIndex].text;
}
this._selectedOption.classList.add(Dropdown.Classes.OPTION_SELECTED);
/**
* Retrieve the selected value.
* @return {string}
*/
// Update display.
this._placeholder.style.display = 'none';
this._placeholder.setAttribute('aria-hidden', true);
this._valueContainer.textContent = text;
this._valueContainer.removeAttribute('aria-hidden');
} else {
this._placeholder.style.display = '';
this._placeholder.removeAttribute('aria-hidden');
this._valueContainer.textContent = '';
this._valueContainer.setAttribute('aria-hidden', true);
}
}
}, {
key: 'value',
get: function get$$1() {
return this._select.value;
}
/**
* Get the disabled state of the component.
* @return {boolean}
*/
/**
* Set the value of the <select> and the custom menu.
* @param {string} value Value which matches one of the options.
*/
,
set: function set$$1(value) {
// Remove the old selected class.
if (this._selectedOption) {
this._selectedOption.classList.remove(Dropdown.Classes.OPTION_SELECTED);
}, {
key: 'disabled',
get: function get$$1() {
return this.select.disabled;
}
// Set new value.
this._select.value = value;
/**
* Set the disabled state of the component.
* @param {boolean} isDisabled Whether it's disabled or not.
*/
,
set: function set$$1(isDisabled) {
this.select.disabled = isDisabled;
this.button.disabled = isDisabled;
}
}]);
return Dropdown;
}(OdoBaseComponent);
// Update currently selected option.
this._selectedOption = this._getCustomSelectedOption();
Dropdown.Classes = {
BASE: 'odo-dropdown',
OPEN: 'odo-dropdown--open',
BUTTON: 'odo-dropdown__button',
OPTIONS_CONTAINER_OPEN: 'odo-dropdown__options--open',
OPTIONS_CONTAINER: 'odo-dropdown__options',
OPTION: 'odo-dropdown__option',
OPTION_SELECTED: 'odo-dropdown__option--active',
OPTION_DISABLED: 'odo-dropdown__option--disabled',
SELECT: 'odo-dropdown__select',
VALUE: 'odo-dropdown__value',
DEFAULT: 'odo-dropdown__default',
BASE_NATIVE: 'odo-dropdown--native'
};
if (this._selectedOption) {
// Read the text for the new value.
var text = this.getDisplayText(this.selectedIndex);
Dropdown.Key = {
TAB: 9,
ENTER: 13,
ESC: 27,
SPACE: 32,
UP: 38,
DOWN: 40
};
this._selectedOption.classList.add(Dropdown.Classes.OPTION_SELECTED);
Dropdown.EventType = {
CHANGE: 'ododropdown:change'
};
// Update display.
this._placeholder.style.display = 'none';
this._placeholder.setAttribute('aria-hidden', true);
this._valueContainer.textContent = text;
this._valueContainer.removeAttribute('aria-hidden');
} else {
this._placeholder.style.display = '';
this._placeholder.removeAttribute('aria-hidden');
this._valueContainer.textContent = '';
this._valueContainer.setAttribute('aria-hidden', true);
}
}
Dropdown.Selector = {
ENABLED_OPTION: '.' + Dropdown.Classes.OPTION + ':not(.' + Dropdown.Classes.OPTION_DISABLED + ')'
};
/**
* Get the disabled state of the component.
* @return {boolean}
*/
Dropdown.Defaults = {
insertMarkup: true,
useNative: OdoDevice.HAS_TOUCH_EVENTS
};
}, {
key: 'disabled',
get: function get$$1() {
return this.select.disabled;
}
/**
* Set the disabled state of the component.
* @param {boolean} isDisabled Whether it's disabled or not.
*/
,
set: function set$$1(isDisabled) {
this.select.disabled = isDisabled;
this.button.disabled = isDisabled;
}
}]);
return Dropdown;
}(OdoBaseComponent);
Dropdown.Classes = {
BASE: 'odo-dropdown',
OPEN: 'odo-dropdown--open',
BUTTON: 'odo-dropdown__button',
OPTIONS_CONTAINER_OPEN: 'odo-dropdown__options--open',
OPTIONS_CONTAINER: 'odo-dropdown__options',
OPTION: 'odo-dropdown__option',
OPTION_SELECTED: 'odo-dropdown__option--active',
OPTION_DISABLED: 'odo-dropdown__option--disabled',
SELECT: 'odo-dropdown__select',
VALUE: 'odo-dropdown__value',
DEFAULT: 'odo-dropdown__default',
BASE_NATIVE: 'odo-dropdown--native'
};
Dropdown.Key = {
TAB: 9,
ENTER: 13,
ESC: 27,
SPACE: 32,
UP: 38,
DOWN: 40
};
Dropdown.EventType = {
CHANGE: 'ododropdown:change'
};
Dropdown.Selector = {
ENABLED_OPTION: '.' + Dropdown.Classes.OPTION + ':not(.' + Dropdown.Classes.OPTION_DISABLED + ')'
};
Dropdown.Defaults = {
insertMarkup: true,
useNative: OdoDevice.HAS_TOUCH_EVENTS
};
return Dropdown;
})));
//# sourceMappingURL=odo-dropdown.js.map
{
"name": "@odopod/odo-dropdown",
"description": "Custom dropdown component that defaults to native select elements on touch devices.",
"version": "2.1.0",
"version": "2.1.1",
"main": "dist/odo-dropdown.js",

@@ -23,4 +23,4 @@ "module": "dist/odo-dropdown.esm.js",

"@odopod/odo-base-component": "^1.2.1",
"@odopod/odo-device": "^1.2.0",
"@odopod/odo-helpers": "^2.0.1"
"@odopod/odo-device": "^1.3.0",
"@odopod/odo-helpers": "^2.0.2"
},

@@ -27,0 +27,0 @@ "homepage": "https://github.com/odopod/code-library/tree/master/packages/odo-dropdown",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc