2020-06-12 01:09:35 +03:00
|
|
|
/* eslint-disable indent */
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
/**
|
|
|
|
* Module alphaPicker.
|
|
|
|
* @module components/alphaPicker/alphaPicker
|
|
|
|
*/
|
|
|
|
|
2020-08-14 08:46:34 +02:00
|
|
|
import focusManager from '../focusManager';
|
|
|
|
import layoutManager from '../layoutManager';
|
|
|
|
import dom from '../../scripts/dom';
|
|
|
|
import './style.css';
|
|
|
|
import '../../elements/emby-button/paper-icon-button-light';
|
|
|
|
import 'material-design-icons-iconfont';
|
2020-06-12 01:09:35 +03:00
|
|
|
|
|
|
|
const selectedButtonClass = 'alphaPickerButton-selected';
|
2018-10-23 01:05:09 +03:00
|
|
|
|
|
|
|
function focus() {
|
2020-06-12 01:09:35 +03:00
|
|
|
const scope = this;
|
|
|
|
const selected = scope.querySelector(`.${selectedButtonClass}`);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
if (selected) {
|
|
|
|
focusManager.focus(selected);
|
|
|
|
} else {
|
|
|
|
focusManager.autoFocus(scope, true);
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function getAlphaPickerButtonClassName(vertical) {
|
2020-06-12 01:09:35 +03:00
|
|
|
let alphaPickerButtonClassName = 'alphaPickerButton';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
if (layoutManager.tv) {
|
|
|
|
alphaPickerButtonClassName += ' alphaPickerButton-tv';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vertical) {
|
|
|
|
alphaPickerButtonClassName += ' alphaPickerButton-vertical';
|
|
|
|
}
|
|
|
|
|
|
|
|
return alphaPickerButtonClassName;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function getLetterButton(l, vertical) {
|
2020-06-12 01:09:35 +03:00
|
|
|
return `<button data-value="${l}" class="${getAlphaPickerButtonClassName(vertical)}">${l}</button>`;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function mapLetters(letters, vertical) {
|
2020-06-12 01:09:35 +03:00
|
|
|
return letters.map(l => {
|
2019-01-10 15:39:37 +03:00
|
|
|
return getLetterButton(l, vertical);
|
|
|
|
});
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function render(element, options) {
|
2019-01-10 15:39:37 +03:00
|
|
|
element.classList.add('alphaPicker');
|
|
|
|
|
|
|
|
if (layoutManager.tv) {
|
|
|
|
element.classList.add('alphaPicker-tv');
|
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
const vertical = element.classList.contains('alphaPicker-vertical');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2019-11-23 00:29:38 +09:00
|
|
|
if (!vertical) {
|
2019-01-10 15:39:37 +03:00
|
|
|
element.classList.add('focuscontainer-x');
|
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
let html = '';
|
|
|
|
let letters;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
const alphaPickerButtonClassName = getAlphaPickerButtonClassName(vertical);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
let rowClassName = 'alphaPickerRow';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
|
|
|
if (vertical) {
|
|
|
|
rowClassName += ' alphaPickerRow-vertical';
|
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
html += `<div class="${rowClassName}">`;
|
2019-01-10 15:39:37 +03:00
|
|
|
if (options.mode === 'keyboard') {
|
2020-06-12 01:09:35 +03:00
|
|
|
html += `<button data-value=" " is="paper-icon-button-light" class="${alphaPickerButtonClassName}"><span class="material-icons alphaPickerButtonIcon space_bar"></span></button>`;
|
2019-01-10 15:39:37 +03:00
|
|
|
} else {
|
|
|
|
letters = ['#'];
|
|
|
|
html += mapLetters(letters, vertical).join('');
|
|
|
|
}
|
|
|
|
|
|
|
|
letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
|
|
|
|
html += mapLetters(letters, vertical).join('');
|
|
|
|
|
|
|
|
if (options.mode === 'keyboard') {
|
2020-06-12 01:09:35 +03:00
|
|
|
html += `<button data-value="backspace" is="paper-icon-button-light" class="${alphaPickerButtonClassName}"><span class="material-icons alphaPickerButtonIcon backspace"></span></button>`;
|
2019-01-10 15:39:37 +03:00
|
|
|
html += '</div>';
|
|
|
|
|
|
|
|
letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
2020-06-12 01:09:35 +03:00
|
|
|
html += `<div class="${rowClassName}">`;
|
2019-01-10 15:39:37 +03:00
|
|
|
html += '<br/>';
|
|
|
|
html += mapLetters(letters, vertical).join('');
|
|
|
|
html += '</div>';
|
|
|
|
} else {
|
|
|
|
html += '</div>';
|
|
|
|
}
|
|
|
|
|
|
|
|
element.innerHTML = html;
|
|
|
|
|
|
|
|
element.classList.add('focusable');
|
|
|
|
element.focus = focus;
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
export class AlphaPicker {
|
|
|
|
constructor(options) {
|
2020-07-25 23:38:42 +02:00
|
|
|
const self = this;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
this.options = options;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
const element = options.element;
|
|
|
|
const itemsContainer = options.itemsContainer;
|
|
|
|
const itemClass = options.itemClass;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
let itemFocusValue;
|
|
|
|
let itemFocusTimeout;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
function onItemFocusTimeout() {
|
|
|
|
itemFocusTimeout = null;
|
2020-07-25 23:38:42 +02:00
|
|
|
self.value(itemFocusValue);
|
2020-06-12 01:09:35 +03:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
let alphaFocusedElement;
|
|
|
|
let alphaFocusTimeout;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-07-25 23:38:42 +02:00
|
|
|
function onAlphaFocusTimeout() {
|
2020-06-12 01:09:35 +03:00
|
|
|
alphaFocusTimeout = null;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (document.activeElement === alphaFocusedElement) {
|
|
|
|
const value = alphaFocusedElement.getAttribute('data-value');
|
2020-07-25 23:38:42 +02:00
|
|
|
self.value(value, true);
|
2020-06-12 01:09:35 +03:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
function onAlphaPickerInKeyboardModeClick(e) {
|
|
|
|
const alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (alphaPickerButton) {
|
|
|
|
const value = alphaPickerButton.getAttribute('data-value');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
element.dispatchEvent(new CustomEvent('alphavalueclicked', {
|
|
|
|
cancelable: false,
|
|
|
|
detail: {
|
|
|
|
value
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
function onAlphaPickerClick(e) {
|
|
|
|
const alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (alphaPickerButton) {
|
|
|
|
const value = alphaPickerButton.getAttribute('data-value');
|
|
|
|
if ((this._currentValue || '').toUpperCase() === value.toUpperCase()) {
|
|
|
|
this.value(null, true);
|
|
|
|
} else {
|
|
|
|
this.value(value, true);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
function onAlphaPickerFocusIn(e) {
|
|
|
|
if (alphaFocusTimeout) {
|
|
|
|
clearTimeout(alphaFocusTimeout);
|
|
|
|
alphaFocusTimeout = null;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
const alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton');
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (alphaPickerButton) {
|
|
|
|
alphaFocusedElement = alphaPickerButton;
|
2020-07-25 23:38:42 +02:00
|
|
|
alphaFocusTimeout = setTimeout(onAlphaFocusTimeout, 600);
|
2020-06-12 01:09:35 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
function onItemsFocusIn(e) {
|
|
|
|
const item = dom.parentWithClass(e.target, itemClass);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (item) {
|
|
|
|
const prefix = item.getAttribute('data-prefix');
|
|
|
|
if (prefix && prefix.length) {
|
|
|
|
itemFocusValue = prefix[0];
|
|
|
|
if (itemFocusTimeout) {
|
|
|
|
clearTimeout(itemFocusTimeout);
|
|
|
|
}
|
|
|
|
itemFocusTimeout = setTimeout(onItemFocusTimeout, 100);
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
this.enabled = function (enabled) {
|
|
|
|
if (enabled) {
|
|
|
|
if (itemsContainer) {
|
|
|
|
itemsContainer.addEventListener('focus', onItemsFocusIn, true);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (options.mode === 'keyboard') {
|
|
|
|
element.addEventListener('click', onAlphaPickerInKeyboardModeClick);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.valueChangeEvent !== 'click') {
|
|
|
|
element.addEventListener('focus', onAlphaPickerFocusIn, true);
|
|
|
|
} else {
|
|
|
|
element.addEventListener('click', onAlphaPickerClick.bind(this));
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
} else {
|
2020-06-12 01:09:35 +03:00
|
|
|
if (itemsContainer) {
|
|
|
|
itemsContainer.removeEventListener('focus', onItemsFocusIn, true);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
element.removeEventListener('click', onAlphaPickerInKeyboardModeClick);
|
|
|
|
element.removeEventListener('focus', onAlphaPickerFocusIn, true);
|
|
|
|
element.removeEventListener('click', onAlphaPickerClick.bind(this));
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2020-06-12 01:09:35 +03:00
|
|
|
};
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
render(element, options);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
this.enabled(true);
|
|
|
|
this.visible(true);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
value(value, applyValue) {
|
|
|
|
const element = this.options.element;
|
|
|
|
let btn;
|
|
|
|
let selected;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (value !== undefined) {
|
|
|
|
if (value != null) {
|
|
|
|
value = value.toUpperCase();
|
|
|
|
this._currentValue = value;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (this.options.mode !== 'keyboard') {
|
|
|
|
selected = element.querySelector(`.${selectedButtonClass}`);
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
try {
|
|
|
|
btn = element.querySelector(`.alphaPickerButton[data-value='${value}']`);
|
|
|
|
} catch (err) {
|
2020-07-02 12:57:29 +09:00
|
|
|
console.error('error in querySelector:', err);
|
2020-06-12 01:09:35 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (btn && btn !== selected) {
|
|
|
|
btn.classList.add(selectedButtonClass);
|
|
|
|
}
|
|
|
|
if (selected && selected !== btn) {
|
|
|
|
selected.classList.remove(selectedButtonClass);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2020-06-12 01:09:35 +03:00
|
|
|
} else {
|
|
|
|
this._currentValue = value;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
selected = element.querySelector(`.${selectedButtonClass}`);
|
|
|
|
if (selected) {
|
2019-01-10 15:39:37 +03:00
|
|
|
selected.classList.remove(selectedButtonClass);
|
|
|
|
}
|
|
|
|
}
|
2020-06-12 01:09:35 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
if (applyValue) {
|
|
|
|
element.dispatchEvent(new CustomEvent('alphavaluechanged', {
|
|
|
|
cancelable: false,
|
|
|
|
detail: {
|
|
|
|
value
|
|
|
|
}
|
|
|
|
}));
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
return this._currentValue;
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
on(name, fn) {
|
|
|
|
const element = this.options.element;
|
|
|
|
element.addEventListener(name, fn);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
off(name, fn) {
|
|
|
|
const element = this.options.element;
|
|
|
|
element.removeEventListener(name, fn);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
visible(visible) {
|
|
|
|
const element = this.options.element;
|
|
|
|
element.style.visibility = visible ? 'visible' : 'hidden';
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
values() {
|
|
|
|
const element = this.options.element;
|
|
|
|
const elems = element.querySelectorAll('.alphaPickerButton');
|
|
|
|
const values = [];
|
|
|
|
for (let i = 0, length = elems.length; i < length; i++) {
|
|
|
|
values.push(elems[i].getAttribute('data-value'));
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
return values;
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
focus() {
|
|
|
|
const element = this.options.element;
|
|
|
|
focusManager.autoFocus(element, true);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
destroy() {
|
|
|
|
const element = this.options.element;
|
|
|
|
this.enabled(false);
|
|
|
|
element.classList.remove('focuscontainer-x');
|
|
|
|
this.options = null;
|
|
|
|
}
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-06-12 01:09:35 +03:00
|
|
|
/* eslint-enable indent */
|
|
|
|
export default AlphaPicker;
|