class CustomAccordion extends HTMLElement { static get observedAttributes() { return ['title', 'initially-open']; } constructor() { super(); this.isOpen = this.getAttribute('initially-open') === 'true'; this.title = this.getAttribute('title') || 'Titre de l\'accordéon'; } connectedCallback() { this.attachShadow({ mode: 'open' }); this.render(); this.initEventListeners(); } attributeChangedCallback(name, oldValue, newValue) { if (name === 'title' && oldValue !== newValue) { const titleElement = this.shadowRoot.querySelector('.accordion-title'); if (titleElement) { titleElement.textContent = newValue; } } if (name === 'initially-open' && oldValue !== newValue) { this.isOpen = newValue === 'true'; this.toggleContent(); } } render() { this.shadowRoot.innerHTML = `

${this.title}

`; // Initialiser les icônes Feather if (typeof feather !== 'undefined') { feather.replace(); } } initEventListeners() { const header = this.shadowRoot.querySelector('#accordionHeader'); const icon = this.shadowRoot.querySelector('#accordionIcon i'); header.addEventListener('click', () => { this.toggle(); // Animation de l'icône if (icon) { if (this.isOpen) { icon.setAttribute('data-feather', 'chevron-up'); } else { icon.setAttribute('data-feather', 'chevron-down'); } feather.replace(); } }); // Animation d'entrée setTimeout(() => { const item = this.shadowRoot.querySelector('.accordion-item'); item.style.opacity = '0'; item.style.transform = 'translateY(10px)'; item.style.transition = 'all 0.4s ease'; setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'translateY(0)'; }, 100); }, 100); } toggle() { this.isOpen = !this.isOpen; const content = this.shadowRoot.querySelector('#accordionContent'); const item = this.shadowRoot.querySelector('.accordion-item'); const icon = this.shadowRoot.querySelector('#accordionIcon i'); if (this.isOpen) { content.classList.add('open'); item.classList.add('open'); if (icon) { icon.style.transform = 'rotate(180deg)'; } // Émettre un événement personnalisé this.dispatchEvent(new CustomEvent('accordion-open', { detail: { title: this.title }, bubbles: true, composed: true })); } else { content.classList.remove('open'); item.classList.remove('open'); if (icon) { icon.style.transform = 'rotate(0)'; } this.dispatchEvent(new CustomEvent('accordion-close', { detail: { title: this.title }, bubbles: true, composed: true })); } } open() { if (!this.isOpen) { this.toggle(); } } close() { if (this.isOpen) { this.toggle(); } } // Méthode publique pour initialiser l'état init() { this.toggleContent(); } toggleContent() { const content = this.shadowRoot.querySelector('#accordionContent'); const item = this.shadowRoot.querySelector('.accordion-item'); if (this.isOpen) { content?.classList.add('open'); item?.classList.add('open'); } else { content?.classList.remove('open'); item?.classList.remove('open'); } } } customElements.define('custom-accordion', CustomAccordion);