UNPKG

@flexilla/accordion

Version:

A versatile and interactive accordion component for creating collapsible sections in web applications, conserving space and improving user experience

1 lines 6.73 kB
import{$ as e,$$ as t,$d as n,dispatchCustomEvent as r,observeChildrenChanges as i}from"@flexilla/utilities";import{collapseElement as a,expandElement as o,initCollapsible as s}from"@flexilla/collapsible";import{$$ as c,$d as l}from"@flexilla/utilities/selector";import{FlexillaManager as u}from"@flexilla/manager";const d=e=>{let t=n(`[data-accordion-trigger]`,e),r=n(`[data-accordion-content]`,e),i=e.hasAttribute(`data-default-open`);if(!(t instanceof HTMLButtonElement))throw Error(`The element does't have a Valid Trigger`);if(!(r instanceof HTMLDivElement))throw Error(`No Valid Content Element`);return{accordionTriggerElement:t,accordionContentElement:r,accordionItemValue:e.getAttribute(`data-accordion-value`)??``,isItemExpanded:t.getAttribute(`aria-expanded`)===`true`,defaultOpened:i}},f=(e,t,n)=>{let r=c(`:scope > [data-accordion-item]`,n),i=e.parentElement;if(!r.includes(i))return null;let a=r.indexOf(i),o=l(`:scope > [data-accordion-trigger]`,r[t?a-1:a+1]??(t?r[r.length-1]:r[0]));return o instanceof HTMLElement?o:null},p=(e,t)=>{if(!(document.activeElement instanceof HTMLElement))return;let n=document.activeElement,r=n.parentElement;if(!(!n.matches(`[data-accordion-trigger]`)||!r?.matches(`[data-accordion-item]`)||r.parentElement!==t)&&(e.key===`ArrowUp`||e.key===`ArrowDown`)){e.preventDefault();let r=f(n,e.key===`ArrowUp`,t);r&&r.focus()}},m=(e,t)=>{e.ariaExpanded=t===`open`?`true`:`false`},h=({collapsible:e,triggerElement:t,state:n,onInit:r})=>{r?(s(e,n),m(t,n)):n===`open`?(m(t,`open`),o(e)):(m(t,`close`),a(e))};var g=class a{accordionEl;options;items;eventListeners=[];cleanupObserver=null;constructor(n,r={}){if(this.accordionEl=typeof n==`string`?e(n):n,!this.accordionEl)throw Error(`Accordion element not found: ${typeof n==`string`?`No element matches selector "${n}"`:`Provided HTMLElement is null or undefined`}`);let i=u.getInstance(`accordion`,this.accordionEl);if(i)return i;this.options={accordionType:this.accordionEl.dataset.accordionType||r.accordionType||`single`,preventClosingAll:this.accordionEl.hasAttribute(`data-prevent-closing-all`)||r.preventClosingAll||!1,defaultValue:this.accordionEl.dataset.defaultValue||r.defaultValue||``,allowCloseFromContent:this.accordionEl.hasAttribute(`data-allow-close-from-content`)||r.allowCloseFromContent||!1,onChangeItem:r.onChangeItem},this.items=t(`[data-accordion-item]`,this.accordionEl).filter(e=>e.parentElement&&e.parentElement===this.accordionEl),this.initAccordion()}initAccordion(){if(!this.accordionEl)return;let{accordionType:e,defaultValue:t,preventClosingAll:r}=this.options,a=n(`[data-accordion-item][data-accordion-value="${t}"]`,this.accordionEl);if(e===`single`)this.options.preventClosingAll&&!(a instanceof HTMLElement)&&(a=this.items[0]),this.closeOther({current:a}),a&&this.setItemState(a,`open`,!0);else{this.closeAll(!0);let e=this.items.some(e=>e.getAttribute(`data-state`)===`open`);if(r&&!e)this.setItemState(this.items[0],`open`,!0);else{let e=this.items.filter(e=>e.getAttribute(`data-state`)===`open`);for(let t of e)this.setItemState(t,`open`,!0)}}this.addEventListeners(),this.accordionEl.addEventListener(`keydown`,this.handleKeyEvents),this.eventListeners.push({element:this.accordionEl,type:`keydown`,listener:this.handleKeyEvents}),u.register(`accordion`,this.accordionEl,this),this.cleanupObserver=i({container:this.accordionEl,attributeToWatch:`data-accordion-item`,onChildAdded:this.reload})}handleKeyEvents=e=>{p(e,this.accordionEl)};reload=()=>{this.cleanup(),this.items=t(`[data-accordion-item]`,this.accordionEl).filter(e=>e.parentElement&&e.parentElement===this.accordionEl),this.initAccordion()};destroy(){this.accordionEl&&(this.items.forEach(e=>{e&&e.hasAttribute(`data-state`)&&e.removeAttribute(`data-state`)}),this.eventListeners.forEach(({element:e,type:t,listener:n})=>{e&&e.removeEventListener&&e.removeEventListener(t,n)}),this.eventListeners=[],this.items=[],u.removeInstance(`accordion`,this.accordionEl),this.cleanupObserver&&=(this.cleanupObserver(),null))}setItemState(e,t,n){e.setAttribute(`data-state`,t);let{accordionContentElement:r,accordionTriggerElement:i}=d(e);h({collapsible:r,triggerElement:i,state:t,onInit:n})}closeOther({current:e,onInit:t}){this.items.forEach(n=>{n!==e&&(t&&this.options.accordionType===`multiple`&&n.hasAttribute(`data-default-open`)?this.setItemState(n,`open`):this.setItemState(n,`close`))})}closeAll(e){this.closeOther({onInit:e})}dispatchedEvent(e){let{accordionContentElement:t,accordionTriggerElement:n,isItemExpanded:i,accordionItemValue:a}=d(e);this.options.onChangeItem&&this.options.onChangeItem({expandedItem:{accordionItem:this.accordionEl,trigger:n,content:t,value:a,isExpanded:i}}),r(this.accordionEl,`change-item`,{targetElement:{trigger:n,content:t,isExpanded:i},items:this.items})}triggerItemState=(e,t,n)=>{this.options.preventClosingAll&&(this.options.accordionType===`single`&&n||this.options.accordionType===`multiple`&&this.items.filter(e=>e.getAttribute(`data-state`)===`open`).length===1&&n)||(this.setItemState(e,t),this.options.accordionType===`single`&&this.closeOther({current:e}),this.dispatchedEvent(e))};addEventListeners(){this.items.forEach(t=>{let n=e(`[data-accordion-trigger]`,t),r=e(`[data-accordion-content]`,t),i=()=>this.triggerItemState(t,`close`,!0),a=e=>{e.preventDefault();let n=t.getAttribute(`data-state`)===`open`,r=n?`close`:`open`;this.triggerItemState(t,r,n)};n&&(n.addEventListener(`click`,a),this.eventListeners.push({element:n,type:`click`,listener:a})),this.options.allowCloseFromContent&&r&&(r.addEventListener(`click`,i),this.eventListeners.push({element:r,type:`click`,listener:i}))})}show(e){let t=n(`[data-accordion-item][data-accordion-value="${e}"]`,this.accordionEl);t&&t.getAttribute(`data-state`)!==`open`&&(this.options.accordionType===`single`&&this.closeOther({current:t}),this.setItemState(t,`open`),this.dispatchedEvent(t))}hide(e){let t=n(`[data-accordion-item][data-accordion-value="${e}"]`,this.accordionEl);if(t&&t.getAttribute(`data-state`)===`open`){if(this.options.preventClosingAll){let e=this.items.filter(e=>e.getAttribute(`data-state`)===`open`);if(e.length===1&&t===e[0])return}this.setItemState(t,`close`),this.dispatchedEvent(t)}}cleanup=()=>{this.accordionEl&&(this.items.forEach(e=>{e&&e.hasAttribute(`data-state`)&&e.removeAttribute(`data-state`)}),this.eventListeners.forEach(({element:e,type:t,listener:n})=>{e&&e.removeEventListener&&e.removeEventListener(t,n)}),this.cleanupObserver&&=(this.cleanupObserver(),null),this.eventListeners=[],this.items=[],u.removeInstance(`accordion`,this.accordionEl))};static autoInit=(e=`[data-fx-accordion]`)=>{let n=t(e,document.documentElement);for(let e of n)new a(e)};static init=(e,t={})=>new a(e,t)};export{g as Accordion};