@travelopia/web-components 0.7.4 → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -298,10 +298,27 @@ export class TPLightboxNavItemElement extends HTMLElement {
298
298
  getIndex(): number;
299
299
  }
300
300
 
301
+ /**
302
+ * Internal dependencies.
303
+ */
304
+ import { TPLightboxElement } from './tp-lightbox';
301
305
  /**
302
306
  * TP Lightbox Nav.
303
307
  */
304
308
  export class TPLightboxNavElement extends HTMLElement {
309
+ /**
310
+ * Properties.
311
+ */
312
+ protected template: HTMLTemplateElement | null;
313
+ protected lightbox: TPLightboxElement | null;
314
+ /**
315
+ * Constructor.
316
+ */
317
+ constructor();
318
+ /**
319
+ * Set the template.
320
+ */
321
+ setTemplate(): void;
305
322
  }
306
323
 
307
324
  /**
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";class t extends HTMLElement{constructor(){var t,e,i;super(),this.currentTemplate=null,this.currentGroup="",this.allGroups=null,this.touchStartX=0,this.touchStartY=0,this.swipeThreshold=200,this.dialogElement=this.querySelector("dialog"),this.lightboxNavItems=this.querySelectorAll("tp-lightbox-nav-item"),null===(t=this.dialogElement)||void 0===t||t.addEventListener("click",this.handleDialogClick.bind(this)),null===(e=this.dialogElement)||void 0===e||e.addEventListener("touchstart",this.handleTouchStart.bind(this)),null===(i=this.dialogElement)||void 0===i||i.addEventListener("touchend",this.handleTouchEnd.bind(this))}static get observedAttributes(){return["open","index","total","close-on-overlay-click","loading"]}attributeChangedCallback(t="",e="",i=""){e!==i&&(this.dispatchEvent(new CustomEvent("change")),"index"===t&&this.triggerCurrentIndexTarget(),"open"!==t&&"index"!==t||this.updateNavCurrentItem())}get template(){return this.currentTemplate}set template(t){this.currentTemplate=t,this.dispatchEvent(new CustomEvent("template-set"));const e=this.querySelector("tp-lightbox-content");if(e)if(this.currentTemplate){const t=this.currentTemplate.content.cloneNode(!0);e.replaceChildren(t),this.dispatchEvent(new CustomEvent("content-change")),setTimeout((()=>{this.prepareImageLoading(),this.prepareNavigation()}),0)}else e.innerHTML=""}get group(){return this.currentGroup}set group(t){this.currentGroup=t}get currentIndex(){var t;return parseInt(null!==(t=this.getAttribute("index"))&&void 0!==t?t:"1")}set currentIndex(t){t<1&&(t=1),this.setAttribute("index",t.toString()),this.dispatchEvent(new CustomEvent("slide-set",{detail:{slideIndex:t}}))}triggerCurrentIndexTarget(){const t=this.getAllGroups();t&&t[this.currentIndex-1]&&t[this.currentIndex-1].trigger()}open(){const t=this.querySelector("dialog");t&&!t.open&&(""===this.group||this.allGroups||this.updateAllGroups(),t.showModal(),this.setAttribute("open","yes"))}close(){const t=this.querySelector("dialog");null==t||t.close(),this.removeAttribute("open"),this.allGroups=null}previous(){""!==this.group&&this.getAllGroups()&&this.currentIndex>1&&this.currentIndex--}next(){if(""===this.group)return;const t=this.getAllGroups();t&&this.currentIndex<t.length&&this.currentIndex++}updateAllGroups(t=null){if(t&&t.length)return this.allGroups=t,void this.setAttribute("total",this.allGroups.length.toString());this.allGroups=document.querySelectorAll(`tp-lightbox-trigger[group="${this.group}"]`),this.allGroups.length?this.setAttribute("total",this.allGroups.length.toString()):this.allGroups=null}getAllGroups(){return this.allGroups}prepareNavigation(){const t=this.querySelector("tp-lightbox-count");null==t||t.update();const e=this.querySelector("tp-lightbox-previous"),i=this.querySelector("tp-lightbox-next");if(!e&&!i)return;if(""===this.group)return null==e||e.setAttribute("disabled","yes"),void(null==i||i.setAttribute("disabled","yes"));const s=this.getAllGroups();if(!s)return null==e||e.setAttribute("disabled","yes"),void(null==i||i.setAttribute("disabled","yes"));this.currentIndex<=1?null==e||e.setAttribute("disabled","yes"):null==e||e.removeAttribute("disabled"),this.currentIndex<s.length?null==i||i.removeAttribute("disabled"):null==i||i.setAttribute("disabled","yes")}prepareImageLoading(){const t=this.querySelector("tp-lightbox-content");if(!t)return;const e=t.querySelectorAll("img");if(!e.length)return void this.removeAttribute("loading");this.setAttribute("loading","yes");let i=0;const s=e.length,r=()=>{i++,i===s&&this.removeAttribute("loading")};e.forEach((t=>{t.complete?r():t.addEventListener("load",r,{once:!0})}))}handleDialogClick(t){"yes"===this.getAttribute("close-on-overlay-click")&&this.querySelector("dialog")===t.target&&this.close()}handleTouchStart(t){"yes"===this.getAttribute("swipe")&&(this.touchStartX=t.touches[0].clientX,this.touchStartY=t.touches[0].clientY)}handleTouchEnd(t){var e;if("yes"!==this.getAttribute("swipe"))return;const i=t.changedTouches[0].clientX,s=t.changedTouches[0].clientY,r=i-this.touchStartX,n=s-this.touchStartY;Math.abs(r)>Math.abs(n)&&(this.swipeThreshold=Number(null!==(e=this.getAttribute("swipe-threshold"))&&void 0!==e?e:"200"),r>0?r<this.swipeThreshold&&this.previous():r<0&&r>-this.swipeThreshold&&this.next())}updateNavCurrentItem(){this.lightboxNavItems&&this.lightboxNavItems.forEach(((t,e)=>{this.currentIndex-1===e?t.setAttribute("current","yes"):t.removeAttribute("current")}))}}class e extends HTMLElement{}class i extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.close.bind(this))}close(){const t=this.closest("tp-lightbox");t&&setTimeout((()=>{t.close()}),0)}}class s extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.previous.bind(this))}previous(){if("yes"===this.getAttribute("disabled"))return;const t=this.closest("tp-lightbox");t&&setTimeout((()=>{t.previous()}),0)}}class r extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.next.bind(this))}next(){if("yes"===this.getAttribute("disabled"))return;const t=this.closest("tp-lightbox");t&&setTimeout((()=>{t.next()}),0)}}class n extends HTMLElement{static get observedAttributes(){return["format"]}get format(){var t;return null!==(t=this.getAttribute("format"))&&void 0!==t?t:"$current / $total"}set format(t){this.setAttribute("format",t)}attributeChangedCallback(){this.update()}update(){var t;const e=this.closest("tp-lightbox");if(!e)return;const i=e.currentIndex.toString(),s=null!==(t=e.getAttribute("total"))&&void 0!==t?t:"";this.innerHTML=this.format.replace("$current",i).replace("$total",s),this.setAttribute("current",i),this.setAttribute("total",s)}}class l extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.trigger.bind(this))}trigger(){var t;const e=this.getAttribute("lightbox"),i=this.querySelector("template");if(!e||!i)return;const s=document.querySelector(`#${e.toString()}`);if(!s)return;const r=null!==(t=this.getAttribute("group"))&&void 0!==t?t:"";setTimeout((()=>{if(s.template=i,s.group=r,""!==r){const t=document.querySelectorAll(`tp-lightbox-trigger[group="${r}"]`);t.length&&(s.updateAllGroups(t),t.forEach(((t,e)=>{this===t&&(s.currentIndex=e+1)})))}s.open()}),0)}}class o extends HTMLElement{}class u extends HTMLElement{constructor(){var t;super(),this.lightbox=this.closest("tp-lightbox"),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.handleClick.bind(this))}handleClick(){var t;this.lightbox&&(this.lightbox.currentIndex=null!==(t=Number(this.getIndex()))&&void 0!==t?t:1,this.lightbox.updateNavCurrentItem())}getIndex(){var t;if(!this.lightbox)return 0;const e=this.closest("tp-lightbox-nav");return Array.from(null!==(t=null==e?void 0:e.children)&&void 0!==t?t:[]).indexOf(this)+1}}customElements.define("tp-lightbox",t),customElements.define("tp-lightbox-content",e),customElements.define("tp-lightbox-close",i),customElements.define("tp-lightbox-previous",s),customElements.define("tp-lightbox-next",r),customElements.define("tp-lightbox-count",n),customElements.define("tp-lightbox-trigger",l),customElements.define("tp-lightbox-nav",o),customElements.define("tp-lightbox-nav-item",u)})();
1
+ (()=>{"use strict";class t extends HTMLElement{constructor(){var t,e,i;super(),this.currentTemplate=null,this.currentGroup="",this.allGroups=null,this.touchStartX=0,this.touchStartY=0,this.swipeThreshold=200,this.dialogElement=this.querySelector("dialog"),this.lightboxNavItems=this.querySelectorAll("tp-lightbox-nav-item"),null===(t=this.dialogElement)||void 0===t||t.addEventListener("click",this.handleDialogClick.bind(this)),null===(e=this.dialogElement)||void 0===e||e.addEventListener("touchstart",this.handleTouchStart.bind(this)),null===(i=this.dialogElement)||void 0===i||i.addEventListener("touchend",this.handleTouchEnd.bind(this))}static get observedAttributes(){return["open","index","total","close-on-overlay-click","loading"]}attributeChangedCallback(t="",e="",i=""){e!==i&&(this.dispatchEvent(new CustomEvent("change")),"index"===t&&this.triggerCurrentIndexTarget(),"open"!==t&&"index"!==t||this.updateNavCurrentItem())}get template(){return this.currentTemplate}set template(t){this.currentTemplate=t,this.dispatchEvent(new CustomEvent("template-set"));const e=this.querySelector("tp-lightbox-content");if(e)if(this.currentTemplate){const t=this.currentTemplate.content.cloneNode(!0);e.replaceChildren(t),this.dispatchEvent(new CustomEvent("content-change")),setTimeout((()=>{this.prepareImageLoading(),this.prepareNavigation()}),0)}else e.innerHTML=""}get group(){return this.currentGroup}set group(t){this.currentGroup=t}get currentIndex(){var t;return parseInt(null!==(t=this.getAttribute("index"))&&void 0!==t?t:"1")}set currentIndex(t){t<1&&(t=1),this.setAttribute("index",t.toString()),this.dispatchEvent(new CustomEvent("slide-set",{detail:{slideIndex:t}}))}triggerCurrentIndexTarget(){const t=this.getAllGroups();t&&t[this.currentIndex-1]&&t[this.currentIndex-1].trigger()}open(){const t=this.querySelector("dialog");t&&!t.open&&(""===this.group||this.allGroups||this.updateAllGroups(),t.showModal(),this.setAttribute("open","yes"))}close(){const t=this.querySelector("dialog");null==t||t.close(),this.removeAttribute("open"),this.allGroups=null}previous(){""!==this.group&&this.getAllGroups()&&this.currentIndex>1&&this.currentIndex--}next(){if(""===this.group)return;const t=this.getAllGroups();t&&this.currentIndex<t.length&&this.currentIndex++}updateAllGroups(t=null){if(t&&t.length)return this.allGroups=t,void this.setAttribute("total",this.allGroups.length.toString());this.allGroups=document.querySelectorAll(`tp-lightbox-trigger[group="${this.group}"]`),this.allGroups.length?this.setAttribute("total",this.allGroups.length.toString()):this.allGroups=null}getAllGroups(){return this.allGroups}prepareNavigation(){const t=this.querySelector("tp-lightbox-count");null==t||t.update();const e=this.querySelector("tp-lightbox-previous"),i=this.querySelector("tp-lightbox-next");if(!e&&!i)return;if(""===this.group)return null==e||e.setAttribute("disabled","yes"),void(null==i||i.setAttribute("disabled","yes"));const s=this.getAllGroups();if(!s)return null==e||e.setAttribute("disabled","yes"),void(null==i||i.setAttribute("disabled","yes"));this.currentIndex<=1?null==e||e.setAttribute("disabled","yes"):null==e||e.removeAttribute("disabled"),this.currentIndex<s.length?null==i||i.removeAttribute("disabled"):null==i||i.setAttribute("disabled","yes")}prepareImageLoading(){const t=this.querySelector("tp-lightbox-content");if(!t)return;const e=t.querySelectorAll("img");if(!e.length)return void this.removeAttribute("loading");this.setAttribute("loading","yes");let i=0;const s=e.length,r=()=>{i++,i===s&&this.removeAttribute("loading")};e.forEach((t=>{t.complete?r():t.addEventListener("load",r,{once:!0})}))}handleDialogClick(t){"yes"===this.getAttribute("close-on-overlay-click")&&this.querySelector("dialog")===t.target&&this.close()}handleTouchStart(t){"yes"===this.getAttribute("swipe")&&(this.touchStartX=t.touches[0].clientX,this.touchStartY=t.touches[0].clientY)}handleTouchEnd(t){var e;if("yes"!==this.getAttribute("swipe"))return;const i=t.changedTouches[0].clientX,s=t.changedTouches[0].clientY,r=i-this.touchStartX,l=s-this.touchStartY;Math.abs(r)>Math.abs(l)&&(this.swipeThreshold=Number(null!==(e=this.getAttribute("swipe-threshold"))&&void 0!==e?e:"200"),r>0?r<this.swipeThreshold&&this.previous():r<0&&r>-this.swipeThreshold&&this.next())}updateNavCurrentItem(){this.lightboxNavItems&&this.lightboxNavItems.forEach(((t,e)=>{this.currentIndex-1===e?t.setAttribute("current","yes"):t.removeAttribute("current")}))}}class e extends HTMLElement{}class i extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.close.bind(this))}close(){const t=this.closest("tp-lightbox");t&&setTimeout((()=>{t.close()}),0)}}class s extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.previous.bind(this))}previous(){if("yes"===this.getAttribute("disabled"))return;const t=this.closest("tp-lightbox");t&&setTimeout((()=>{t.previous()}),0)}}class r extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.next.bind(this))}next(){if("yes"===this.getAttribute("disabled"))return;const t=this.closest("tp-lightbox");t&&setTimeout((()=>{t.next()}),0)}}class l extends HTMLElement{static get observedAttributes(){return["format"]}get format(){var t;return null!==(t=this.getAttribute("format"))&&void 0!==t?t:"$current / $total"}set format(t){this.setAttribute("format",t)}attributeChangedCallback(){this.update()}update(){var t;const e=this.closest("tp-lightbox");if(!e)return;const i=e.currentIndex.toString(),s=null!==(t=e.getAttribute("total"))&&void 0!==t?t:"";this.innerHTML=this.format.replace("$current",i).replace("$total",s),this.setAttribute("current",i),this.setAttribute("total",s)}}class n extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.trigger.bind(this))}trigger(){var t;const e=this.getAttribute("lightbox"),i=this.querySelector("template");if(!e||!i)return;const s=document.querySelector(`#${e.toString()}`);if(!s)return;const r=null!==(t=this.getAttribute("group"))&&void 0!==t?t:"";setTimeout((()=>{if(s.template=i,s.group=r,""!==r){const t=document.querySelectorAll(`tp-lightbox-trigger[group="${r}"]`);t.length&&(s.updateAllGroups(t),t.forEach(((t,e)=>{this===t&&(s.currentIndex=e+1)})))}s.open()}),0)}}class o extends HTMLElement{constructor(){var t;super(),this.template=null,this.template=this.querySelector("template"),this.lightbox=this.closest("tp-lightbox"),null===(t=this.lightbox)||void 0===t||t.addEventListener("template-set",this.setTemplate.bind(this))}setTemplate(){var t,e;if(!this.template)return;const i=Number(null!==(e=null===(t=this.lightbox)||void 0===t?void 0:t.getAttribute("total"))&&void 0!==e?e:0);this.innerHTML="";for(let t=0;t<i;t++){const t=this.template.content.cloneNode(!0);this.appendChild(t)}}}class u extends HTMLElement{constructor(){var t;super(),this.lightbox=this.closest("tp-lightbox"),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.handleClick.bind(this))}handleClick(){var t;this.lightbox&&(this.lightbox.currentIndex=null!==(t=Number(this.getIndex()))&&void 0!==t?t:1,this.lightbox.updateNavCurrentItem())}getIndex(){var t;if(!this.lightbox)return 0;const e=this.closest("tp-lightbox-nav");return Array.from(null!==(t=null==e?void 0:e.children)&&void 0!==t?t:[]).indexOf(this)+1}}customElements.define("tp-lightbox",t),customElements.define("tp-lightbox-content",e),customElements.define("tp-lightbox-close",i),customElements.define("tp-lightbox-previous",s),customElements.define("tp-lightbox-next",r),customElements.define("tp-lightbox-count",l),customElements.define("tp-lightbox-trigger",n),customElements.define("tp-lightbox-nav",o),customElements.define("tp-lightbox-nav-item",u)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/lightbox/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/lightbox/tp-lightbox.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-content.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-close.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-previous.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-next.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-count.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-trigger.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-nav.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-nav-item.ts","webpack://@travelopia/web-components/./src/lightbox/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPLightboxContentElement } from './tp-lightbox-content';\nimport { TPLightboxPreviousElement } from './tp-lightbox-previous';\nimport { TPLightboxNextElement } from './tp-lightbox-next';\nimport { TPLightboxTriggerElement } from './tp-lightbox-trigger';\nimport { TPLightboxCountElement } from './tp-lightbox-count';\nimport { TPLightboxNavItemElement } from './tp-lightbox-nav-item';\n\n/**\n * TP Lightbox.\n */\nexport class TPLightboxElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected currentTemplate: HTMLTemplateElement | null = null;\n\tprotected currentGroup: string = '';\n\tprotected allGroups: NodeListOf<TPLightboxTriggerElement> | null = null;\n\tprotected touchStartX: number = 0;\n\tprotected touchStartY: number = 0;\n\tprotected swipeThreshold: number = 200;\n\tprotected dialogElement: HTMLDialogElement | null;\n\tprotected lightboxNavItems: NodeListOf<TPLightboxNavItemElement> | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Initialize\n\t\tthis.dialogElement = this.querySelector( 'dialog' );\n\t\tthis.lightboxNavItems = this.querySelectorAll( 'tp-lightbox-nav-item' );\n\n\t\t// Event listeners.\n\t\tthis.dialogElement?.addEventListener( 'click', this.handleDialogClick.bind( this ) );\n\t\tthis.dialogElement?.addEventListener( 'touchstart', this.handleTouchStart.bind( this ) );\n\t\tthis.dialogElement?.addEventListener( 'touchend', this.handleTouchEnd.bind( this ) );\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'open', 'index', 'total', 'close-on-overlay-click', 'loading' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Prevent redundant updates.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Trigger change event.\n\t\tthis.dispatchEvent( new CustomEvent( 'change' ) );\n\n\t\t// Trigger current index target if index has changed.\n\t\tif ( 'index' === name ) {\n\t\t\tthis.triggerCurrentIndexTarget();\n\t\t}\n\n\t\t// Trigger navigation update if open or index has changed.\n\t\tif ( 'open' === name || 'index' === name ) {\n\t\t\tthis.updateNavCurrentItem();\n\t\t}\n\t}\n\n\t/**\n\t * Get template.\n\t */\n\tget template(): HTMLTemplateElement | null {\n\t\t// Return current template.\n\t\treturn this.currentTemplate;\n\t}\n\n\t/**\n\t * Set template.\n\t *\n\t * @param {HTMLTemplateElement} template The template.\n\t */\n\tset template( template: HTMLTemplateElement | null ) {\n\t\t// Set the template.\n\t\tthis.currentTemplate = template;\n\t\tthis.dispatchEvent( new CustomEvent( 'template-set' ) );\n\n\t\t// Get lightbox content element.\n\t\tconst content: TPLightboxContentElement | null = this.querySelector( 'tp-lightbox-content' );\n\n\t\t// Check if we have a content.\n\t\tif ( ! content ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have a template.\n\t\tif ( this.currentTemplate ) {\n\t\t\t/**\n\t\t\t * We do, update content with template's content.\n\t\t\t * We do this rather than a string to avoid script injection.\n\t\t\t */\n\t\t\tconst templateContent: Node = this.currentTemplate.content.cloneNode( true );\n\t\t\tcontent.replaceChildren( templateContent );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'content-change' ) );\n\n\t\t\t// Prepare image loading.\n\t\t\tsetTimeout( (): void => {\n\t\t\t\t// We do, prepare image loading.\n\t\t\t\tthis.prepareImageLoading();\n\t\t\t\tthis.prepareNavigation();\n\t\t\t}, 0 );\n\t\t} else {\n\t\t\t// We don't, set content as empty.\n\t\t\tcontent.innerHTML = '';\n\t\t}\n\t}\n\n\t/**\n\t * Get current group.\n\t */\n\tget group(): string {\n\t\t// Return current group.\n\t\treturn this.currentGroup;\n\t}\n\n\t/**\n\t * Set current group.\n\t *\n\t * @param {string} group Group name.\n\t */\n\tset group( group: string ) {\n\t\t// Set current group.\n\t\tthis.currentGroup = group;\n\t}\n\n\t/**\n\t * Get current index.\n\t */\n\tget currentIndex(): number {\n\t\t// Return current index.\n\t\treturn parseInt( this.getAttribute( 'index' ) ?? '1' );\n\t}\n\n\t/**\n\t * Set current index.\n\t *\n\t * @param {number} index Current index.\n\t */\n\tset currentIndex( index: number ) {\n\t\t// Set current index.\n\t\tif ( index < 1 ) {\n\t\t\tindex = 1;\n\t\t}\n\n\t\t// Setting this attributes triggers a re-trigger.\n\t\tthis.setAttribute( 'index', index.toString() );\n\n\t\t// dispatch slide-set event.\n\t\tthis.dispatchEvent( new CustomEvent( 'slide-set', {\n\t\t\tdetail: {\n\t\t\t\tslideIndex: index,\n\t\t\t},\n\t\t} ) );\n\t}\n\n\t/**\n\t * Trigger the target that matches the current index within current group.\n\t */\n\ttriggerCurrentIndexTarget(): void {\n\t\t// Get all groups and check if current index exists within group.\n\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> | null = this.getAllGroups();\n\n\t\t// Bail early if we don't have groups.\n\t\tif ( ! allGroups || ! allGroups[ this.currentIndex - 1 ] ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Trigger element within group.\n\t\tallGroups[ this.currentIndex - 1 ].trigger();\n\t}\n\n\t/**\n\t * Open lightbox.\n\t */\n\topen(): void {\n\t\t// Get the dialog element.\n\t\tconst dialog: HTMLDialogElement | null = this.querySelector( 'dialog' );\n\n\t\t// Check if dialog exists or is already open.\n\t\tif ( ! dialog || dialog.open ) {\n\t\t\t// Yes it is, Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// First, take this opportunity to update all groups (if it wasn't set from the trigger).\n\t\tif ( '' !== this.group && ! this.allGroups ) {\n\t\t\tthis.updateAllGroups();\n\t\t}\n\n\t\t// Now, show the modal.\n\t\tdialog.showModal();\n\t\tthis.setAttribute( 'open', 'yes' );\n\t}\n\n\t/**\n\t * Close lightbox.\n\t */\n\tclose(): void {\n\t\t// Find and close the dialog.\n\t\tconst dialog: HTMLDialogElement | null = this.querySelector( 'dialog' );\n\t\tdialog?.close();\n\t\tthis.removeAttribute( 'open' );\n\n\t\t// Clear groups from memory.\n\t\tthis.allGroups = null;\n\t}\n\n\t/**\n\t * Navigate previous.\n\t */\n\tprevious(): void {\n\t\t// Check if we even have a group.\n\t\tif ( '' === this.group ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have elements within group.\n\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> | null = this.getAllGroups();\n\n\t\t// Bail early if we don't have groups.\n\t\tif ( ! allGroups ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Decrement the current index.\n\t\tif ( this.currentIndex > 1 ) {\n\t\t\tthis.currentIndex--;\n\t\t}\n\t}\n\n\t/**\n\t * Navigate next.\n\t */\n\tnext(): void {\n\t\t// Check if we even have a group.\n\t\tif ( '' === this.group ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have elements within group.\n\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> | null = this.getAllGroups();\n\n\t\t// Bail early if we don't have groups.\n\t\tif ( ! allGroups ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Increment the current index.\n\t\tif ( this.currentIndex < allGroups.length ) {\n\t\t\tthis.currentIndex++;\n\t\t}\n\t}\n\n\t/**\n\t * Update all groups and save it to memory.\n\t *\n\t * @param {NodeList} allGroups All groups.\n\t */\n\tupdateAllGroups( allGroups: NodeListOf<TPLightboxTriggerElement> | null = null ): void {\n\t\t// Update all groups.\n\t\tif ( allGroups && allGroups.length ) {\n\t\t\tthis.allGroups = allGroups;\n\t\t\tthis.setAttribute( 'total', this.allGroups.length.toString() );\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get all groups.\n\t\tthis.allGroups = document.querySelectorAll( `tp-lightbox-trigger[group=\"${ this.group }\"]` );\n\n\t\t// Update total.\n\t\tif ( ! this.allGroups.length ) {\n\t\t\tthis.allGroups = null;\n\t\t} else {\n\t\t\tthis.setAttribute( 'total', this.allGroups.length.toString() );\n\t\t}\n\t}\n\n\t/**\n\t * Get all groups from memory.\n\t */\n\tgetAllGroups(): NodeListOf<TPLightboxTriggerElement> | null {\n\t\t// Return all groups.\n\t\treturn this.allGroups;\n\t}\n\n\t/**\n\t * Prepare navigation.\n\t */\n\tprepareNavigation(): void {\n\t\t// Update counter.\n\t\tconst count: TPLightboxCountElement | null = this.querySelector( 'tp-lightbox-count' );\n\t\tcount?.update();\n\n\t\t// Get previous and next elements.\n\t\tconst previous: TPLightboxPreviousElement | null = this.querySelector( 'tp-lightbox-previous' );\n\t\tconst next: TPLightboxNextElement | null = this.querySelector( 'tp-lightbox-next' );\n\n\t\t// Bail early if we don't have either.\n\t\tif ( ! previous && ! next ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have a group.\n\t\tif ( '' === this.group ) {\n\t\t\tprevious?.setAttribute( 'disabled', 'yes' );\n\t\t\tnext?.setAttribute( 'disabled', 'yes' );\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have elements within the group.\n\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> | null = this.getAllGroups();\n\n\t\t// Disable if we don't have any.\n\t\tif ( ! allGroups ) {\n\t\t\tprevious?.setAttribute( 'disabled', 'yes' );\n\t\t\tnext?.setAttribute( 'disabled', 'yes' );\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Enable / disable previous navigation.\n\t\tif ( this.currentIndex <= 1 ) {\n\t\t\tprevious?.setAttribute( 'disabled', 'yes' );\n\t\t} else {\n\t\t\tprevious?.removeAttribute( 'disabled' );\n\t\t}\n\n\t\t// Enable / disable next navigation.\n\t\tif ( this.currentIndex < allGroups.length ) {\n\t\t\tnext?.removeAttribute( 'disabled' );\n\t\t} else {\n\t\t\tnext?.setAttribute( 'disabled', 'yes' );\n\t\t}\n\t}\n\n\t/**\n\t * Prepare image loading.\n\t */\n\tprepareImageLoading(): void {\n\t\t// Get lightbox content element.\n\t\tconst content: TPLightboxContentElement | null = this.querySelector( 'tp-lightbox-content' );\n\n\t\t// Bail early if we don't have content.\n\t\tif ( ! content ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Bail if there are no images within current content.\n\t\tconst images: NodeListOf<HTMLImageElement> = content.querySelectorAll( 'img' );\n\n\t\t// Exit early if there are no images.\n\t\tif ( ! images.length ) {\n\t\t\tthis.removeAttribute( 'loading' );\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Start off by setting the state as loading.\n\t\tthis.setAttribute( 'loading', 'yes' );\n\n\t\t// Prepare increment variables.\n\t\tlet counter: number = 0;\n\t\tconst totalImages: number = images.length;\n\n\t\t/**\n\t\t * Increment counter.\n\t\t */\n\t\tconst incrementLoadingCounter = (): void => {\n\t\t\t// Increment\n\t\t\tcounter++;\n\n\t\t\t// Remove loading attribute once all images have loaded.\n\t\t\tif ( counter === totalImages ) {\n\t\t\t\tthis.removeAttribute( 'loading' );\n\t\t\t}\n\t\t};\n\n\t\t// Check if images have loaded, else add an event listener.\n\t\timages.forEach( ( image: HTMLImageElement ): void => {\n\t\t\t// Check if image has loaded.\n\t\t\tif ( image.complete ) {\n\t\t\t\tincrementLoadingCounter();\n\t\t\t} else {\n\t\t\t\timage.addEventListener( 'load', incrementLoadingCounter, { once: true } );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Handle when the dialog is clicked.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\thandleDialogClick( e: MouseEvent ): void {\n\t\t// Close on overlay click.\n\t\tif (\n\t\t\t'yes' === this.getAttribute( 'close-on-overlay-click' ) &&\n\t\t\tthis.querySelector( 'dialog' ) === e.target\n\t\t) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/**\n\t * Handles the touch start event.\n\t *\n\t * @param { TouchEvent } evt The touch event.\n\t */\n\thandleTouchStart( evt: TouchEvent ): void {\n\t\t// Check if we should allow swiping?\n\t\tif ( 'yes' !== this.getAttribute( 'swipe' ) ) {\n\t\t\t// Nope.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the start points.\n\t\tthis.touchStartX = evt.touches[ 0 ].clientX;\n\t\tthis.touchStartY = evt.touches[ 0 ].clientY;\n\t}\n\n\t/**\n\t * Handles the touch end event.\n\t *\n\t * @param { TouchEvent } evt The touch event.\n\t */\n\thandleTouchEnd( evt: TouchEvent ): void {\n\t\t// Check if we should allow swiping?\n\t\tif ( 'yes' !== this.getAttribute( 'swipe' ) ) {\n\t\t\t// Nope.\n\t\t\treturn;\n\t\t}\n\n\t\t// Calculate the distances.\n\t\tconst touchEndX: number = evt.changedTouches[ 0 ].clientX;\n\t\tconst touchEndY: number = evt.changedTouches[ 0 ].clientY;\n\t\tconst swipeDistanceX: number = touchEndX - this.touchStartX;\n\t\tconst swipeDistanceY: number = touchEndY - this.touchStartY;\n\n\t\t// Is this horizontal swipe?\n\t\tconst isHorizontalSwipe = Math.abs( swipeDistanceX ) > Math.abs( swipeDistanceY );\n\n\t\t// Check if this was a horizontal swipe?\n\t\tif ( ! isHorizontalSwipe ) {\n\t\t\t// Bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Swipe settings\n\t\tthis.swipeThreshold = Number( this.getAttribute( 'swipe-threshold' ) ?? '200' );\n\n\t\t// Check if it's a right or left swipe.\n\t\tif ( swipeDistanceX > 0 ) {\n\t\t\t// Right-Swipe: Check if horizontal swipe distance is less than the threshold.\n\t\t\tif ( swipeDistanceX < this.swipeThreshold ) {\n\t\t\t\tthis.previous();\n\t\t\t}\n\t\t} else if ( swipeDistanceX < 0 ) {\n\t\t\t// Left-Swipe: Check if horizontal swipe distance is less than the threshold.\n\t\t\tif ( swipeDistanceX > -this.swipeThreshold ) {\n\t\t\t\tthis.next();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update current item in navigation.\n\t */\n\tupdateNavCurrentItem(): void {\n\t\t// Bail if we don't have nav items.\n\t\tif ( ! this.lightboxNavItems ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update current item.\n\t\tthis.lightboxNavItems.forEach( ( navItem: TPLightboxNavItemElement, index: number ): void => {\n\t\t\t// Update current attribute.\n\t\t\tif ( this.currentIndex - 1 === index ) {\n\t\t\t\tnavItem.setAttribute( 'current', 'yes' );\n\t\t\t} else {\n\t\t\t\tnavItem.removeAttribute( 'current' );\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * TP Lightbox Content.\n */\nexport class TPLightboxContentElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Close.\n */\nexport class TPLightboxCloseElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.close.bind( this ) );\n\t}\n\n\t/**\n\t * Close the lightbox.\n\t */\n\tclose(): void {\n\t\t// Get lightbox.\n\t\tconst lightbox: TPLightboxElement | null = this.closest( 'tp-lightbox' );\n\n\t\t// Check if we have a lightbox.\n\t\tif ( lightbox ) {\n\t\t\tsetTimeout( (): void => {\n\t\t\t\t// Close the lightbox.\n\t\t\t\tlightbox.close();\n\t\t\t}, 0 );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Close.\n */\nexport class TPLightboxPreviousElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.previous.bind( this ) );\n\t}\n\n\t/**\n\t * Navigate previous.\n\t */\n\tprevious(): void {\n\t\t// Check if we are disabled.\n\t\tif ( 'yes' === this.getAttribute( 'disabled' ) ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get lightbox.\n\t\tconst lightbox: TPLightboxElement | null = this.closest( 'tp-lightbox' );\n\n\t\t// Check if we have a lightbox.\n\t\tif ( lightbox ) {\n\t\t\tsetTimeout( (): void => {\n\t\t\t\t// Previous.\n\t\t\t\tlightbox.previous();\n\t\t\t}, 0 );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Close.\n */\nexport class TPLightboxNextElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.next.bind( this ) );\n\t}\n\n\t/**\n\t * Navigate next.\n\t */\n\tnext(): void {\n\t\t// Check if next is disabled.\n\t\tif ( 'yes' === this.getAttribute( 'disabled' ) ) {\n\t\t\t// Yes it is. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get lightbox.\n\t\tconst lightbox: TPLightboxElement | null = this.closest( 'tp-lightbox' );\n\n\t\t// Check if we have a lightbox.\n\t\tif ( lightbox ) {\n\t\t\tsetTimeout( (): void => {\n\t\t\t\t// Initiate next.\n\t\t\t\tlightbox.next();\n\t\t\t}, 0 );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Slider Count.\n */\nexport class TPLightboxCountElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} Observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'format' ];\n\t}\n\n\t/**\n\t * Get format.\n\t *\n\t * @return {string} Format.\n\t */\n\tget format(): string {\n\t\t// Get format.\n\t\treturn this.getAttribute( 'format' ) ?? '$current / $total';\n\t}\n\n\t/**\n\t * Set format.\n\t *\n\t * @param {string} format Format.\n\t */\n\tset format( format: string ) {\n\t\t// Set the 'format' attribute value.\n\t\tthis.setAttribute( 'format', format );\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t */\n\tattributeChangedCallback(): void {\n\t\t// On change of format attribute, update the component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update component.\n\t */\n\tupdate(): void {\n\t\t// Get lightbox.\n\t\tconst lightbox: TPLightboxElement | null = this.closest( 'tp-lightbox' );\n\n\t\t// Check if we have a lightbox.\n\t\tif ( ! lightbox ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current and total.\n\t\tconst current: string = lightbox.currentIndex.toString();\n\t\tconst total: string = lightbox.getAttribute( 'total' ) ?? '';\n\n\t\t// Update variables in format attribute.\n\t\tthis.innerHTML =\n\t\t\tthis.format\n\t\t\t\t.replace( '$current', current )\n\t\t\t\t.replace( '$total', total );\n\n\t\t// Update current and total attributes.\n\t\tthis.setAttribute( 'current', current );\n\t\tthis.setAttribute( 'total', total );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Trigger.\n */\nexport class TPLightboxTriggerElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.trigger.bind( this ) );\n\t}\n\n\t/**\n\t * Trigger the lightbox.\n\t */\n\ttrigger(): void {\n\t\t// Get lightbox ID and template.\n\t\tconst lightboxId: string | null = this.getAttribute( 'lightbox' );\n\t\tconst template: HTMLTemplateElement | null = this.querySelector( 'template' );\n\n\t\t// We can't proceed without them.\n\t\tif ( ! lightboxId || ! template ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the lightbox.\n\t\tconst lightbox: TPLightboxElement | null = document.querySelector( `#${ lightboxId.toString() }` );\n\n\t\t// Check to see if we have a lightbox.\n\t\tif ( ! lightbox ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check to see if we have a group.\n\t\tconst group: string = this.getAttribute( 'group' ) ?? '';\n\n\t\t// Yield to main thread.\n\t\tsetTimeout( (): void => {\n\t\t\t// Prepare lightbox.\n\t\t\tlightbox.template = template;\n\t\t\tlightbox.group = group;\n\n\t\t\t// Set index and group if we have them.\n\t\t\tif ( '' !== group ) {\n\t\t\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> = document.querySelectorAll( `tp-lightbox-trigger[group=\"${ group }\"]` );\n\n\t\t\t\t// Update all groups.\n\t\t\t\tif ( allGroups.length ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * We do this when we're opening a lightbox, or navigating.\n\t\t\t\t\t * This allows consumers to inject elements at any point.\n\t\t\t\t\t */\n\t\t\t\t\tlightbox.updateAllGroups( allGroups );\n\n\t\t\t\t\t// Get current trigger's index within the group.\n\t\t\t\t\tallGroups.forEach( ( triggerElement: TPLightboxTriggerElement, index: number ): void => {\n\t\t\t\t\t\t// Update current index.\n\t\t\t\t\t\tif ( this === triggerElement ) {\n\t\t\t\t\t\t\tlightbox.currentIndex = index + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// All done, lets open the lightbox.\n\t\t\tlightbox.open();\n\t\t}, 0 );\n\t}\n}\n","/**\n * TP Lightbox Nav.\n */\nexport class TPLightboxNavElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\nimport { TPLightboxNavElement } from './tp-lightbox-nav';\n\n/**\n * TP Lightbox Nav Item.\n */\nexport class TPLightboxNavItemElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected lightbox : TPLightboxElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.lightbox = this.closest( 'tp-lightbox' );\n\n\t\t// Get the nav-item button.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle when the button is clicked.\n\t */\n\thandleClick(): void {\n\t\t// Check if lightbox exists.\n\t\tif ( ! this.lightbox ) {\n\t\t\t// No its not! Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set current slide.\n\t\tthis.lightbox.currentIndex = Number( this.getIndex() ) ?? 1;\n\n\t\t// Update navigation current item.\n\t\tthis.lightbox.updateNavCurrentItem();\n\t}\n\n\t/**\n\t * Get index of this item inside the navigation.\n\t *\n\t * @return {number} Index.\n\t */\n\tgetIndex(): number {\n\t\t// Bail if no lightbox.\n\t\tif ( ! this.lightbox ) {\n\t\t\t// Exit.\n\t\t\treturn 0;\n\t\t}\n\n\t\t// No, find it in the navigation.\n\t\tconst lightboxNav: TPLightboxNavElement | null = this.closest( 'tp-lightbox-nav' );\n\n\t\t// Return index of this element considering the step value.\n\t\treturn ( Array.from( lightboxNav?.children ?? [] ).indexOf( this ) ) + 1;\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPLightboxElement } from './tp-lightbox';\nimport { TPLightboxContentElement } from './tp-lightbox-content';\nimport { TPLightboxCloseElement } from './tp-lightbox-close';\nimport { TPLightboxPreviousElement } from './tp-lightbox-previous';\nimport { TPLightboxNextElement } from './tp-lightbox-next';\nimport { TPLightboxCountElement } from './tp-lightbox-count';\nimport { TPLightboxTriggerElement } from './tp-lightbox-trigger';\nimport { TPLightboxNavElement } from './tp-lightbox-nav';\nimport { TPLightboxNavItemElement } from './tp-lightbox-nav-item';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-lightbox', TPLightboxElement );\ncustomElements.define( 'tp-lightbox-content', TPLightboxContentElement );\ncustomElements.define( 'tp-lightbox-close', TPLightboxCloseElement );\ncustomElements.define( 'tp-lightbox-previous', TPLightboxPreviousElement );\ncustomElements.define( 'tp-lightbox-next', TPLightboxNextElement );\ncustomElements.define( 'tp-lightbox-count', TPLightboxCountElement );\ncustomElements.define( 'tp-lightbox-trigger', TPLightboxTriggerElement );\ncustomElements.define( 'tp-lightbox-nav', TPLightboxNavElement );\ncustomElements.define( 'tp-lightbox-nav-item', TPLightboxNavItemElement );\n"],"names":["TPLightboxElement","HTMLElement","constructor","super","currentTemplate","currentGroup","allGroups","touchStartX","touchStartY","swipeThreshold","this","dialogElement","querySelector","lightboxNavItems","querySelectorAll","addEventListener","handleDialogClick","bind","handleTouchStart","handleTouchEnd","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","triggerCurrentIndexTarget","updateNavCurrentItem","template","content","templateContent","cloneNode","replaceChildren","setTimeout","prepareImageLoading","prepareNavigation","innerHTML","group","currentIndex","parseInt","getAttribute","index","setAttribute","toString","detail","slideIndex","getAllGroups","trigger","open","dialog","updateAllGroups","showModal","close","removeAttribute","previous","next","length","document","count","update","images","counter","totalImages","incrementLoadingCounter","forEach","image","complete","once","e","target","evt","touches","clientX","clientY","touchEndX","changedTouches","touchEndY","swipeDistanceX","swipeDistanceY","Math","abs","Number","navItem","TPLightboxContentElement","TPLightboxCloseElement","lightbox","closest","TPLightboxPreviousElement","TPLightboxNextElement","TPLightboxCountElement","format","current","total","replace","TPLightboxTriggerElement","lightboxId","triggerElement","TPLightboxNavElement","TPLightboxNavItemElement","handleClick","getIndex","lightboxNav","Array","from","children","indexOf","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/lightbox/index.js","mappings":"mBAaO,MAAMA,UAA0BC,YAgBtC,WAAAC,G,UAECC,QAdS,KAAAC,gBAA8C,KAC9C,KAAAC,aAAuB,GACvB,KAAAC,UAAyD,KACzD,KAAAC,YAAsB,EACtB,KAAAC,YAAsB,EACtB,KAAAC,eAAyB,IAYlCC,KAAKC,cAAgBD,KAAKE,cAAe,UACzCF,KAAKG,iBAAmBH,KAAKI,iBAAkB,wBAG7B,QAAlB,EAAAJ,KAAKC,qBAAa,SAAEI,iBAAkB,QAASL,KAAKM,kBAAkBC,KAAMP,OAC1D,QAAlB,EAAAA,KAAKC,qBAAa,SAAEI,iBAAkB,aAAcL,KAAKQ,iBAAiBD,KAAMP,OAC9D,QAAlB,EAAAA,KAAKC,qBAAa,SAAEI,iBAAkB,WAAYL,KAAKS,eAAeF,KAAMP,MAC7E,CAOA,6BAAWU,GAEV,MAAO,CAAE,OAAQ,QAAS,QAAS,yBAA0B,UAC9D,CASA,wBAAAC,CAA0BC,EAAe,GAAIC,EAAmB,GAAIC,EAAmB,IAEjFD,IAAaC,IAMlBd,KAAKe,cAAe,IAAIC,YAAa,WAGhC,UAAYJ,GAChBZ,KAAKiB,4BAID,SAAWL,GAAQ,UAAYA,GACnCZ,KAAKkB,uBAEP,CAKA,YAAIC,GAEH,OAAOnB,KAAKN,eACb,CAOA,YAAIyB,CAAUA,GAEbnB,KAAKN,gBAAkByB,EACvBnB,KAAKe,cAAe,IAAIC,YAAa,iBAGrC,MAAMI,EAA2CpB,KAAKE,cAAe,uBAGrE,GAAOkB,EAMP,GAAKpB,KAAKN,gBAAkB,CAK3B,MAAM2B,EAAwBrB,KAAKN,gBAAgB0B,QAAQE,WAAW,GACtEF,EAAQG,gBAAiBF,GACzBrB,KAAKe,cAAe,IAAIC,YAAa,mBAGrCQ,YAAY,KAEXxB,KAAKyB,sBACLzB,KAAK0B,mBAAmB,GACtB,E,MAGHN,EAAQO,UAAY,EAEtB,CAKA,SAAIC,GAEH,OAAO5B,KAAKL,YACb,CAOA,SAAIiC,CAAOA,GAEV5B,KAAKL,aAAeiC,CACrB,CAKA,gBAAIC,G,MAEH,OAAOC,SAAsC,QAA5B,EAAA9B,KAAK+B,aAAc,gBAAS,QAAI,IAClD,CAOA,gBAAIF,CAAcG,GAEZA,EAAQ,IACZA,EAAQ,GAIThC,KAAKiC,aAAc,QAASD,EAAME,YAGlClC,KAAKe,cAAe,IAAIC,YAAa,YAAa,CACjDmB,OAAQ,CACPC,WAAYJ,KAGf,CAKA,yBAAAf,GAEC,MAAMrB,EAAyDI,KAAKqC,eAG7DzC,GAAeA,EAAWI,KAAK6B,aAAe,IAMrDjC,EAAWI,KAAK6B,aAAe,GAAIS,SACpC,CAKA,IAAAC,GAEC,MAAMC,EAAmCxC,KAAKE,cAAe,UAGtDsC,IAAUA,EAAOD,OAMnB,KAAOvC,KAAK4B,OAAW5B,KAAKJ,WAChCI,KAAKyC,kBAIND,EAAOE,YACP1C,KAAKiC,aAAc,OAAQ,OAC5B,CAKA,KAAAU,GAEC,MAAMH,EAAmCxC,KAAKE,cAAe,UAC7DsC,SAAAA,EAAQG,QACR3C,KAAK4C,gBAAiB,QAGtB5C,KAAKJ,UAAY,IAClB,CAKA,QAAAiD,GAEM,KAAO7C,KAAK4B,OAM8C5B,KAAKqC,gBAS/DrC,KAAK6B,aAAe,GACxB7B,KAAK6B,cAEP,CAKA,IAAAiB,GAEC,GAAK,KAAO9C,KAAK4B,MAEhB,OAID,MAAMhC,EAAyDI,KAAKqC,eAG7DzC,GAMFI,KAAK6B,aAAejC,EAAUmD,QAClC/C,KAAK6B,cAEP,CAOA,eAAAY,CAAiB7C,EAAyD,MAEzE,GAAKA,GAAaA,EAAUmD,OAK3B,OAJA/C,KAAKJ,UAAYA,OACjBI,KAAKiC,aAAc,QAASjC,KAAKJ,UAAUmD,OAAOb,YAOnDlC,KAAKJ,UAAYoD,SAAS5C,iBAAkB,8BAA+BJ,KAAK4B,WAGzE5B,KAAKJ,UAAUmD,OAGrB/C,KAAKiC,aAAc,QAASjC,KAAKJ,UAAUmD,OAAOb,YAFlDlC,KAAKJ,UAAY,IAInB,CAKA,YAAAyC,GAEC,OAAOrC,KAAKJ,SACb,CAKA,iBAAA8B,GAEC,MAAMuB,EAAuCjD,KAAKE,cAAe,qBACjE+C,SAAAA,EAAOC,SAGP,MAAML,EAA6C7C,KAAKE,cAAe,wBACjE4C,EAAqC9C,KAAKE,cAAe,oBAG/D,IAAO2C,IAAcC,EAEpB,OAID,GAAK,KAAO9C,KAAK4B,MAKhB,OAJAiB,SAAAA,EAAUZ,aAAc,WAAY,YACpCa,SAAAA,EAAMb,aAAc,WAAY,QAOjC,MAAMrC,EAAyDI,KAAKqC,eAGpE,IAAOzC,EAKN,OAJAiD,SAAAA,EAAUZ,aAAc,WAAY,YACpCa,SAAAA,EAAMb,aAAc,WAAY,QAO5BjC,KAAK6B,cAAgB,EACzBgB,SAAAA,EAAUZ,aAAc,WAAY,OAEpCY,SAAAA,EAAUD,gBAAiB,YAIvB5C,KAAK6B,aAAejC,EAAUmD,OAClCD,SAAAA,EAAMF,gBAAiB,YAEvBE,SAAAA,EAAMb,aAAc,WAAY,MAElC,CAKA,mBAAAR,GAEC,MAAML,EAA2CpB,KAAKE,cAAe,uBAGrE,IAAOkB,EAEN,OAID,MAAM+B,EAAuC/B,EAAQhB,iBAAkB,OAGvE,IAAO+C,EAAOJ,OAIb,YAHA/C,KAAK4C,gBAAiB,WAOvB5C,KAAKiC,aAAc,UAAW,OAG9B,IAAImB,EAAkB,EACtB,MAAMC,EAAsBF,EAAOJ,OAK7BO,EAA0B,KAE/BF,IAGKA,IAAYC,GAChBrD,KAAK4C,gBAAiB,U,EAKxBO,EAAOI,SAAWC,IAEZA,EAAMC,SACVH,IAEAE,EAAMnD,iBAAkB,OAAQiD,EAAyB,CAAEI,MAAM,G,GAGpE,CAOA,iBAAApD,CAAmBqD,GAGjB,QAAU3D,KAAK+B,aAAc,2BAC7B/B,KAAKE,cAAe,YAAeyD,EAAEC,QAErC5D,KAAK2C,OAEP,CAOA,gBAAAnC,CAAkBqD,GAEZ,QAAU7D,KAAK+B,aAAc,WAMlC/B,KAAKH,YAAcgE,EAAIC,QAAS,GAAIC,QACpC/D,KAAKF,YAAc+D,EAAIC,QAAS,GAAIE,QACrC,CAOA,cAAAvD,CAAgBoD,G,MAEf,GAAK,QAAU7D,KAAK+B,aAAc,SAEjC,OAID,MAAMkC,EAAoBJ,EAAIK,eAAgB,GAAIH,QAC5CI,EAAoBN,EAAIK,eAAgB,GAAIF,QAC5CI,EAAyBH,EAAYjE,KAAKH,YAC1CwE,EAAyBF,EAAYnE,KAAKF,YAGtBwE,KAAKC,IAAKH,GAAmBE,KAAKC,IAAKF,KASjErE,KAAKD,eAAiByE,OAA8C,QAAtC,EAAAxE,KAAK+B,aAAc,0BAAmB,QAAI,OAGnEqC,EAAiB,EAEhBA,EAAiBpE,KAAKD,gBAC1BC,KAAK6C,WAEKuB,EAAiB,GAEvBA,GAAkBpE,KAAKD,gBAC3BC,KAAK8C,OAGR,CAKA,oBAAA5B,GAEQlB,KAAKG,kBAMZH,KAAKG,iBAAiBoD,SAAS,CAAEkB,EAAmCzC,KAE9DhC,KAAK6B,aAAe,IAAMG,EAC9ByC,EAAQxC,aAAc,UAAW,OAEjCwC,EAAQ7B,gBAAiB,U,GAG5B,ECpgBM,MAAM8B,UAAiCnF,aCKvC,MAAMoF,UAA+BpF,YAI3C,WAAAC,G,MAECC,QAG8B,QAA9B,EAAAO,KAAKE,cAAe,iBAAU,SAAEG,iBAAkB,QAASL,KAAK2C,MAAMpC,KAAMP,MAC7E,CAKA,KAAA2C,GAEC,MAAMiC,EAAqC5E,KAAK6E,QAAS,eAGpDD,GACJpD,YAAY,KAEXoD,EAASjC,OAAO,GACd,EAEL,EC1BM,MAAMmC,UAAkCvF,YAI9C,WAAAC,G,MAECC,QAG8B,QAA9B,EAAAO,KAAKE,cAAe,iBAAU,SAAEG,iBAAkB,QAASL,KAAK6C,SAAStC,KAAMP,MAChF,CAKA,QAAA6C,GAEC,GAAK,QAAU7C,KAAK+B,aAAc,YAEjC,OAID,MAAM6C,EAAqC5E,KAAK6E,QAAS,eAGpDD,GACJpD,YAAY,KAEXoD,EAAS/B,UAAU,GACjB,EAEL,EChCM,MAAMkC,UAA8BxF,YAI1C,WAAAC,G,MAECC,QAG8B,QAA9B,EAAAO,KAAKE,cAAe,iBAAU,SAAEG,iBAAkB,QAASL,KAAK8C,KAAKvC,KAAMP,MAC5E,CAKA,IAAA8C,GAEC,GAAK,QAAU9C,KAAK+B,aAAc,YAEjC,OAID,MAAM6C,EAAqC5E,KAAK6E,QAAS,eAGpDD,GACJpD,YAAY,KAEXoD,EAAS9B,MAAM,GACb,EAEL,EChCM,MAAMkC,UAA+BzF,YAM3C,6BAAWmB,GAEV,MAAO,CAAE,SACV,CAOA,UAAIuE,G,MAEH,OAAoC,QAA7B,EAAAjF,KAAK+B,aAAc,iBAAU,QAAI,mBACzC,CAOA,UAAIkD,CAAQA,GAEXjF,KAAKiC,aAAc,SAAUgD,EAC9B,CAKA,wBAAAtE,GAECX,KAAKkD,QACN,CAKA,MAAAA,G,MAEC,MAAM0B,EAAqC5E,KAAK6E,QAAS,eAGzD,IAAOD,EAEN,OAID,MAAMM,EAAkBN,EAAS/C,aAAaK,WACxCiD,EAAgD,QAAhC,EAAAP,EAAS7C,aAAc,gBAAS,QAAI,GAG1D/B,KAAK2B,UACJ3B,KAAKiF,OACHG,QAAS,WAAYF,GACrBE,QAAS,SAAUD,GAGtBnF,KAAKiC,aAAc,UAAWiD,GAC9BlF,KAAKiC,aAAc,QAASkD,EAC7B,ECjEM,MAAME,UAAiC9F,YAI7C,WAAAC,G,MAECC,QAG8B,QAA9B,EAAAO,KAAKE,cAAe,iBAAU,SAAEG,iBAAkB,QAASL,KAAKsC,QAAQ/B,KAAMP,MAC/E,CAKA,OAAAsC,G,MAEC,MAAMgD,EAA4BtF,KAAK+B,aAAc,YAC/CZ,EAAuCnB,KAAKE,cAAe,YAGjE,IAAOoF,IAAgBnE,EAEtB,OAID,MAAMyD,EAAqC5B,SAAS9C,cAAe,IAAKoF,EAAWpD,cAGnF,IAAO0C,EAEN,OAID,MAAMhD,EAA4C,QAA5B,EAAA5B,KAAK+B,aAAc,gBAAS,QAAI,GAGtDP,YAAY,KAMX,GAJAoD,EAASzD,SAAWA,EACpByD,EAAShD,MAAQA,EAGZ,KAAOA,EAAQ,CACnB,MAAMhC,EAAkDoD,SAAS5C,iBAAkB,8BAA+BwB,OAG7GhC,EAAUmD,SAKd6B,EAASnC,gBAAiB7C,GAG1BA,EAAU2D,SAAS,CAAEgC,EAA0CvD,KAEzDhC,OAASuF,IACbX,EAAS/C,aAAeG,EAAQ,E,KAOpC4C,EAASrC,MAAM,GACb,EACJ,ECrEM,MAAMiD,UAA6BjG,YAUzC,WAAAC,G,MAECC,QARS,KAAA0B,SAAuC,KAWhDnB,KAAKmB,SAAWnB,KAAKE,cAAe,YACpCF,KAAK4E,SAAW5E,KAAK6E,QAAS,eAGjB,QAAb,EAAA7E,KAAK4E,gBAAQ,SAAEvE,iBAAkB,eAAgBL,KAAKyF,YAAYlF,KAAMP,MACzE,CAKA,WAAAyF,G,QAEC,IAAOzF,KAAKmB,SAEX,OAID,MAAMuE,EAAclB,OAA8C,QAAtC,EAAa,QAAb,EAAAxE,KAAK4E,gBAAQ,eAAE7C,aAAc,gBAAS,QAAI,GAGtE/B,KAAK2B,UAAY,GAGjB,IAAM,IAAIgE,EAAI,EAAGA,EAAID,EAAaC,IAAM,CAEvC,MAAMlB,EAAUzE,KAAKmB,SAASC,QAAQE,WAAW,GAGjDtB,KAAK4F,YAAanB,E,CAEpB,EC7CM,MAAMoB,UAAiCtG,YAS7C,WAAAC,G,MAECC,QACAO,KAAK4E,SAAW5E,KAAK6E,QAAS,eAGA,QAA9B,EAAA7E,KAAKE,cAAe,iBAAU,SAAEG,iBAAkB,QAASL,KAAK8F,YAAYvF,KAAMP,MACnF,CAKA,WAAA8F,G,MAEQ9F,KAAK4E,WAMZ5E,KAAK4E,SAAS/C,aAAwC,QAAzB,EAAA2C,OAAQxE,KAAK+F,mBAAY,QAAI,EAG1D/F,KAAK4E,SAAS1D,uBACf,CAOA,QAAA6E,G,MAEC,IAAO/F,KAAK4E,SAEX,OAAO,EAIR,MAAMoB,EAA2ChG,KAAK6E,QAAS,mBAG/D,OAASoB,MAAMC,KAA2B,QAArB,EAAAF,aAAW,EAAXA,EAAaG,gBAAQ,QAAI,IAAKC,QAASpG,MAAW,CACxE,ECxCDqG,eAAeC,OAAQ,cAAehH,GACtC+G,eAAeC,OAAQ,sBAAuB5B,GAC9C2B,eAAeC,OAAQ,oBAAqB3B,GAC5C0B,eAAeC,OAAQ,uBAAwBxB,GAC/CuB,eAAeC,OAAQ,mBAAoBvB,GAC3CsB,eAAeC,OAAQ,oBAAqBtB,GAC5CqB,eAAeC,OAAQ,sBAAuBjB,GAC9CgB,eAAeC,OAAQ,kBAAmBd,GAC1Ca,eAAeC,OAAQ,uBAAwBT,E","sources":["webpack://@travelopia/web-components/./src/lightbox/tp-lightbox.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-content.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-close.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-previous.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-next.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-count.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-trigger.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-nav.ts","webpack://@travelopia/web-components/./src/lightbox/tp-lightbox-nav-item.ts","webpack://@travelopia/web-components/./src/lightbox/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPLightboxContentElement } from './tp-lightbox-content';\nimport { TPLightboxPreviousElement } from './tp-lightbox-previous';\nimport { TPLightboxNextElement } from './tp-lightbox-next';\nimport { TPLightboxTriggerElement } from './tp-lightbox-trigger';\nimport { TPLightboxCountElement } from './tp-lightbox-count';\nimport { TPLightboxNavItemElement } from './tp-lightbox-nav-item';\n\n/**\n * TP Lightbox.\n */\nexport class TPLightboxElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected currentTemplate: HTMLTemplateElement | null = null;\n\tprotected currentGroup: string = '';\n\tprotected allGroups: NodeListOf<TPLightboxTriggerElement> | null = null;\n\tprotected touchStartX: number = 0;\n\tprotected touchStartY: number = 0;\n\tprotected swipeThreshold: number = 200;\n\tprotected dialogElement: HTMLDialogElement | null;\n\tprotected lightboxNavItems: NodeListOf<TPLightboxNavItemElement> | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Initialize\n\t\tthis.dialogElement = this.querySelector( 'dialog' );\n\t\tthis.lightboxNavItems = this.querySelectorAll( 'tp-lightbox-nav-item' );\n\n\t\t// Event listeners.\n\t\tthis.dialogElement?.addEventListener( 'click', this.handleDialogClick.bind( this ) );\n\t\tthis.dialogElement?.addEventListener( 'touchstart', this.handleTouchStart.bind( this ) );\n\t\tthis.dialogElement?.addEventListener( 'touchend', this.handleTouchEnd.bind( this ) );\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'open', 'index', 'total', 'close-on-overlay-click', 'loading' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Prevent redundant updates.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Trigger change event.\n\t\tthis.dispatchEvent( new CustomEvent( 'change' ) );\n\n\t\t// Trigger current index target if index has changed.\n\t\tif ( 'index' === name ) {\n\t\t\tthis.triggerCurrentIndexTarget();\n\t\t}\n\n\t\t// Trigger navigation update if open or index has changed.\n\t\tif ( 'open' === name || 'index' === name ) {\n\t\t\tthis.updateNavCurrentItem();\n\t\t}\n\t}\n\n\t/**\n\t * Get template.\n\t */\n\tget template(): HTMLTemplateElement | null {\n\t\t// Return current template.\n\t\treturn this.currentTemplate;\n\t}\n\n\t/**\n\t * Set template.\n\t *\n\t * @param {HTMLTemplateElement} template The template.\n\t */\n\tset template( template: HTMLTemplateElement | null ) {\n\t\t// Set the template.\n\t\tthis.currentTemplate = template;\n\t\tthis.dispatchEvent( new CustomEvent( 'template-set' ) );\n\n\t\t// Get lightbox content element.\n\t\tconst content: TPLightboxContentElement | null = this.querySelector( 'tp-lightbox-content' );\n\n\t\t// Check if we have a content.\n\t\tif ( ! content ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have a template.\n\t\tif ( this.currentTemplate ) {\n\t\t\t/**\n\t\t\t * We do, update content with template's content.\n\t\t\t * We do this rather than a string to avoid script injection.\n\t\t\t */\n\t\t\tconst templateContent: Node = this.currentTemplate.content.cloneNode( true );\n\t\t\tcontent.replaceChildren( templateContent );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'content-change' ) );\n\n\t\t\t// Prepare image loading.\n\t\t\tsetTimeout( (): void => {\n\t\t\t\t// We do, prepare image loading.\n\t\t\t\tthis.prepareImageLoading();\n\t\t\t\tthis.prepareNavigation();\n\t\t\t}, 0 );\n\t\t} else {\n\t\t\t// We don't, set content as empty.\n\t\t\tcontent.innerHTML = '';\n\t\t}\n\t}\n\n\t/**\n\t * Get current group.\n\t */\n\tget group(): string {\n\t\t// Return current group.\n\t\treturn this.currentGroup;\n\t}\n\n\t/**\n\t * Set current group.\n\t *\n\t * @param {string} group Group name.\n\t */\n\tset group( group: string ) {\n\t\t// Set current group.\n\t\tthis.currentGroup = group;\n\t}\n\n\t/**\n\t * Get current index.\n\t */\n\tget currentIndex(): number {\n\t\t// Return current index.\n\t\treturn parseInt( this.getAttribute( 'index' ) ?? '1' );\n\t}\n\n\t/**\n\t * Set current index.\n\t *\n\t * @param {number} index Current index.\n\t */\n\tset currentIndex( index: number ) {\n\t\t// Set current index.\n\t\tif ( index < 1 ) {\n\t\t\tindex = 1;\n\t\t}\n\n\t\t// Setting this attributes triggers a re-trigger.\n\t\tthis.setAttribute( 'index', index.toString() );\n\n\t\t// dispatch slide-set event.\n\t\tthis.dispatchEvent( new CustomEvent( 'slide-set', {\n\t\t\tdetail: {\n\t\t\t\tslideIndex: index,\n\t\t\t},\n\t\t} ) );\n\t}\n\n\t/**\n\t * Trigger the target that matches the current index within current group.\n\t */\n\ttriggerCurrentIndexTarget(): void {\n\t\t// Get all groups and check if current index exists within group.\n\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> | null = this.getAllGroups();\n\n\t\t// Bail early if we don't have groups.\n\t\tif ( ! allGroups || ! allGroups[ this.currentIndex - 1 ] ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Trigger element within group.\n\t\tallGroups[ this.currentIndex - 1 ].trigger();\n\t}\n\n\t/**\n\t * Open lightbox.\n\t */\n\topen(): void {\n\t\t// Get the dialog element.\n\t\tconst dialog: HTMLDialogElement | null = this.querySelector( 'dialog' );\n\n\t\t// Check if dialog exists or is already open.\n\t\tif ( ! dialog || dialog.open ) {\n\t\t\t// Yes it is, Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// First, take this opportunity to update all groups (if it wasn't set from the trigger).\n\t\tif ( '' !== this.group && ! this.allGroups ) {\n\t\t\tthis.updateAllGroups();\n\t\t}\n\n\t\t// Now, show the modal.\n\t\tdialog.showModal();\n\t\tthis.setAttribute( 'open', 'yes' );\n\t}\n\n\t/**\n\t * Close lightbox.\n\t */\n\tclose(): void {\n\t\t// Find and close the dialog.\n\t\tconst dialog: HTMLDialogElement | null = this.querySelector( 'dialog' );\n\t\tdialog?.close();\n\t\tthis.removeAttribute( 'open' );\n\n\t\t// Clear groups from memory.\n\t\tthis.allGroups = null;\n\t}\n\n\t/**\n\t * Navigate previous.\n\t */\n\tprevious(): void {\n\t\t// Check if we even have a group.\n\t\tif ( '' === this.group ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have elements within group.\n\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> | null = this.getAllGroups();\n\n\t\t// Bail early if we don't have groups.\n\t\tif ( ! allGroups ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Decrement the current index.\n\t\tif ( this.currentIndex > 1 ) {\n\t\t\tthis.currentIndex--;\n\t\t}\n\t}\n\n\t/**\n\t * Navigate next.\n\t */\n\tnext(): void {\n\t\t// Check if we even have a group.\n\t\tif ( '' === this.group ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have elements within group.\n\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> | null = this.getAllGroups();\n\n\t\t// Bail early if we don't have groups.\n\t\tif ( ! allGroups ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Increment the current index.\n\t\tif ( this.currentIndex < allGroups.length ) {\n\t\t\tthis.currentIndex++;\n\t\t}\n\t}\n\n\t/**\n\t * Update all groups and save it to memory.\n\t *\n\t * @param {NodeList} allGroups All groups.\n\t */\n\tupdateAllGroups( allGroups: NodeListOf<TPLightboxTriggerElement> | null = null ): void {\n\t\t// Update all groups.\n\t\tif ( allGroups && allGroups.length ) {\n\t\t\tthis.allGroups = allGroups;\n\t\t\tthis.setAttribute( 'total', this.allGroups.length.toString() );\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get all groups.\n\t\tthis.allGroups = document.querySelectorAll( `tp-lightbox-trigger[group=\"${ this.group }\"]` );\n\n\t\t// Update total.\n\t\tif ( ! this.allGroups.length ) {\n\t\t\tthis.allGroups = null;\n\t\t} else {\n\t\t\tthis.setAttribute( 'total', this.allGroups.length.toString() );\n\t\t}\n\t}\n\n\t/**\n\t * Get all groups from memory.\n\t */\n\tgetAllGroups(): NodeListOf<TPLightboxTriggerElement> | null {\n\t\t// Return all groups.\n\t\treturn this.allGroups;\n\t}\n\n\t/**\n\t * Prepare navigation.\n\t */\n\tprepareNavigation(): void {\n\t\t// Update counter.\n\t\tconst count: TPLightboxCountElement | null = this.querySelector( 'tp-lightbox-count' );\n\t\tcount?.update();\n\n\t\t// Get previous and next elements.\n\t\tconst previous: TPLightboxPreviousElement | null = this.querySelector( 'tp-lightbox-previous' );\n\t\tconst next: TPLightboxNextElement | null = this.querySelector( 'tp-lightbox-next' );\n\n\t\t// Bail early if we don't have either.\n\t\tif ( ! previous && ! next ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have a group.\n\t\tif ( '' === this.group ) {\n\t\t\tprevious?.setAttribute( 'disabled', 'yes' );\n\t\t\tnext?.setAttribute( 'disabled', 'yes' );\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have elements within the group.\n\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> | null = this.getAllGroups();\n\n\t\t// Disable if we don't have any.\n\t\tif ( ! allGroups ) {\n\t\t\tprevious?.setAttribute( 'disabled', 'yes' );\n\t\t\tnext?.setAttribute( 'disabled', 'yes' );\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Enable / disable previous navigation.\n\t\tif ( this.currentIndex <= 1 ) {\n\t\t\tprevious?.setAttribute( 'disabled', 'yes' );\n\t\t} else {\n\t\t\tprevious?.removeAttribute( 'disabled' );\n\t\t}\n\n\t\t// Enable / disable next navigation.\n\t\tif ( this.currentIndex < allGroups.length ) {\n\t\t\tnext?.removeAttribute( 'disabled' );\n\t\t} else {\n\t\t\tnext?.setAttribute( 'disabled', 'yes' );\n\t\t}\n\t}\n\n\t/**\n\t * Prepare image loading.\n\t */\n\tprepareImageLoading(): void {\n\t\t// Get lightbox content element.\n\t\tconst content: TPLightboxContentElement | null = this.querySelector( 'tp-lightbox-content' );\n\n\t\t// Bail early if we don't have content.\n\t\tif ( ! content ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Bail if there are no images within current content.\n\t\tconst images: NodeListOf<HTMLImageElement> = content.querySelectorAll( 'img' );\n\n\t\t// Exit early if there are no images.\n\t\tif ( ! images.length ) {\n\t\t\tthis.removeAttribute( 'loading' );\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Start off by setting the state as loading.\n\t\tthis.setAttribute( 'loading', 'yes' );\n\n\t\t// Prepare increment variables.\n\t\tlet counter: number = 0;\n\t\tconst totalImages: number = images.length;\n\n\t\t/**\n\t\t * Increment counter.\n\t\t */\n\t\tconst incrementLoadingCounter = (): void => {\n\t\t\t// Increment\n\t\t\tcounter++;\n\n\t\t\t// Remove loading attribute once all images have loaded.\n\t\t\tif ( counter === totalImages ) {\n\t\t\t\tthis.removeAttribute( 'loading' );\n\t\t\t}\n\t\t};\n\n\t\t// Check if images have loaded, else add an event listener.\n\t\timages.forEach( ( image: HTMLImageElement ): void => {\n\t\t\t// Check if image has loaded.\n\t\t\tif ( image.complete ) {\n\t\t\t\tincrementLoadingCounter();\n\t\t\t} else {\n\t\t\t\timage.addEventListener( 'load', incrementLoadingCounter, { once: true } );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Handle when the dialog is clicked.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\thandleDialogClick( e: MouseEvent ): void {\n\t\t// Close on overlay click.\n\t\tif (\n\t\t\t'yes' === this.getAttribute( 'close-on-overlay-click' ) &&\n\t\t\tthis.querySelector( 'dialog' ) === e.target\n\t\t) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/**\n\t * Handles the touch start event.\n\t *\n\t * @param { TouchEvent } evt The touch event.\n\t */\n\thandleTouchStart( evt: TouchEvent ): void {\n\t\t// Check if we should allow swiping?\n\t\tif ( 'yes' !== this.getAttribute( 'swipe' ) ) {\n\t\t\t// Nope.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the start points.\n\t\tthis.touchStartX = evt.touches[ 0 ].clientX;\n\t\tthis.touchStartY = evt.touches[ 0 ].clientY;\n\t}\n\n\t/**\n\t * Handles the touch end event.\n\t *\n\t * @param { TouchEvent } evt The touch event.\n\t */\n\thandleTouchEnd( evt: TouchEvent ): void {\n\t\t// Check if we should allow swiping?\n\t\tif ( 'yes' !== this.getAttribute( 'swipe' ) ) {\n\t\t\t// Nope.\n\t\t\treturn;\n\t\t}\n\n\t\t// Calculate the distances.\n\t\tconst touchEndX: number = evt.changedTouches[ 0 ].clientX;\n\t\tconst touchEndY: number = evt.changedTouches[ 0 ].clientY;\n\t\tconst swipeDistanceX: number = touchEndX - this.touchStartX;\n\t\tconst swipeDistanceY: number = touchEndY - this.touchStartY;\n\n\t\t// Is this horizontal swipe?\n\t\tconst isHorizontalSwipe = Math.abs( swipeDistanceX ) > Math.abs( swipeDistanceY );\n\n\t\t// Check if this was a horizontal swipe?\n\t\tif ( ! isHorizontalSwipe ) {\n\t\t\t// Bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Swipe settings\n\t\tthis.swipeThreshold = Number( this.getAttribute( 'swipe-threshold' ) ?? '200' );\n\n\t\t// Check if it's a right or left swipe.\n\t\tif ( swipeDistanceX > 0 ) {\n\t\t\t// Right-Swipe: Check if horizontal swipe distance is less than the threshold.\n\t\t\tif ( swipeDistanceX < this.swipeThreshold ) {\n\t\t\t\tthis.previous();\n\t\t\t}\n\t\t} else if ( swipeDistanceX < 0 ) {\n\t\t\t// Left-Swipe: Check if horizontal swipe distance is less than the threshold.\n\t\t\tif ( swipeDistanceX > -this.swipeThreshold ) {\n\t\t\t\tthis.next();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update current item in navigation.\n\t */\n\tupdateNavCurrentItem(): void {\n\t\t// Bail if we don't have nav items.\n\t\tif ( ! this.lightboxNavItems ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update current item.\n\t\tthis.lightboxNavItems.forEach( ( navItem: TPLightboxNavItemElement, index: number ): void => {\n\t\t\t// Update current attribute.\n\t\t\tif ( this.currentIndex - 1 === index ) {\n\t\t\t\tnavItem.setAttribute( 'current', 'yes' );\n\t\t\t} else {\n\t\t\t\tnavItem.removeAttribute( 'current' );\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * TP Lightbox Content.\n */\nexport class TPLightboxContentElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Close.\n */\nexport class TPLightboxCloseElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.close.bind( this ) );\n\t}\n\n\t/**\n\t * Close the lightbox.\n\t */\n\tclose(): void {\n\t\t// Get lightbox.\n\t\tconst lightbox: TPLightboxElement | null = this.closest( 'tp-lightbox' );\n\n\t\t// Check if we have a lightbox.\n\t\tif ( lightbox ) {\n\t\t\tsetTimeout( (): void => {\n\t\t\t\t// Close the lightbox.\n\t\t\t\tlightbox.close();\n\t\t\t}, 0 );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Close.\n */\nexport class TPLightboxPreviousElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.previous.bind( this ) );\n\t}\n\n\t/**\n\t * Navigate previous.\n\t */\n\tprevious(): void {\n\t\t// Check if we are disabled.\n\t\tif ( 'yes' === this.getAttribute( 'disabled' ) ) {\n\t\t\t// No we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get lightbox.\n\t\tconst lightbox: TPLightboxElement | null = this.closest( 'tp-lightbox' );\n\n\t\t// Check if we have a lightbox.\n\t\tif ( lightbox ) {\n\t\t\tsetTimeout( (): void => {\n\t\t\t\t// Previous.\n\t\t\t\tlightbox.previous();\n\t\t\t}, 0 );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Close.\n */\nexport class TPLightboxNextElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.next.bind( this ) );\n\t}\n\n\t/**\n\t * Navigate next.\n\t */\n\tnext(): void {\n\t\t// Check if next is disabled.\n\t\tif ( 'yes' === this.getAttribute( 'disabled' ) ) {\n\t\t\t// Yes it is. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get lightbox.\n\t\tconst lightbox: TPLightboxElement | null = this.closest( 'tp-lightbox' );\n\n\t\t// Check if we have a lightbox.\n\t\tif ( lightbox ) {\n\t\t\tsetTimeout( (): void => {\n\t\t\t\t// Initiate next.\n\t\t\t\tlightbox.next();\n\t\t\t}, 0 );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Slider Count.\n */\nexport class TPLightboxCountElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} Observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'format' ];\n\t}\n\n\t/**\n\t * Get format.\n\t *\n\t * @return {string} Format.\n\t */\n\tget format(): string {\n\t\t// Get format.\n\t\treturn this.getAttribute( 'format' ) ?? '$current / $total';\n\t}\n\n\t/**\n\t * Set format.\n\t *\n\t * @param {string} format Format.\n\t */\n\tset format( format: string ) {\n\t\t// Set the 'format' attribute value.\n\t\tthis.setAttribute( 'format', format );\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t */\n\tattributeChangedCallback(): void {\n\t\t// On change of format attribute, update the component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update component.\n\t */\n\tupdate(): void {\n\t\t// Get lightbox.\n\t\tconst lightbox: TPLightboxElement | null = this.closest( 'tp-lightbox' );\n\n\t\t// Check if we have a lightbox.\n\t\tif ( ! lightbox ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current and total.\n\t\tconst current: string = lightbox.currentIndex.toString();\n\t\tconst total: string = lightbox.getAttribute( 'total' ) ?? '';\n\n\t\t// Update variables in format attribute.\n\t\tthis.innerHTML =\n\t\t\tthis.format\n\t\t\t\t.replace( '$current', current )\n\t\t\t\t.replace( '$total', total );\n\n\t\t// Update current and total attributes.\n\t\tthis.setAttribute( 'current', current );\n\t\tthis.setAttribute( 'total', total );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Trigger.\n */\nexport class TPLightboxTriggerElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.trigger.bind( this ) );\n\t}\n\n\t/**\n\t * Trigger the lightbox.\n\t */\n\ttrigger(): void {\n\t\t// Get lightbox ID and template.\n\t\tconst lightboxId: string | null = this.getAttribute( 'lightbox' );\n\t\tconst template: HTMLTemplateElement | null = this.querySelector( 'template' );\n\n\t\t// We can't proceed without them.\n\t\tif ( ! lightboxId || ! template ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the lightbox.\n\t\tconst lightbox: TPLightboxElement | null = document.querySelector( `#${ lightboxId.toString() }` );\n\n\t\t// Check to see if we have a lightbox.\n\t\tif ( ! lightbox ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check to see if we have a group.\n\t\tconst group: string = this.getAttribute( 'group' ) ?? '';\n\n\t\t// Yield to main thread.\n\t\tsetTimeout( (): void => {\n\t\t\t// Prepare lightbox.\n\t\t\tlightbox.template = template;\n\t\t\tlightbox.group = group;\n\n\t\t\t// Set index and group if we have them.\n\t\t\tif ( '' !== group ) {\n\t\t\t\tconst allGroups: NodeListOf<TPLightboxTriggerElement> = document.querySelectorAll( `tp-lightbox-trigger[group=\"${ group }\"]` );\n\n\t\t\t\t// Update all groups.\n\t\t\t\tif ( allGroups.length ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * We do this when we're opening a lightbox, or navigating.\n\t\t\t\t\t * This allows consumers to inject elements at any point.\n\t\t\t\t\t */\n\t\t\t\t\tlightbox.updateAllGroups( allGroups );\n\n\t\t\t\t\t// Get current trigger's index within the group.\n\t\t\t\t\tallGroups.forEach( ( triggerElement: TPLightboxTriggerElement, index: number ): void => {\n\t\t\t\t\t\t// Update current index.\n\t\t\t\t\t\tif ( this === triggerElement ) {\n\t\t\t\t\t\t\tlightbox.currentIndex = index + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// All done, lets open the lightbox.\n\t\t\tlightbox.open();\n\t\t}, 0 );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\n\n/**\n * TP Lightbox Nav.\n */\nexport class TPLightboxNavElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected template: HTMLTemplateElement | null = null;\n\tprotected lightbox : TPLightboxElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Initialize properties.\n\t\tthis.template = this.querySelector( 'template' );\n\t\tthis.lightbox = this.closest( 'tp-lightbox' );\n\n\t\t// Add event listener.\n\t\tthis.lightbox?.addEventListener( 'template-set', this.setTemplate.bind( this ) );\n\t}\n\n\t/**\n\t * Set the template.\n\t */\n\tsetTemplate(): void {\n\t\t// Bail if no template.\n\t\tif ( ! this.template ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Total slides.\n\t\tconst totalSlides = Number( this.lightbox?.getAttribute( 'total' ) ?? 0 );\n\n\t\t// Clear the navigation.\n\t\tthis.innerHTML = '';\n\n\t\t// Append the navigation items.\n\t\tfor ( let i = 0; i < totalSlides; i++ ) {\n\t\t\t// Clone the template.\n\t\t\tconst navItem = this.template.content.cloneNode( true );\n\n\t\t\t// Append the clone.\n\t\t\tthis.appendChild( navItem );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPLightboxElement } from './tp-lightbox';\nimport { TPLightboxNavElement } from './tp-lightbox-nav';\n\n/**\n * TP Lightbox Nav Item.\n */\nexport class TPLightboxNavItemElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected lightbox : TPLightboxElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.lightbox = this.closest( 'tp-lightbox' );\n\n\t\t// Get the nav-item button.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle when the button is clicked.\n\t */\n\thandleClick(): void {\n\t\t// Check if lightbox exists.\n\t\tif ( ! this.lightbox ) {\n\t\t\t// No its not! Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set current slide.\n\t\tthis.lightbox.currentIndex = Number( this.getIndex() ) ?? 1;\n\n\t\t// Update navigation current item.\n\t\tthis.lightbox.updateNavCurrentItem();\n\t}\n\n\t/**\n\t * Get index of this item inside the navigation.\n\t *\n\t * @return {number} Index.\n\t */\n\tgetIndex(): number {\n\t\t// Bail if no lightbox.\n\t\tif ( ! this.lightbox ) {\n\t\t\t// Exit.\n\t\t\treturn 0;\n\t\t}\n\n\t\t// No, find it in the navigation.\n\t\tconst lightboxNav: TPLightboxNavElement | null = this.closest( 'tp-lightbox-nav' );\n\n\t\t// Return index of this element considering the step value.\n\t\treturn ( Array.from( lightboxNav?.children ?? [] ).indexOf( this ) ) + 1;\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPLightboxElement } from './tp-lightbox';\nimport { TPLightboxContentElement } from './tp-lightbox-content';\nimport { TPLightboxCloseElement } from './tp-lightbox-close';\nimport { TPLightboxPreviousElement } from './tp-lightbox-previous';\nimport { TPLightboxNextElement } from './tp-lightbox-next';\nimport { TPLightboxCountElement } from './tp-lightbox-count';\nimport { TPLightboxTriggerElement } from './tp-lightbox-trigger';\nimport { TPLightboxNavElement } from './tp-lightbox-nav';\nimport { TPLightboxNavItemElement } from './tp-lightbox-nav-item';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-lightbox', TPLightboxElement );\ncustomElements.define( 'tp-lightbox-content', TPLightboxContentElement );\ncustomElements.define( 'tp-lightbox-close', TPLightboxCloseElement );\ncustomElements.define( 'tp-lightbox-previous', TPLightboxPreviousElement );\ncustomElements.define( 'tp-lightbox-next', TPLightboxNextElement );\ncustomElements.define( 'tp-lightbox-count', TPLightboxCountElement );\ncustomElements.define( 'tp-lightbox-trigger', TPLightboxTriggerElement );\ncustomElements.define( 'tp-lightbox-nav', TPLightboxNavElement );\ncustomElements.define( 'tp-lightbox-nav-item', TPLightboxNavItemElement );\n"],"names":["TPLightboxElement","HTMLElement","constructor","super","currentTemplate","currentGroup","allGroups","touchStartX","touchStartY","swipeThreshold","this","dialogElement","querySelector","lightboxNavItems","querySelectorAll","addEventListener","handleDialogClick","bind","handleTouchStart","handleTouchEnd","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","triggerCurrentIndexTarget","updateNavCurrentItem","template","content","templateContent","cloneNode","replaceChildren","setTimeout","prepareImageLoading","prepareNavigation","innerHTML","group","currentIndex","parseInt","getAttribute","index","setAttribute","toString","detail","slideIndex","getAllGroups","trigger","open","dialog","updateAllGroups","showModal","close","removeAttribute","previous","next","length","document","count","update","images","counter","totalImages","incrementLoadingCounter","forEach","image","complete","once","e","target","evt","touches","clientX","clientY","touchEndX","changedTouches","touchEndY","swipeDistanceX","swipeDistanceY","Math","abs","Number","navItem","TPLightboxContentElement","TPLightboxCloseElement","lightbox","closest","TPLightboxPreviousElement","TPLightboxNextElement","TPLightboxCountElement","format","current","total","replace","TPLightboxTriggerElement","lightboxId","triggerElement","TPLightboxNavElement","setTemplate","totalSlides","i","appendChild","TPLightboxNavItemElement","handleClick","getIndex","lightboxNav","Array","from","children","indexOf","customElements","define"],"sourceRoot":""}
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.currentlyHighlightedOption=-1,this.keyboardEventListener=this.handleKeyboardInputs.bind(this),document.addEventListener("click",this.handleDocumentClick.bind(this)),this.addEventListener("change",this.update.bind(this));const t=this.querySelector("tp-multi-select-options");t&&new MutationObserver(this.initialize.bind(this)).observe(t,{childList:!0,subtree:!0}),this.initialize()}static get observedAttributes(){return["open"]}attributeChangedCallback(t="",e="",l=""){e!==l&&"open"===t&&("yes"===l?(document.addEventListener("keydown",this.keyboardEventListener),this.dispatchEvent(new CustomEvent("open",{bubbles:!0}))):(this.unHighlightAllOptions(),document.removeEventListener("keydown",this.keyboardEventListener),this.dispatchEvent(new CustomEvent("close",{bubbles:!0}))))}set value(t){if(!t||!Array.isArray(t))return;const e=this.querySelectorAll("tp-multi-select-option");null==e||e.forEach((e=>{var l;t.includes(null!==(l=e.getAttribute("value"))&&void 0!==l?l:"")?e.setAttribute("selected","yes"):e.removeAttribute("selected")})),this.dispatchEvent(new CustomEvent("change",{bubbles:!0}))}get value(){const t=[],e=this.querySelectorAll("select option[selected]");return null==e||e.forEach((e=>{const l=e.getAttribute("value");l&&t.push(l)})),t}updateFormFieldValue(){const t=this.querySelectorAll("tp-multi-select-option"),e=this.querySelector("select");if(!t||!e)return;const l=Array.from(e.options);t.forEach((t=>{var i,s;const n=null!==(i=t.getAttribute("value"))&&void 0!==i?i:"";if(n){const i=l.find((t=>t.value===n));if("yes"===t.getAttribute("selected"))if(i)i.setAttribute("selected","selected");else{const l=document.createElement("option");l.setAttribute("value",null!==(s=t.getAttribute("value"))&&void 0!==s?s:""),l.setAttribute("selected","selected"),null==e||e.append(l)}else null==i||i.remove()}})),e.dispatchEvent(new Event("change"))}update(){this.updateFormFieldValue();const t=this.value;0!==t.length?this.setAttribute("selected","yes"):this.removeAttribute("selected");const e=this.querySelector("tp-multi-select-status");e&&(t.length>0?e.setAttribute("total",t.length.toString()):e.removeAttribute("total"))}handleDocumentClick(t){this===t.target||this.contains(t.target)||this.removeAttribute("open")}initialize(){var t;let e=this.querySelector("select");if(e)e.innerHTML="";else{e=document.createElement("select"),e.setAttribute("name",null!==(t=this.getAttribute("name"))&&void 0!==t?t:"");const l=this.getAttribute("form");l&&e.setAttribute("form",l),"no"!==this.getAttribute("multiple")&&e.setAttribute("multiple","multiple"),this.append(e)}this.update()}select(t=""){if("no"===this.getAttribute("multiple")&&(this.unSelectAll(),""===t))return void("yes"===this.getAttribute("close-on-select")&&this.removeAttribute("open"));const e=this.querySelectorAll(`tp-multi-select-option[value="${t}"]`);null==e||e.forEach((t=>{"yes"!==t.getAttribute("disabled")&&t.setAttribute("selected","yes")}));const l=this.querySelector("tp-multi-select-search");null==l||l.clear(),null==l||l.focus(),"yes"===this.getAttribute("close-on-select")&&this.removeAttribute("open"),this.update()}selectAll(){const t=this.querySelectorAll("tp-multi-select-option");null==t||t.forEach((t=>{"yes"!==t.getAttribute("disabled")&&t.setAttribute("selected","yes")})),this.update()}unSelect(t=""){const e=this.querySelectorAll(`tp-multi-select-option[value="${t}"]`);null==e||e.forEach((t=>{t.removeAttribute("selected")})),this.update()}unSelectAll(){const t=this.querySelectorAll("tp-multi-select-option");null==t||t.forEach((t=>{t.removeAttribute("selected")})),this.update()}handleKeyboardInputs(t){switch(t.key){case"ArrowDown":t.preventDefault(),this.highlightNextOption();break;case"ArrowUp":t.preventDefault(),this.highlightPreviousOption();break;case"Enter":this.toggleHighlightedOption();break;case"Escape":this.unHighlightAllOptions(),this.removeAttribute("open")}}highlightNextOption(){const t=this.querySelectorAll('tp-multi-select-option:not([hidden="yes"])');if(!t)return void(this.currentlyHighlightedOption=-1);let e=this.currentlyHighlightedOption+1;for(;e<t.length&&"yes"===t[e].getAttribute("disabled");)e++;e!==t.length&&(-1!==this.currentlyHighlightedOption&&t[this.currentlyHighlightedOption].removeAttribute("highlighted"),t[e].setAttribute("highlighted","yes"),t[e].scrollIntoView({behavior:"smooth",block:"nearest"}),this.currentlyHighlightedOption=e)}highlightPreviousOption(){const t=this.querySelectorAll('tp-multi-select-option:not([hidden="yes"])');if(!t)return void(this.currentlyHighlightedOption=-1);let e=this.currentlyHighlightedOption-1;for(;e>=0&&"yes"===t[e].getAttribute("disabled");)e--;e<0||(0!==this.currentlyHighlightedOption&&t[this.currentlyHighlightedOption].removeAttribute("highlighted"),t[e].setAttribute("highlighted","yes"),t[e].scrollIntoView({behavior:"smooth",block:"nearest"}),this.currentlyHighlightedOption=e)}toggleHighlightedOption(){const t=this.querySelector('tp-multi-select-option[highlighted="yes"]');null==t||t.toggle(null)}unHighlightAllOptions(){this.currentlyHighlightedOption=-1;const t=this.querySelectorAll("tp-multi-select-option");t&&t.forEach((t=>{t.removeAttribute("highlighted")}))}}class e extends HTMLElement{constructor(){super(),this.addEventListener("click",this.toggleOpen.bind(this))}toggleOpen(){const t=this.closest("tp-multi-select");t&&("yes"===t.getAttribute("open")?t.removeAttribute("open"):t.setAttribute("open","yes"))}}class l extends HTMLElement{}class i extends HTMLElement{static get observedAttributes(){return["total","format"]}attributeChangedCallback(t="",e="",l=""){e!==l&&this.update()}update(){var t,e,l,i;const s=null!==(t=this.getAttribute("format"))&&void 0!==t?t:"$total Selected";let n=s.replace("$total",null!==(e=this.getAttribute("total"))&&void 0!==e?e:"");if(s.includes("$value")){const t=this.closest("tp-multi-select");if(t){const e=null!==(l=t.value)&&void 0!==l?l:[];let s="";if(e.length>0){const l=t.querySelector(`tp-multi-select-option[value="${e[0]}"]`);l&&(s=null!==(i=l.getAttribute("label"))&&void 0!==i?i:"")}n=n.replace("$value",s)}}this.innerHTML=n}}class s extends HTMLElement{}class n extends HTMLElement{constructor(){super(),this.addEventListener("click",this.toggle.bind(this))}toggle(t){var e;null==t||t.preventDefault(),null==t||t.stopPropagation();const l=this.closest("tp-multi-select"),i=null!==(e=this.getAttribute("value"))&&void 0!==e?e:"";"yes"!==this.getAttribute("selected")?(null==l||l.select(i),null==l||l.dispatchEvent(new CustomEvent("select",{bubbles:!0,detail:{value:i}}))):(null==l||l.unSelect(i),null==l||l.dispatchEvent(new CustomEvent("unselect",{bubbles:!0,detail:{value:i}}))),null==l||l.dispatchEvent(new CustomEvent("change",{bubbles:!0}))}}class u extends HTMLElement{constructor(){var t;super();const e=this.querySelector("input");e&&(e.addEventListener("keydown",this.handleKeyboardInputs.bind(this)),e.addEventListener("keyup",this.handleSearchChange.bind(this)),e.addEventListener("input",this.handleSearchChange.bind(this)),this.addEventListener("click",this.handleClick.bind(this)),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("open",this.focus.bind(this)))}handleKeyboardInputs(t){const e=this.closest("tp-multi-select"),l=this.querySelector("input");if(e&&l)switch(t.key){case"Enter":t.preventDefault();break;case"ArrowDown":e.setAttribute("open","yes");break;case"Backspace":if(0===l.value.length){const t=e.querySelector("tp-multi-select-pill:last-of-type");t&&t.removePill()}}}handleSearchChange(){var t;const e=this.closest("tp-multi-select"),l=this.querySelector("input"),i=null===(t=this.closest("tp-multi-select"))||void 0===t?void 0:t.querySelectorAll("tp-multi-select-option");if(!e||!l||!i)return;let s=0;i.forEach((t=>{var e;(null===(e=t.getAttribute("label"))||void 0===e?void 0:e.toLowerCase().match(new RegExp(`.*${l.value.toLowerCase().replace(/\s/g,".*")}.*`)))?(t.removeAttribute("hidden"),s++):t.setAttribute("hidden","yes")})),""===l.value?l.removeAttribute("style"):(l.style.width=`${l.value.length+2}ch`,e.setAttribute("open","yes")),e.setAttribute("visible-options",s.toString())}handleClick(t){var e;t.preventDefault(),t.stopPropagation(),this.dispatchEvent(new CustomEvent("multi-select-opened")),document.dispatchEvent(new Event("click")),null===(e=this.closest("tp-multi-select"))||void 0===e||e.setAttribute("open","yes")}clear(){const t=this.querySelector("input");t&&(t.value="",t.dispatchEvent(new Event("change")))}focus(){var t;this.handleSearchChange(),null===(t=this.querySelector("input"))||void 0===t||t.focus()}}class o extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.handleButtonClick.bind(this))}handleButtonClick(t){null==t||t.preventDefault(),null==t||t.stopPropagation(),this.removePill()}removePill(){var t;const e=this.closest("tp-multi-select");e&&this.getAttribute("value")&&(e.unSelect(null!==(t=this.getAttribute("value"))&&void 0!==t?t:""),e.dispatchEvent(new CustomEvent("unselect",{bubbles:!0})),e.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}}class r extends HTMLElement{constructor(){var t,e,l;super(),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("change",this.update.bind(this)),null===(l=null===(e=this.closest("tp-multi-select"))||void 0===e?void 0:e.querySelector("select"))||void 0===l||l.addEventListener("change",(()=>this.update())),this.update()}update(){var t;const e=this.closest("tp-multi-select");if(!e)return;const l=this.querySelectorAll("tp-multi-select-pill"),i=null!==(t=e.value)&&void 0!==t?t:[],s=[];l.forEach((t=>{var e;const l=null!==(e=t.getAttribute("value"))&&void 0!==e?e:"";""!==l&&(s.push(l),i.includes(l)||t.remove())})),i.filter((t=>!s.includes(t))).forEach((t=>{var l;if(""===t)return;const i=e.querySelector(`tp-multi-select-option[value="${t}"]`);i&&this.appendChild(this.createPill(t,null!==(l=i.getAttribute("label"))&&void 0!==l?l:""))}))}createPill(t,e){const l=document.createElement("tp-multi-select-pill");l.setAttribute("value",t);const i=document.createElement("span");i.textContent=e;const s=document.createElement("button");return s.setAttribute("type","button"),s.textContent="x",s.addEventListener("click",(()=>{l.removePill()})),l.appendChild(i),l.appendChild(s),l}}class c extends HTMLElement{constructor(){var t;super(),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("change",this.handleValueChanged.bind(this)),this.addEventListener("click",this.toggleSelectAll.bind(this))}handleValueChanged(){var t,e;const l=this.closest("tp-multi-select"),i=null==l?void 0:l.querySelectorAll("tp-multi-select-option");l&&i&&(Array.from(i).filter((t=>"yes"!==t.getAttribute("disabled"))).length===l.value.length?(this.setAttribute("selected","yes"),this.innerHTML=null!==(t=this.getAttribute("unselect-text"))&&void 0!==t?t:""):(this.removeAttribute("selected"),this.innerHTML=null!==(e=this.getAttribute("select-text"))&&void 0!==e?e:""))}toggleSelectAll(){const t=this.closest("tp-multi-select");t&&("yes"!==this.getAttribute("selected")?(t.selectAll(),t.dispatchEvent(new CustomEvent("select-all",{bubbles:!0}))):(t.unSelectAll(),t.dispatchEvent(new CustomEvent("unselect-all",{bubbles:!0}))),t.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}}customElements.define("tp-multi-select",t),customElements.define("tp-multi-select-field",e),customElements.define("tp-multi-select-placeholder",l),customElements.define("tp-multi-select-status",i),customElements.define("tp-multi-select-options",s),customElements.define("tp-multi-select-option",n),customElements.define("tp-multi-select-search",u),customElements.define("tp-multi-select-pill",o),customElements.define("tp-multi-select-pills",r),customElements.define("tp-multi-select-select-all",c)})();
1
+ (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.currentlyHighlightedOption=-1,this.keyboardEventListener=this.handleKeyboardInputs.bind(this),document.addEventListener("click",this.handleDocumentClick.bind(this)),this.addEventListener("change",this.update.bind(this));const t=this.querySelector("tp-multi-select-options");t&&new MutationObserver(this.initialize.bind(this)).observe(t,{childList:!0,subtree:!0}),this.initialize()}static get observedAttributes(){return["open"]}attributeChangedCallback(t="",e="",l=""){e!==l&&"open"===t&&("yes"===l?(document.addEventListener("keydown",this.keyboardEventListener),this.dispatchEvent(new CustomEvent("open",{bubbles:!0}))):(this.unHighlightAllOptions(),document.removeEventListener("keydown",this.keyboardEventListener),this.dispatchEvent(new CustomEvent("close",{bubbles:!0}))))}set value(t){if(!t||!Array.isArray(t))return;const e=this.querySelectorAll("tp-multi-select-option");null==e||e.forEach((e=>{var l;t.includes(null!==(l=e.getAttribute("value"))&&void 0!==l?l:"")?e.setAttribute("selected","yes"):e.removeAttribute("selected")})),this.dispatchEvent(new CustomEvent("change",{bubbles:!0}))}get value(){const t=[],e=this.querySelectorAll("select option[selected]");return null==e||e.forEach((e=>{const l=e.getAttribute("value");l&&t.push(l)})),t}updateFormFieldValue(){const t=this.querySelectorAll("tp-multi-select-option"),e=this.querySelector("select");if(!t||!e)return;const l=Array.from(e.options);t.forEach((t=>{var i,s;const n=null!==(i=t.getAttribute("value"))&&void 0!==i?i:"";if(n){const i=l.find((t=>t.value===n));if("yes"===t.getAttribute("selected"))if(i)i.setAttribute("selected","selected");else{const l=document.createElement("option");l.setAttribute("value",null!==(s=t.getAttribute("value"))&&void 0!==s?s:""),l.setAttribute("selected","selected"),null==e||e.append(l)}else null==i||i.remove()}})),e.dispatchEvent(new Event("change"))}update(){this.updateFormFieldValue();const t=this.value;0!==t.length?this.setAttribute("selected","yes"):this.removeAttribute("selected");const e=this.querySelector("tp-multi-select-status");e&&(t.length>0?e.setAttribute("total",t.length.toString()):e.removeAttribute("total"))}handleDocumentClick(t){this===t.target||this.contains(t.target)||this.removeAttribute("open")}initialize(){var t;let e=this.querySelector("select");if(e)e.innerHTML="";else{e=document.createElement("select"),e.setAttribute("name",null!==(t=this.getAttribute("name"))&&void 0!==t?t:"");const l=this.getAttribute("form");l&&e.setAttribute("form",l),"no"!==this.getAttribute("multiple")&&e.setAttribute("multiple","multiple"),this.append(e)}this.update()}select(t=""){if("no"===this.getAttribute("multiple")&&(this.unSelectAll(),""===t))return void("yes"===this.getAttribute("close-on-select")&&this.removeAttribute("open"));const e=this.querySelectorAll(`tp-multi-select-option[value="${t}"]`);null==e||e.forEach((t=>{"yes"!==t.getAttribute("disabled")&&t.setAttribute("selected","yes")}));const l=this.querySelector("tp-multi-select-search");null==l||l.clear(),null==l||l.focus(),"yes"===this.getAttribute("close-on-select")&&this.removeAttribute("open"),this.update()}selectAll(){const t=this.querySelectorAll("tp-multi-select-option");null==t||t.forEach((t=>{"yes"!==t.getAttribute("disabled")&&t.setAttribute("selected","yes")})),this.update()}unSelect(t=""){const e=this.querySelectorAll(`tp-multi-select-option[value="${t}"]`);null==e||e.forEach((t=>{t.removeAttribute("selected")})),this.update()}unSelectAll(){const t=this.querySelectorAll("tp-multi-select-option");null==t||t.forEach((t=>{t.removeAttribute("selected")})),this.update()}handleKeyboardInputs(t){switch(t.key){case"ArrowDown":t.preventDefault(),this.highlightNextOption();break;case"ArrowUp":t.preventDefault(),this.highlightPreviousOption();break;case"Enter":this.toggleHighlightedOption();break;case"Escape":this.unHighlightAllOptions(),this.removeAttribute("open")}}highlightNextOption(){const t=this.querySelectorAll('tp-multi-select-option:not([hidden="yes"])');if(!t)return void(this.currentlyHighlightedOption=-1);let e=this.currentlyHighlightedOption+1;for(;e<t.length&&"yes"===t[e].getAttribute("disabled");)e++;e!==t.length&&(-1!==this.currentlyHighlightedOption&&t[this.currentlyHighlightedOption].removeAttribute("highlighted"),t[e].setAttribute("highlighted","yes"),t[e].scrollIntoView({behavior:"smooth",block:"nearest"}),this.currentlyHighlightedOption=e)}highlightPreviousOption(){const t=this.querySelectorAll('tp-multi-select-option:not([hidden="yes"])');if(!t)return void(this.currentlyHighlightedOption=-1);let e=this.currentlyHighlightedOption-1;for(;e>=0&&"yes"===t[e].getAttribute("disabled");)e--;e<0||(0!==this.currentlyHighlightedOption&&t[this.currentlyHighlightedOption].removeAttribute("highlighted"),t[e].setAttribute("highlighted","yes"),t[e].scrollIntoView({behavior:"smooth",block:"nearest"}),this.currentlyHighlightedOption=e)}toggleHighlightedOption(){const t=this.querySelector('tp-multi-select-option[highlighted="yes"]');null==t||t.toggle(null)}unHighlightAllOptions(){this.currentlyHighlightedOption=-1;const t=this.querySelectorAll("tp-multi-select-option");t&&t.forEach((t=>{t.removeAttribute("highlighted")}))}}class e extends HTMLElement{constructor(){super(),this.addEventListener("click",this.toggleOpen.bind(this))}toggleOpen(){const t=this.closest("tp-multi-select");t&&("yes"===t.getAttribute("open")?t.removeAttribute("open"):t.setAttribute("open","yes"))}}class l extends HTMLElement{}class i extends HTMLElement{static get observedAttributes(){return["total","format"]}attributeChangedCallback(t="",e="",l=""){e!==l&&this.update()}update(){var t,e,l,i;const s=null!==(t=this.getAttribute("format"))&&void 0!==t?t:"$total Selected";let n=s.replace("$total",null!==(e=this.getAttribute("total"))&&void 0!==e?e:"");if(s.includes("$value")){const t=this.closest("tp-multi-select");if(t){const e=null!==(l=t.value)&&void 0!==l?l:[];let s="";if(e.length>0){const l=t.querySelector(`tp-multi-select-option[value="${e[0]}"]`);l&&(s=null!==(i=l.getAttribute("label"))&&void 0!==i?i:"")}n=n.replace("$value",s)}}this.innerHTML=n}}class s extends HTMLElement{}class n extends HTMLElement{constructor(){super(),this.addEventListener("click",this.toggle.bind(this))}toggle(t){var e;null==t||t.preventDefault(),null==t||t.stopPropagation();const l=this.closest("tp-multi-select"),i=null!==(e=this.getAttribute("value"))&&void 0!==e?e:"";"yes"!==this.getAttribute("selected")?(null==l||l.select(i),null==l||l.dispatchEvent(new CustomEvent("select",{bubbles:!0,detail:{value:i}}))):(null==l||l.unSelect(i),null==l||l.dispatchEvent(new CustomEvent("unselect",{bubbles:!0,detail:{value:i}}))),null==l||l.dispatchEvent(new CustomEvent("change",{bubbles:!0}))}}class u extends HTMLElement{constructor(){var t;super();const e=this.querySelector("input");e&&(e.addEventListener("keydown",this.handleKeyboardInputs.bind(this)),e.addEventListener("keyup",this.handleSearchChange.bind(this)),e.addEventListener("input",this.handleSearchChange.bind(this)),this.addEventListener("click",this.handleClick.bind(this)),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("open",this.focus.bind(this)))}handleKeyboardInputs(t){const e=this.closest("tp-multi-select"),l=this.querySelector("input");if(e&&l)switch(t.key){case"Enter":t.preventDefault();break;case"ArrowDown":e.setAttribute("open","yes");break;case"Backspace":if(0===l.value.length){const t=e.querySelector("tp-multi-select-pill:last-of-type");t&&t.removePill()}}}handleSearchChange(){var t;const e=this.closest("tp-multi-select"),l=this.querySelector("input"),i=null===(t=this.closest("tp-multi-select"))||void 0===t?void 0:t.querySelectorAll("tp-multi-select-option");if(!e||!l||!i)return;let s=0;i.forEach((t=>{var e;(null===(e=t.getAttribute("label"))||void 0===e?void 0:e.toLowerCase().match(new RegExp(`.*${l.value.toLowerCase().replace(/\s/g,".*")}.*`)))?(t.removeAttribute("hidden"),s++):t.setAttribute("hidden","yes")})),""===l.value?l.removeAttribute("style"):(l.style.width=`${l.value.length+2}ch`,e.setAttribute("open","yes")),e.setAttribute("visible-options",s.toString())}handleClick(t){var e;t.preventDefault(),t.stopPropagation(),this.dispatchEvent(new CustomEvent("multi-select-opened")),document.dispatchEvent(new Event("click")),null===(e=this.closest("tp-multi-select"))||void 0===e||e.setAttribute("open","yes")}clear(){const t=this.querySelector("input");t&&(t.value="",t.dispatchEvent(new Event("change")))}focus(){var t;this.handleSearchChange(),null===(t=this.querySelector("input"))||void 0===t||t.focus()}}class o extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.handleButtonClick.bind(this))}handleButtonClick(t){null==t||t.preventDefault(),null==t||t.stopPropagation(),this.removePill()}removePill(){var t;const e=this.closest("tp-multi-select");e&&this.getAttribute("value")&&(e.unSelect(null!==(t=this.getAttribute("value"))&&void 0!==t?t:""),e.dispatchEvent(new CustomEvent("unselect",{bubbles:!0})),e.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}}class r extends HTMLElement{constructor(){var t,e,l;super(),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("change",this.update.bind(this)),null===(l=null===(e=this.closest("tp-multi-select"))||void 0===e?void 0:e.querySelector("select"))||void 0===l||l.addEventListener("change",(()=>this.update())),this.update()}update(){var t;const e=this.closest("tp-multi-select");if(!e)return;const l=this.querySelectorAll("tp-multi-select-pill"),i=null!==(t=[...new Set(e.value)])&&void 0!==t?t:[],s=[];l.forEach((t=>{var e;const l=null!==(e=t.getAttribute("value"))&&void 0!==e?e:"";""!==l&&(s.push(l),i.includes(l)||t.remove())})),i.filter((t=>!s.includes(t))).forEach((t=>{var l;if(""===t)return;const i=e.querySelector(`tp-multi-select-option[value="${t}"]`);i&&this.appendChild(this.createPill(t,null!==(l=i.getAttribute("label"))&&void 0!==l?l:""))}))}createPill(t,e){const l=document.createElement("tp-multi-select-pill");l.setAttribute("value",t);const i=document.createElement("span");i.textContent=e;const s=document.createElement("button");return s.setAttribute("type","button"),s.textContent="x",s.addEventListener("click",(()=>{l.removePill()})),l.appendChild(i),l.appendChild(s),l}}class c extends HTMLElement{constructor(){var t;super(),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("change",this.handleValueChanged.bind(this)),this.addEventListener("click",this.toggleSelectAll.bind(this))}handleValueChanged(){var t,e;const l=this.closest("tp-multi-select"),i=null==l?void 0:l.querySelectorAll("tp-multi-select-option");l&&i&&(Array.from(i).filter((t=>"yes"!==t.getAttribute("disabled"))).length===l.value.length?(this.setAttribute("selected","yes"),this.innerHTML=null!==(t=this.getAttribute("unselect-text"))&&void 0!==t?t:""):(this.removeAttribute("selected"),this.innerHTML=null!==(e=this.getAttribute("select-text"))&&void 0!==e?e:""))}toggleSelectAll(){const t=this.closest("tp-multi-select");t&&("yes"!==this.getAttribute("selected")?(t.selectAll(),t.dispatchEvent(new CustomEvent("select-all",{bubbles:!0}))):(t.unSelectAll(),t.dispatchEvent(new CustomEvent("unselect-all",{bubbles:!0}))),t.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}}customElements.define("tp-multi-select",t),customElements.define("tp-multi-select-field",e),customElements.define("tp-multi-select-placeholder",l),customElements.define("tp-multi-select-status",i),customElements.define("tp-multi-select-options",s),customElements.define("tp-multi-select-option",n),customElements.define("tp-multi-select-search",u),customElements.define("tp-multi-select-pill",o),customElements.define("tp-multi-select-pills",r),customElements.define("tp-multi-select-select-all",c)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/multi-select/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/multi-select/tp-multi-select.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-field.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-placeholder.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-status.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-options.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-option.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-search.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pill.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pills.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-select-all.ts","webpack://@travelopia/web-components/./src/multi-select/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\n\n/**\n * TP Multi Select.\n */\nexport class TPMultiSelectElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tcurrentlyHighlightedOption: number = -1;\n\tprotected keyboardEventListener: EventListener;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.keyboardEventListener = this.handleKeyboardInputs.bind( this ) as EventListener;\n\t\tdocument.addEventListener( 'click', this.handleDocumentClick.bind( this ) );\n\t\tthis.addEventListener( 'change', this.update.bind( this ) );\n\n\t\t// Get options.\n\t\tconst options: TPMultiSelectOptionsElement | null = this.querySelector( 'tp-multi-select-options' );\n\n\t\t// Listen for dynamic changes to the option values.\n\t\tif ( options ) {\n\t\t\tconst mutationObserver: MutationObserver = new MutationObserver( this.initialize.bind( this ) );\n\t\t\tmutationObserver.observe( options, { childList: true, subtree: true } );\n\t\t}\n\n\t\t// Initialize component.\n\t\tthis.initialize();\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'open' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// If no changes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Changed attribute name is 'open'.\n\t\tif ( 'open' === name ) {\n\t\t\t// If new value is 'yes' then open the dropdown.\n\t\t\tif ( 'yes' === newValue ) {\n\t\t\t\tdocument.addEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'open', { bubbles: true } ) );\n\t\t\t} else {\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tdocument.removeEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'close', { bubbles: true } ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set the value of this component.\n\t *\n\t * @param {Array} value Value.\n\t */\n\tset value( value: string[] ) {\n\t\t// Bail if value is not an array.\n\t\tif ( ! value || ! Array.isArray( value ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value of the select field.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Check if the value is in the array.\n\t\t\tif ( value.includes( option.getAttribute( 'value' ) ?? '' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t} else {\n\t\t\t\toption.removeAttribute( 'selected' );\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch change event.\n\t\tthis.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n\n\t/**\n\t * Get the value of this component.\n\t *\n\t * @return {Array} Value of this component.\n\t */\n\tget value(): string[] {\n\t\t// Get the value of the select field.\n\t\tconst value: string[] = [];\n\n\t\t// Get selected options.\n\t\tconst selectedOptions: NodeListOf<HTMLOptionElement> | null = this.querySelectorAll( 'select option[selected]' );\n\t\tselectedOptions?.forEach( ( option: HTMLOptionElement ) => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' );\n\n\t\t\t// Add value to array.\n\t\t\tif ( optionValue ) {\n\t\t\t\tvalue.push( optionValue );\n\t\t\t}\n\t\t} );\n\n\t\t// Return value.\n\t\treturn value;\n\t}\n\n\t/**\n\t * Update the value of the select field.\n\t */\n\tprotected updateFormFieldValue(): void {\n\t\t// Get options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option` );\n\t\tconst selectField: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Bail if there's no styled selected options or select field.\n\t\tif ( ! styledSelectedOptions || ! selectField ) {\n\t\t\t// Bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get selected options.\n\t\tconst selectOptions: HTMLOptionElement[] = Array.from( selectField.options );\n\n\t\t// Traverse options.\n\t\tstyledSelectedOptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' ) ?? '';\n\n\t\t\t// If option value is present.\n\t\t\tif ( optionValue ) {\n\t\t\t\tconst matchingSelectOption: HTMLOptionElement | undefined = selectOptions.find( ( selectOption ) => selectOption.value === optionValue );\n\n\t\t\t\t// Update select field.\n\t\t\t\tif ( 'yes' === option.getAttribute( 'selected' ) ) {\n\t\t\t\t\t// Update select field.\n\t\t\t\t\tif ( matchingSelectOption ) {\n\t\t\t\t\t\tmatchingSelectOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst newOption: HTMLOptionElement = document.createElement( 'option' );\n\t\t\t\t\t\tnewOption.setAttribute( 'value', option.getAttribute( 'value' ) ?? '' );\n\t\t\t\t\t\tnewOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t\tselectField?.append( newOption );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmatchingSelectOption?.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch events.\n\t\tselectField.dispatchEvent( new Event( 'change' ) );\n\t}\n\n\t/**\n\t * Update component and sub-components.\n\t */\n\tupdate(): void {\n\t\t// First, update field value.\n\t\tthis.updateFormFieldValue();\n\n\t\t// Get value.\n\t\tconst value: string[] = this.value;\n\n\t\t// Toggle selected attribute.\n\t\tif ( 0 !== value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t}\n\n\t\t// Get status.\n\t\tconst status: TPMultiSelectStatusElement | null = this.querySelector( 'tp-multi-select-status' );\n\n\t\t// Update status.\n\t\tif ( status ) {\n\t\t\t// Update status.\n\t\t\tif ( value.length > 0 ) {\n\t\t\t\tstatus.setAttribute( 'total', value.length.toString() );\n\t\t\t} else {\n\t\t\t\tstatus.removeAttribute( 'total' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle clicking the document.\n\t *\n\t * @param {Event} e Event.\n\t */\n\tprotected handleDocumentClick( e: Event ): void {\n\t\t// Close on click outside.\n\t\tif ( this !== e.target && ! this.contains( e.target as Node ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\t}\n\n\t/**\n\t * Initialize component.\n\t */\n\tinitialize(): void {\n\t\t// Get select element.\n\t\tlet selectElement: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Create select element (if it doesn't already exist).\n\t\tif ( ! selectElement ) {\n\t\t\tselectElement = document.createElement( 'select' );\n\t\t\tselectElement.setAttribute( 'name', this.getAttribute( 'name' ) ?? '' );\n\n\t\t\t// Get form reference.\n\t\t\tconst formReference = this.getAttribute( 'form' );\n\n\t\t\t// Add form reference.\n\t\t\tif ( formReference ) {\n\t\t\t\tselectElement.setAttribute( 'form', formReference );\n\t\t\t}\n\n\t\t\t// Set multiple.\n\t\t\tif ( 'no' !== this.getAttribute( 'multiple' ) ) {\n\t\t\t\tselectElement.setAttribute( 'multiple', 'multiple' );\n\t\t\t}\n\n\t\t\t// Append.\n\t\t\tthis.append( selectElement );\n\t\t} else {\n\t\t\tselectElement.innerHTML = '';\n\t\t}\n\n\t\t// Update components for selected options.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select a value.\n\t *\n\t * @param {string} value Value to select.\n\t */\n\tselect( value: string = '' ): void {\n\t\t// Stuff for single-select.\n\t\tif ( 'no' === this.getAttribute( 'multiple' ) ) {\n\t\t\t// First, unselect everything.\n\t\t\tthis.unSelectAll();\n\n\t\t\t// If the value is blank, don't do anything else.\n\t\t\tif ( '' === value ) {\n\t\t\t\t// Close the field, if applicable.\n\t\t\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\t}\n\n\t\t\t\t// Exit.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Select all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Search stuff.\n\t\tconst search: TPMultiSelectSearchElement | null = this.querySelector( 'tp-multi-select-search' );\n\t\tsearch?.clear();\n\t\tsearch?.focus();\n\n\t\t// Close the field, if applicable.\n\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select all values.\n\t */\n\tselectAll(): void {\n\t\t// Get all options.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select a value.\n\t *\n\t * @param {string} value Value to unselect.\n\t */\n\tunSelect( value: string = '' ): void {\n\t\t// Get all options with the specified value.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select all values.\n\t */\n\tunSelectAll(): void {\n\t\t// Get all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Keyboard events.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightNextOption();\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightPreviousOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Enter':\n\t\t\t\tthis.toggleHighlightedOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Escape':\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Highlight the next option.\n\t */\n\thighlightNextOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the next option to be highlighted. Assume next option is the favorable option.\n\t\tlet nextToBeHighlighted = this.currentlyHighlightedOption + 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( nextToBeHighlighted < options.length && options[ nextToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tnextToBeHighlighted++;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit. Here, the last highlighted option keeps highlighted.\n\t\tif ( nextToBeHighlighted === options.length ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== -1 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ nextToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ nextToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = nextToBeHighlighted;\n\t}\n\n\t/**\n\t * Highlight previous option.\n\t */\n\thighlightPreviousOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the previous option to be highlighted. Assume previous option is the favorable option.\n\t\tlet previousToBeHighlighted = this.currentlyHighlightedOption - 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( previousToBeHighlighted >= 0 && options[ previousToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tpreviousToBeHighlighted--;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit.\n\t\tif ( previousToBeHighlighted < 0 ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== 0 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ previousToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ previousToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = previousToBeHighlighted;\n\t}\n\n\t/**\n\t * Toggle highlighted option.\n\t */\n\ttoggleHighlightedOption(): void {\n\t\t// Get option and if it exists set it to null.\n\t\tconst option: TPMultiSelectOptionElement | null = this.querySelector( `tp-multi-select-option[highlighted=\"yes\"]` );\n\t\toption?.toggle( null );\n\t}\n\n\t/**\n\t * Un-highlight all options.\n\t */\n\tunHighlightAllOptions(): void {\n\t\t// Reset the currentlyHighlightedOption.\n\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// If there are options, un-highlight them.\n\t\tif ( options ) {\n\t\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t\t// Remove highlighted attribute.\n\t\t\t\toption.removeAttribute( 'highlighted' );\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Field.\n */\nexport class TPMultiSelectFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.addEventListener( 'click', this.toggleOpen.bind( this ) );\n\t}\n\n\t/**\n\t * Toggle opening this component.\n\t */\n\ttoggleOpen(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail early if we don't have a multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle open.\n\t\tif ( 'yes' === multiSelect.getAttribute( 'open' ) ) {\n\t\t\tmultiSelect.removeAttribute( 'open' );\n\t\t} else {\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\t}\n}\n","/**\n * TP Multi Select Placeholder.\n */\nexport class TPMultiSelectPlaceholderElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Status.\n */\nexport class TPMultiSelectStatusElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'total', 'format' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} _name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( _name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Update component.\n\t\tif ( oldValue !== newValue ) {\n\t\t\tthis.update();\n\t\t}\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get format attribute.\n\t\tconst format: string = this.getAttribute( 'format' ) ?? '$total Selected';\n\t\tlet html: string = format.replace( '$total', this.getAttribute( 'total' ) ?? '' );\n\n\t\t// Format string includes $value.\n\t\tif ( format.includes( '$value' ) ) {\n\t\t\t// Get multi-select.\n\t\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t\t// Check if multi-select exists.\n\t\t\tif ( multiSelect ) {\n\t\t\t\t// Get value if present or create an empty array.\n\t\t\t\tconst value: string[] = multiSelect.value ?? [];\n\t\t\t\tlet replace: string = '';\n\n\t\t\t\t// Check if value array is not empty.\n\t\t\t\tif ( value.length > 0 ) {\n\t\t\t\t\t// Get first value.\n\t\t\t\t\tconst option: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ value[ 0 ] }\"]` );\n\n\t\t\t\t\t// Check if option exists.\n\t\t\t\t\tif ( option ) {\n\t\t\t\t\t\treplace = option.getAttribute( 'label' ) ?? '';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Replace $value.\n\t\t\t\thtml = html.replace( '$value', replace );\n\t\t\t}\n\t\t}\n\n\t\t// Set inner HTML.\n\t\tthis.innerHTML = html;\n\t}\n}\n","/**\n * TP Multi Select Options.\n */\nexport class TPMultiSelectOptionsElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Option.\n */\nexport class TPMultiSelectOptionElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener to toggle the selected state.\n\t\tthis.addEventListener( 'click', this.toggle.bind( this ) );\n\t}\n\n\t/**\n\t * Select / un-select this option.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\ttoggle( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Get multi-select element and value of option.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst value: string = this.getAttribute( 'value' ) ?? '';\n\n\t\t// Toggle selected state. Dispatch custom events accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect?.select( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'select', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t} else {\n\t\t\tmultiSelect?.unSelect( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'unselect', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\n\n/**\n * TP Multi Select Search.\n */\nexport class TPMultiSelectSearchElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// get input.\n\t\tconst input: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if input exists.\n\t\tif ( ! input ) {\n\t\t\t// No, its not. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Add event listeners.\n\t\tinput.addEventListener( 'keydown', this.handleKeyboardInputs.bind( this ) );\n\t\tinput.addEventListener( 'keyup', this.handleSearchChange.bind( this ) );\n\t\tinput.addEventListener( 'input', this.handleSearchChange.bind( this ) );\n\t\tthis.addEventListener( 'click', this.handleClick.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'open', this.focus.bind( this ) );\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Get multi select and search field.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if multi select and search field exists.\n\t\tif ( ! multiSelect || ! search ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle keyboard inputs.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'Enter':\n\t\t\t\te.preventDefault(); // Prevent inadvertent form submits.\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowDown':\n\t\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t\t\tbreak;\n\t\t\tcase 'Backspace': // Remove last pill if search is empty.\n\t\t\t\tif ( 0 === search.value.length ) {\n\t\t\t\t\tconst pill: TPMultiSelectPillElement | null = multiSelect.querySelector( 'tp-multi-select-pill:last-of-type' );\n\n\t\t\t\t\t// Check if pill exists, remove it.\n\t\t\t\t\tif ( pill ) {\n\t\t\t\t\t\tpill.removePill();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Handle search field value changed.\n\t */\n\tprotected handleSearchChange(): void {\n\t\t// Get search field and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | undefined = this.closest( 'tp-multi-select' )?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select, search, and options field exists.\n\t\tif ( ! multiSelect || ! search || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize matched option count.\n\t\tlet matchedOptionCount = 0;\n\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Hide and show options based on search.\n\t\t\tif ( option.getAttribute( 'label' )?.toLowerCase().match( new RegExp( `.*${ search.value.toLowerCase().replace( /\\s/g, '.*' ) }.*` ) ) ) {\n\t\t\t\toption.removeAttribute( 'hidden' );\n\t\t\t\tmatchedOptionCount++;\n\t\t\t} else {\n\t\t\t\toption.setAttribute( 'hidden', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Resize input width.\n\t\tif ( '' === search.value ) {\n\t\t\tsearch.removeAttribute( 'style' );\n\t\t} else {\n\t\t\tsearch.style.width = `${ search.value.length + 2 }ch`;\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\n\t\t// Show matched option count.\n\t\tmultiSelect.setAttribute( 'visible-options', matchedOptionCount.toString() );\n\t}\n\n\t/**\n\t * Handle click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\tprotected handleClick( e: Event ): void {\n\t\t// First, prevent propagation to avoid document.click set on `tp-multi-select`.\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\t// Now send the event so other stuff can work as per normal, and another event for good measure.\n\t\tthis.dispatchEvent( new CustomEvent( 'multi-select-opened' ) );\n\t\tdocument.dispatchEvent( new Event( 'click' ) );\n\n\t\t// Open multi select.\n\t\tthis.closest( 'tp-multi-select' )?.setAttribute( 'open', 'yes' );\n\t}\n\n\t/**\n\t * Clear the search field.\n\t */\n\tclear(): void {\n\t\t// Clear search field.\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if search field exists.\n\t\tif ( search ) {\n\t\t\t// Set value to empty string and dispatch change event.\n\t\t\tsearch.value = '';\n\t\t\tsearch.dispatchEvent( new Event( 'change' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Set focus on the search field.\n\t */\n\tfocus(): void {\n\t\t// When it's focused, use search change to ensure the results are refreshed.\n\t\tthis.handleSearchChange();\n\n\t\t// Focus on input.\n\t\tthis.querySelector( 'input' )?.focus();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Pill.\n */\nexport class TPMultiSelectPillElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleButtonClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle button click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\thandleButtonClick( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Remove pill.\n\t\tthis.removePill();\n\t}\n\n\t/**\n\t * Remove this pill.\n\t */\n\tremovePill(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Unselect value.\n\t\tif ( multiSelect && this.getAttribute( 'value' ) ) {\n\t\t\tmultiSelect.unSelect( this.getAttribute( 'value' ) ?? '' );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect', { bubbles: true } ) );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Pills.\n */\nexport class TPMultiSelectPillsElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.update.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.querySelector( 'select' )?.addEventListener( 'change', ( () => this.update() ) as EventListener );\n\n\t\t// Update.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail if there's no multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine pills.\n\t\tconst pills: NodeListOf<TPMultiSelectPillElement> | null = this.querySelectorAll( 'tp-multi-select-pill' );\n\t\tconst values: string[] = multiSelect.value ?? [];\n\t\tconst pillValues: string[] = [];\n\n\t\t// Remove pills that shouldn't exist.\n\t\tpills.forEach( ( pill: TPMultiSelectPillElement ): void => {\n\t\t\t// Get pill value.\n\t\t\tconst pillValue: string = pill.getAttribute( 'value' ) ?? '';\n\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill value to the array.\n\t\t\tpillValues.push( pillValue );\n\n\t\t\t// Remove pill if it doesn't exist in the values.\n\t\t\tif ( ! values.includes( pillValue ) ) {\n\t\t\t\tpill.remove();\n\t\t\t}\n\t\t} );\n\n\t\t// Create new pills.\n\t\tconst pillsToCreate: string[] = values.filter( ( value: string ) => ! pillValues.includes( value ) );\n\n\t\t// Create pills.\n\t\tpillsToCreate.forEach( ( pillValue: string ): void => {\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get multi-select option.\n\t\t\tconst multiSelectOption: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ pillValue }\"]` );\n\n\t\t\t// Bail early if there's no multi-select option.\n\t\t\tif ( ! multiSelectOption ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill.\n\t\t\tthis.appendChild( this.createPill( pillValue, multiSelectOption.getAttribute( 'label' ) ?? '' ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Create a new pill.\n\t *\n\t * @param {string} value Pill value.\n\t * @param {string} label Pill label.\n\t *\n\t * @return {TPMultiSelectPillElement} New pill.\n\t */\n\tcreatePill( value: string, label: string ): TPMultiSelectPillElement {\n\t\t// Create pill and set value attribute.\n\t\tconst newPill = document.createElement( 'tp-multi-select-pill' ) as TPMultiSelectPillElement;\n\t\tnewPill.setAttribute( 'value', value );\n\n\t\t// Create pill label.\n\t\tconst pillLabel: HTMLElement = document.createElement( 'span' );\n\t\tpillLabel.textContent = label;\n\n\t\t// Create pill close button.\n\t\tconst pillCloseButton: HTMLElement = document.createElement( 'button' );\n\t\tpillCloseButton.setAttribute( 'type', 'button' );\n\t\tpillCloseButton.textContent = 'x';\n\n\t\t// Add event listener.\n\t\tpillCloseButton.addEventListener( 'click', () => {\n\t\t\t// On click, run removePill method.\n\t\t\tnewPill.removePill();\n\t\t} );\n\n\t\t// Append label and close button to pill.\n\t\tnewPill.appendChild( pillLabel );\n\t\tnewPill.appendChild( pillCloseButton );\n\n\t\t// Return newPill element.\n\t\treturn newPill;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Select All.\n */\nexport class TPMultiSelectSelectAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listeners.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.handleValueChanged.bind( this ) );\n\t\tthis.addEventListener( 'click', this.toggleSelectAll.bind( this ) );\n\t}\n\n\t/**\n\t * Handle value changed.\n\t */\n\thandleValueChanged(): void {\n\t\t// Get multi select and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null | undefined = multiSelect?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select and options exists.\n\t\tif ( ! multiSelect || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if all options are selected.\n\t\tif ( Array.from( options ).filter( ( optionNode ) => optionNode.getAttribute( 'disabled' ) !== 'yes' ).length === multiSelect.value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t\tthis.innerHTML = this.getAttribute( 'unselect-text' ) ?? '';\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t\tthis.innerHTML = this.getAttribute( 'select-text' ) ?? '';\n\t\t}\n\t}\n\n\t/**\n\t * Toggle select all.\n\t */\n\ttoggleSelectAll(): void {\n\t\t// Get multi select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if multi select exists.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if select all is yes. Apply selectAll and unselectAll methods accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect.selectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'select-all', { bubbles: true } ) );\n\t\t} else {\n\t\t\tmultiSelect.unSelectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect-all', { bubbles: true } ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectFieldElement } from './tp-multi-select-field';\nimport { TPMultiSelectPlaceholderElement } from './tp-multi-select-placeholder';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectPillsElement } from './tp-multi-select-pills';\nimport { TPMultiSelectSelectAllElement } from './tp-multi-select-select-all';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-multi-select', TPMultiSelectElement );\ncustomElements.define( 'tp-multi-select-field', TPMultiSelectFieldElement );\ncustomElements.define( 'tp-multi-select-placeholder', TPMultiSelectPlaceholderElement );\ncustomElements.define( 'tp-multi-select-status', TPMultiSelectStatusElement );\ncustomElements.define( 'tp-multi-select-options', TPMultiSelectOptionsElement );\ncustomElements.define( 'tp-multi-select-option', TPMultiSelectOptionElement );\ncustomElements.define( 'tp-multi-select-search', TPMultiSelectSearchElement );\ncustomElements.define( 'tp-multi-select-pill', TPMultiSelectPillElement );\ncustomElements.define( 'tp-multi-select-pills', TPMultiSelectPillsElement );\ncustomElements.define( 'tp-multi-select-select-all', TPMultiSelectSelectAllElement );\n"],"names":["TPMultiSelectElement","HTMLElement","constructor","super","currentlyHighlightedOption","this","keyboardEventListener","handleKeyboardInputs","bind","document","addEventListener","handleDocumentClick","update","options","querySelector","MutationObserver","initialize","observe","childList","subtree","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","bubbles","unHighlightAllOptions","removeEventListener","value","Array","isArray","styledOptions","querySelectorAll","forEach","option","includes","getAttribute","setAttribute","removeAttribute","selectedOptions","optionValue","push","updateFormFieldValue","styledSelectedOptions","selectField","selectOptions","from","matchingSelectOption","find","selectOption","newOption","createElement","append","remove","Event","length","status","toString","e","target","contains","selectElement","innerHTML","formReference","select","unSelectAll","search","clear","focus","selectAll","unSelect","key","preventDefault","highlightNextOption","highlightPreviousOption","toggleHighlightedOption","nextToBeHighlighted","scrollIntoView","behavior","block","previousToBeHighlighted","toggle","TPMultiSelectFieldElement","toggleOpen","multiSelect","closest","TPMultiSelectPlaceholderElement","TPMultiSelectStatusElement","_name","format","html","replace","TPMultiSelectOptionsElement","TPMultiSelectOptionElement","stopPropagation","detail","TPMultiSelectSearchElement","input","handleSearchChange","handleClick","pill","removePill","matchedOptionCount","toLowerCase","match","RegExp","style","width","TPMultiSelectPillElement","handleButtonClick","TPMultiSelectPillsElement","pills","values","pillValues","pillValue","filter","multiSelectOption","appendChild","createPill","label","newPill","pillLabel","textContent","pillCloseButton","TPMultiSelectSelectAllElement","handleValueChanged","toggleSelectAll","optionNode","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/multi-select/index.js","mappings":"mBAWO,MAAMA,UAA6BC,YAUzC,WAAAC,GAECC,QARD,KAAAC,4BAAsC,EAWrCC,KAAKC,sBAAwBD,KAAKE,qBAAqBC,KAAMH,MAC7DI,SAASC,iBAAkB,QAASL,KAAKM,oBAAoBH,KAAMH,OACnEA,KAAKK,iBAAkB,SAAUL,KAAKO,OAAOJ,KAAMH,OAGnD,MAAMQ,EAA8CR,KAAKS,cAAe,2BAGnED,GACuC,IAAIE,iBAAkBV,KAAKW,WAAWR,KAAMH,OACtEY,QAASJ,EAAS,CAAEK,WAAW,EAAMC,SAAS,IAIhEd,KAAKW,YACN,CAOA,6BAAWI,GAEV,MAAO,CAAE,OACV,CASA,wBAAAC,CAA0BC,EAAe,GAAIC,EAAmB,GAAIC,EAAmB,IAEjFD,IAAaC,GAMb,SAAWF,IAEV,QAAUE,GACdf,SAASC,iBAAkB,UAAWL,KAAKC,uBAC3CD,KAAKoB,cAAe,IAAIC,YAAa,OAAQ,CAAEC,SAAS,OAExDtB,KAAKuB,wBACLnB,SAASoB,oBAAqB,UAAWxB,KAAKC,uBAC9CD,KAAKoB,cAAe,IAAIC,YAAa,QAAS,CAAEC,SAAS,MAG5D,CAOA,SAAIG,CAAOA,GAEV,IAAOA,IAAWC,MAAMC,QAASF,GAEhC,OAID,MAAMG,EAA+D5B,KAAK6B,iBAAkB,0BAC5FD,SAAAA,EAAeE,SAAWC,I,MAEpBN,EAAMO,SAAwC,QAA9B,EAAAD,EAAOE,aAAc,gBAAS,QAAI,IACtDF,EAAOG,aAAc,WAAY,OAEjCH,EAAOI,gBAAiB,W,IAK1BnC,KAAKoB,cAAe,IAAIC,YAAa,SAAU,CAAEC,SAAS,IAC3D,CAOA,SAAIG,GAEH,MAAMA,EAAkB,GAGlBW,EAAwDpC,KAAK6B,iBAAkB,2BAYrF,OAXAO,SAAAA,EAAiBN,SAAWC,IAE3B,MAAMM,EAAcN,EAAOE,aAAc,SAGpCI,GACJZ,EAAMa,KAAMD,E,IAKPZ,CACR,CAKU,oBAAAc,GAET,MAAMC,EAAuExC,KAAK6B,iBAAkB,0BAC9FY,EAAwCzC,KAAKS,cAAe,UAGlE,IAAO+B,IAA2BC,EAEjC,OAID,MAAMC,EAAqChB,MAAMiB,KAAMF,EAAYjC,SAGnEgC,EAAsBV,SAAWC,I,QAEhC,MAAMM,EAA4C,QAA9B,EAAAN,EAAOE,aAAc,gBAAS,QAAI,GAGtD,GAAKI,EAAc,CAClB,MAAMO,EAAsDF,EAAcG,MAAQC,GAAkBA,EAAarB,QAAUY,IAG3H,GAAK,QAAUN,EAAOE,aAAc,YAEnC,GAAKW,EACJA,EAAqBV,aAAc,WAAY,gBACzC,CACN,MAAMa,EAA+B3C,SAAS4C,cAAe,UAC7DD,EAAUb,aAAc,QAAuC,QAA9B,EAAAH,EAAOE,aAAc,gBAAS,QAAI,IACnEc,EAAUb,aAAc,WAAY,YACpCO,SAAAA,EAAaQ,OAAQF,E,MAGtBH,SAAAA,EAAsBM,Q,KAMzBT,EAAYrB,cAAe,IAAI+B,MAAO,UACvC,CAKA,MAAA5C,GAECP,KAAKuC,uBAGL,MAAMd,EAAkBzB,KAAKyB,MAGxB,IAAMA,EAAM2B,OAChBpD,KAAKkC,aAAc,WAAY,OAE/BlC,KAAKmC,gBAAiB,YAIvB,MAAMkB,EAA4CrD,KAAKS,cAAe,0BAGjE4C,IAEC5B,EAAM2B,OAAS,EACnBC,EAAOnB,aAAc,QAAST,EAAM2B,OAAOE,YAE3CD,EAAOlB,gBAAiB,SAG3B,CAOU,mBAAA7B,CAAqBiD,GAEzBvD,OAASuD,EAAEC,QAAYxD,KAAKyD,SAAUF,EAAEC,SAC5CxD,KAAKmC,gBAAiB,OAExB,CAKA,UAAAxB,G,MAEC,IAAI+C,EAA0C1D,KAAKS,cAAe,UAGlE,GAAOiD,EAoBNA,EAAcC,UAAY,OApBJ,CACtBD,EAAgBtD,SAAS4C,cAAe,UACxCU,EAAcxB,aAAc,OAAmC,QAA3B,EAAAlC,KAAKiC,aAAc,eAAQ,QAAI,IAGnE,MAAM2B,EAAgB5D,KAAKiC,aAAc,QAGpC2B,GACJF,EAAcxB,aAAc,OAAQ0B,GAIhC,OAAS5D,KAAKiC,aAAc,aAChCyB,EAAcxB,aAAc,WAAY,YAIzClC,KAAKiD,OAAQS,E,CAMd1D,KAAKO,QACN,CAOA,MAAAsD,CAAQpC,EAAgB,IAEvB,GAAK,OAASzB,KAAKiC,aAAc,cAEhCjC,KAAK8D,cAGA,KAAOrC,GAOX,YALK,QAAUzB,KAAKiC,aAAc,oBACjCjC,KAAKmC,gBAAiB,SASzB,MAAMK,EAAuExC,KAAK6B,iBAAkB,iCAAkCJ,OACtIe,SAAAA,EAAuBV,SAAWC,IAE5B,QAAUA,EAAOE,aAAc,aACnCF,EAAOG,aAAc,WAAY,M,IAKnC,MAAM6B,EAA4C/D,KAAKS,cAAe,0BACtEsD,SAAAA,EAAQC,QACRD,SAAAA,EAAQE,QAGH,QAAUjE,KAAKiC,aAAc,oBACjCjC,KAAKmC,gBAAiB,QAIvBnC,KAAKO,QACN,CAKA,SAAA2D,GAEC,MAAMtC,EAA+D5B,KAAK6B,iBAAkB,0BAC5FD,SAAAA,EAAeE,SAAWC,IAEpB,QAAUA,EAAOE,aAAc,aACnCF,EAAOG,aAAc,WAAY,M,IAKnClC,KAAKO,QACN,CAOA,QAAA4D,CAAU1C,EAAgB,IAEzB,MAAMe,EAAuExC,KAAK6B,iBAAkB,iCAAkCJ,OACtIe,SAAAA,EAAuBV,SAAWC,IAEjCA,EAAOI,gBAAiB,WAAY,IAIrCnC,KAAKO,QACN,CAKA,WAAAuD,GAEC,MAAMtB,EAAuExC,KAAK6B,iBAAkB,0BACpGW,SAAAA,EAAuBV,SAAWC,IAEjCA,EAAOI,gBAAiB,WAAY,IAIrCnC,KAAKO,QACN,CAOA,oBAAAL,CAAsBqD,GAErB,OAASA,EAAEa,KACV,IAAK,YACJb,EAAEc,iBACFrE,KAAKsE,sBACL,MACD,IAAK,UACJf,EAAEc,iBACFrE,KAAKuE,0BACL,MACD,IAAK,QACJvE,KAAKwE,0BACL,MACD,IAAK,SACJxE,KAAKuB,wBACLvB,KAAKmC,gBAAiB,QAGzB,CAKA,mBAAAmC,GAEC,MAAM9D,EAAyDR,KAAK6B,iBAAkB,8CAGtF,IAAOrB,EAIN,YAHAR,KAAKD,4BAA8B,GAOpC,IAAI0E,EAAsBzE,KAAKD,2BAA6B,EAG5D,KAAQ0E,EAAsBjE,EAAQ4C,QAAwE,QAA9D5C,EAASiE,GAAsBxC,aAAc,aAC5FwC,IAIIA,IAAwBjE,EAAQ4C,UAMK,IAArCpD,KAAKD,4BACTS,EAASR,KAAKD,4BAA6BoC,gBAAiB,eAI7D3B,EAASiE,GAAsBvC,aAAc,cAAe,OAG5D1B,EAASiE,GAAsBC,eAAgB,CAAEC,SAAU,SAAUC,MAAO,YAG5E5E,KAAKD,2BAA6B0E,EACnC,CAKA,uBAAAF,GAEC,MAAM/D,EAAyDR,KAAK6B,iBAAkB,8CAGtF,IAAOrB,EAIN,YAHAR,KAAKD,4BAA8B,GAOpC,IAAI8E,EAA0B7E,KAAKD,2BAA6B,EAGhE,KAAQ8E,GAA2B,GAAuE,QAAlErE,EAASqE,GAA0B5C,aAAc,aACxF4C,IAIIA,EAA0B,IAMU,IAApC7E,KAAKD,4BACTS,EAASR,KAAKD,4BAA6BoC,gBAAiB,eAI7D3B,EAASqE,GAA0B3C,aAAc,cAAe,OAGhE1B,EAASqE,GAA0BH,eAAgB,CAAEC,SAAU,SAAUC,MAAO,YAGhF5E,KAAKD,2BAA6B8E,EACnC,CAKA,uBAAAL,GAEC,MAAMzC,EAA4C/B,KAAKS,cAAe,6CACtEsB,SAAAA,EAAQ+C,OAAQ,KACjB,CAKA,qBAAAvD,GAECvB,KAAKD,4BAA8B,EAGnC,MAAMS,EAAyDR,KAAK6B,iBAAkB,0BAGjFrB,GACJA,EAAQsB,SAAWC,IAElBA,EAAOI,gBAAiB,cAAe,GAG1C,ECreM,MAAM4C,UAAkCnF,YAI9C,WAAAC,GAECC,QAGAE,KAAKK,iBAAkB,QAASL,KAAKgF,WAAW7E,KAAMH,MACvD,CAKA,UAAAgF,GAEC,MAAMC,EAA2CjF,KAAKkF,QAAS,mBAGxDD,IAMF,QAAUA,EAAYhD,aAAc,QACxCgD,EAAY9C,gBAAiB,QAE7B8C,EAAY/C,aAAc,OAAQ,OAEpC,ECpCM,MAAMiD,UAAwCvF,aCM9C,MAAMwF,UAAmCxF,YAM/C,6BAAWmB,GAEV,MAAO,CAAE,QAAS,SACnB,CASA,wBAAAC,CAA0BqE,EAAgB,GAAInE,EAAmB,GAAIC,EAAmB,IAElFD,IAAaC,GACjBnB,KAAKO,QAEP,CAKA,MAAAA,G,YAEC,MAAM+E,EAA8C,QAA7B,EAAAtF,KAAKiC,aAAc,iBAAU,QAAI,kBACxD,IAAIsD,EAAeD,EAAOE,QAAS,SAAsC,QAA5B,EAAAxF,KAAKiC,aAAc,gBAAS,QAAI,IAG7E,GAAKqD,EAAOtD,SAAU,UAAa,CAElC,MAAMiD,EAA2CjF,KAAKkF,QAAS,mBAG/D,GAAKD,EAAc,CAElB,MAAMxD,EAAmC,QAAjB,EAAAwD,EAAYxD,aAAK,QAAI,GAC7C,IAAI+D,EAAkB,GAGtB,GAAK/D,EAAM2B,OAAS,EAAI,CAEvB,MAAMrB,EAA4CkD,EAAYxE,cAAe,iCAAkCgB,EAAO,QAGjHM,IACJyD,EAAwC,QAA9B,EAAAzD,EAAOE,aAAc,gBAAS,QAAI,G,CAK9CsD,EAAOA,EAAKC,QAAS,SAAUA,E,EAKjCxF,KAAK2D,UAAY4B,CAClB,ECpEM,MAAME,UAAoC7F,aCK1C,MAAM8F,UAAmC9F,YAI/C,WAAAC,GAECC,QAGAE,KAAKK,iBAAkB,QAASL,KAAK8E,OAAO3E,KAAMH,MACnD,CAOA,MAAA8E,CAAQvB,G,MAEPA,SAAAA,EAAGc,iBACHd,SAAAA,EAAGoC,kBAGH,MAAMV,EAA2CjF,KAAKkF,QAAS,mBACzDzD,EAA4C,QAA5B,EAAAzB,KAAKiC,aAAc,gBAAS,QAAI,GAGjD,QAAUjC,KAAKiC,aAAc,aACjCgD,SAAAA,EAAapB,OAAQpC,GACrBwD,SAAAA,EAAa7D,cAAe,IAAIC,YAAa,SAAU,CACtDC,SAAS,EACTsE,OAAQ,CAAEnE,cAGXwD,SAAAA,EAAad,SAAU1C,GACvBwD,SAAAA,EAAa7D,cAAe,IAAIC,YAAa,WAAY,CACxDC,SAAS,EACTsE,OAAQ,CAAEnE,aAKZwD,SAAAA,EAAa7D,cAAe,IAAIC,YAAa,SAAU,CAAEC,SAAS,IACnE,ECzCM,MAAMuE,UAAmCjG,YAI/C,WAAAC,G,MAECC,QAGA,MAAMgG,EAAiC9F,KAAKS,cAAe,SAGpDqF,IAMPA,EAAMzF,iBAAkB,UAAWL,KAAKE,qBAAqBC,KAAMH,OACnE8F,EAAMzF,iBAAkB,QAASL,KAAK+F,mBAAmB5F,KAAMH,OAC/D8F,EAAMzF,iBAAkB,QAASL,KAAK+F,mBAAmB5F,KAAMH,OAC/DA,KAAKK,iBAAkB,QAASL,KAAKgG,YAAY7F,KAAMH,OACtB,QAAjC,EAAAA,KAAKkF,QAAS,0BAAmB,SAAE7E,iBAAkB,OAAQL,KAAKiE,MAAM9D,KAAMH,OAC/E,CAOA,oBAAAE,CAAsBqD,GAErB,MAAM0B,EAA2CjF,KAAKkF,QAAS,mBACzDnB,EAAkC/D,KAAKS,cAAe,SAG5D,GAAOwE,GAAiBlB,EAMxB,OAASR,EAAEa,KACV,IAAK,QACJb,EAAEc,iBACF,MACD,IAAK,YACJY,EAAY/C,aAAc,OAAQ,OAClC,MACD,IAAK,YACJ,GAAK,IAAM6B,EAAOtC,MAAM2B,OAAS,CAChC,MAAM6C,EAAwChB,EAAYxE,cAAe,qCAGpEwF,GACJA,EAAKC,Y,EAKV,CAKU,kBAAAH,G,MAET,MAAMd,EAA2CjF,KAAKkF,QAAS,mBACzDnB,EAAkC/D,KAAKS,cAAe,SACtDD,EAA+F,QAAjC,EAAAR,KAAKkF,QAAS,0BAAmB,eAAErD,iBAAkB,0BAGzH,IAAOoD,IAAiBlB,IAAYvD,EAEnC,OAID,IAAI2F,EAAqB,EACzB3F,EAAQsB,SAAWC,I,OAEiB,QAA9B,EAAAA,EAAOE,aAAc,gBAAS,eAAEmE,cAAcC,MAAO,IAAIC,OAAQ,KAAMvC,EAAOtC,MAAM2E,cAAcZ,QAAS,MAAO,cACtHzD,EAAOI,gBAAiB,UACxBgE,KAEApE,EAAOG,aAAc,SAAU,M,IAK5B,KAAO6B,EAAOtC,MAClBsC,EAAO5B,gBAAiB,UAExB4B,EAAOwC,MAAMC,MAAQ,GAAIzC,EAAOtC,MAAM2B,OAAS,MAC/C6B,EAAY/C,aAAc,OAAQ,QAInC+C,EAAY/C,aAAc,kBAAmBiE,EAAmB7C,WACjE,CAOU,WAAA0C,CAAazC,G,MAEtBA,EAAEc,iBACFd,EAAEoC,kBAGF3F,KAAKoB,cAAe,IAAIC,YAAa,wBACrCjB,SAASgB,cAAe,IAAI+B,MAAO,UAGF,QAAjC,EAAAnD,KAAKkF,QAAS,0BAAmB,SAAEhD,aAAc,OAAQ,MAC1D,CAKA,KAAA8B,GAEC,MAAMD,EAAkC/D,KAAKS,cAAe,SAGvDsD,IAEJA,EAAOtC,MAAQ,GACfsC,EAAO3C,cAAe,IAAI+B,MAAO,WAEnC,CAKA,KAAAc,G,MAECjE,KAAK+F,qBAGwB,QAA7B,EAAA/F,KAAKS,cAAe,gBAAS,SAAEwD,OAChC,ECjJM,MAAMwC,UAAiC7G,YAI7C,WAAAC,G,MAECC,QAG8B,QAA9B,EAAAE,KAAKS,cAAe,iBAAU,SAAEJ,iBAAkB,QAASL,KAAK0G,kBAAkBvG,KAAMH,MACzF,CAOA,iBAAA0G,CAAmBnD,GAElBA,SAAAA,EAAGc,iBACHd,SAAAA,EAAGoC,kBAGH3F,KAAKkG,YACN,CAKA,UAAAA,G,MAEC,MAAMjB,EAA2CjF,KAAKkF,QAAS,mBAG1DD,GAAejF,KAAKiC,aAAc,WACtCgD,EAAYd,SAAsC,QAA5B,EAAAnE,KAAKiC,aAAc,gBAAS,QAAI,IACtDgD,EAAY7D,cAAe,IAAIC,YAAa,WAAY,CAAEC,SAAS,KACnE2D,EAAY7D,cAAe,IAAIC,YAAa,SAAU,CAAEC,SAAS,KAEnE,ECrCM,MAAMqF,UAAkC/G,YAI9C,WAAAC,G,UAECC,QAGiC,QAAjC,EAAAE,KAAKkF,QAAS,0BAAmB,SAAE7E,iBAAkB,SAAUL,KAAKO,OAAOJ,KAAMH,OACrB,QAA5D,EAAiC,QAAjC,EAAAA,KAAKkF,QAAS,0BAAmB,eAAEzE,cAAe,iBAAU,SAAEJ,iBAAkB,UAAU,IAAQL,KAAKO,WAGvGP,KAAKO,QACN,CAKA,MAAAA,G,MAEC,MAAM0E,EAA2CjF,KAAKkF,QAAS,mBAG/D,IAAOD,EAEN,OAID,MAAM2B,EAAqD5G,KAAK6B,iBAAkB,wBAC5EgF,EAAsD,QAAnC,MAAK,IAAIC,IAAK7B,EAAYxD,eAAS,QAAI,GAC1DsF,EAAuB,GAG7BH,EAAM9E,SAAWmE,I,MAEhB,MAAMe,EAAgD,QAA5B,EAAAf,EAAKhE,aAAc,gBAAS,QAAI,GAGrD,KAAO+E,IAMZD,EAAWzE,KAAM0E,GAGVH,EAAO7E,SAAUgF,IACvBf,EAAK/C,S,IAKyB2D,EAAOI,QAAUxF,IAAqBsF,EAAW/E,SAAUP,KAG7EK,SAAWkF,I,MAExB,GAAK,KAAOA,EAEX,OAID,MAAME,EAAuDjC,EAAYxE,cAAe,iCAAkCuG,OAGnHE,GAMPlH,KAAKmH,YAAanH,KAAKoH,WAAYJ,EAAoD,QAAzC,EAAAE,EAAkBjF,aAAc,gBAAS,QAAI,IAAM,GAEnG,CAUA,UAAAmF,CAAY3F,EAAe4F,GAE1B,MAAMC,EAAUlH,SAAS4C,cAAe,wBACxCsE,EAAQpF,aAAc,QAAST,GAG/B,MAAM8F,EAAyBnH,SAAS4C,cAAe,QACvDuE,EAAUC,YAAcH,EAGxB,MAAMI,EAA+BrH,SAAS4C,cAAe,UAe7D,OAdAyE,EAAgBvF,aAAc,OAAQ,UACtCuF,EAAgBD,YAAc,IAG9BC,EAAgBpH,iBAAkB,SAAS,KAE1CiH,EAAQpB,YAAY,IAIrBoB,EAAQH,YAAaI,GACrBD,EAAQH,YAAaM,GAGdH,CACR,EClHM,MAAMI,UAAsC9H,YAIlD,WAAAC,G,MAECC,QAGiC,QAAjC,EAAAE,KAAKkF,QAAS,0BAAmB,SAAE7E,iBAAkB,SAAUL,KAAK2H,mBAAmBxH,KAAMH,OAC7FA,KAAKK,iBAAkB,QAASL,KAAK4H,gBAAgBzH,KAAMH,MAC5D,CAKA,kBAAA2H,G,QAEC,MAAM1C,EAA2CjF,KAAKkF,QAAS,mBACzD1E,EAAqEyE,aAAW,EAAXA,EAAapD,iBAAkB,0BAGnGoD,GAAiBzE,IAMnBkB,MAAMiB,KAAMnC,GAAUyG,QAAUY,GAA0D,QAA1CA,EAAW5F,aAAc,cAAyBmB,SAAW6B,EAAYxD,MAAM2B,QACnIpD,KAAKkC,aAAc,WAAY,OAC/BlC,KAAK2D,UAAgD,QAApC,EAAA3D,KAAKiC,aAAc,wBAAiB,QAAI,KAEzDjC,KAAKmC,gBAAiB,YACtBnC,KAAK2D,UAA8C,QAAlC,EAAA3D,KAAKiC,aAAc,sBAAe,QAAI,IAEzD,CAKA,eAAA2F,GAEC,MAAM3C,EAA2CjF,KAAKkF,QAAS,mBAGxDD,IAMF,QAAUjF,KAAKiC,aAAc,aACjCgD,EAAYf,YACZe,EAAY7D,cAAe,IAAIC,YAAa,aAAc,CAAEC,SAAS,OAErE2D,EAAYnB,cACZmB,EAAY7D,cAAe,IAAIC,YAAa,eAAgB,CAAEC,SAAS,MAIxE2D,EAAY7D,cAAe,IAAIC,YAAa,SAAU,CAAEC,SAAS,KAClE,EChDDwG,eAAeC,OAAQ,kBAAmBpI,GAC1CmI,eAAeC,OAAQ,wBAAyBhD,GAChD+C,eAAeC,OAAQ,8BAA+B5C,GACtD2C,eAAeC,OAAQ,yBAA0B3C,GACjD0C,eAAeC,OAAQ,0BAA2BtC,GAClDqC,eAAeC,OAAQ,yBAA0BrC,GACjDoC,eAAeC,OAAQ,yBAA0BlC,GACjDiC,eAAeC,OAAQ,uBAAwBtB,GAC/CqB,eAAeC,OAAQ,wBAAyBpB,GAChDmB,eAAeC,OAAQ,6BAA8BL,E","sources":["webpack://@travelopia/web-components/./src/multi-select/tp-multi-select.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-field.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-placeholder.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-status.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-options.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-option.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-search.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pill.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pills.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-select-all.ts","webpack://@travelopia/web-components/./src/multi-select/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\n\n/**\n * TP Multi Select.\n */\nexport class TPMultiSelectElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tcurrentlyHighlightedOption: number = -1;\n\tprotected keyboardEventListener: EventListener;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.keyboardEventListener = this.handleKeyboardInputs.bind( this ) as EventListener;\n\t\tdocument.addEventListener( 'click', this.handleDocumentClick.bind( this ) );\n\t\tthis.addEventListener( 'change', this.update.bind( this ) );\n\n\t\t// Get options.\n\t\tconst options: TPMultiSelectOptionsElement | null = this.querySelector( 'tp-multi-select-options' );\n\n\t\t// Listen for dynamic changes to the option values.\n\t\tif ( options ) {\n\t\t\tconst mutationObserver: MutationObserver = new MutationObserver( this.initialize.bind( this ) );\n\t\t\tmutationObserver.observe( options, { childList: true, subtree: true } );\n\t\t}\n\n\t\t// Initialize component.\n\t\tthis.initialize();\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'open' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// If no changes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Changed attribute name is 'open'.\n\t\tif ( 'open' === name ) {\n\t\t\t// If new value is 'yes' then open the dropdown.\n\t\t\tif ( 'yes' === newValue ) {\n\t\t\t\tdocument.addEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'open', { bubbles: true } ) );\n\t\t\t} else {\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tdocument.removeEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'close', { bubbles: true } ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set the value of this component.\n\t *\n\t * @param {Array} value Value.\n\t */\n\tset value( value: string[] ) {\n\t\t// Bail if value is not an array.\n\t\tif ( ! value || ! Array.isArray( value ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value of the select field.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Check if the value is in the array.\n\t\t\tif ( value.includes( option.getAttribute( 'value' ) ?? '' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t} else {\n\t\t\t\toption.removeAttribute( 'selected' );\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch change event.\n\t\tthis.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n\n\t/**\n\t * Get the value of this component.\n\t *\n\t * @return {Array} Value of this component.\n\t */\n\tget value(): string[] {\n\t\t// Get the value of the select field.\n\t\tconst value: string[] = [];\n\n\t\t// Get selected options.\n\t\tconst selectedOptions: NodeListOf<HTMLOptionElement> | null = this.querySelectorAll( 'select option[selected]' );\n\t\tselectedOptions?.forEach( ( option: HTMLOptionElement ) => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' );\n\n\t\t\t// Add value to array.\n\t\t\tif ( optionValue ) {\n\t\t\t\tvalue.push( optionValue );\n\t\t\t}\n\t\t} );\n\n\t\t// Return value.\n\t\treturn value;\n\t}\n\n\t/**\n\t * Update the value of the select field.\n\t */\n\tprotected updateFormFieldValue(): void {\n\t\t// Get options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option` );\n\t\tconst selectField: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Bail if there's no styled selected options or select field.\n\t\tif ( ! styledSelectedOptions || ! selectField ) {\n\t\t\t// Bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get selected options.\n\t\tconst selectOptions: HTMLOptionElement[] = Array.from( selectField.options );\n\n\t\t// Traverse options.\n\t\tstyledSelectedOptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' ) ?? '';\n\n\t\t\t// If option value is present.\n\t\t\tif ( optionValue ) {\n\t\t\t\tconst matchingSelectOption: HTMLOptionElement | undefined = selectOptions.find( ( selectOption ) => selectOption.value === optionValue );\n\n\t\t\t\t// Update select field.\n\t\t\t\tif ( 'yes' === option.getAttribute( 'selected' ) ) {\n\t\t\t\t\t// Update select field.\n\t\t\t\t\tif ( matchingSelectOption ) {\n\t\t\t\t\t\tmatchingSelectOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst newOption: HTMLOptionElement = document.createElement( 'option' );\n\t\t\t\t\t\tnewOption.setAttribute( 'value', option.getAttribute( 'value' ) ?? '' );\n\t\t\t\t\t\tnewOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t\tselectField?.append( newOption );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmatchingSelectOption?.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch events.\n\t\tselectField.dispatchEvent( new Event( 'change' ) );\n\t}\n\n\t/**\n\t * Update component and sub-components.\n\t */\n\tupdate(): void {\n\t\t// First, update field value.\n\t\tthis.updateFormFieldValue();\n\n\t\t// Get value.\n\t\tconst value: string[] = this.value;\n\n\t\t// Toggle selected attribute.\n\t\tif ( 0 !== value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t}\n\n\t\t// Get status.\n\t\tconst status: TPMultiSelectStatusElement | null = this.querySelector( 'tp-multi-select-status' );\n\n\t\t// Update status.\n\t\tif ( status ) {\n\t\t\t// Update status.\n\t\t\tif ( value.length > 0 ) {\n\t\t\t\tstatus.setAttribute( 'total', value.length.toString() );\n\t\t\t} else {\n\t\t\t\tstatus.removeAttribute( 'total' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle clicking the document.\n\t *\n\t * @param {Event} e Event.\n\t */\n\tprotected handleDocumentClick( e: Event ): void {\n\t\t// Close on click outside.\n\t\tif ( this !== e.target && ! this.contains( e.target as Node ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\t}\n\n\t/**\n\t * Initialize component.\n\t */\n\tinitialize(): void {\n\t\t// Get select element.\n\t\tlet selectElement: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Create select element (if it doesn't already exist).\n\t\tif ( ! selectElement ) {\n\t\t\tselectElement = document.createElement( 'select' );\n\t\t\tselectElement.setAttribute( 'name', this.getAttribute( 'name' ) ?? '' );\n\n\t\t\t// Get form reference.\n\t\t\tconst formReference = this.getAttribute( 'form' );\n\n\t\t\t// Add form reference.\n\t\t\tif ( formReference ) {\n\t\t\t\tselectElement.setAttribute( 'form', formReference );\n\t\t\t}\n\n\t\t\t// Set multiple.\n\t\t\tif ( 'no' !== this.getAttribute( 'multiple' ) ) {\n\t\t\t\tselectElement.setAttribute( 'multiple', 'multiple' );\n\t\t\t}\n\n\t\t\t// Append.\n\t\t\tthis.append( selectElement );\n\t\t} else {\n\t\t\tselectElement.innerHTML = '';\n\t\t}\n\n\t\t// Update components for selected options.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select a value.\n\t *\n\t * @param {string} value Value to select.\n\t */\n\tselect( value: string = '' ): void {\n\t\t// Stuff for single-select.\n\t\tif ( 'no' === this.getAttribute( 'multiple' ) ) {\n\t\t\t// First, unselect everything.\n\t\t\tthis.unSelectAll();\n\n\t\t\t// If the value is blank, don't do anything else.\n\t\t\tif ( '' === value ) {\n\t\t\t\t// Close the field, if applicable.\n\t\t\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\t}\n\n\t\t\t\t// Exit.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Select all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Search stuff.\n\t\tconst search: TPMultiSelectSearchElement | null = this.querySelector( 'tp-multi-select-search' );\n\t\tsearch?.clear();\n\t\tsearch?.focus();\n\n\t\t// Close the field, if applicable.\n\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select all values.\n\t */\n\tselectAll(): void {\n\t\t// Get all options.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select a value.\n\t *\n\t * @param {string} value Value to unselect.\n\t */\n\tunSelect( value: string = '' ): void {\n\t\t// Get all options with the specified value.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select all values.\n\t */\n\tunSelectAll(): void {\n\t\t// Get all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Keyboard events.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightNextOption();\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightPreviousOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Enter':\n\t\t\t\tthis.toggleHighlightedOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Escape':\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Highlight the next option.\n\t */\n\thighlightNextOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the next option to be highlighted. Assume next option is the favorable option.\n\t\tlet nextToBeHighlighted = this.currentlyHighlightedOption + 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( nextToBeHighlighted < options.length && options[ nextToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tnextToBeHighlighted++;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit. Here, the last highlighted option keeps highlighted.\n\t\tif ( nextToBeHighlighted === options.length ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== -1 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ nextToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ nextToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = nextToBeHighlighted;\n\t}\n\n\t/**\n\t * Highlight previous option.\n\t */\n\thighlightPreviousOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the previous option to be highlighted. Assume previous option is the favorable option.\n\t\tlet previousToBeHighlighted = this.currentlyHighlightedOption - 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( previousToBeHighlighted >= 0 && options[ previousToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tpreviousToBeHighlighted--;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit.\n\t\tif ( previousToBeHighlighted < 0 ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== 0 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ previousToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ previousToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = previousToBeHighlighted;\n\t}\n\n\t/**\n\t * Toggle highlighted option.\n\t */\n\ttoggleHighlightedOption(): void {\n\t\t// Get option and if it exists set it to null.\n\t\tconst option: TPMultiSelectOptionElement | null = this.querySelector( `tp-multi-select-option[highlighted=\"yes\"]` );\n\t\toption?.toggle( null );\n\t}\n\n\t/**\n\t * Un-highlight all options.\n\t */\n\tunHighlightAllOptions(): void {\n\t\t// Reset the currentlyHighlightedOption.\n\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// If there are options, un-highlight them.\n\t\tif ( options ) {\n\t\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t\t// Remove highlighted attribute.\n\t\t\t\toption.removeAttribute( 'highlighted' );\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Field.\n */\nexport class TPMultiSelectFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.addEventListener( 'click', this.toggleOpen.bind( this ) );\n\t}\n\n\t/**\n\t * Toggle opening this component.\n\t */\n\ttoggleOpen(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail early if we don't have a multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle open.\n\t\tif ( 'yes' === multiSelect.getAttribute( 'open' ) ) {\n\t\t\tmultiSelect.removeAttribute( 'open' );\n\t\t} else {\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\t}\n}\n","/**\n * TP Multi Select Placeholder.\n */\nexport class TPMultiSelectPlaceholderElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Status.\n */\nexport class TPMultiSelectStatusElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'total', 'format' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} _name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( _name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Update component.\n\t\tif ( oldValue !== newValue ) {\n\t\t\tthis.update();\n\t\t}\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get format attribute.\n\t\tconst format: string = this.getAttribute( 'format' ) ?? '$total Selected';\n\t\tlet html: string = format.replace( '$total', this.getAttribute( 'total' ) ?? '' );\n\n\t\t// Format string includes $value.\n\t\tif ( format.includes( '$value' ) ) {\n\t\t\t// Get multi-select.\n\t\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t\t// Check if multi-select exists.\n\t\t\tif ( multiSelect ) {\n\t\t\t\t// Get value if present or create an empty array.\n\t\t\t\tconst value: string[] = multiSelect.value ?? [];\n\t\t\t\tlet replace: string = '';\n\n\t\t\t\t// Check if value array is not empty.\n\t\t\t\tif ( value.length > 0 ) {\n\t\t\t\t\t// Get first value.\n\t\t\t\t\tconst option: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ value[ 0 ] }\"]` );\n\n\t\t\t\t\t// Check if option exists.\n\t\t\t\t\tif ( option ) {\n\t\t\t\t\t\treplace = option.getAttribute( 'label' ) ?? '';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Replace $value.\n\t\t\t\thtml = html.replace( '$value', replace );\n\t\t\t}\n\t\t}\n\n\t\t// Set inner HTML.\n\t\tthis.innerHTML = html;\n\t}\n}\n","/**\n * TP Multi Select Options.\n */\nexport class TPMultiSelectOptionsElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Option.\n */\nexport class TPMultiSelectOptionElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener to toggle the selected state.\n\t\tthis.addEventListener( 'click', this.toggle.bind( this ) );\n\t}\n\n\t/**\n\t * Select / un-select this option.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\ttoggle( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Get multi-select element and value of option.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst value: string = this.getAttribute( 'value' ) ?? '';\n\n\t\t// Toggle selected state. Dispatch custom events accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect?.select( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'select', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t} else {\n\t\t\tmultiSelect?.unSelect( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'unselect', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\n\n/**\n * TP Multi Select Search.\n */\nexport class TPMultiSelectSearchElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// get input.\n\t\tconst input: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if input exists.\n\t\tif ( ! input ) {\n\t\t\t// No, its not. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Add event listeners.\n\t\tinput.addEventListener( 'keydown', this.handleKeyboardInputs.bind( this ) );\n\t\tinput.addEventListener( 'keyup', this.handleSearchChange.bind( this ) );\n\t\tinput.addEventListener( 'input', this.handleSearchChange.bind( this ) );\n\t\tthis.addEventListener( 'click', this.handleClick.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'open', this.focus.bind( this ) );\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Get multi select and search field.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if multi select and search field exists.\n\t\tif ( ! multiSelect || ! search ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle keyboard inputs.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'Enter':\n\t\t\t\te.preventDefault(); // Prevent inadvertent form submits.\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowDown':\n\t\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t\t\tbreak;\n\t\t\tcase 'Backspace': // Remove last pill if search is empty.\n\t\t\t\tif ( 0 === search.value.length ) {\n\t\t\t\t\tconst pill: TPMultiSelectPillElement | null = multiSelect.querySelector( 'tp-multi-select-pill:last-of-type' );\n\n\t\t\t\t\t// Check if pill exists, remove it.\n\t\t\t\t\tif ( pill ) {\n\t\t\t\t\t\tpill.removePill();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Handle search field value changed.\n\t */\n\tprotected handleSearchChange(): void {\n\t\t// Get search field and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | undefined = this.closest( 'tp-multi-select' )?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select, search, and options field exists.\n\t\tif ( ! multiSelect || ! search || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize matched option count.\n\t\tlet matchedOptionCount = 0;\n\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Hide and show options based on search.\n\t\t\tif ( option.getAttribute( 'label' )?.toLowerCase().match( new RegExp( `.*${ search.value.toLowerCase().replace( /\\s/g, '.*' ) }.*` ) ) ) {\n\t\t\t\toption.removeAttribute( 'hidden' );\n\t\t\t\tmatchedOptionCount++;\n\t\t\t} else {\n\t\t\t\toption.setAttribute( 'hidden', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Resize input width.\n\t\tif ( '' === search.value ) {\n\t\t\tsearch.removeAttribute( 'style' );\n\t\t} else {\n\t\t\tsearch.style.width = `${ search.value.length + 2 }ch`;\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\n\t\t// Show matched option count.\n\t\tmultiSelect.setAttribute( 'visible-options', matchedOptionCount.toString() );\n\t}\n\n\t/**\n\t * Handle click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\tprotected handleClick( e: Event ): void {\n\t\t// First, prevent propagation to avoid document.click set on `tp-multi-select`.\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\t// Now send the event so other stuff can work as per normal, and another event for good measure.\n\t\tthis.dispatchEvent( new CustomEvent( 'multi-select-opened' ) );\n\t\tdocument.dispatchEvent( new Event( 'click' ) );\n\n\t\t// Open multi select.\n\t\tthis.closest( 'tp-multi-select' )?.setAttribute( 'open', 'yes' );\n\t}\n\n\t/**\n\t * Clear the search field.\n\t */\n\tclear(): void {\n\t\t// Clear search field.\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if search field exists.\n\t\tif ( search ) {\n\t\t\t// Set value to empty string and dispatch change event.\n\t\t\tsearch.value = '';\n\t\t\tsearch.dispatchEvent( new Event( 'change' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Set focus on the search field.\n\t */\n\tfocus(): void {\n\t\t// When it's focused, use search change to ensure the results are refreshed.\n\t\tthis.handleSearchChange();\n\n\t\t// Focus on input.\n\t\tthis.querySelector( 'input' )?.focus();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Pill.\n */\nexport class TPMultiSelectPillElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleButtonClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle button click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\thandleButtonClick( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Remove pill.\n\t\tthis.removePill();\n\t}\n\n\t/**\n\t * Remove this pill.\n\t */\n\tremovePill(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Unselect value.\n\t\tif ( multiSelect && this.getAttribute( 'value' ) ) {\n\t\t\tmultiSelect.unSelect( this.getAttribute( 'value' ) ?? '' );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect', { bubbles: true } ) );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Pills.\n */\nexport class TPMultiSelectPillsElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.update.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.querySelector( 'select' )?.addEventListener( 'change', ( () => this.update() ) as EventListener );\n\n\t\t// Update.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail if there's no multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine pills.\n\t\tconst pills: NodeListOf<TPMultiSelectPillElement> | null = this.querySelectorAll( 'tp-multi-select-pill' );\n\t\tconst values: string[] = [ ...new Set( multiSelect.value ) ] ?? [];\n\t\tconst pillValues: string[] = [];\n\n\t\t// Remove pills that shouldn't exist.\n\t\tpills.forEach( ( pill: TPMultiSelectPillElement ): void => {\n\t\t\t// Get pill value.\n\t\t\tconst pillValue: string = pill.getAttribute( 'value' ) ?? '';\n\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill value to the array.\n\t\t\tpillValues.push( pillValue );\n\n\t\t\t// Remove pill if it doesn't exist in the values.\n\t\t\tif ( ! values.includes( pillValue ) ) {\n\t\t\t\tpill.remove();\n\t\t\t}\n\t\t} );\n\n\t\t// Create new pills.\n\t\tconst pillsToCreate: string[] = values.filter( ( value: string ) => ! pillValues.includes( value ) );\n\n\t\t// Create pills.\n\t\tpillsToCreate.forEach( ( pillValue: string ): void => {\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get multi-select option.\n\t\t\tconst multiSelectOption: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ pillValue }\"]` );\n\n\t\t\t// Bail early if there's no multi-select option.\n\t\t\tif ( ! multiSelectOption ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill.\n\t\t\tthis.appendChild( this.createPill( pillValue, multiSelectOption.getAttribute( 'label' ) ?? '' ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Create a new pill.\n\t *\n\t * @param {string} value Pill value.\n\t * @param {string} label Pill label.\n\t *\n\t * @return {TPMultiSelectPillElement} New pill.\n\t */\n\tcreatePill( value: string, label: string ): TPMultiSelectPillElement {\n\t\t// Create pill and set value attribute.\n\t\tconst newPill = document.createElement( 'tp-multi-select-pill' ) as TPMultiSelectPillElement;\n\t\tnewPill.setAttribute( 'value', value );\n\n\t\t// Create pill label.\n\t\tconst pillLabel: HTMLElement = document.createElement( 'span' );\n\t\tpillLabel.textContent = label;\n\n\t\t// Create pill close button.\n\t\tconst pillCloseButton: HTMLElement = document.createElement( 'button' );\n\t\tpillCloseButton.setAttribute( 'type', 'button' );\n\t\tpillCloseButton.textContent = 'x';\n\n\t\t// Add event listener.\n\t\tpillCloseButton.addEventListener( 'click', () => {\n\t\t\t// On click, run removePill method.\n\t\t\tnewPill.removePill();\n\t\t} );\n\n\t\t// Append label and close button to pill.\n\t\tnewPill.appendChild( pillLabel );\n\t\tnewPill.appendChild( pillCloseButton );\n\n\t\t// Return newPill element.\n\t\treturn newPill;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Select All.\n */\nexport class TPMultiSelectSelectAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listeners.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.handleValueChanged.bind( this ) );\n\t\tthis.addEventListener( 'click', this.toggleSelectAll.bind( this ) );\n\t}\n\n\t/**\n\t * Handle value changed.\n\t */\n\thandleValueChanged(): void {\n\t\t// Get multi select and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null | undefined = multiSelect?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select and options exists.\n\t\tif ( ! multiSelect || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if all options are selected.\n\t\tif ( Array.from( options ).filter( ( optionNode ) => optionNode.getAttribute( 'disabled' ) !== 'yes' ).length === multiSelect.value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t\tthis.innerHTML = this.getAttribute( 'unselect-text' ) ?? '';\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t\tthis.innerHTML = this.getAttribute( 'select-text' ) ?? '';\n\t\t}\n\t}\n\n\t/**\n\t * Toggle select all.\n\t */\n\ttoggleSelectAll(): void {\n\t\t// Get multi select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if multi select exists.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if select all is yes. Apply selectAll and unselectAll methods accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect.selectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'select-all', { bubbles: true } ) );\n\t\t} else {\n\t\t\tmultiSelect.unSelectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect-all', { bubbles: true } ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectFieldElement } from './tp-multi-select-field';\nimport { TPMultiSelectPlaceholderElement } from './tp-multi-select-placeholder';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectPillsElement } from './tp-multi-select-pills';\nimport { TPMultiSelectSelectAllElement } from './tp-multi-select-select-all';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-multi-select', TPMultiSelectElement );\ncustomElements.define( 'tp-multi-select-field', TPMultiSelectFieldElement );\ncustomElements.define( 'tp-multi-select-placeholder', TPMultiSelectPlaceholderElement );\ncustomElements.define( 'tp-multi-select-status', TPMultiSelectStatusElement );\ncustomElements.define( 'tp-multi-select-options', TPMultiSelectOptionsElement );\ncustomElements.define( 'tp-multi-select-option', TPMultiSelectOptionElement );\ncustomElements.define( 'tp-multi-select-search', TPMultiSelectSearchElement );\ncustomElements.define( 'tp-multi-select-pill', TPMultiSelectPillElement );\ncustomElements.define( 'tp-multi-select-pills', TPMultiSelectPillsElement );\ncustomElements.define( 'tp-multi-select-select-all', TPMultiSelectSelectAllElement );\n"],"names":["TPMultiSelectElement","HTMLElement","constructor","super","currentlyHighlightedOption","this","keyboardEventListener","handleKeyboardInputs","bind","document","addEventListener","handleDocumentClick","update","options","querySelector","MutationObserver","initialize","observe","childList","subtree","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","bubbles","unHighlightAllOptions","removeEventListener","value","Array","isArray","styledOptions","querySelectorAll","forEach","option","includes","getAttribute","setAttribute","removeAttribute","selectedOptions","optionValue","push","updateFormFieldValue","styledSelectedOptions","selectField","selectOptions","from","matchingSelectOption","find","selectOption","newOption","createElement","append","remove","Event","length","status","toString","e","target","contains","selectElement","innerHTML","formReference","select","unSelectAll","search","clear","focus","selectAll","unSelect","key","preventDefault","highlightNextOption","highlightPreviousOption","toggleHighlightedOption","nextToBeHighlighted","scrollIntoView","behavior","block","previousToBeHighlighted","toggle","TPMultiSelectFieldElement","toggleOpen","multiSelect","closest","TPMultiSelectPlaceholderElement","TPMultiSelectStatusElement","_name","format","html","replace","TPMultiSelectOptionsElement","TPMultiSelectOptionElement","stopPropagation","detail","TPMultiSelectSearchElement","input","handleSearchChange","handleClick","pill","removePill","matchedOptionCount","toLowerCase","match","RegExp","style","width","TPMultiSelectPillElement","handleButtonClick","TPMultiSelectPillsElement","pills","values","Set","pillValues","pillValue","filter","multiSelectOption","appendChild","createPill","label","newPill","pillLabel","textContent","pillCloseButton","TPMultiSelectSelectAllElement","handleValueChanged","toggleSelectAll","optionNode","customElements","define"],"sourceRoot":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travelopia/web-components",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "Accessible web components for the modern web",
5
5
  "files": [
6
6
  "dist"