Newer
Older
import { Component, Prop, State, Element, h } from '@stencil/core';
@Component({
tag: 'hy-accordion-item',
styleUrl: 'accordion-item.scss',
shadow: false
})
export class AccordionItem {
@State() ready: boolean = false;
componentDidLoad() {
this.ready = true;
}
function collapseSection(element) {
element.style.height = 0 + 'px';
element.setAttribute('data-collapsed', 'true');
}
function expandSection(element) {
element.style.height = element.scrollHeight + 'px';
element.setAttribute('data-collapsed', 'false');
}
if (this.ready && containerId.length > 0) {
document.querySelectorAll(`#${containerId}`).forEach(function (accordion) {
const allowMultiple = accordion.hasAttribute('data-allow-multiple');
const allowToggle = (allowMultiple) ? allowMultiple : accordion.hasAttribute('data-allow-toggle');
const triggers = Array.prototype.slice.call(accordion.querySelectorAll('.hy-accordion__button'));
accordion.addEventListener('click', function (event) {
let target = event.target as HTMLTextAreaElement;
if (target && target.classList.contains('hy-accordion__button')) {
let targetParent = target.closest('.hy-accordion__item');
let targetContent = targetParent.querySelectorAll('.hy-accordion__content')[0];
const isExpanded = target.getAttribute('aria-expanded') == 'true';
const active = accordion.querySelector('[aria-expanded="true"]');
if (!allowMultiple && active && active !== target) {
active.setAttribute('aria-expanded', 'false');
collapseSection(targetContent);
if (targetParent.classList.contains('hy-accordion__item__is-open')) {
targetParent.classList.remove('hy-accordion__item__is-open');
}
accordion.querySelector(`#${active.getAttribute('aria-controls')}`).setAttribute('aria-hidden', 'true');
if (!allowToggle) {
active.removeAttribute('aria-disabled');
}
if (!isExpanded) {
expandSection(targetContent);
target.setAttribute('aria-expanded', 'true');
targetParent.classList.add('hy-accordion__item__is-open');
accordion.querySelector(`#${target.getAttribute('aria-controls')}`).setAttribute('aria-hidden', 'false');
if (!allowToggle) {
target.setAttribute('aria-disabled', 'true');
}
else if (allowToggle && isExpanded) {
target.setAttribute('aria-expanded', 'false');
collapseSection(targetContent);
if (targetParent.classList.contains('hy-accordion__item__is-open')) {
targetParent.classList.remove('hy-accordion__item__is-open');
}
accordion.querySelector(`#${target.getAttribute('aria-controls')}`).setAttribute('aria-hidden', 'true');
if (accordion) {
accordion.addEventListener('keydown', function (event: KeyboardEvent) {
const target = event.target as HTMLButtonElement;
const key = event.which.toString();
if (target.classList.contains('hy-accordion__button')) {
// Up/ Down arrow and Control + Page Up/ Page Down keyboard operations
// 38 = Up, 40 = Down
if (key.match(/38|40/) || ctrlModifier) {
const index = triggers.indexOf(target);
const direction = (key.match(/34|40/)) ? 1 : -1;
const length = triggers.length;
const newIndex = (index + length + direction) % length;
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
triggers[newIndex].focus();
event.preventDefault();
}
else if (key.match(/35|36/)) {
// 35 = End, 36 = Home keyboard operations
switch (key) {
// Go to first accordion
case '36':
triggers[0].focus();
break;
// Go to last accordion
case '35':
triggers[triggers.length - 1].focus();
break;
}
event.preventDefault();
}
}
});
accordion.querySelectorAll('.hy-accordion__button').forEach(function (trigger) {
trigger.addEventListener('focus', function () {
trigger.classList.add('focus');
});
trigger.addEventListener('blur', function () {
trigger.classList.remove('focus');
});
});
});
}
const classAttributes = ["hy-accordion__item"];
const titleAsId = this.accordiontitle.toLowerCase().replace(/\W/g,'-');
return (
<div class={classAttributes.join(" ")}>
<button
aria-expanded="false"
aria-controls={`${titleAsId}--content`}
class="hy-accordion__button"
id={`${titleAsId}--title`}
>
<span class="hy-accordion--heading__icon">
<hy-icon icon={'hy-icon-caret-down'} size={16} />
</span>
{ this.accordiontitle }
</button>
<div
aria-labelledBy={`${titleAsId}--title`}
class="hy-accordion__content"
id={`${titleAsId}--content`}
role="region"
>
<div class="hy-accordion__content--inner-wrapper">
<slot></slot>
</div>