@randstad-design/orbit-multitheme
Version:
multitheme Front-end code based on Randstad Human Forward components
156 lines (141 loc) • 3.63 kB
JavaScript
/**
* toast.js
* show toast and handle click + fadeout
*
*/
import ElementHelpers from '../helpers/element-helpers';
import trapFocus from '../helpers/trapFocus';
/**
* Declare constants
*/
const attributeBase = 'data-rs-toast';
export class Toast {
constructor(element) {
this.element = element;
this.id = this.element.getAttribute(attributeBase);
this.triggerElement = ElementHelpers.getElementByAttribute(
this.attributes.show,
this.id
);
this.closeElement = ElementHelpers.getElementByAttribute(
'data-rs-closable',
`${attributeBase}-${this.id}`
);
this.addEventHandlers();
this.closeTimeout;
this.toastOpen;
this.keystroke = 0;
}
/**
* Declare attribute constants
*/
get attributes() {
return {
show: `${attributeBase}-show`
};
}
/**
* Declare classes
*/
get classes() {
return {
image: `${attributeBase}-image`,
show: 'show',
closableClosed: 'closable--closed',
toastActive: 'toast--active'
};
}
/**
* Add event handlers
*/
addEventHandlers() {
// handle click trigger element
this.triggerElement.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault();
this.show();
this.destroyCloseTimeout();
this.createCloseTimeOut();
});
this.closeElement.addEventListener('click', () => {
this.keystroke = 0;
});
this.element.addEventListener('mouseenter', () => {
this.destroyCloseTimeout();
});
this.element.addEventListener('mouseleave', () => {
this.closeTimeout = this.createCloseTimeOut();
});
document.addEventListener('keydown', (keydownEvent) => {
this.handleButtonKeys(keydownEvent);
});
this.closeElement.addEventListener('click', () => {
this.keystroke = 0;
this.toastOpen = false;
});
}
show() {
this.toastOpen = true;
this.element.classList.remove(this.classes.closableClosed);
this.element.classList.add(this.classes.show);
this.element.classList.add(this.classes.toastActive);
}
hide() {
this.toastOpen = false;
this.element.classList.remove(this.classes.show);
this.element.classList.remove(this.classes.toastActive);
this.element.classList.add(this.classes.closableClosed);
this.keystroke = 0;
}
/**
* Create close time out - closes element if pointer is not on element
*/
createCloseTimeOut() {
this.closeTimeout = setTimeout(() => {
if (!ElementHelpers.isMouseOver(this.element)) {
this.hide();
}
}, 10000);
}
/**
* Handle button keys - handle key presses escape
*
* @param {Event} event - event triggered
*/
handleButtonKeys(event) {
if (event != null) {
switch (ElementHelpers.getKeyCodeOnKeyDownEvent(event)) {
case 'Tab':
trapFocus(event, this.element, this.toastOpen, this.keystroke);
if (this.toastOpen) {
this.keystroke++;
}
if (!this.toastOpen) {
this.keystroke = 0;
}
break;
case 'Escape':
if (this.toastOpen) {
this.hide();
if (this.triggerElement) {
this.triggerElement.focus();
}
}
if (!this.toastOpen) {
this.keystroke = 0;
}
}
}
}
/**
* Destroy close time out - closes element if pointer is not on element
*/
destroyCloseTimeout() {
clearTimeout(this.closeTimeout);
}
/**
* Get selector
*/
static getSelector() {
return `[${attributeBase}]`;
}
}