@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
95 lines (94 loc) • 3.6 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var ESLA11yGroup_1;
import { ExportNs } from '../../esl-utils/environment/export-ns';
import { ESLBaseElement } from '../../esl-base-element/core';
import { attr, boolAttr, listen } from '../../esl-utils/decorators';
import { ESLTraversingQuery } from '../../esl-traversing-query/core';
import { ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP } from '../../esl-utils/dom/keys';
/**
* ESLA11yGroup component
* @author Julia Murashko
*
* ESLA11yGroup - helper custom element that adds a11y group behavior to targets.
*/
let ESLA11yGroup = ESLA11yGroup_1 = class ESLA11yGroup extends ESLBaseElement {
/** @returns HTMLElement root element of the group */
get $root() {
return this.parentElement;
}
/** @returns HTMLElement[] targets of the group */
get $targets() {
if (!this.$root)
return [];
return ESLTraversingQuery.all(this.targets, this.$root);
}
_onKeydown(e) {
const target = e.target;
if (!this.$targets.includes(target))
return;
const groupTarget = this.constructor.KEY_MAP[e.key];
if (!groupTarget)
return;
this.goTo(groupTarget, target);
e.preventDefault();
}
/** Go to the target from the passed element or currently focused target by default */
goTo(target, from = this.current()) {
if (!from)
return;
const targetEl = this[target](from);
if (!targetEl)
return;
targetEl.focus({ preventScroll: this.preventScroll });
this.activateSelected && targetEl.click();
}
/** @returns HTMLElement next target fot trigger */
next(trigger) {
const triggers = this.$targets;
const index = triggers.indexOf(trigger);
return triggers[(index + 1) % triggers.length];
}
/** @returns HTMLElement previous target fot trigger */
prev(trigger) {
const triggers = this.$targets;
const index = triggers.indexOf(trigger);
return triggers[(index - 1 + triggers.length) % triggers.length];
}
/** @returns HTMLElement currently focused element from targets */
current() {
const $active = document.activeElement;
return this.$targets.includes($active) ? $active : null;
}
};
ESLA11yGroup.is = 'esl-a11y-group';
/** Mapping of the keyboard keys to {@link GroupTarget} */
ESLA11yGroup.KEY_MAP = {
[ARROW_UP]: 'prev',
[ARROW_LEFT]: 'prev',
[ARROW_DOWN]: 'next',
[ARROW_RIGHT]: 'next'
};
__decorate([
attr({ defaultValue: '::child' })
], ESLA11yGroup.prototype, "targets", void 0);
__decorate([
boolAttr({})
], ESLA11yGroup.prototype, "activateSelected", void 0);
__decorate([
boolAttr({})
], ESLA11yGroup.prototype, "preventScroll", void 0);
__decorate([
listen({
event: 'keydown',
target: (target) => target.$root
})
], ESLA11yGroup.prototype, "_onKeydown", null);
ESLA11yGroup = ESLA11yGroup_1 = __decorate([
ExportNs('A11yGroup')
], ESLA11yGroup);
export { ESLA11yGroup };