@randstad-design/orbit-multitheme
Version:
multitheme Front-end code based on Randstad Human Forward components
173 lines (157 loc) • 4.57 kB
JavaScript
/**
* card.js
* show and hide backside information
*
*/
import ElementHelpers from '../helpers/element-helpers';
/**
* Declare constants
*/
const attributeBase = 'data-rs-card';
export class Card {
constructor(element) {
this.element = element;
this.initVariables();
this.addEventHandlers();
}
/**
* Declare attribute constants
*/
get attributes() {
return {
showBackSideCard: `${attributeBase}-show-backside`,
hideBackSideCard: `${attributeBase}-hide-backside`,
selectAllCards: `li[${attributeBase}]`
};
}
/**
* Declare classes
*/
get classes() {
return {
backsideActive: 'cards__item--backside-active',
animate: 'cards__item--animate'
};
}
/**
* Initialise variables
*/
initVariables() {
this.showBackSideCard = ElementHelpers.getElementByAttributeWithinElement(
this.element,
this.attributes.showBackSideCard
);
this.hideBackSideCard = ElementHelpers.getElementByAttributeWithinElement(
this.element,
this.attributes.hideBackSideCard
);
this.listParent = this.element.closest('ul');
this.selectAllCards = this.listParent.querySelectorAll(
this.attributes.selectAllCards
);
}
/**
* Add event handlers
*/
addEventHandlers() {
['click', 'keydown'].forEach((evt) => {
this.showBackSideCard &&
this.showBackSideCard.addEventListener(evt, (e) => {
if (
(e.type === 'keydown' && e.keyCode === 13) ||
e.type === 'click'
) {
this.setCardHeights(true);
}
});
this.hideBackSideCard &&
this.hideBackSideCard.addEventListener(evt, (e) => {
if (
(e.type === 'keydown' && e.keyCode === 13) ||
e.type === 'click'
) {
this.setCardHeights();
}
});
});
window.addEventListener('resize', () => {
this.resizeCards();
});
}
/**
* Check if slick slider is active and parent DIV exists
* @param element - element containing the card
*/
slickSliderActive(element) {
return (
element.hasAttribute('data-rs-carousel-card') &&
element.parentElement.tagName === 'DIV'
);
}
removeAnimationAndHeight() {
this.element.classList.remove(this.classes.animate);
this.element.style.removeProperty('height');
}
/**
* set fixed heights for the backside-card to keep all card-heights in sync
* @param show - boolean
*/
setCardHeights(show) {
if (show) {
const rect = this.element.getBoundingClientRect();
this.selectAllCards.forEach((card) => {
//overwrite 'height:100%' set for slick-slider, otherwise different heights appear when backside is shown
this.slickSliderActive(card)
? (card.parentElement.style.height = `${rect.height}px`)
: '';
if (
card !== this.element &&
card.classList.contains(this.classes.backsideActive)
) {
card.classList.remove(this.classes.backsideActive);
card.classList.add(this.classes.animate);
setTimeout(() => card.classList.remove(this.classes.animate), 100);
}
});
this.element.setAttribute('aria-expanded', true);
this.element.style.height = `${rect.height}px`;
this.element.classList.add(this.classes.backsideActive);
this.hideBackSideCard.setAttribute('tabindex', '0');
this.hideBackSideCard.previousElementSibling.setAttribute(
'tabindex',
'0'
);
this.element;
} else {
this.selectAllCards.forEach((card) => {
this.slickSliderActive(card)
? card.parentElement.style.removeProperty('height')
: '';
});
this.element.setAttribute('aria-expanded', false);
this.element.classList.remove(this.classes.backsideActive);
this.element.classList.add(this.classes.animate);
this.hideBackSideCard.setAttribute('tabindex', '-1');
this.hideBackSideCard.previousElementSibling.setAttribute(
'tabindex',
'-1'
);
// set tabindex to -1
setTimeout(this.removeAnimationAndHeight.bind(this), 100);
}
}
resizeCards() {
this.selectAllCards.forEach((card) => {
this.slickSliderActive(card)
? card.parentElement.style.removeProperty('height')
: '';
});
this.element.classList.remove(this.classes.backsideActive);
}
/**
* Get selector
*/
static getSelector() {
return `[${attributeBase}]`;
}
}