@travelopia/web-components 0.9.10 → 0.9.12

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.
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";class t extends HTMLElement{static get observedAttributes(){return["collapse-all","expand-all"]}attributeChangedCallback(t="",e="",s=""){e!==s&&(this.update(),"yes"!==s||"collapse-all"!==t&&"expand-all"!==t||this.dispatchEvent(new CustomEvent(t,{bubbles:!0})))}update(){const t=this.querySelectorAll("tp-accordion-item");if(!t)return;let e="";"yes"===this.getAttribute("expand-all")?e="expand-all":"yes"===this.getAttribute("collapse-all")&&(e="collapse-all"),""!==e&&t.forEach((t=>{"expand-all"===e?t.setAttribute("open","yes"):"collapse-all"===e&&t.removeAttribute("open")}))}}class e extends HTMLElement{}class s extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.toggle.bind(this))}toggle(){const t=this.closest("tp-accordion-item");t&&("yes"!==t.getAttribute("open")?t.setAttribute("open","yes"):t.removeAttribute("open"))}}class o extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",(()=>this.collapseAll()))}collapseAll(){const t=this.closest("tp-accordion");t&&(t.removeAttribute("expand-all"),t.setAttribute("collapse-all","yes"))}}class n extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.expandAll.bind(this))}expandAll(){const t=this.closest("tp-accordion");t&&(t.setAttribute("expand-all","yes"),t.removeAttribute("collapse-all"))}}class i extends HTMLElement{constructor(){super(),"yes"===this.getAttribute("open-by-default")&&this.setAttribute("open","yes"),this.setupAriaControls(),this.updateAriaState("yes"===this.getAttribute("open")),this.setupBeforeMatchListener()}setupBeforeMatchListener(){const t=this.querySelector("tp-accordion-content");t&&t.addEventListener("beforematch",(()=>{this.setAttribute("open","yes")}))}setupAriaControls(){if(!this.isAriaEnabled())return;const t=this.querySelector("tp-accordion-handle button"),e=this.querySelector("tp-accordion-content");t&&e&&(e.id||(e.id=`tp-accordion-content-${Math.random().toString(36).substring(2,9)}`),t.hasAttribute("aria-controls")||t.setAttribute("aria-controls",e.id))}isAriaEnabled(){const t=this.closest("tp-accordion");return"no"!==(null==t?void 0:t.getAttribute("aria"))}updateAriaState(t){if(!this.isAriaEnabled())return;const e=this.querySelector("tp-accordion-handle button"),s=this.querySelector("tp-accordion-content");e&&e.setAttribute("aria-expanded",t?"true":"false"),s&&(t?s.removeAttribute("hidden"):s.setAttribute("hidden","until-found"))}static get observedAttributes(){return["open"]}attributeChangedCallback(t,e,s){e!==s&&"open"===t&&("yes"===s?this.open():this.close(),this.removeAttribute("open-by-default"))}open(){const t=this.querySelector("tp-accordion-content");t&&(this.dispatchEvent(new CustomEvent("before-open",{bubbles:!0})),this.updateAriaState(!0),((t,e=300,s=()=>{})=>{t.style.height=`${t.scrollHeight}px`,setTimeout((()=>{t.style.height="auto",s&&s()}),e)})(t,600),this.dispatchEvent(new CustomEvent("open",{bubbles:!0})))}close(){const t=this.querySelector("tp-accordion-content");t&&(this.dispatchEvent(new CustomEvent("before-close",{bubbles:!0})),((t,e=300,s=()=>{})=>{t.style.height=`${t.scrollHeight}px`,t.offsetHeight,t.style.height="0px",setTimeout((()=>{t.style.height="0px",s&&s()}),e)})(t,600,(()=>{this.updateAriaState(!1),this.dispatchEvent(new CustomEvent("close",{bubbles:!0}))})))}}customElements.define("tp-accordion",t),customElements.define("tp-accordion-content",e),customElements.define("tp-accordion-handle",s),customElements.define("tp-accordion-collapse-all",o),customElements.define("tp-accordion-expand-all",n),customElements.define("tp-accordion-item",i)})();
1
+ (()=>{"use strict";class t extends HTMLElement{static get observedAttributes(){return["collapse-all","expand-all"]}attributeChangedCallback(t="",e="",s=""){e!==s&&(this.update(),"yes"!==s||"collapse-all"!==t&&"expand-all"!==t||this.dispatchEvent(new CustomEvent(t,{bubbles:!0})))}update(){const t=this.querySelectorAll("tp-accordion-item");if(!t)return;let e="";"yes"===this.getAttribute("expand-all")?e="expand-all":"yes"===this.getAttribute("collapse-all")&&(e="collapse-all"),""!==e&&t.forEach(t=>{"expand-all"===e?t.setAttribute("open","yes"):"collapse-all"===e&&t.removeAttribute("open")})}}class e extends HTMLElement{}class s extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.toggle.bind(this))}toggle(){const t=this.closest("tp-accordion-item");t&&("yes"!==t.getAttribute("open")?t.setAttribute("open","yes"):t.removeAttribute("open"))}}class o extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",()=>this.collapseAll())}collapseAll(){const t=this.closest("tp-accordion");t&&(t.removeAttribute("expand-all"),t.setAttribute("collapse-all","yes"))}}class n extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.expandAll.bind(this))}expandAll(){const t=this.closest("tp-accordion");t&&(t.setAttribute("expand-all","yes"),t.removeAttribute("collapse-all"))}}class i extends HTMLElement{constructor(){super(),"yes"===this.getAttribute("open-by-default")&&this.setAttribute("open","yes"),this.setupAriaControls(),this.updateAriaState("yes"===this.getAttribute("open")),this.setupBeforeMatchListener()}setupBeforeMatchListener(){const t=this.querySelector("tp-accordion-content");t&&t.addEventListener("beforematch",()=>{this.setAttribute("open","yes")})}setupAriaControls(){if(!this.isAriaEnabled())return;const t=this.querySelector("tp-accordion-handle button"),e=this.querySelector("tp-accordion-content");t&&e&&(e.id||(e.id=`tp-accordion-content-${Math.random().toString(36).substring(2,9)}`),t.hasAttribute("aria-controls")||t.setAttribute("aria-controls",e.id))}isAriaEnabled(){const t=this.closest("tp-accordion");return"no"!==(null==t?void 0:t.getAttribute("aria"))}updateAriaState(t){if(!this.isAriaEnabled())return;const e=this.querySelector("tp-accordion-handle button"),s=this.querySelector("tp-accordion-content");e&&e.setAttribute("aria-expanded",t?"true":"false"),s&&(t?s.removeAttribute("hidden"):s.setAttribute("hidden","until-found"))}static get observedAttributes(){return["open"]}attributeChangedCallback(t,e,s){e!==s&&"open"===t&&("yes"===s?this.open():this.close(),this.removeAttribute("open-by-default"))}open(){const t=this.querySelector("tp-accordion-content");t&&(this.dispatchEvent(new CustomEvent("before-open",{bubbles:!0})),this.updateAriaState(!0),((t,e=300,s=()=>{})=>{t.style.height=`${t.scrollHeight}px`,setTimeout(()=>{t.style.height="auto",s&&s()},e)})(t,600),this.dispatchEvent(new CustomEvent("open",{bubbles:!0})))}close(){const t=this.querySelector("tp-accordion-content");t&&(this.dispatchEvent(new CustomEvent("before-close",{bubbles:!0})),((t,e=300,s=()=>{})=>{t.style.height=`${t.scrollHeight}px`,t.offsetHeight,t.style.height="0px",setTimeout(()=>{t.style.height="0px",s&&s()},e)})(t,600,()=>{this.updateAriaState(!1),this.dispatchEvent(new CustomEvent("close",{bubbles:!0}))}))}}customElements.define("tp-accordion",t),customElements.define("tp-accordion-content",e),customElements.define("tp-accordion-handle",s),customElements.define("tp-accordion-collapse-all",o),customElements.define("tp-accordion-expand-all",n),customElements.define("tp-accordion-item",i)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/accordion/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/accordion/tp-accordion.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-content.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-handle.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-collapse-all.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-expand-all.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-item.ts","webpack://@travelopia/web-components/./src/utility.ts","webpack://@travelopia/web-components/./src/accordion/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPAccordionItemElement } from './tp-accordion-item';\n\n/**\n * TP Accordion.\n */\nexport class TPAccordionElement 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 observed in the TPAccordionItemElement web-component.\n\t\treturn [ 'collapse-all', 'expand-all' ];\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// To check if observed attributes are changed.\n\n\t\t//Early return if no change in attributes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update initially according to the value present in expand-all or collapse all.\n\t\tthis.update();\n\n\t\t// If attribute value is changed then open and close according to the name of event.\n\t\tif ( 'yes' === newValue && ( 'collapse-all' === name || 'expand-all' === name ) ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( name, { bubbles: true } ) );\n\t\t}\n\t}\n\n\t/**\n\t * Update.\n\t */\n\tupdate(): void {\n\t\t// Get accordion items.\n\t\tconst accordionItems: NodeListOf<TPAccordionItemElement> = this.querySelectorAll( 'tp-accordion-item' );\n\n\t\t//Early return if accordion items are not present.\n\t\tif ( ! accordionItems ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize action variable.\n\t\tlet action: string = '';\n\n\t\t// Determine action.\n\t\tif ( 'yes' === this.getAttribute( 'expand-all' ) ) {\n\t\t\taction = 'expand-all';\n\t\t} else if ( 'yes' === this.getAttribute( 'collapse-all' ) ) {\n\t\t\taction = 'collapse-all';\n\t\t}\n\n\t\t// Check if we have an action.\n\t\tif ( '' === action ) {\n\t\t\t// Return if action is not present.\n\t\t\treturn;\n\t\t}\n\n\t\t// Expand or collapse accordion items.\n\t\taccordionItems.forEach( ( accordionItem: TPAccordionItemElement ): void => {\n\t\t\t// Conditionally expand or collapse each item.\n\t\t\tif ( 'expand-all' === action ) {\n\t\t\t\taccordionItem.setAttribute( 'open', 'yes' );\n\t\t\t} else if ( 'collapse-all' === action ) {\n\t\t\t\taccordionItem.removeAttribute( 'open' );\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * TP Accordion Content.\n */\nexport class TPAccordionContentElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPAccordionItemElement } from './tp-accordion-item';\n\n/**\n * TP Accordion Handle.\n */\nexport class TPAccordionHandleElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.toggle.bind( this ) );\n\t}\n\n\t/**\n\t * Toggle accordion.\n\t */\n\ttoggle(): void {\n\t\t// Variables.\n\t\tconst accordionItem: TPAccordionItemElement | null = this.closest( 'tp-accordion-item' );\n\n\t\t// Terminates if accordion item is not present.\n\t\tif ( ! accordionItem ) {\n\t\t\t//Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// If accordion item is open.\n\t\tif ( 'yes' !== accordionItem.getAttribute( 'open' ) ) {\n\t\t\taccordionItem.setAttribute( 'open', 'yes' );\n\t\t} else {\n\t\t\taccordionItem.removeAttribute( 'open' );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPAccordionElement } from './tp-accordion';\n\n/**\n * TP Accordion Collapse All.\n */\nexport class TPAccordionCollapseAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', () => this.collapseAll() );\n\t}\n\n\t/**\n\t * Collapse All.\n\t */\n\tcollapseAll(): void {\n\t\t// Get accordion element.\n\t\tconst accordion: TPAccordionElement | null = this.closest( 'tp-accordion' );\n\n\t\t// Terminates the function if accordion is not available.\n\t\tif ( ! accordion ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set attributes for expand-all and collapse-all.\n\t\taccordion.removeAttribute( 'expand-all' );\n\t\taccordion.setAttribute( 'collapse-all', 'yes' );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPAccordionElement } from './tp-accordion';\n\n/**\n * TP Accordion Expand All.\n */\nexport class TPAccordionExpandAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.expandAll.bind( this ) );\n\t}\n\n\t/**\n\t * Expand all.\n\t */\n\texpandAll() {\n\t\t// Get accordion.\n\t\tconst accordion: TPAccordionElement | null = this.closest( 'tp-accordion' );\n\n\t\t// Terminates if accordion is not present.\n\t\tif ( ! accordion ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set attributes for expand-all and collapse-all.\n\t\taccordion.setAttribute( 'expand-all', 'yes' );\n\t\taccordion.removeAttribute( 'collapse-all' );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPAccordionContentElement } from './tp-accordion-content';\nimport { TPAccordionElement } from './tp-accordion';\nimport { slideElementDown, slideElementUp } from '../utility';\n\n/**\n * TP Accordion Item.\n */\nexport class TPAccordionItemElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Check if by default accordion item is open.\n\t\tif ( 'yes' === this.getAttribute( 'open-by-default' ) ) {\n\t\t\tthis.setAttribute( 'open', 'yes' );\n\t\t}\n\n\t\t// ARIA stuff.\n\t\tthis.setupAriaControls();\n\t\tthis.updateAriaState( 'yes' === this.getAttribute( 'open' ) );\n\t\tthis.setupBeforeMatchListener();\n\t}\n\n\t/**\n\t * Set up beforematch event listener for find-in-page support.\n\t */\n\tprivate setupBeforeMatchListener(): void {\n\t\t// Get content element.\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Bail if no content.\n\t\tif ( ! content ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// When browser finds content via find-in-page, open this accordion item.\n\t\tcontent.addEventListener( 'beforematch', () => {\n\t\t\t// Open the accordion item.\n\t\t\tthis.setAttribute( 'open', 'yes' );\n\t\t} );\n\t}\n\n\t/**\n\t * Set up aria-controls linkage between button and content.\n\t */\n\tprivate setupAriaControls(): void {\n\t\t// Check if aria management is enabled.\n\t\tif ( ! this.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get button and content elements.\n\t\tconst button = this.querySelector( 'tp-accordion-handle button' );\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Bail if no button or content.\n\t\tif ( ! button || ! content ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Generate ID for content if not present.\n\t\tif ( ! content.id ) {\n\t\t\tcontent.id = `tp-accordion-content-${ Math.random().toString( 36 ).substring( 2, 9 ) }`;\n\t\t}\n\n\t\t// Set aria-controls on button if not present.\n\t\tif ( ! button.hasAttribute( 'aria-controls' ) ) {\n\t\t\tbutton.setAttribute( 'aria-controls', content.id );\n\t\t}\n\t}\n\n\t/**\n\t * Check if ARIA management is enabled.\n\t *\n\t * @return {boolean} Whether ARIA management is enabled.\n\t */\n\tprivate isAriaEnabled(): boolean {\n\t\t// Get parent accordion.\n\t\tconst accordion: TPAccordionElement | null = this.closest( 'tp-accordion' );\n\n\t\t// Return whether aria management is enabled.\n\t\treturn 'no' !== accordion?.getAttribute( 'aria' );\n\t}\n\n\t/**\n\t * Update ARIA state for handle button and content.\n\t *\n\t * @param {boolean} isOpen Whether the accordion item is open.\n\t */\n\tprivate updateAriaState( isOpen: boolean ): void {\n\t\t// Check if aria management is enabled.\n\t\tif ( ! this.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get button and content elements.\n\t\tconst button = this.querySelector( 'tp-accordion-handle button' );\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Update button aria-expanded.\n\t\tif ( button ) {\n\t\t\tbutton.setAttribute( 'aria-expanded', isOpen ? 'true' : 'false' );\n\t\t}\n\n\t\t// Bail if no content.\n\t\tif ( ! content ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set or remove hidden attribute.\n\t\tif ( isOpen ) {\n\t\t\tcontent.removeAttribute( 'hidden' );\n\t\t} else {\n\t\t\tcontent.setAttribute( 'hidden', 'until-found' );\n\t\t}\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 observed in the TPAccordionItemElement web-component.\n\t\treturn [ 'open' ];\n\t}\n\n\t/**\n\t * Attributes callback.\n\t *\n\t * Fired on attribute change.\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// To check if observed attributes are changed.\n\n\t\t// Early return if no change in attributes.\n\t\tif ( oldValue === newValue || 'open' !== name ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Conditionally open or close based on changed value.\n\t\tif ( 'yes' === newValue ) {\n\t\t\tthis.open();\n\t\t} else {\n\t\t\tthis.close();\n\t\t}\n\n\t\t// Removing default value.\n\t\tthis.removeAttribute( 'open-by-default' );\n\t}\n\n\t/**\n\t * Open accordion item.\n\t */\n\topen(): void {\n\t\t// Initializing variables.\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Open the accordion.\n\t\tif ( content ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'before-open', { bubbles: true } ) );\n\t\t\tthis.updateAriaState( true );\n\t\t\tslideElementDown( content, 600 );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'open', { bubbles: true } ) );\n\t\t}\n\t}\n\n\t/**\n\t * Close accordion item.\n\t */\n\tclose(): void {\n\t\t// Initializing variables.\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Close the accordion.\n\t\tif ( content ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'before-close', { bubbles: true } ) );\n\t\t\tslideElementUp( content, 600, () => {\n\t\t\t\t// Update state.\n\t\t\t\tthis.updateAriaState( false );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'close', { bubbles: true } ) );\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * Utility functions.\n */\n\n/**\n * Slide element down.\n *\n * @param {HTMLElement|null} element Target element.\n * @param {number} duration Animation duration.\n * @param {Function} callback Callback function.\n */\nexport const slideElementDown = ( element: HTMLElement, duration: number = 300, callback: Function = () => {} ) => { // eslint-disable-line\n\t// Get element height.\n\telement.style.height = `${ element.scrollHeight }px`;\n\n\t// Set timeout.\n\tsetTimeout( () => {\n\t\t// Set element's height.\n\t\telement.style.height = 'auto';\n\n\t\t// If callback is available, call the function.\n\t\tif ( callback ) {\n\t\t\tcallback();\n\t\t}\n\t}, duration );\n};\n\n/**\n * Slide element up.\n *\n * @param {HTMLElement|null} element Target element.\n * @param {number} duration Animation duration.\n * @param {Function} callback Callback function.\n */\nexport const slideElementUp = ( element: HTMLElement, duration: number = 300, callback: Function = () => {} ) => { // eslint-disable-line\n\t// Get element height.\n\telement.style.height = `${ element.scrollHeight }px`;\n\telement.offsetHeight; // eslint-disable-line\n\telement.style.height = '0px';\n\n\t// Set timeout.\n\tsetTimeout( () => {\n\t\t// Set element's height.\n\t\telement.style.height = '0px';\n\n\t\t// If callback is available, call the function.\n\t\tif ( callback ) {\n\t\t\tcallback();\n\t\t}\n\t}, duration );\n};\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPAccordionElement } from './tp-accordion';\nimport { TPAccordionContentElement } from './tp-accordion-content';\nimport { TPAccordionHandleElement } from './tp-accordion-handle';\nimport { TPAccordionCollapseAllElement } from './tp-accordion-collapse-all';\nimport { TPAccordionExpandAllElement } from './tp-accordion-expand-all';\nimport { TPAccordionItemElement } from './tp-accordion-item';\n\n/**\n * Initialize.\n */\ncustomElements.define( 'tp-accordion', TPAccordionElement );\ncustomElements.define( 'tp-accordion-content', TPAccordionContentElement );\ncustomElements.define( 'tp-accordion-handle', TPAccordionHandleElement );\ncustomElements.define( 'tp-accordion-collapse-all', TPAccordionCollapseAllElement );\ncustomElements.define( 'tp-accordion-expand-all', TPAccordionExpandAllElement );\ncustomElements.define( 'tp-accordion-item', TPAccordionItemElement );\n"],"names":["TPAccordionElement","HTMLElement","observedAttributes","attributeChangedCallback","name","oldValue","newValue","this","update","dispatchEvent","CustomEvent","bubbles","accordionItems","querySelectorAll","action","getAttribute","forEach","accordionItem","setAttribute","removeAttribute","TPAccordionContentElement","TPAccordionHandleElement","constructor","super","querySelector","addEventListener","toggle","bind","closest","TPAccordionCollapseAllElement","collapseAll","accordion","TPAccordionExpandAllElement","expandAll","TPAccordionItemElement","setupAriaControls","updateAriaState","setupBeforeMatchListener","content","isAriaEnabled","button","id","Math","random","toString","substring","hasAttribute","isOpen","open","close","element","duration","callback","style","height","scrollHeight","setTimeout","slideElementDown","offsetHeight","slideElementUp","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/accordion/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/accordion/tp-accordion.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-content.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-handle.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-collapse-all.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-expand-all.ts","webpack://@travelopia/web-components/./src/accordion/tp-accordion-item.ts","webpack://@travelopia/web-components/./src/utility.ts","webpack://@travelopia/web-components/./src/accordion/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPAccordionItemElement } from './tp-accordion-item';\n\n/**\n * TP Accordion.\n */\nexport class TPAccordionElement 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 observed in the TPAccordionItemElement web-component.\n\t\treturn [ 'collapse-all', 'expand-all' ];\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// To check if observed attributes are changed.\n\n\t\t//Early return if no change in attributes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update initially according to the value present in expand-all or collapse all.\n\t\tthis.update();\n\n\t\t// If attribute value is changed then open and close according to the name of event.\n\t\tif ( 'yes' === newValue && ( 'collapse-all' === name || 'expand-all' === name ) ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( name, { bubbles: true } ) );\n\t\t}\n\t}\n\n\t/**\n\t * Update.\n\t */\n\tupdate(): void {\n\t\t// Get accordion items.\n\t\tconst accordionItems: NodeListOf<TPAccordionItemElement> = this.querySelectorAll( 'tp-accordion-item' );\n\n\t\t//Early return if accordion items are not present.\n\t\tif ( ! accordionItems ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize action variable.\n\t\tlet action: string = '';\n\n\t\t// Determine action.\n\t\tif ( 'yes' === this.getAttribute( 'expand-all' ) ) {\n\t\t\taction = 'expand-all';\n\t\t} else if ( 'yes' === this.getAttribute( 'collapse-all' ) ) {\n\t\t\taction = 'collapse-all';\n\t\t}\n\n\t\t// Check if we have an action.\n\t\tif ( '' === action ) {\n\t\t\t// Return if action is not present.\n\t\t\treturn;\n\t\t}\n\n\t\t// Expand or collapse accordion items.\n\t\taccordionItems.forEach( ( accordionItem: TPAccordionItemElement ): void => {\n\t\t\t// Conditionally expand or collapse each item.\n\t\t\tif ( 'expand-all' === action ) {\n\t\t\t\taccordionItem.setAttribute( 'open', 'yes' );\n\t\t\t} else if ( 'collapse-all' === action ) {\n\t\t\t\taccordionItem.removeAttribute( 'open' );\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * TP Accordion Content.\n */\nexport class TPAccordionContentElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPAccordionItemElement } from './tp-accordion-item';\n\n/**\n * TP Accordion Handle.\n */\nexport class TPAccordionHandleElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.toggle.bind( this ) );\n\t}\n\n\t/**\n\t * Toggle accordion.\n\t */\n\ttoggle(): void {\n\t\t// Variables.\n\t\tconst accordionItem: TPAccordionItemElement | null = this.closest( 'tp-accordion-item' );\n\n\t\t// Terminates if accordion item is not present.\n\t\tif ( ! accordionItem ) {\n\t\t\t//Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// If accordion item is open.\n\t\tif ( 'yes' !== accordionItem.getAttribute( 'open' ) ) {\n\t\t\taccordionItem.setAttribute( 'open', 'yes' );\n\t\t} else {\n\t\t\taccordionItem.removeAttribute( 'open' );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPAccordionElement } from './tp-accordion';\n\n/**\n * TP Accordion Collapse All.\n */\nexport class TPAccordionCollapseAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', () => this.collapseAll() );\n\t}\n\n\t/**\n\t * Collapse All.\n\t */\n\tcollapseAll(): void {\n\t\t// Get accordion element.\n\t\tconst accordion: TPAccordionElement | null = this.closest( 'tp-accordion' );\n\n\t\t// Terminates the function if accordion is not available.\n\t\tif ( ! accordion ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set attributes for expand-all and collapse-all.\n\t\taccordion.removeAttribute( 'expand-all' );\n\t\taccordion.setAttribute( 'collapse-all', 'yes' );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPAccordionElement } from './tp-accordion';\n\n/**\n * TP Accordion Expand All.\n */\nexport class TPAccordionExpandAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.expandAll.bind( this ) );\n\t}\n\n\t/**\n\t * Expand all.\n\t */\n\texpandAll() {\n\t\t// Get accordion.\n\t\tconst accordion: TPAccordionElement | null = this.closest( 'tp-accordion' );\n\n\t\t// Terminates if accordion is not present.\n\t\tif ( ! accordion ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set attributes for expand-all and collapse-all.\n\t\taccordion.setAttribute( 'expand-all', 'yes' );\n\t\taccordion.removeAttribute( 'collapse-all' );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPAccordionContentElement } from './tp-accordion-content';\nimport { TPAccordionElement } from './tp-accordion';\nimport { slideElementDown, slideElementUp } from '../utility';\n\n/**\n * TP Accordion Item.\n */\nexport class TPAccordionItemElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Check if by default accordion item is open.\n\t\tif ( 'yes' === this.getAttribute( 'open-by-default' ) ) {\n\t\t\tthis.setAttribute( 'open', 'yes' );\n\t\t}\n\n\t\t// ARIA stuff.\n\t\tthis.setupAriaControls();\n\t\tthis.updateAriaState( 'yes' === this.getAttribute( 'open' ) );\n\t\tthis.setupBeforeMatchListener();\n\t}\n\n\t/**\n\t * Set up beforematch event listener for find-in-page support.\n\t */\n\tprivate setupBeforeMatchListener(): void {\n\t\t// Get content element.\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Bail if no content.\n\t\tif ( ! content ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// When browser finds content via find-in-page, open this accordion item.\n\t\tcontent.addEventListener( 'beforematch', () => {\n\t\t\t// Open the accordion item.\n\t\t\tthis.setAttribute( 'open', 'yes' );\n\t\t} );\n\t}\n\n\t/**\n\t * Set up aria-controls linkage between button and content.\n\t */\n\tprivate setupAriaControls(): void {\n\t\t// Check if aria management is enabled.\n\t\tif ( ! this.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get button and content elements.\n\t\tconst button = this.querySelector( 'tp-accordion-handle button' );\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Bail if no button or content.\n\t\tif ( ! button || ! content ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Generate ID for content if not present.\n\t\tif ( ! content.id ) {\n\t\t\tcontent.id = `tp-accordion-content-${ Math.random().toString( 36 ).substring( 2, 9 ) }`;\n\t\t}\n\n\t\t// Set aria-controls on button if not present.\n\t\tif ( ! button.hasAttribute( 'aria-controls' ) ) {\n\t\t\tbutton.setAttribute( 'aria-controls', content.id );\n\t\t}\n\t}\n\n\t/**\n\t * Check if ARIA management is enabled.\n\t *\n\t * @return {boolean} Whether ARIA management is enabled.\n\t */\n\tprivate isAriaEnabled(): boolean {\n\t\t// Get parent accordion.\n\t\tconst accordion: TPAccordionElement | null = this.closest( 'tp-accordion' );\n\n\t\t// Return whether aria management is enabled.\n\t\treturn 'no' !== accordion?.getAttribute( 'aria' );\n\t}\n\n\t/**\n\t * Update ARIA state for handle button and content.\n\t *\n\t * @param {boolean} isOpen Whether the accordion item is open.\n\t */\n\tprivate updateAriaState( isOpen: boolean ): void {\n\t\t// Check if aria management is enabled.\n\t\tif ( ! this.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get button and content elements.\n\t\tconst button = this.querySelector( 'tp-accordion-handle button' );\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Update button aria-expanded.\n\t\tif ( button ) {\n\t\t\tbutton.setAttribute( 'aria-expanded', isOpen ? 'true' : 'false' );\n\t\t}\n\n\t\t// Bail if no content.\n\t\tif ( ! content ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set or remove hidden attribute.\n\t\tif ( isOpen ) {\n\t\t\tcontent.removeAttribute( 'hidden' );\n\t\t} else {\n\t\t\tcontent.setAttribute( 'hidden', 'until-found' );\n\t\t}\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 observed in the TPAccordionItemElement web-component.\n\t\treturn [ 'open' ];\n\t}\n\n\t/**\n\t * Attributes callback.\n\t *\n\t * Fired on attribute change.\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// To check if observed attributes are changed.\n\n\t\t// Early return if no change in attributes.\n\t\tif ( oldValue === newValue || 'open' !== name ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Conditionally open or close based on changed value.\n\t\tif ( 'yes' === newValue ) {\n\t\t\tthis.open();\n\t\t} else {\n\t\t\tthis.close();\n\t\t}\n\n\t\t// Removing default value.\n\t\tthis.removeAttribute( 'open-by-default' );\n\t}\n\n\t/**\n\t * Open accordion item.\n\t */\n\topen(): void {\n\t\t// Initializing variables.\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Open the accordion.\n\t\tif ( content ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'before-open', { bubbles: true } ) );\n\t\t\tthis.updateAriaState( true );\n\t\t\tslideElementDown( content, 600 );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'open', { bubbles: true } ) );\n\t\t}\n\t}\n\n\t/**\n\t * Close accordion item.\n\t */\n\tclose(): void {\n\t\t// Initializing variables.\n\t\tconst content: TPAccordionContentElement | null = this.querySelector( 'tp-accordion-content' );\n\n\t\t// Close the accordion.\n\t\tif ( content ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'before-close', { bubbles: true } ) );\n\t\t\tslideElementUp( content, 600, () => {\n\t\t\t\t// Update state.\n\t\t\t\tthis.updateAriaState( false );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'close', { bubbles: true } ) );\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * Utility functions.\n */\n\n/**\n * Slide element down.\n *\n * @param {HTMLElement|null} element Target element.\n * @param {number} duration Animation duration.\n * @param {Function} callback Callback function.\n */\nexport const slideElementDown = ( element: HTMLElement, duration: number = 300, callback: Function = () => {} ) => { // eslint-disable-line\n\t// Get element height.\n\telement.style.height = `${ element.scrollHeight }px`;\n\n\t// Set timeout.\n\tsetTimeout( () => {\n\t\t// Set element's height.\n\t\telement.style.height = 'auto';\n\n\t\t// If callback is available, call the function.\n\t\tif ( callback ) {\n\t\t\tcallback();\n\t\t}\n\t}, duration );\n};\n\n/**\n * Slide element up.\n *\n * @param {HTMLElement|null} element Target element.\n * @param {number} duration Animation duration.\n * @param {Function} callback Callback function.\n */\nexport const slideElementUp = ( element: HTMLElement, duration: number = 300, callback: Function = () => {} ) => { // eslint-disable-line\n\t// Get element height.\n\telement.style.height = `${ element.scrollHeight }px`;\n\telement.offsetHeight; // eslint-disable-line\n\telement.style.height = '0px';\n\n\t// Set timeout.\n\tsetTimeout( () => {\n\t\t// Set element's height.\n\t\telement.style.height = '0px';\n\n\t\t// If callback is available, call the function.\n\t\tif ( callback ) {\n\t\t\tcallback();\n\t\t}\n\t}, duration );\n};\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPAccordionElement } from './tp-accordion';\nimport { TPAccordionContentElement } from './tp-accordion-content';\nimport { TPAccordionHandleElement } from './tp-accordion-handle';\nimport { TPAccordionCollapseAllElement } from './tp-accordion-collapse-all';\nimport { TPAccordionExpandAllElement } from './tp-accordion-expand-all';\nimport { TPAccordionItemElement } from './tp-accordion-item';\n\n/**\n * Initialize.\n */\ncustomElements.define( 'tp-accordion', TPAccordionElement );\ncustomElements.define( 'tp-accordion-content', TPAccordionContentElement );\ncustomElements.define( 'tp-accordion-handle', TPAccordionHandleElement );\ncustomElements.define( 'tp-accordion-collapse-all', TPAccordionCollapseAllElement );\ncustomElements.define( 'tp-accordion-expand-all', TPAccordionExpandAllElement );\ncustomElements.define( 'tp-accordion-item', TPAccordionItemElement );\n"],"names":["TPAccordionElement","HTMLElement","observedAttributes","attributeChangedCallback","name","oldValue","newValue","this","update","dispatchEvent","CustomEvent","bubbles","accordionItems","querySelectorAll","action","getAttribute","forEach","accordionItem","setAttribute","removeAttribute","TPAccordionContentElement","TPAccordionHandleElement","constructor","super","querySelector","addEventListener","toggle","bind","closest","TPAccordionCollapseAllElement","collapseAll","accordion","TPAccordionExpandAllElement","expandAll","TPAccordionItemElement","setupAriaControls","updateAriaState","setupBeforeMatchListener","content","isAriaEnabled","button","id","Math","random","toString","substring","hasAttribute","isOpen","open","close","element","duration","callback","style","height","scrollHeight","setTimeout","slideElementDown","offsetHeight","slideElementUp","customElements","define"],"ignoreList":[],"sourceRoot":""}
@@ -624,6 +624,11 @@ export class TPLightboxElement extends HTMLElement {
624
624
  * @param {Event} e Click event.
625
625
  */
626
626
  handleDialogClick(e: MouseEvent): void;
627
+ /**
628
+ * Handle when the dialog is closed (e.g., via Escape key).
629
+ * Syncs lightbox state with native dialog close behavior.
630
+ */
631
+ handleDialogClose(): void;
627
632
  /**
628
633
  * Handles the touch start event.
629
634
  *
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";var e={d:(t,r)=>{for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{errorMessage:()=>d,name:()=>u,summaryErrorMessage:()=>m,validator:()=>c});var r={};e.r(r),e.d(r,{errorMessage:()=>h,name:()=>v,summaryErrorMessage:()=>g,validator:()=>b});var s={};e.r(s),e.d(s,{errorMessage:()=>f,name:()=>p,summaryErrorMessage:()=>y,validator:()=>E});var i={};e.r(i),e.d(i,{errorMessage:()=>M,name:()=>A,summaryErrorMessage:()=>S,validator:()=>w});var n={};e.r(n),e.d(n,{errorMessage:()=>C,name:()=>x,summaryErrorMessage:()=>F,validator:()=>q});var o={};e.r(o),e.d(o,{errorMessage:()=>L,name:()=>T,summaryErrorMessage:()=>P,validator:()=>H});const a=(e="")=>{const{tpFormErrors:t}=window;return t&&""!==e&&e in t&&"string"==typeof t[e]?t[e]:""},l=(e="",t)=>{const{tpFormSummaryErrors:r}=window;if(!r||""===e||!(e in r))return"";const s=r[e];if("string"!=typeof s)return"";const i=(e=>{var t;const r=e.querySelector("label");return(null===(t=null==r?void 0:r.textContent)||void 0===t?void 0:t.trim())||""})(t);return s.replace("%label%",i)},u="required",d="This field is required",m="%label%: This field is required",c={validate:e=>{var t,r;return null!==(r=""!==(null===(t=e.getField())||void 0===t?void 0:t.value))&&void 0!==r?r:""},getErrorMessage:()=>a(u),getSummaryMessage:e=>l(u,e)},v="email",h="Please enter a valid email address",g="%label%: Please enter a valid email address",b={validate:e=>{var t,r;return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(null!==(r=null===(t=e.getField())||void 0===t?void 0:t.value)&&void 0!==r?r:"")},getErrorMessage:()=>a(v),getSummaryMessage:e=>l(v,e)},p="min-length",f="Must be at least %1 characters",y="%label%: Must be at least %1 characters",E={validate:e=>{var t,r,s;const i=parseInt(null!==(t=e.getAttribute("min-length"))&&void 0!==t?t:"0"),n=null!==(s=null===(r=e.getField())||void 0===r?void 0:r.value)&&void 0!==s?s:"";return""===n||n.length>=i},getErrorMessage:e=>{var t;const r=a(p),s=null!==(t=e.getAttribute("min-length"))&&void 0!==t?t:"";return r.replace("%1",s)},getSummaryMessage:e=>{var t;const r=l(p,e),s=null!==(t=e.getAttribute("min-length"))&&void 0!==t?t:"";return r.replace("%1",s)}},A="max-length",M="Must be less than %1 characters",S="%label%: Must be less than %1 characters",w={validate:e=>{var t,r,s;const i=parseInt(null!==(t=e.getAttribute("max-length"))&&void 0!==t?t:"0"),n=null!==(s=null===(r=e.getField())||void 0===r?void 0:r.value)&&void 0!==s?s:"";return""===n||n.length<=i},getErrorMessage:e=>{var t;const r=a(A),s=null!==(t=e.getAttribute("max-length"))&&void 0!==t?t:"";return r.replace("%1",s)},getSummaryMessage:e=>{var t;const r=l(A,e),s=null!==(t=e.getAttribute("max-length"))&&void 0!==t?t:"";return r.replace("%1",s)}},x="no-empty-spaces",C="This field should not contain only white-spaces",F="%label%: Should not contain only white-spaces",q={validate:e=>{const t=e.getField();return!!t&&(""===t.value||""!==t.value.trim())},getErrorMessage:()=>a(x),getSummaryMessage:e=>l(x,e)},T="zip",L="Please enter a valid zip code",P="%label%: Please enter a valid zip code",H={validate:e=>{var t,r;const s=null!==(r=null===(t=e.getField())||void 0===t?void 0:t.value)&&void 0!==r?r:"",i=e.getAttribute("regex");return new RegExp(null!=i?i:"^[A-Za-z0-9][A-Za-z0-9\\- ]{1,8}[A-Za-z0-9]$").test(s.trim())},getErrorMessage:()=>a(T),getSummaryMessage:e=>l(T,e)};var V=function(e,t,r,s){return new(r||(r=Promise))((function(i,n){function o(e){try{l(s.next(e))}catch(e){n(e)}}function a(e){try{l(s.throw(e))}catch(e){n(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,a)}l((s=s.apply(e,t||[])).next())}))};class k extends HTMLElement{constructor(){var e;super(),this.form=this.querySelector("form"),null===(e=this.form)||void 0===e||e.addEventListener("submit",this.handleFormSubmit.bind(this))}handleFormSubmit(e){var t;return V(this,void 0,void 0,(function*(){e.preventDefault(),e.stopImmediatePropagation();const r=this.querySelector("tp-form-submit");null==r||r.setAttribute("submitting","yes"),"yes"!==this.getAttribute("suspense")&&((yield this.validate())?(this.dispatchEvent(new CustomEvent("submit-validation-success",{bubbles:!0})),"yes"!==this.getAttribute("prevent-submit")&&(null===(t=this.form)||void 0===t||t.submit())):null==r||r.removeAttribute("submitting"))}))}validate(){return V(this,void 0,void 0,(function*(){this.dispatchEvent(new CustomEvent("validate",{bubbles:!0}));const e=this.querySelectorAll("tp-form-field");if(!e)return this.dispatchEvent(new CustomEvent("validation-success",{bubbles:!0})),!0;this.setAttribute("suspense","yes");let t=!0;const r=Array.from(e).map((e=>V(this,void 0,void 0,(function*(){return yield e.validate()}))));return yield Promise.all(r).then((e=>{t=e.every((e=>e))})).catch((()=>{t=!1})).finally((()=>this.removeAttribute("suspense"))),t?(this.dispatchEvent(new CustomEvent("validation-success",{bubbles:!0})),this.clearErrorSummary()):(this.dispatchEvent(new CustomEvent("validation-error",{bubbles:!0})),this.handleValidationError(e)),t}))}handleValidationError(e){const t=Array.from(e).filter((e=>e.hasAttribute("error")&&e.offsetWidth>0&&e.offsetHeight>0)),r=this.querySelector("tp-form-errors");if(r)r.update(t),setTimeout((()=>r.focus()),0);else if(t.length>0){const e=t[0].getField();null==e||e.focus()}}clearErrorSummary(){const e=this.querySelector("tp-form-errors");null==e||e.clear()}validateField(e){return V(this,void 0,void 0,(function*(){this.setAttribute("suspense","yes");const t=yield e.validate();return this.removeAttribute("suspense"),t}))}resetValidation(){const e=this.querySelectorAll("tp-form-field");if(!e)return;e.forEach((e=>{e.removeAttribute("valid"),e.removeAttribute("error"),e.removeAttribute("suspense")})),this.removeAttribute("suspense");const t=this.querySelector("tp-form-submit");null==t||t.removeAttribute("submitting"),this.clearErrorSummary()}}class z extends HTMLElement{constructor(){super();const e=this.getField();null==e||e.addEventListener("keyup",this.handleFieldChanged.bind(this)),null==e||e.addEventListener("change",this.handleFieldChanged.bind(this)),this.setupAccessibility()}setupAccessibility(){const e=this.getField();if(!e)return;e.id||(e.id=`tp-field-${Math.random().toString(36).substring(2,9)}`);const t=this.querySelector("label");t&&!t.hasAttribute("for")&&t.setAttribute("for",e.id)}handleFieldChanged(){if("no"!==this.getAttribute("revalidate-on-change")&&(this.getAttribute("valid")||this.getAttribute("error"))){const e=this.closest("tp-form");null==e||e.validateField(this)}}static get observedAttributes(){return["valid","error","suspense"]}attributeChangedCallback(e="",t="",r=""){"valid"!==e&&"error"!==e&&"suspense"!==e||t===r||this.dispatchEvent(new CustomEvent("validate",{bubbles:!0})),this.update()}update(){var e,t,r;const{tpFormValidators:s}=window;if(!s)return;const i=null!==(e=this.getAttribute("error"))&&void 0!==e?e:"";""!==i&&i in s&&"function"==typeof s[i].getErrorMessage?this.setErrorMessage(s[i].getErrorMessage(this)):this.removeErrorMessage();const n=null!==(t=this.getAttribute("suspense"))&&void 0!==t?t:"";""!==n&&n in s&&"function"==typeof s[n].getSuspenseMessage?this.setSuspenseMessage(null===(r=s[n])||void 0===r?void 0:r.getSuspenseMessage(this)):this.removeSuspenseMessage()}getField(){return this.querySelector("input,select,textarea")}validate(){return e=this,t=void 0,s=function*(){const{tpFormValidators:e}=window;if(!e)return!0;if(this.offsetWidth<=0||this.offsetHeight<=0)return!0;let t=!0,r=null,s="";return this.getAttributeNames().every((i=>{if(i in e&&"function"==typeof e[i].validate){const n=e[i].validate(this);if(s=i,n instanceof Promise)return t=!1,this.dispatchEvent(new CustomEvent("validation-suspense-start")),r=new Promise(((e,t)=>{n.then((t=>{!0===t?(this.setAttribute("valid","yes"),this.removeAttribute("error"),e(!0)):(this.removeAttribute("valid"),this.setAttribute("error",s),e(!1)),this.dispatchEvent(new CustomEvent("validation-suspense-success"))})).catch((()=>{this.removeAttribute("valid"),this.setAttribute("error",s),this.dispatchEvent(new CustomEvent("validation-suspense-error")),t(!1)})).finally((()=>{this.removeAttribute("suspense")}))})),!1;if(!1===n)return t=!1,!1}return!0})),t?(this.setAttribute("valid","yes"),this.removeAttribute("error"),this.removeAttribute("suspense")):(this.removeAttribute("valid"),r?(this.setAttribute("suspense",s),this.removeAttribute("error")):(this.removeAttribute("suspense"),this.setAttribute("error",s))),r||t},new((r=void 0)||(r=Promise))((function(i,n){function o(e){try{l(s.next(e))}catch(e){n(e)}}function a(e){try{l(s.throw(e))}catch(e){n(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,a)}l((s=s.apply(e,t||[])).next())}));var e,t,r,s}setErrorMessage(e=""){let t=this.querySelector("tp-form-error");t?t.textContent=e:(t=document.createElement("tp-form-error"),t.textContent=e,t.setAttribute("role","alert"),this.appendChild(t));const r=this.getField();r&&(r.setAttribute("aria-invalid","true"),t.id||(t.id=`tp-error-${Math.random().toString(36).substring(2,9)}`),r.setAttribute("aria-describedby",t.id)),this.dispatchEvent(new CustomEvent("validation-error"))}removeErrorMessage(){var e;null===(e=this.querySelector("tp-form-error"))||void 0===e||e.remove();const t=this.getField();t&&(t.removeAttribute("aria-invalid"),t.removeAttribute("aria-describedby")),this.dispatchEvent(new CustomEvent("validation-success"))}setSuspenseMessage(e=""){const t=this.querySelector("tp-form-suspense");if(t)t.textContent=e;else{const t=document.createElement("tp-form-suspense");t.textContent=e,t.setAttribute("aria-live","polite"),this.appendChild(t)}}removeSuspenseMessage(){var e;null===(e=this.querySelector("tp-form-suspense"))||void 0===e||e.remove()}}class $ extends HTMLElement{}class O extends HTMLElement{update(e){const t=this.querySelector("tp-form-errors-heading"),r=this.querySelector("tp-form-errors-list");if(0===e.length)return this.removeAttribute("active"),this.removeAttribute("tabindex"),null==t||t.update(0),void(null==r||r.clear());this.setAttribute("active","yes"),this.setAttribute("tabindex","-1"),null==t||t.update(e.length),null==r||r.update(e)}clear(){this.removeAttribute("active"),this.removeAttribute("tabindex");const e=this.querySelector("tp-form-errors-heading"),t=this.querySelector("tp-form-errors-list");null==e||e.update(0),null==t||t.clear()}}class j extends HTMLElement{get format(){var e;return null!==(e=this.getAttribute("format"))&&void 0!==e?e:""}set format(e){this.setAttribute("format",e)}update(e){this.textContent=this.format.replace("$count",e.toString())}}class I extends HTMLElement{update(e){this.textContent="";const{tpFormValidators:t}=window;e.forEach((e=>{var r,s;const i=e.getField(),n=null!==(r=null==i?void 0:i.id)&&void 0!==r?r:"";if(!n)return;const o=null!==(s=e.getAttribute("error"))&&void 0!==s?s:"";let a="";if(o&&t&&o in t){const r=t[o];"function"==typeof r.getSummaryMessage?a=r.getSummaryMessage(e):"function"==typeof r.getErrorMessage&&(a=r.getErrorMessage(e))}if(!a)return;const l=document.createElement("tp-form-errors-error");l.setAttribute("role","listitem");const u=document.createElement("a");u.href=`#${n}`,u.textContent=a,l.appendChild(u),this.appendChild(l)}))}clear(){this.textContent=""}}class Z extends HTMLElement{constructor(){super(),this.addEventListener("click",this.handleClick.bind(this))}handleClick(e){var t;const r=e.target.closest("a");if(!r)return;e.preventDefault();const s=(null!==(t=r.getAttribute("href"))&&void 0!==t?t:"").replace("#","");if(s){const e=document.getElementById(s);null==e||e.focus()}}}class D extends HTMLElement{}class W extends HTMLElement{static get observedAttributes(){return["submitting-text","original-text","submitting"]}attributeChangedCallback(e="",t="",r=""){t!==r&&this.update()}update(){var e,t;const r=this.querySelector('button[type="submit"]');if(!r)return;const s=null!==(e=this.getAttribute("submitting-text"))&&void 0!==e?e:"",i=null!==(t=this.getAttribute("original-text"))&&void 0!==t?t:r.innerHTML;"yes"===this.getAttribute("submitting")?(r.setAttribute("disabled","disabled"),this.setAttribute("original-text",i),r.textContent=s):(r.removeAttribute("disabled"),this.removeAttribute("submitting"),this.removeAttribute("original-text"),r.innerHTML=i)}}const _=[t,r,s,i,n,o];window.tpFormValidators={},window.tpFormErrors={},window.tpFormSummaryErrors={},window.tpFormSuspenseMessages={},_.forEach((({name:e,validator:t,errorMessage:r,summaryErrorMessage:s})=>{window.tpFormValidators[e]=t,window.tpFormErrors[e]=r,s&&(window.tpFormSummaryErrors[e]=s)})),customElements.define("tp-form",k),customElements.define("tp-form-field",z),customElements.define("tp-form-error",$),customElements.define("tp-form-errors",O),customElements.define("tp-form-errors-heading",j),customElements.define("tp-form-errors-list",I),customElements.define("tp-form-errors-error",Z),customElements.define("tp-form-suspense",D),customElements.define("tp-form-submit",W)})();
1
+ (()=>{"use strict";var e={d:(t,r)=>{for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{errorMessage:()=>d,name:()=>u,summaryErrorMessage:()=>m,validator:()=>c});var r={};e.r(r),e.d(r,{errorMessage:()=>h,name:()=>v,summaryErrorMessage:()=>g,validator:()=>b});var s={};e.r(s),e.d(s,{errorMessage:()=>f,name:()=>p,summaryErrorMessage:()=>y,validator:()=>E});var i={};e.r(i),e.d(i,{errorMessage:()=>M,name:()=>A,summaryErrorMessage:()=>S,validator:()=>w});var n={};e.r(n),e.d(n,{errorMessage:()=>C,name:()=>x,summaryErrorMessage:()=>F,validator:()=>q});var o={};e.r(o),e.d(o,{errorMessage:()=>L,name:()=>T,summaryErrorMessage:()=>P,validator:()=>H});const a=(e="")=>{const{tpFormErrors:t}=window;return t&&""!==e&&e in t&&"string"==typeof t[e]?t[e]:""},l=(e="",t)=>{const{tpFormSummaryErrors:r}=window;if(!r||""===e||!(e in r))return"";const s=r[e];if("string"!=typeof s)return"";const i=(e=>{var t;const r=e.querySelector("label");return(null===(t=null==r?void 0:r.textContent)||void 0===t?void 0:t.trim())||""})(t);return s.replace("%label%",i)},u="required",d="This field is required",m="%label%: This field is required",c={validate:e=>{var t,r;return""!==(null!==(r=null===(t=e.getField())||void 0===t?void 0:t.value)&&void 0!==r?r:"")},getErrorMessage:()=>a(u),getSummaryMessage:e=>l(u,e)},v="email",h="Please enter a valid email address",g="%label%: Please enter a valid email address",b={validate:e=>{var t,r;return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(null!==(r=null===(t=e.getField())||void 0===t?void 0:t.value)&&void 0!==r?r:"")},getErrorMessage:()=>a(v),getSummaryMessage:e=>l(v,e)},p="min-length",f="Must be at least %1 characters",y="%label%: Must be at least %1 characters",E={validate:e=>{var t,r,s;const i=parseInt(null!==(t=e.getAttribute("min-length"))&&void 0!==t?t:"0"),n=null!==(s=null===(r=e.getField())||void 0===r?void 0:r.value)&&void 0!==s?s:"";return""===n||n.length>=i},getErrorMessage:e=>{var t;const r=a(p),s=null!==(t=e.getAttribute("min-length"))&&void 0!==t?t:"";return r.replace("%1",s)},getSummaryMessage:e=>{var t;const r=l(p,e),s=null!==(t=e.getAttribute("min-length"))&&void 0!==t?t:"";return r.replace("%1",s)}},A="max-length",M="Must be less than %1 characters",S="%label%: Must be less than %1 characters",w={validate:e=>{var t,r,s;const i=parseInt(null!==(t=e.getAttribute("max-length"))&&void 0!==t?t:"0"),n=null!==(s=null===(r=e.getField())||void 0===r?void 0:r.value)&&void 0!==s?s:"";return""===n||n.length<=i},getErrorMessage:e=>{var t;const r=a(A),s=null!==(t=e.getAttribute("max-length"))&&void 0!==t?t:"";return r.replace("%1",s)},getSummaryMessage:e=>{var t;const r=l(A,e),s=null!==(t=e.getAttribute("max-length"))&&void 0!==t?t:"";return r.replace("%1",s)}},x="no-empty-spaces",C="This field should not contain only white-spaces",F="%label%: Should not contain only white-spaces",q={validate:e=>{const t=e.getField();return!!t&&(""===t.value||""!==t.value.trim())},getErrorMessage:()=>a(x),getSummaryMessage:e=>l(x,e)},T="zip",L="Please enter a valid zip code",P="%label%: Please enter a valid zip code",H={validate:e=>{var t,r;const s=null!==(r=null===(t=e.getField())||void 0===t?void 0:t.value)&&void 0!==r?r:"",i=e.getAttribute("regex");return new RegExp(null!=i?i:"^[A-Za-z0-9][A-Za-z0-9\\- ]{1,8}[A-Za-z0-9]$").test(s.trim())},getErrorMessage:()=>a(T),getSummaryMessage:e=>l(T,e)};var V=function(e,t,r,s){return new(r||(r=Promise))(function(i,n){function o(e){try{l(s.next(e))}catch(e){n(e)}}function a(e){try{l(s.throw(e))}catch(e){n(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(o,a)}l((s=s.apply(e,t||[])).next())})};class k extends HTMLElement{constructor(){var e;super(),this.form=this.querySelector("form"),null===(e=this.form)||void 0===e||e.addEventListener("submit",this.handleFormSubmit.bind(this))}handleFormSubmit(e){return V(this,void 0,void 0,function*(){var t;e.preventDefault(),e.stopImmediatePropagation();const r=this.querySelector("tp-form-submit");null==r||r.setAttribute("submitting","yes"),"yes"!==this.getAttribute("suspense")&&((yield this.validate())?(this.dispatchEvent(new CustomEvent("submit-validation-success",{bubbles:!0})),"yes"!==this.getAttribute("prevent-submit")&&(null===(t=this.form)||void 0===t||t.submit())):null==r||r.removeAttribute("submitting"))})}validate(){return V(this,void 0,void 0,function*(){this.dispatchEvent(new CustomEvent("validate",{bubbles:!0}));const e=this.querySelectorAll("tp-form-field");if(!e)return this.dispatchEvent(new CustomEvent("validation-success",{bubbles:!0})),!0;this.setAttribute("suspense","yes");let t=!0;const r=Array.from(e).map(e=>V(this,void 0,void 0,function*(){return yield e.validate()}));return yield Promise.all(r).then(e=>{t=e.every(e=>e)}).catch(()=>{t=!1}).finally(()=>this.removeAttribute("suspense")),t?(this.dispatchEvent(new CustomEvent("validation-success",{bubbles:!0})),this.clearErrorSummary()):(this.dispatchEvent(new CustomEvent("validation-error",{bubbles:!0})),this.handleValidationError(e)),t})}handleValidationError(e){const t=Array.from(e).filter(e=>e.hasAttribute("error")&&e.offsetWidth>0&&e.offsetHeight>0),r=this.querySelector("tp-form-errors");if(r)r.update(t),setTimeout(()=>r.focus(),0);else if(t.length>0){const e=t[0].getField();null==e||e.focus()}}clearErrorSummary(){const e=this.querySelector("tp-form-errors");null==e||e.clear()}validateField(e){return V(this,void 0,void 0,function*(){this.setAttribute("suspense","yes");const t=yield e.validate();return this.removeAttribute("suspense"),t})}resetValidation(){const e=this.querySelectorAll("tp-form-field");if(!e)return;e.forEach(e=>{e.removeAttribute("valid"),e.removeAttribute("error"),e.removeAttribute("suspense")}),this.removeAttribute("suspense");const t=this.querySelector("tp-form-submit");null==t||t.removeAttribute("submitting"),this.clearErrorSummary()}}class z extends HTMLElement{constructor(){super();const e=this.getField();null==e||e.addEventListener("keyup",this.handleFieldChanged.bind(this)),null==e||e.addEventListener("change",this.handleFieldChanged.bind(this)),this.setupAccessibility()}setupAccessibility(){const e=this.getField();if(!e)return;e.id||(e.id=`tp-field-${Math.random().toString(36).substring(2,9)}`);const t=this.querySelector("label");t&&!t.hasAttribute("for")&&t.setAttribute("for",e.id)}handleFieldChanged(){if("no"!==this.getAttribute("revalidate-on-change")&&(this.getAttribute("valid")||this.getAttribute("error"))){const e=this.closest("tp-form");null==e||e.validateField(this)}}static get observedAttributes(){return["valid","error","suspense"]}attributeChangedCallback(e="",t="",r=""){"valid"!==e&&"error"!==e&&"suspense"!==e||t===r||this.dispatchEvent(new CustomEvent("validate",{bubbles:!0})),this.update()}update(){var e,t,r;const{tpFormValidators:s}=window;if(!s)return;const i=null!==(e=this.getAttribute("error"))&&void 0!==e?e:"";""!==i&&i in s&&"function"==typeof s[i].getErrorMessage?this.setErrorMessage(s[i].getErrorMessage(this)):this.removeErrorMessage();const n=null!==(t=this.getAttribute("suspense"))&&void 0!==t?t:"";""!==n&&n in s&&"function"==typeof s[n].getSuspenseMessage?this.setSuspenseMessage(null===(r=s[n])||void 0===r?void 0:r.getSuspenseMessage(this)):this.removeSuspenseMessage()}getField(){return this.querySelector("input,select,textarea")}validate(){return e=this,t=void 0,s=function*(){const{tpFormValidators:e}=window;if(!e)return!0;if(this.offsetWidth<=0||this.offsetHeight<=0)return!0;let t=!0,r=null,s="";return this.getAttributeNames().every(i=>{if(i in e&&"function"==typeof e[i].validate){const n=e[i].validate(this);if(s=i,n instanceof Promise)return t=!1,this.dispatchEvent(new CustomEvent("validation-suspense-start")),r=new Promise((e,t)=>{n.then(t=>{!0===t?(this.setAttribute("valid","yes"),this.removeAttribute("error"),e(!0)):(this.removeAttribute("valid"),this.setAttribute("error",s),e(!1)),this.dispatchEvent(new CustomEvent("validation-suspense-success"))}).catch(()=>{this.removeAttribute("valid"),this.setAttribute("error",s),this.dispatchEvent(new CustomEvent("validation-suspense-error")),t(!1)}).finally(()=>{this.removeAttribute("suspense")})}),!1;if(!1===n)return t=!1,!1}return!0}),t?(this.setAttribute("valid","yes"),this.removeAttribute("error"),this.removeAttribute("suspense")):(this.removeAttribute("valid"),r?(this.setAttribute("suspense",s),this.removeAttribute("error")):(this.removeAttribute("suspense"),this.setAttribute("error",s))),r||t},new((r=void 0)||(r=Promise))(function(i,n){function o(e){try{l(s.next(e))}catch(e){n(e)}}function a(e){try{l(s.throw(e))}catch(e){n(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(o,a)}l((s=s.apply(e,t||[])).next())});var e,t,r,s}setErrorMessage(e=""){let t=this.querySelector("tp-form-error");t?t.textContent=e:(t=document.createElement("tp-form-error"),t.textContent=e,t.setAttribute("role","alert"),this.appendChild(t));const r=this.getField();r&&(r.setAttribute("aria-invalid","true"),t.id||(t.id=`tp-error-${Math.random().toString(36).substring(2,9)}`),r.setAttribute("aria-describedby",t.id)),this.dispatchEvent(new CustomEvent("validation-error"))}removeErrorMessage(){var e;null===(e=this.querySelector("tp-form-error"))||void 0===e||e.remove();const t=this.getField();t&&(t.removeAttribute("aria-invalid"),t.removeAttribute("aria-describedby")),this.dispatchEvent(new CustomEvent("validation-success"))}setSuspenseMessage(e=""){const t=this.querySelector("tp-form-suspense");if(t)t.textContent=e;else{const t=document.createElement("tp-form-suspense");t.textContent=e,t.setAttribute("aria-live","polite"),this.appendChild(t)}}removeSuspenseMessage(){var e;null===(e=this.querySelector("tp-form-suspense"))||void 0===e||e.remove()}}class $ extends HTMLElement{}class O extends HTMLElement{update(e){const t=this.querySelector("tp-form-errors-heading"),r=this.querySelector("tp-form-errors-list");if(0===e.length)return this.removeAttribute("active"),this.removeAttribute("tabindex"),null==t||t.update(0),void(null==r||r.clear());this.setAttribute("active","yes"),this.setAttribute("tabindex","-1"),null==t||t.update(e.length),null==r||r.update(e)}clear(){this.removeAttribute("active"),this.removeAttribute("tabindex");const e=this.querySelector("tp-form-errors-heading"),t=this.querySelector("tp-form-errors-list");null==e||e.update(0),null==t||t.clear()}}class j extends HTMLElement{get format(){var e;return null!==(e=this.getAttribute("format"))&&void 0!==e?e:""}set format(e){this.setAttribute("format",e)}update(e){this.textContent=this.format.replace("$count",e.toString())}}class I extends HTMLElement{update(e){this.textContent="";const{tpFormValidators:t}=window;e.forEach(e=>{var r,s;const i=e.getField(),n=null!==(r=null==i?void 0:i.id)&&void 0!==r?r:"";if(!n)return;const o=null!==(s=e.getAttribute("error"))&&void 0!==s?s:"";let a="";if(o&&t&&o in t){const r=t[o];"function"==typeof r.getSummaryMessage?a=r.getSummaryMessage(e):"function"==typeof r.getErrorMessage&&(a=r.getErrorMessage(e))}if(!a)return;const l=document.createElement("tp-form-errors-error");l.setAttribute("role","listitem");const u=document.createElement("a");u.href=`#${n}`,u.textContent=a,l.appendChild(u),this.appendChild(l)})}clear(){this.textContent=""}}class Z extends HTMLElement{constructor(){super(),this.addEventListener("click",this.handleClick.bind(this))}handleClick(e){var t;const r=e.target.closest("a");if(!r)return;e.preventDefault();const s=(null!==(t=r.getAttribute("href"))&&void 0!==t?t:"").replace("#","");if(s){const e=document.getElementById(s);null==e||e.focus()}}}class D extends HTMLElement{}class W extends HTMLElement{static get observedAttributes(){return["submitting-text","original-text","submitting"]}attributeChangedCallback(e="",t="",r=""){t!==r&&this.update()}update(){var e,t;const r=this.querySelector('button[type="submit"]');if(!r)return;const s=null!==(e=this.getAttribute("submitting-text"))&&void 0!==e?e:"",i=null!==(t=this.getAttribute("original-text"))&&void 0!==t?t:r.innerHTML;"yes"===this.getAttribute("submitting")?(r.setAttribute("disabled","disabled"),this.setAttribute("original-text",i),r.textContent=s):(r.removeAttribute("disabled"),this.removeAttribute("submitting"),this.removeAttribute("original-text"),r.innerHTML=i)}}const _=[t,r,s,i,n,o];window.tpFormValidators={},window.tpFormErrors={},window.tpFormSummaryErrors={},window.tpFormSuspenseMessages={},_.forEach(({name:e,validator:t,errorMessage:r,summaryErrorMessage:s})=>{window.tpFormValidators[e]=t,window.tpFormErrors[e]=r,s&&(window.tpFormSummaryErrors[e]=s)}),customElements.define("tp-form",k),customElements.define("tp-form-field",z),customElements.define("tp-form-error",$),customElements.define("tp-form-errors",O),customElements.define("tp-form-errors-heading",j),customElements.define("tp-form-errors-list",I),customElements.define("tp-form-errors-error",Z),customElements.define("tp-form-suspense",D),customElements.define("tp-form-submit",W)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/form/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/webpack/bootstrap","webpack://@travelopia/web-components/webpack/runtime/define property getters","webpack://@travelopia/web-components/webpack/runtime/hasOwnProperty shorthand","webpack://@travelopia/web-components/webpack/runtime/make namespace object","webpack://@travelopia/web-components/./src/form/utility.ts","webpack://@travelopia/web-components/./src/form/validators/required.ts","webpack://@travelopia/web-components/./src/form/validators/email.ts","webpack://@travelopia/web-components/./src/form/validators/min-length.ts","webpack://@travelopia/web-components/./src/form/validators/max-length.ts","webpack://@travelopia/web-components/./src/form/validators/no-empty-spaces.ts","webpack://@travelopia/web-components/./src/form/validators/zip.ts","webpack://@travelopia/web-components/./src/form/tp-form.ts","webpack://@travelopia/web-components/./src/form/tp-form-field.ts","webpack://@travelopia/web-components/./src/form/tp-form-error.ts","webpack://@travelopia/web-components/./src/form/tp-form-errors.ts","webpack://@travelopia/web-components/./src/form/tp-form-errors-heading.ts","webpack://@travelopia/web-components/./src/form/tp-form-errors-list.ts","webpack://@travelopia/web-components/./src/form/tp-form-errors-error.ts","webpack://@travelopia/web-components/./src/form/tp-form-suspense.ts","webpack://@travelopia/web-components/./src/form/tp-form-submit.ts","webpack://@travelopia/web-components/./src/form/index.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\n\n/**\n * Get the error message based on its code.\n *\n * @param {string} error Error code.\n *\n * @return {string} The error message.\n */\nexport const getErrorMessage = ( error: string = '' ): string => {\n\t// Check if tpFormErrors exist in the window object.\n\tconst { tpFormErrors } = window;\n\n\t// If tpFormErrors does not exist.\n\tif ( ! tpFormErrors ) {\n\t\t// Return an empty string.\n\t\treturn '';\n\t}\n\n\t// Check if the error exists and has a corresponding error message.\n\tif ( '' !== error && error in tpFormErrors && 'string' === typeof tpFormErrors[ error ] ) {\n\t\t// Return the error message.\n\t\treturn tpFormErrors[ error ];\n\t}\n\n\t// Return an empty string.\n\treturn '';\n};\n\n/**\n * Get the field label text.\n *\n * @param {TPFormFieldElement} field The form field element.\n *\n * @return {string} The label text.\n */\nexport const getFieldLabel = ( field: TPFormFieldElement ): string => {\n\t// Query for the label element.\n\tconst label = field.querySelector( 'label' );\n\n\t// Return the label text or a fallback.\n\treturn label?.textContent?.trim() || '';\n};\n\n/**\n * Get the summary error message based on its code, with label substitution.\n *\n * @param {string} error Error code.\n * @param {TPFormFieldElement} field The form field element.\n *\n * @return {string} The summary error message with %label% replaced.\n */\nexport const getSummaryErrorMessage = ( error: string = '', field: TPFormFieldElement ): string => {\n\t// Check if tpFormSummaryErrors exist in the window object.\n\tconst { tpFormSummaryErrors } = window;\n\n\t// If tpFormSummaryErrors does not exist or error not found.\n\tif ( ! tpFormSummaryErrors || '' === error || ! ( error in tpFormSummaryErrors ) ) {\n\t\t// Return an empty string.\n\t\treturn '';\n\t}\n\n\t// Get the message template.\n\tconst template = tpFormSummaryErrors[ error ];\n\n\t// If not a string, return empty.\n\tif ( 'string' !== typeof template ) {\n\t\t// Return an empty string.\n\t\treturn '';\n\t}\n\n\t// Get the field label.\n\tconst label = getFieldLabel( field );\n\n\t// Replace %label% placeholder and return.\n\treturn template.replace( '%label%', label );\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'required';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'This field is required';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: This field is required';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\t// Validate.\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Check if the field is empty.\n\t\treturn '' !== field.getField()?.value ?? '';\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => getSummaryErrorMessage( name, field ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'email';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Please enter a valid email address';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Please enter a valid email address';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Boolean value to determine if the field is valid or not.\n\t\treturn /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test( field.getField()?.value ?? '' );\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => getSummaryErrorMessage( name, field ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'min-length';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Must be at least %1 characters';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Must be at least %1 characters';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get min length and value.\n\t\tconst minLength: number = parseInt( field.getAttribute( 'min-length' ) ?? '0' );\n\t\tconst value: string = field.getField()?.value ?? '';\n\n\t\t// Validate.\n\t\treturn '' === value || value.length >= minLength;\n\t},\n\tgetErrorMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get error message.\n\t\tconst error: string = getErrorMessage( name );\n\t\tconst minLength: string = field.getAttribute( 'min-length' ) ?? '';\n\n\t\t// Return error message.\n\t\treturn error.replace( '%1', minLength );\n\t},\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get summary message with label.\n\t\tconst message = getSummaryErrorMessage( name, field );\n\t\tconst minLength: string = field.getAttribute( 'min-length' ) ?? '';\n\n\t\t// Replace %1 with min length value.\n\t\treturn message.replace( '%1', minLength );\n\t},\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'max-length';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Must be less than %1 characters';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Must be less than %1 characters';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get max length and value.\n\t\tconst maxLength: number = parseInt( field.getAttribute( 'max-length' ) ?? '0' );\n\t\tconst value: string = field.getField()?.value ?? '';\n\n\t\t// Validate.\n\t\treturn '' === value || value.length <= maxLength;\n\t},\n\tgetErrorMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get error message.\n\t\tconst error: string = getErrorMessage( name );\n\t\tconst maxLength: string = field.getAttribute( 'max-length' ) ?? '';\n\n\t\t// Return error message.\n\t\treturn error.replace( '%1', maxLength );\n\t},\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get summary message with label.\n\t\tconst message = getSummaryErrorMessage( name, field );\n\t\tconst maxLength: string = field.getAttribute( 'max-length' ) ?? '';\n\n\t\t// Replace %1 with max length value.\n\t\treturn message.replace( '%1', maxLength );\n\t},\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'no-empty-spaces';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'This field should not contain only white-spaces';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Should not contain only white-spaces';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Check if the field is empty.\n\t\tconst inputField = field.getField();\n\n\t\t// If no field is found return false.\n\t\tif ( ! inputField ) {\n\t\t\t// Return false.\n\t\t\treturn false;\n\t\t}\n\n\t\t// This case is not our concern. This is handled by `required` validator.\n\t\tif ( '' === inputField.value ) {\n\t\t\t// Return true.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Return true if field is not empty.\n\t\treturn '' !== inputField.value.trim();\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => getSummaryErrorMessage( name, field ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'zip';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Please enter a valid zip code';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Please enter a valid zip code';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get the field value or default to empty string.\n\t\tconst value = field.getField()?.value ?? '';\n\n\t\t// Get custom regex pattern from regex attribute or use default.\n\t\tconst customPattern: string | null = field.getAttribute( 'regex' );\n\t\tconst defaultPattern: string = '^[A-Za-z0-9][A-Za-z0-9\\\\- ]{1,8}[A-Za-z0-9]$';\n\t\tconst pattern: string = customPattern ?? defaultPattern;\n\n\t\t// Create regex object from pattern.\n\t\tconst zipCodeRegex: RegExp = new RegExp( pattern );\n\n\t\t// Test the trimmed value against the regex pattern.\n\t\treturn zipCodeRegex.test( value.trim() );\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => getSummaryErrorMessage( name, field ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormSubmitElement } from './tp-form-submit';\nimport { TPFormErrorsElement } from './tp-form-errors';\n\n/**\n * TP Form.\n */\nexport class TPFormElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected readonly form: HTMLFormElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get form.\n\t\tthis.form = this.querySelector( 'form' );\n\n\t\t// Add event listeners.\n\t\tthis.form?.addEventListener( 'submit', this.handleFormSubmit.bind( this ) );\n\t}\n\n\t/**\n\t * Handle form submission.\n\t *\n\t * @param {Event} e Submit event.\n\t */\n\tprotected async handleFormSubmit( e: SubmitEvent ): Promise<void> {\n\t\t// Stop normal form submission.\n\t\te.preventDefault();\n\t\te.stopImmediatePropagation();\n\n\t\t// Get submit button.\n\t\tconst submit: TPFormSubmitElement | null = this.querySelector( 'tp-form-submit' );\n\t\tsubmit?.setAttribute( 'submitting', 'yes' );\n\n\t\t// Ignore a form that currently has suspense.\n\t\tif ( 'yes' === this.getAttribute( 'suspense' ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Validate the form.\n\t\tconst formValid: boolean = await this.validate();\n\n\t\t// If form is valid then dispatch a custom 'submit-validation-success' event.\n\t\tif ( formValid ) {\n\t\t\t// Trigger event.\n\t\t\tthis.dispatchEvent( new CustomEvent( 'submit-validation-success', { bubbles: true } ) );\n\n\t\t\t// Submit form.\n\t\t\tif ( 'yes' !== this.getAttribute( 'prevent-submit' ) ) {\n\t\t\t\tthis.form?.submit();\n\t\t\t}\n\t\t} else {\n\t\t\t// Form is not valid, remove submitting attribute.\n\t\t\tsubmit?.removeAttribute( 'submitting' );\n\t\t}\n\t}\n\n\t/**\n\t * Validate the form.\n\t *\n\t * @return {boolean} Whether the form is valid or not.\n\t */\n\tasync validate(): Promise<boolean> {\n\t\t// Dispatch a custom 'validate' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );\n\n\t\t// Get the form fields.\n\t\tconst fields: NodeListOf<TPFormFieldElement> | null = this.querySelectorAll( 'tp-form-field' );\n\n\t\t// If no fields are found, return true indicating validation passed.\n\t\tif ( ! fields ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-success', { bubbles: true } ) );\n\n\t\t\t// Return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Start by setting the form as suspense.\n\t\tthis.setAttribute( 'suspense', 'yes' );\n\n\t\t// Check if all fields are valid.\n\t\tlet formValid: boolean = true;\n\t\tconst validationPromises: Promise<boolean>[] = Array\n\t\t\t.from( fields )\n\t\t\t.map( async ( field: TPFormFieldElement ): Promise<boolean> => await field.validate() );\n\n\t\t// Wait for promises to resolve.\n\t\tawait Promise.all( validationPromises )\n\t\t\t.then( ( results: boolean[] ): void => {\n\t\t\t\t// Check if all fields are valid.\n\t\t\t\tformValid = results.every( ( isValid: boolean ) => isValid );\n\t\t\t} )\n\t\t\t.catch( () => {\n\t\t\t\t// There was an error with one or more fields.\n\t\t\t\tformValid = false;\n\t\t\t} )\n\t\t\t.finally( () => this.removeAttribute( 'suspense' ) );\n\n\t\t// If form is valid then dispatch a custom 'validation-success' event else send a custom 'validation-error' event.\n\t\tif ( formValid ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-success', { bubbles: true } ) );\n\n\t\t\t// Clear error summary if it exists.\n\t\t\tthis.clearErrorSummary();\n\t\t} else {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-error', { bubbles: true } ) );\n\n\t\t\t// Update error summary and manage focus.\n\t\t\tthis.handleValidationError( fields );\n\t\t}\n\n\t\t// Return whether the form is valid or not.\n\t\treturn formValid;\n\t}\n\n\t/**\n\t * Handle validation error - update error summary and manage focus.\n\t *\n\t * @param {NodeList} fields All form fields.\n\t */\n\tprotected handleValidationError( fields: NodeListOf<TPFormFieldElement> ): void {\n\t\t// Get invalid fields that are visible.\n\t\tconst invalidFields: TPFormFieldElement[] = Array.from( fields ).filter(\n\t\t\t( field: TPFormFieldElement ): boolean =>\n\t\t\t\tfield.hasAttribute( 'error' ) && field.offsetWidth > 0 && field.offsetHeight > 0\n\t\t);\n\n\t\t// Get error summary element.\n\t\tconst errorSummary: TPFormErrorsElement | null = this.querySelector( 'tp-form-errors' );\n\n\t\t// If error summary exists, populate it and move focus to it.\n\t\tif ( errorSummary ) {\n\t\t\terrorSummary.update( invalidFields );\n\n\t\t\t// Timeout needed for Safari to focus after DOM update.\n\t\t\tsetTimeout( () => errorSummary.focus(), 0 );\n\t\t} else if ( invalidFields.length > 0 ) {\n\t\t\t// No error summary, move focus to first visible invalid field.\n\t\t\tconst firstInvalidField = invalidFields[ 0 ].getField();\n\t\t\tfirstInvalidField?.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Clear the error summary.\n\t */\n\tprotected clearErrorSummary(): void {\n\t\t// Clear summary.\n\t\tconst errorSummary: TPFormErrorsElement | null = this.querySelector( 'tp-form-errors' );\n\t\terrorSummary?.clear();\n\t}\n\n\t/**\n\t * Validate one field.\n\t *\n\t * @param {HTMLElement} field Field node.\n\t */\n\tasync validateField( field: TPFormFieldElement ): Promise<boolean> {\n\t\t// Set form as suspense, validate and undo suspense.\n\t\tthis.setAttribute( 'suspense', 'yes' );\n\t\tconst fieldValid: boolean = await field.validate();\n\t\tthis.removeAttribute( 'suspense' );\n\n\t\t// Return result.\n\t\treturn fieldValid;\n\t}\n\n\t/**\n\t * Reset form validation.\n\t */\n\tresetValidation(): void {\n\t\t// Get the form fields.\n\t\tconst fields: NodeListOf<TPFormFieldElement> | null = this.querySelectorAll( 'tp-form-field' );\n\n\t\t// If no fields are found.\n\t\tif ( ! fields ) {\n\t\t\t// Exit the function.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove 'valid' and 'error' attributes from all fields.\n\t\tfields.forEach( ( field: TPFormFieldElement ): void => {\n\t\t\t// Remove 'valid' and 'error' and 'suspense' attributes.\n\t\t\tfield.removeAttribute( 'valid' );\n\t\t\tfield.removeAttribute( 'error' );\n\t\t\tfield.removeAttribute( 'suspense' );\n\t\t} );\n\n\t\t// Remove 'suspense' attribute from form.\n\t\tthis.removeAttribute( 'suspense' );\n\n\t\t// Remove 'submitting' attribute from submit button.\n\t\tconst submit: TPFormSubmitElement | null = this.querySelector( 'tp-form-submit' );\n\t\tsubmit?.removeAttribute( 'submitting' );\n\n\t\t// Clear error summary.\n\t\tthis.clearErrorSummary();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPFormElement } from './tp-form';\nimport { TPFormErrorElement } from './tp-form-error';\nimport { TPFormSuspenseElement } from './tp-form-suspense';\n\n/**\n * TP Form Field.\n */\nexport class TPFormFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get field.\n\t\tconst field = this.getField();\n\n\t\t// Add event listeners.\n\t\tfield?.addEventListener( 'keyup', this.handleFieldChanged.bind( this ) );\n\t\tfield?.addEventListener( 'change', this.handleFieldChanged.bind( this ) );\n\n\t\t// Set up accessibility attributes.\n\t\tthis.setupAccessibility();\n\t}\n\n\t/**\n\t * Set up accessibility attributes (label linking, IDs).\n\t */\n\tprivate setupAccessibility(): void {\n\t\t// Get the field.\n\t\tconst field = this.getField();\n\n\t\t// Bail if no field.\n\t\tif ( ! field ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Generate ID for the field if not present.\n\t\tif ( ! field.id ) {\n\t\t\tfield.id = `tp-field-${ Math.random().toString( 36 ).substring( 2, 9 ) }`;\n\t\t}\n\n\t\t// Get label.\n\t\tconst label = this.querySelector( 'label' );\n\n\t\t// Set for attribute on label if not present.\n\t\tif ( label && ! label.hasAttribute( 'for' ) ) {\n\t\t\tlabel.setAttribute( 'for', field.id );\n\t\t}\n\t}\n\n\t/**\n\t * Update validation when the field has changed.\n\t */\n\thandleFieldChanged(): void {\n\t\t// Check if we want to ignore field revalidations.\n\t\tif ( 'no' === this.getAttribute( 'revalidate-on-change' ) ) {\n\t\t\t// Yes we do, bail!\n\t\t\treturn;\n\t\t}\n\n\t\t// Validate the field again if 'valid' or 'error' attribute is present.\n\t\tif ( this.getAttribute( 'valid' ) || this.getAttribute( 'error' ) ) {\n\t\t\tconst form: TPFormElement | null = this.closest( 'tp-form' );\n\t\t\tform?.validateField( this );\n\t\t}\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 observed in the TPFormFieldElement web-component.\n\t\treturn [ 'valid', 'error', 'suspense' ];\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// Check if the observed attributes 'valid' or 'error' have changed.\n\n\t\t// Dispatch a custom 'validate' event.\n\t\tif ( ( 'valid' === name || 'error' === name || 'suspense' === name ) && oldValue !== newValue ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );\n\t\t}\n\n\t\t// Update the component after the attribute change.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update component.\n\t */\n\tupdate(): void {\n\t\t// Check if tpFormValidators exist in the window object.\n\t\tconst { tpFormValidators } = window;\n\n\t\t// Exit the function if validators are not available.\n\t\tif ( ! tpFormValidators ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the 'error' attribute value.\n\t\tconst error: string = this.getAttribute( 'error' ) ?? '';\n\n\t\t// Check if the error exists and has a corresponding error message function.\n\t\tif ( '' !== error && error in tpFormValidators && 'function' === typeof tpFormValidators[ error ].getErrorMessage ) {\n\t\t\tthis.setErrorMessage( tpFormValidators[ error ].getErrorMessage( this ) );\n\t\t} else {\n\t\t\tthis.removeErrorMessage();\n\t\t}\n\n\t\t// Get the 'suspense' attribute value.\n\t\tconst suspense: string = this.getAttribute( 'suspense' ) ?? '';\n\n\t\t// Check if the suspense exists and has a corresponding suspense message function.\n\t\tif ( '' !== suspense && suspense in tpFormValidators && 'function' === typeof tpFormValidators[ suspense ].getSuspenseMessage ) {\n\t\t\t// @ts-ignore\n\t\t\tthis.setSuspenseMessage( tpFormValidators[ suspense ]?.getSuspenseMessage( this ) );\n\t\t} else {\n\t\t\tthis.removeSuspenseMessage();\n\t\t}\n\t}\n\n\t/**\n\t * Get the associated field.\n\t *\n\t * @return {HTMLElement} The associated field for this component.\n\t */\n\tgetField(): HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null {\n\t\t// Return the associated field by querying input, select, or textarea elements.\n\t\treturn this.querySelector( 'input,select,textarea' );\n\t}\n\n\t/**\n\t * Validate this field.\n\t *\n\t * @return {boolean} Whether this field passed validation.\n\t */\n\tasync validate(): Promise<boolean> {\n\t\t// Retrieve tpFormValidators from the window object.\n\t\tconst { tpFormValidators } = window;\n\n\t\t// Exit the function if validators are not available.\n\t\tif ( ! tpFormValidators ) {\n\t\t\t// If no validators are found, return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if the field is visible.\n\t\tif ( this.offsetWidth <= 0 || this.offsetHeight <= 0 ) {\n\t\t\t// If the field is not visible, return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Prepare error and valid status.\n\t\tlet valid: boolean = true;\n\t\tlet suspense: Promise<boolean> | null = null;\n\t\tlet error: string = '';\n\t\tconst allAttributes: string[] = this.getAttributeNames();\n\n\t\t// Traverse all attributes to see if we find a matching validator.\n\t\tallAttributes.every( ( attributeName: string ): boolean => {\n\t\t\t// Check if the attribute is a validator.\n\t\t\tif ( attributeName in tpFormValidators && 'function' === typeof tpFormValidators[ attributeName ].validate ) {\n\t\t\t\t// We found one, lets validate the field.\n\t\t\t\tconst isValid: boolean | Promise<boolean> = tpFormValidators[ attributeName ].validate( this );\n\t\t\t\terror = attributeName;\n\n\t\t\t\t// First check for a Promise.\n\t\t\t\tif ( isValid instanceof Promise ) {\n\t\t\t\t\t// Yes it is an async validation.\n\t\t\t\t\tvalid = false;\n\n\t\t\t\t\t// Dispatch a custom 'validation-suspense-start' event.\n\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-start' ) );\n\n\t\t\t\t\t// Create the promise.\n\t\t\t\t\tsuspense = new Promise( ( resolve, reject ): void => {\n\t\t\t\t\t\t// Validate it.\n\t\t\t\t\t\tisValid\n\t\t\t\t\t\t\t.then( ( suspenseIsValid: boolean ) => {\n\t\t\t\t\t\t\t\t// Validation is complete.\n\t\t\t\t\t\t\t\tif ( true === suspenseIsValid ) {\n\t\t\t\t\t\t\t\t\tthis.setAttribute( 'valid', 'yes' );\n\t\t\t\t\t\t\t\t\tthis.removeAttribute( 'error' );\n\n\t\t\t\t\t\t\t\t\t// Resolve the promise.\n\t\t\t\t\t\t\t\t\tresolve( true );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tthis.removeAttribute( 'valid' );\n\t\t\t\t\t\t\t\t\tthis.setAttribute( 'error', error );\n\n\t\t\t\t\t\t\t\t\t// Resolve the promise.\n\t\t\t\t\t\t\t\t\tresolve( false );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Dispatch a custom 'validation-suspense-success' event.\n\t\t\t\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-success' ) );\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.catch( (): void => {\n\t\t\t\t\t\t\t\t// There was an error.\n\t\t\t\t\t\t\t\tthis.removeAttribute( 'valid' );\n\t\t\t\t\t\t\t\tthis.setAttribute( 'error', error );\n\n\t\t\t\t\t\t\t\t// Dispatch a custom 'validation-suspense-error' event.\n\t\t\t\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-error' ) );\n\n\t\t\t\t\t\t\t\t// Reject the promise.\n\t\t\t\t\t\t\t\treject( false );\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.finally( (): void => {\n\t\t\t\t\t\t\t\t// Clean up.\n\t\t\t\t\t\t\t\tthis.removeAttribute( 'suspense' );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Return.\n\t\t\t\t\treturn false;\n\t\t\t\t} else if ( false === isValid ) {\n\t\t\t\t\t// Not a Promise, but looks like we found an error!\n\t\t\t\t\tvalid = false;\n\n\t\t\t\t\t// Return.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// No error found, all good.\n\t\t\treturn true;\n\t\t} );\n\n\t\t// Check if the field is valid or not.\n\t\tif ( valid ) {\n\t\t\tthis.setAttribute( 'valid', 'yes' );\n\t\t\tthis.removeAttribute( 'error' );\n\t\t\tthis.removeAttribute( 'suspense' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'valid' );\n\n\t\t\t// Check for suspense.\n\t\t\tif ( suspense ) {\n\t\t\t\tthis.setAttribute( 'suspense', error );\n\t\t\t\tthis.removeAttribute( 'error' );\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute( 'suspense' );\n\t\t\t\tthis.setAttribute( 'error', error );\n\t\t\t}\n\t\t}\n\n\t\t// Do we have a suspense?\n\t\tif ( suspense ) {\n\t\t\t// Yes we do, return the promise.\n\t\t\treturn suspense;\n\t\t}\n\n\t\t// No we don't, return a resolved promise.\n\t\treturn valid;\n\t}\n\n\t/**\n\t * Set the error message.\n\t *\n\t * @param {string} message Error message.\n\t */\n\tsetErrorMessage( message: string = '' ): void {\n\t\t// Look for an existing tp-form-error element.\n\t\tlet error: TPFormErrorElement | null = this.querySelector( 'tp-form-error' );\n\n\t\t// If found, update its textContent with the error message. Otherwise, create a new tp-form-error element and append it to the component.\n\t\tif ( error ) {\n\t\t\terror.textContent = message;\n\t\t} else {\n\t\t\terror = document.createElement( 'tp-form-error' );\n\t\t\terror.textContent = message;\n\t\t\terror.setAttribute( 'role', 'alert' );\n\t\t\tthis.appendChild( error );\n\t\t}\n\n\t\t// Set up accessibility for the error message.\n\t\tconst field = this.getField();\n\n\t\t// Set aria-invalid on the field.\n\t\tif ( field ) {\n\t\t\tfield.setAttribute( 'aria-invalid', 'true' );\n\n\t\t\t// Generate ID for error element if not present.\n\t\t\tif ( ! error.id ) {\n\t\t\t\terror.id = `tp-error-${ Math.random().toString( 36 ).substring( 2, 9 ) }`;\n\t\t\t}\n\n\t\t\t// Link field to error via aria-describedby.\n\t\t\tfield.setAttribute( 'aria-describedby', error.id );\n\t\t}\n\n\t\t// Dispatch a custom 'validation-error' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validation-error' ) );\n\t}\n\n\t/**\n\t * Remove the error message.\n\t */\n\tremoveErrorMessage(): void {\n\t\t// Find and remove the tp-form-error element.\n\t\tthis.querySelector( 'tp-form-error' )?.remove();\n\n\t\t// Remove accessibility attributes from the field.\n\t\tconst field = this.getField();\n\n\t\t// Remove aria-invalid and aria-describedby.\n\t\tif ( field ) {\n\t\t\tfield.removeAttribute( 'aria-invalid' );\n\t\t\tfield.removeAttribute( 'aria-describedby' );\n\t\t}\n\n\t\t// Dispatch a custom 'validation-success' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validation-success' ) );\n\t}\n\n\t/**\n\t * Set the suspense message.\n\t *\n\t * @param {string} message Suspense message.\n\t */\n\tsetSuspenseMessage( message: string = '' ): void {\n\t\t// Look for an existing tp-form-error element.\n\t\tconst suspense: TPFormSuspenseElement | null = this.querySelector( 'tp-form-suspense' );\n\n\t\t// If found, update its textContent with the suspense message. Otherwise, create a new tp-form-suspense element and append it to the component.\n\t\tif ( suspense ) {\n\t\t\tsuspense.textContent = message;\n\t\t} else {\n\t\t\tconst suspenseElement: TPFormSuspenseElement = document.createElement( 'tp-form-suspense' );\n\t\t\tsuspenseElement.textContent = message;\n\t\t\tsuspenseElement.setAttribute( 'aria-live', 'polite' );\n\t\t\tthis.appendChild( suspenseElement );\n\t\t}\n\t}\n\n\t/**\n\t * Remove the suspense message.\n\t */\n\tremoveSuspenseMessage(): void {\n\t\t// Find and remove the tp-form-suspense element.\n\t\tthis.querySelector( 'tp-form-suspense' )?.remove();\n\t}\n}\n","/**\n * TP Form Error.\n */\nexport class TPFormErrorElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormErrorsHeadingElement } from './tp-form-errors-heading';\nimport { TPFormErrorsListElement } from './tp-form-errors-list';\n\n/**\n * TP Form Errors.\n */\nexport class TPFormErrorsElement extends HTMLElement {\n\t/**\n\t * Update the error summary with the given invalid fields.\n\t *\n\t * @param {TPFormFieldElement[]} invalidFields Array of invalid form fields.\n\t */\n\tupdate( invalidFields: TPFormFieldElement[] ): void {\n\t\t// Get child components.\n\t\tconst heading = this.querySelector( 'tp-form-errors-heading' ) as TPFormErrorsHeadingElement | null;\n\t\tconst list = this.querySelector( 'tp-form-errors-list' ) as TPFormErrorsListElement | null;\n\n\t\t// If no errors, remove active state.\n\t\tif ( 0 === invalidFields.length ) {\n\t\t\tthis.removeAttribute( 'active' );\n\t\t\tthis.removeAttribute( 'tabindex' );\n\t\t\theading?.update( 0 );\n\t\t\tlist?.clear();\n\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set active state and make focusable.\n\t\tthis.setAttribute( 'active', 'yes' );\n\t\tthis.setAttribute( 'tabindex', '-1' );\n\n\t\t// Update child components.\n\t\theading?.update( invalidFields.length );\n\t\tlist?.update( invalidFields );\n\t}\n\n\t/**\n\t * Clear the error summary.\n\t */\n\tclear(): void {\n\t\t// Clear attributes.\n\t\tthis.removeAttribute( 'active' );\n\t\tthis.removeAttribute( 'tabindex' );\n\n\t\t// Get heading and list.\n\t\tconst heading = this.querySelector( 'tp-form-errors-heading' ) as TPFormErrorsHeadingElement | null;\n\t\tconst list = this.querySelector( 'tp-form-errors-list' ) as TPFormErrorsListElement | null;\n\n\t\t// Update them.\n\t\theading?.update( 0 );\n\t\tlist?.clear();\n\t}\n}\n","/**\n * TP Form Errors Heading.\n *\n * Displays the error count. User controls the heading element wrapper.\n */\nexport class TPFormErrorsHeadingElement extends HTMLElement {\n\t/**\n\t * Get format.\n\t *\n\t * @return {string} Format with $count placeholder.\n\t */\n\tget format(): string {\n\t\t// Get format.\n\t\treturn this.getAttribute( 'format' ) ?? '';\n\t}\n\n\t/**\n\t * Set format.\n\t *\n\t * @param {string} format Format string.\n\t */\n\tset format( format: string ) {\n\t\t// Set format.\n\t\tthis.setAttribute( 'format', format );\n\t}\n\n\t/**\n\t * Update the heading with the error count.\n\t *\n\t * @param {number} count Number of errors.\n\t */\n\tupdate( count: number ): void {\n\t\t// Update count.\n\t\tthis.textContent = this.format.replace( '$count', count.toString() );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\n\n/**\n * TP Form Errors List.\n *\n * Displays the list of error links using tp-form-errors-error elements.\n */\nexport class TPFormErrorsListElement extends HTMLElement {\n\t/**\n\t * Update the list with error links.\n\t *\n\t * @param {TPFormFieldElement[]} invalidFields Array of invalid form fields.\n\t */\n\tupdate( invalidFields: TPFormFieldElement[] ): void {\n\t\t// Clear existing content.\n\t\tthis.textContent = '';\n\n\t\t// Get validators for summary messages.\n\t\tconst { tpFormValidators } = window;\n\t\tinvalidFields.forEach( ( field: TPFormFieldElement ): void => {\n\t\t\t// Get field ID for the link.\n\t\t\tconst inputField = field.getField();\n\t\t\tconst fieldId = inputField?.id ?? '';\n\n\t\t\t// Skip if no field ID.\n\t\t\tif ( ! fieldId ) {\n\t\t\t\t// Bail.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get the error type from the field's error attribute.\n\t\t\tconst errorType = field.getAttribute( 'error' ) ?? '';\n\n\t\t\t// Get the summary message.\n\t\t\tlet message = '';\n\n\t\t\t// Check if we have everything.\n\t\t\tif ( errorType && tpFormValidators && errorType in tpFormValidators ) {\n\t\t\t\tconst validator = tpFormValidators[ errorType ];\n\n\t\t\t\t// Try getSummaryMessage first, fall back to getErrorMessage.\n\t\t\t\tif ( 'function' === typeof validator.getSummaryMessage ) {\n\t\t\t\t\tmessage = validator.getSummaryMessage( field );\n\t\t\t\t} else if ( 'function' === typeof validator.getErrorMessage ) {\n\t\t\t\t\tmessage = validator.getErrorMessage( field );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Skip if no message.\n\t\t\tif ( ! message ) {\n\t\t\t\t// Bail.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Create error element with link.\n\t\t\tconst errorElement = document.createElement( 'tp-form-errors-error' );\n\t\t\terrorElement.setAttribute( 'role', 'listitem' );\n\t\t\tconst link = document.createElement( 'a' );\n\t\t\tlink.href = `#${ fieldId }`;\n\t\t\tlink.textContent = message;\n\t\t\terrorElement.appendChild( link );\n\t\t\tthis.appendChild( errorElement );\n\t\t} );\n\t}\n\n\t/**\n\t * Clear the list.\n\t */\n\tclear(): void {\n\t\t// Clear.\n\t\tthis.textContent = '';\n\t}\n}\n","/**\n * TP Form Errors Error.\n */\nexport class TPFormErrorsErrorElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Use event delegation to handle clicks on dynamically added anchors.\n\t\tthis.addEventListener( 'click', this.handleClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle click on error link.\n\t *\n\t * @param {Event} event Click event.\n\t */\n\tprotected handleClick( event: Event ): void {\n\t\t// Find the anchor element.\n\t\tconst target = event.target as HTMLElement;\n\t\tconst anchor = target.closest( 'a' );\n\n\t\t// Only handle clicks on anchors.\n\t\tif ( ! anchor ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prevent default to avoid hash in URL.\n\t\tevent.preventDefault();\n\n\t\t// Get the field ID from href.\n\t\tconst href = anchor.getAttribute( 'href' ) ?? '';\n\t\tconst fieldId = href.replace( '#', '' );\n\n\t\t// Focus the target field.\n\t\tif ( fieldId ) {\n\t\t\tconst targetField = document.getElementById( fieldId );\n\t\t\ttargetField?.focus();\n\t\t}\n\t}\n}\n","/**\n * TP Form Suspense.\n */\nexport class TPFormSuspenseElement extends HTMLElement {\n}\n","/**\n * TP Form Submit.\n */\nexport class TPFormSubmitElement 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 observed in the TPFormSubmitElement web-component.\n\t\treturn [ 'submitting-text', 'original-text', 'submitting' ];\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 if attribute has changed.\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 submit button.\n\t\tconst submitButton: HTMLButtonElement | null = this.querySelector( 'button[type=\"submit\"]' );\n\n\t\t// Check if we have a submit button.\n\t\tif ( ! submitButton ) {\n\t\t\t// No, we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prepare submit button text.\n\t\tconst submittingText: string = this.getAttribute( 'submitting-text' ) ?? '';\n\t\tconst originalText: string = this.getAttribute( 'original-text' ) ?? submitButton.innerHTML;\n\n\t\t// Check if we are submitting.\n\t\tif ( 'yes' === this.getAttribute( 'submitting' ) ) {\n\t\t\tsubmitButton.setAttribute( 'disabled', 'disabled' );\n\t\t\tthis.setAttribute( 'original-text', originalText );\n\t\t\tsubmitButton.textContent = submittingText;\n\t\t} else {\n\t\t\tsubmitButton.removeAttribute( 'disabled' );\n\t\t\tthis.removeAttribute( 'submitting' );\n\t\t\tthis.removeAttribute( 'original-text' );\n\t\t\tsubmitButton.innerHTML = originalText;\n\t\t}\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Validators.\n */\n\n// Import validators.\nimport { TPFormValidator } from './definitions';\nimport * as required from './validators/required';\nimport * as email from './validators/email';\nimport * as minLength from './validators/min-length';\nimport * as maxLength from './validators/max-length';\nimport * as noEmptySpaces from './validators/no-empty-spaces';\nimport * as zip from './validators/zip';\n\n// Prepare validators.\nconst validators = [\n\trequired,\n\temail,\n\tminLength,\n\tmaxLength,\n\tnoEmptySpaces,\n\tzip,\n];\n\n/**\n * Register Validators and Errors.\n */\nwindow.tpFormValidators = {};\nwindow.tpFormErrors = {};\nwindow.tpFormSummaryErrors = {};\nwindow.tpFormSuspenseMessages = {};\n\n// Register validators.\nvalidators.forEach( (\n\t{ name, validator, errorMessage, summaryErrorMessage }: { name: string, validator: TPFormValidator, errorMessage: string, summaryErrorMessage?: string }\n): void => {\n\t// Assigning validators and error messages to various fields.\n\twindow.tpFormValidators[ name ] = validator;\n\twindow.tpFormErrors[ name ] = errorMessage;\n\n\t// Register summary error message if provided.\n\tif ( summaryErrorMessage ) {\n\t\twindow.tpFormSummaryErrors[ name ] = summaryErrorMessage;\n\t}\n} );\n\n/**\n * Components.\n */\nimport { TPFormElement } from './tp-form';\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormErrorElement } from './tp-form-error';\nimport { TPFormErrorsElement } from './tp-form-errors';\nimport { TPFormErrorsHeadingElement } from './tp-form-errors-heading';\nimport { TPFormErrorsListElement } from './tp-form-errors-list';\nimport { TPFormErrorsErrorElement } from './tp-form-errors-error';\nimport { TPFormSuspenseElement } from './tp-form-suspense';\nimport { TPFormSubmitElement } from './tp-form-submit';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-form', TPFormElement );\ncustomElements.define( 'tp-form-field', TPFormFieldElement );\ncustomElements.define( 'tp-form-error', TPFormErrorElement );\ncustomElements.define( 'tp-form-errors', TPFormErrorsElement );\ncustomElements.define( 'tp-form-errors-heading', TPFormErrorsHeadingElement );\ncustomElements.define( 'tp-form-errors-list', TPFormErrorsListElement );\ncustomElements.define( 'tp-form-errors-error', TPFormErrorsErrorElement );\ncustomElements.define( 'tp-form-suspense', TPFormSuspenseElement );\ncustomElements.define( 'tp-form-submit', TPFormSubmitElement );\n"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","getErrorMessage","error","tpFormErrors","window","getSummaryErrorMessage","field","tpFormSummaryErrors","template","label","querySelector","textContent","trim","getFieldLabel","replace","errorMessage","summaryErrorMessage","validator","validate","getField","getSummaryMessage","test","minLength","parseInt","getAttribute","length","message","maxLength","inputField","customPattern","RegExp","TPFormElement","HTMLElement","constructor","super","this","form","addEventListener","handleFormSubmit","bind","e","preventDefault","stopImmediatePropagation","submit","setAttribute","dispatchEvent","CustomEvent","bubbles","removeAttribute","fields","querySelectorAll","formValid","validationPromises","Array","from","map","Promise","all","then","results","every","isValid","catch","finally","clearErrorSummary","handleValidationError","invalidFields","filter","hasAttribute","offsetWidth","offsetHeight","errorSummary","update","setTimeout","focus","firstInvalidField","clear","validateField","fieldValid","resetValidation","forEach","TPFormFieldElement","handleFieldChanged","setupAccessibility","id","Math","random","toString","substring","closest","observedAttributes","attributeChangedCallback","name","oldValue","newValue","tpFormValidators","setErrorMessage","removeErrorMessage","suspense","getSuspenseMessage","setSuspenseMessage","removeSuspenseMessage","valid","getAttributeNames","attributeName","resolve","reject","suspenseIsValid","document","createElement","appendChild","remove","suspenseElement","TPFormErrorElement","TPFormErrorsElement","heading","list","TPFormErrorsHeadingElement","format","count","TPFormErrorsListElement","fieldId","errorType","errorElement","link","href","TPFormErrorsErrorElement","handleClick","event","anchor","target","targetField","getElementById","TPFormSuspenseElement","TPFormSubmitElement","_name","submitButton","submittingText","originalText","innerHTML","validators","tpFormSuspenseMessages","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/form/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/webpack/bootstrap","webpack://@travelopia/web-components/webpack/runtime/define property getters","webpack://@travelopia/web-components/webpack/runtime/hasOwnProperty shorthand","webpack://@travelopia/web-components/webpack/runtime/make namespace object","webpack://@travelopia/web-components/./src/form/utility.ts","webpack://@travelopia/web-components/./src/form/validators/required.ts","webpack://@travelopia/web-components/./src/form/validators/email.ts","webpack://@travelopia/web-components/./src/form/validators/min-length.ts","webpack://@travelopia/web-components/./src/form/validators/max-length.ts","webpack://@travelopia/web-components/./src/form/validators/no-empty-spaces.ts","webpack://@travelopia/web-components/./src/form/validators/zip.ts","webpack://@travelopia/web-components/./src/form/tp-form.ts","webpack://@travelopia/web-components/./src/form/tp-form-field.ts","webpack://@travelopia/web-components/./src/form/tp-form-error.ts","webpack://@travelopia/web-components/./src/form/tp-form-errors.ts","webpack://@travelopia/web-components/./src/form/tp-form-errors-heading.ts","webpack://@travelopia/web-components/./src/form/tp-form-errors-list.ts","webpack://@travelopia/web-components/./src/form/tp-form-errors-error.ts","webpack://@travelopia/web-components/./src/form/tp-form-suspense.ts","webpack://@travelopia/web-components/./src/form/tp-form-submit.ts","webpack://@travelopia/web-components/./src/form/index.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\n\n/**\n * Get the error message based on its code.\n *\n * @param {string} error Error code.\n *\n * @return {string} The error message.\n */\nexport const getErrorMessage = ( error: string = '' ): string => {\n\t// Check if tpFormErrors exist in the window object.\n\tconst { tpFormErrors } = window;\n\n\t// If tpFormErrors does not exist.\n\tif ( ! tpFormErrors ) {\n\t\t// Return an empty string.\n\t\treturn '';\n\t}\n\n\t// Check if the error exists and has a corresponding error message.\n\tif ( '' !== error && error in tpFormErrors && 'string' === typeof tpFormErrors[ error ] ) {\n\t\t// Return the error message.\n\t\treturn tpFormErrors[ error ];\n\t}\n\n\t// Return an empty string.\n\treturn '';\n};\n\n/**\n * Get the field label text.\n *\n * @param {TPFormFieldElement} field The form field element.\n *\n * @return {string} The label text.\n */\nexport const getFieldLabel = ( field: TPFormFieldElement ): string => {\n\t// Query for the label element.\n\tconst label = field.querySelector( 'label' );\n\n\t// Return the label text or a fallback.\n\treturn label?.textContent?.trim() || '';\n};\n\n/**\n * Get the summary error message based on its code, with label substitution.\n *\n * @param {string} error Error code.\n * @param {TPFormFieldElement} field The form field element.\n *\n * @return {string} The summary error message with %label% replaced.\n */\nexport const getSummaryErrorMessage = ( error: string = '', field: TPFormFieldElement ): string => {\n\t// Check if tpFormSummaryErrors exist in the window object.\n\tconst { tpFormSummaryErrors } = window;\n\n\t// If tpFormSummaryErrors does not exist or error not found.\n\tif ( ! tpFormSummaryErrors || '' === error || ! ( error in tpFormSummaryErrors ) ) {\n\t\t// Return an empty string.\n\t\treturn '';\n\t}\n\n\t// Get the message template.\n\tconst template = tpFormSummaryErrors[ error ];\n\n\t// If not a string, return empty.\n\tif ( 'string' !== typeof template ) {\n\t\t// Return an empty string.\n\t\treturn '';\n\t}\n\n\t// Get the field label.\n\tconst label = getFieldLabel( field );\n\n\t// Replace %label% placeholder and return.\n\treturn template.replace( '%label%', label );\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'required';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'This field is required';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: This field is required';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\t// Validate.\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Check if the field is empty.\n\t\treturn '' !== ( field.getField()?.value ?? '' );\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => getSummaryErrorMessage( name, field ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'email';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Please enter a valid email address';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Please enter a valid email address';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Boolean value to determine if the field is valid or not.\n\t\treturn /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test( field.getField()?.value ?? '' );\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => getSummaryErrorMessage( name, field ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'min-length';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Must be at least %1 characters';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Must be at least %1 characters';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get min length and value.\n\t\tconst minLength: number = parseInt( field.getAttribute( 'min-length' ) ?? '0' );\n\t\tconst value: string = field.getField()?.value ?? '';\n\n\t\t// Validate.\n\t\treturn '' === value || value.length >= minLength;\n\t},\n\tgetErrorMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get error message.\n\t\tconst error: string = getErrorMessage( name );\n\t\tconst minLength: string = field.getAttribute( 'min-length' ) ?? '';\n\n\t\t// Return error message.\n\t\treturn error.replace( '%1', minLength );\n\t},\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get summary message with label.\n\t\tconst message = getSummaryErrorMessage( name, field );\n\t\tconst minLength: string = field.getAttribute( 'min-length' ) ?? '';\n\n\t\t// Replace %1 with min length value.\n\t\treturn message.replace( '%1', minLength );\n\t},\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'max-length';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Must be less than %1 characters';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Must be less than %1 characters';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get max length and value.\n\t\tconst maxLength: number = parseInt( field.getAttribute( 'max-length' ) ?? '0' );\n\t\tconst value: string = field.getField()?.value ?? '';\n\n\t\t// Validate.\n\t\treturn '' === value || value.length <= maxLength;\n\t},\n\tgetErrorMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get error message.\n\t\tconst error: string = getErrorMessage( name );\n\t\tconst maxLength: string = field.getAttribute( 'max-length' ) ?? '';\n\n\t\t// Return error message.\n\t\treturn error.replace( '%1', maxLength );\n\t},\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get summary message with label.\n\t\tconst message = getSummaryErrorMessage( name, field );\n\t\tconst maxLength: string = field.getAttribute( 'max-length' ) ?? '';\n\n\t\t// Replace %1 with max length value.\n\t\treturn message.replace( '%1', maxLength );\n\t},\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'no-empty-spaces';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'This field should not contain only white-spaces';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Should not contain only white-spaces';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Check if the field is empty.\n\t\tconst inputField = field.getField();\n\n\t\t// If no field is found return false.\n\t\tif ( ! inputField ) {\n\t\t\t// Return false.\n\t\t\treturn false;\n\t\t}\n\n\t\t// This case is not our concern. This is handled by `required` validator.\n\t\tif ( '' === inputField.value ) {\n\t\t\t// Return true.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Return true if field is not empty.\n\t\treturn '' !== inputField.value.trim();\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => getSummaryErrorMessage( name, field ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage, getSummaryErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'zip';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Please enter a valid zip code';\n\n/**\n * Summary error message (supports %label% placeholder).\n */\nexport const summaryErrorMessage: string = '%label%: Please enter a valid zip code';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get the field value or default to empty string.\n\t\tconst value = field.getField()?.value ?? '';\n\n\t\t// Get custom regex pattern from regex attribute or use default.\n\t\tconst customPattern: string | null = field.getAttribute( 'regex' );\n\t\tconst defaultPattern: string = '^[A-Za-z0-9][A-Za-z0-9\\\\- ]{1,8}[A-Za-z0-9]$';\n\t\tconst pattern: string = customPattern ?? defaultPattern;\n\n\t\t// Create regex object from pattern.\n\t\tconst zipCodeRegex: RegExp = new RegExp( pattern );\n\n\t\t// Test the trimmed value against the regex pattern.\n\t\treturn zipCodeRegex.test( value.trim() );\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n\tgetSummaryMessage: ( field: TPFormFieldElement ): string => getSummaryErrorMessage( name, field ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormSubmitElement } from './tp-form-submit';\nimport { TPFormErrorsElement } from './tp-form-errors';\n\n/**\n * TP Form.\n */\nexport class TPFormElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected readonly form: HTMLFormElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get form.\n\t\tthis.form = this.querySelector( 'form' );\n\n\t\t// Add event listeners.\n\t\tthis.form?.addEventListener( 'submit', this.handleFormSubmit.bind( this ) );\n\t}\n\n\t/**\n\t * Handle form submission.\n\t *\n\t * @param {Event} e Submit event.\n\t */\n\tprotected async handleFormSubmit( e: SubmitEvent ): Promise<void> {\n\t\t// Stop normal form submission.\n\t\te.preventDefault();\n\t\te.stopImmediatePropagation();\n\n\t\t// Get submit button.\n\t\tconst submit: TPFormSubmitElement | null = this.querySelector( 'tp-form-submit' );\n\t\tsubmit?.setAttribute( 'submitting', 'yes' );\n\n\t\t// Ignore a form that currently has suspense.\n\t\tif ( 'yes' === this.getAttribute( 'suspense' ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Validate the form.\n\t\tconst formValid: boolean = await this.validate();\n\n\t\t// If form is valid then dispatch a custom 'submit-validation-success' event.\n\t\tif ( formValid ) {\n\t\t\t// Trigger event.\n\t\t\tthis.dispatchEvent( new CustomEvent( 'submit-validation-success', { bubbles: true } ) );\n\n\t\t\t// Submit form.\n\t\t\tif ( 'yes' !== this.getAttribute( 'prevent-submit' ) ) {\n\t\t\t\tthis.form?.submit();\n\t\t\t}\n\t\t} else {\n\t\t\t// Form is not valid, remove submitting attribute.\n\t\t\tsubmit?.removeAttribute( 'submitting' );\n\t\t}\n\t}\n\n\t/**\n\t * Validate the form.\n\t *\n\t * @return {boolean} Whether the form is valid or not.\n\t */\n\tasync validate(): Promise<boolean> {\n\t\t// Dispatch a custom 'validate' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );\n\n\t\t// Get the form fields.\n\t\tconst fields: NodeListOf<TPFormFieldElement> | null = this.querySelectorAll( 'tp-form-field' );\n\n\t\t// If no fields are found, return true indicating validation passed.\n\t\tif ( ! fields ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-success', { bubbles: true } ) );\n\n\t\t\t// Return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Start by setting the form as suspense.\n\t\tthis.setAttribute( 'suspense', 'yes' );\n\n\t\t// Check if all fields are valid.\n\t\tlet formValid: boolean = true;\n\t\tconst validationPromises: Promise<boolean>[] = Array\n\t\t\t.from( fields )\n\t\t\t.map( async ( field: TPFormFieldElement ): Promise<boolean> => await field.validate() );\n\n\t\t// Wait for promises to resolve.\n\t\tawait Promise.all( validationPromises )\n\t\t\t.then( ( results: boolean[] ): void => {\n\t\t\t\t// Check if all fields are valid.\n\t\t\t\tformValid = results.every( ( isValid: boolean ) => isValid );\n\t\t\t} )\n\t\t\t.catch( () => {\n\t\t\t\t// There was an error with one or more fields.\n\t\t\t\tformValid = false;\n\t\t\t} )\n\t\t\t.finally( () => this.removeAttribute( 'suspense' ) );\n\n\t\t// If form is valid then dispatch a custom 'validation-success' event else send a custom 'validation-error' event.\n\t\tif ( formValid ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-success', { bubbles: true } ) );\n\n\t\t\t// Clear error summary if it exists.\n\t\t\tthis.clearErrorSummary();\n\t\t} else {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-error', { bubbles: true } ) );\n\n\t\t\t// Update error summary and manage focus.\n\t\t\tthis.handleValidationError( fields );\n\t\t}\n\n\t\t// Return whether the form is valid or not.\n\t\treturn formValid;\n\t}\n\n\t/**\n\t * Handle validation error - update error summary and manage focus.\n\t *\n\t * @param {NodeList} fields All form fields.\n\t */\n\tprotected handleValidationError( fields: NodeListOf<TPFormFieldElement> ): void {\n\t\t// Get invalid fields that are visible.\n\t\tconst invalidFields: TPFormFieldElement[] = Array.from( fields ).filter(\n\t\t\t( field: TPFormFieldElement ): boolean =>\n\t\t\t\tfield.hasAttribute( 'error' ) && field.offsetWidth > 0 && field.offsetHeight > 0\n\t\t);\n\n\t\t// Get error summary element.\n\t\tconst errorSummary: TPFormErrorsElement | null = this.querySelector( 'tp-form-errors' );\n\n\t\t// If error summary exists, populate it and move focus to it.\n\t\tif ( errorSummary ) {\n\t\t\terrorSummary.update( invalidFields );\n\n\t\t\t// Timeout needed for Safari to focus after DOM update.\n\t\t\tsetTimeout( () => errorSummary.focus(), 0 );\n\t\t} else if ( invalidFields.length > 0 ) {\n\t\t\t// No error summary, move focus to first visible invalid field.\n\t\t\tconst firstInvalidField = invalidFields[ 0 ].getField();\n\t\t\tfirstInvalidField?.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Clear the error summary.\n\t */\n\tprotected clearErrorSummary(): void {\n\t\t// Clear summary.\n\t\tconst errorSummary: TPFormErrorsElement | null = this.querySelector( 'tp-form-errors' );\n\t\terrorSummary?.clear();\n\t}\n\n\t/**\n\t * Validate one field.\n\t *\n\t * @param {HTMLElement} field Field node.\n\t */\n\tasync validateField( field: TPFormFieldElement ): Promise<boolean> {\n\t\t// Set form as suspense, validate and undo suspense.\n\t\tthis.setAttribute( 'suspense', 'yes' );\n\t\tconst fieldValid: boolean = await field.validate();\n\t\tthis.removeAttribute( 'suspense' );\n\n\t\t// Return result.\n\t\treturn fieldValid;\n\t}\n\n\t/**\n\t * Reset form validation.\n\t */\n\tresetValidation(): void {\n\t\t// Get the form fields.\n\t\tconst fields: NodeListOf<TPFormFieldElement> | null = this.querySelectorAll( 'tp-form-field' );\n\n\t\t// If no fields are found.\n\t\tif ( ! fields ) {\n\t\t\t// Exit the function.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove 'valid' and 'error' attributes from all fields.\n\t\tfields.forEach( ( field: TPFormFieldElement ): void => {\n\t\t\t// Remove 'valid' and 'error' and 'suspense' attributes.\n\t\t\tfield.removeAttribute( 'valid' );\n\t\t\tfield.removeAttribute( 'error' );\n\t\t\tfield.removeAttribute( 'suspense' );\n\t\t} );\n\n\t\t// Remove 'suspense' attribute from form.\n\t\tthis.removeAttribute( 'suspense' );\n\n\t\t// Remove 'submitting' attribute from submit button.\n\t\tconst submit: TPFormSubmitElement | null = this.querySelector( 'tp-form-submit' );\n\t\tsubmit?.removeAttribute( 'submitting' );\n\n\t\t// Clear error summary.\n\t\tthis.clearErrorSummary();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPFormElement } from './tp-form';\nimport { TPFormErrorElement } from './tp-form-error';\nimport { TPFormSuspenseElement } from './tp-form-suspense';\n\n/**\n * TP Form Field.\n */\nexport class TPFormFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get field.\n\t\tconst field = this.getField();\n\n\t\t// Add event listeners.\n\t\tfield?.addEventListener( 'keyup', this.handleFieldChanged.bind( this ) );\n\t\tfield?.addEventListener( 'change', this.handleFieldChanged.bind( this ) );\n\n\t\t// Set up accessibility attributes.\n\t\tthis.setupAccessibility();\n\t}\n\n\t/**\n\t * Set up accessibility attributes (label linking, IDs).\n\t */\n\tprivate setupAccessibility(): void {\n\t\t// Get the field.\n\t\tconst field = this.getField();\n\n\t\t// Bail if no field.\n\t\tif ( ! field ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Generate ID for the field if not present.\n\t\tif ( ! field.id ) {\n\t\t\tfield.id = `tp-field-${ Math.random().toString( 36 ).substring( 2, 9 ) }`;\n\t\t}\n\n\t\t// Get label.\n\t\tconst label = this.querySelector( 'label' );\n\n\t\t// Set for attribute on label if not present.\n\t\tif ( label && ! label.hasAttribute( 'for' ) ) {\n\t\t\tlabel.setAttribute( 'for', field.id );\n\t\t}\n\t}\n\n\t/**\n\t * Update validation when the field has changed.\n\t */\n\thandleFieldChanged(): void {\n\t\t// Check if we want to ignore field revalidations.\n\t\tif ( 'no' === this.getAttribute( 'revalidate-on-change' ) ) {\n\t\t\t// Yes we do, bail!\n\t\t\treturn;\n\t\t}\n\n\t\t// Validate the field again if 'valid' or 'error' attribute is present.\n\t\tif ( this.getAttribute( 'valid' ) || this.getAttribute( 'error' ) ) {\n\t\t\tconst form: TPFormElement | null = this.closest( 'tp-form' );\n\t\t\tform?.validateField( this );\n\t\t}\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 observed in the TPFormFieldElement web-component.\n\t\treturn [ 'valid', 'error', 'suspense' ];\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// Check if the observed attributes 'valid' or 'error' have changed.\n\n\t\t// Dispatch a custom 'validate' event.\n\t\tif ( ( 'valid' === name || 'error' === name || 'suspense' === name ) && oldValue !== newValue ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );\n\t\t}\n\n\t\t// Update the component after the attribute change.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update component.\n\t */\n\tupdate(): void {\n\t\t// Check if tpFormValidators exist in the window object.\n\t\tconst { tpFormValidators } = window;\n\n\t\t// Exit the function if validators are not available.\n\t\tif ( ! tpFormValidators ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the 'error' attribute value.\n\t\tconst error: string = this.getAttribute( 'error' ) ?? '';\n\n\t\t// Check if the error exists and has a corresponding error message function.\n\t\tif ( '' !== error && error in tpFormValidators && 'function' === typeof tpFormValidators[ error ].getErrorMessage ) {\n\t\t\tthis.setErrorMessage( tpFormValidators[ error ].getErrorMessage( this ) );\n\t\t} else {\n\t\t\tthis.removeErrorMessage();\n\t\t}\n\n\t\t// Get the 'suspense' attribute value.\n\t\tconst suspense: string = this.getAttribute( 'suspense' ) ?? '';\n\n\t\t// Check if the suspense exists and has a corresponding suspense message function.\n\t\tif ( '' !== suspense && suspense in tpFormValidators && 'function' === typeof tpFormValidators[ suspense ].getSuspenseMessage ) {\n\t\t\t// @ts-ignore\n\t\t\tthis.setSuspenseMessage( tpFormValidators[ suspense ]?.getSuspenseMessage( this ) );\n\t\t} else {\n\t\t\tthis.removeSuspenseMessage();\n\t\t}\n\t}\n\n\t/**\n\t * Get the associated field.\n\t *\n\t * @return {HTMLElement} The associated field for this component.\n\t */\n\tgetField(): HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null {\n\t\t// Return the associated field by querying input, select, or textarea elements.\n\t\treturn this.querySelector( 'input,select,textarea' );\n\t}\n\n\t/**\n\t * Validate this field.\n\t *\n\t * @return {boolean} Whether this field passed validation.\n\t */\n\tasync validate(): Promise<boolean> {\n\t\t// Retrieve tpFormValidators from the window object.\n\t\tconst { tpFormValidators } = window;\n\n\t\t// Exit the function if validators are not available.\n\t\tif ( ! tpFormValidators ) {\n\t\t\t// If no validators are found, return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if the field is visible.\n\t\tif ( this.offsetWidth <= 0 || this.offsetHeight <= 0 ) {\n\t\t\t// If the field is not visible, return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Prepare error and valid status.\n\t\tlet valid: boolean = true;\n\t\tlet suspense: Promise<boolean> | null = null;\n\t\tlet error: string = '';\n\t\tconst allAttributes: string[] = this.getAttributeNames();\n\n\t\t// Traverse all attributes to see if we find a matching validator.\n\t\tallAttributes.every( ( attributeName: string ): boolean => {\n\t\t\t// Check if the attribute is a validator.\n\t\t\tif ( attributeName in tpFormValidators && 'function' === typeof tpFormValidators[ attributeName ].validate ) {\n\t\t\t\t// We found one, lets validate the field.\n\t\t\t\tconst isValid: boolean | Promise<boolean> = tpFormValidators[ attributeName ].validate( this );\n\t\t\t\terror = attributeName;\n\n\t\t\t\t// First check for a Promise.\n\t\t\t\tif ( isValid instanceof Promise ) {\n\t\t\t\t\t// Yes it is an async validation.\n\t\t\t\t\tvalid = false;\n\n\t\t\t\t\t// Dispatch a custom 'validation-suspense-start' event.\n\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-start' ) );\n\n\t\t\t\t\t// Create the promise.\n\t\t\t\t\tsuspense = new Promise( ( resolve, reject ): void => {\n\t\t\t\t\t\t// Validate it.\n\t\t\t\t\t\tisValid\n\t\t\t\t\t\t\t.then( ( suspenseIsValid: boolean ) => {\n\t\t\t\t\t\t\t\t// Validation is complete.\n\t\t\t\t\t\t\t\tif ( true === suspenseIsValid ) {\n\t\t\t\t\t\t\t\t\tthis.setAttribute( 'valid', 'yes' );\n\t\t\t\t\t\t\t\t\tthis.removeAttribute( 'error' );\n\n\t\t\t\t\t\t\t\t\t// Resolve the promise.\n\t\t\t\t\t\t\t\t\tresolve( true );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tthis.removeAttribute( 'valid' );\n\t\t\t\t\t\t\t\t\tthis.setAttribute( 'error', error );\n\n\t\t\t\t\t\t\t\t\t// Resolve the promise.\n\t\t\t\t\t\t\t\t\tresolve( false );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Dispatch a custom 'validation-suspense-success' event.\n\t\t\t\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-success' ) );\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.catch( (): void => {\n\t\t\t\t\t\t\t\t// There was an error.\n\t\t\t\t\t\t\t\tthis.removeAttribute( 'valid' );\n\t\t\t\t\t\t\t\tthis.setAttribute( 'error', error );\n\n\t\t\t\t\t\t\t\t// Dispatch a custom 'validation-suspense-error' event.\n\t\t\t\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-error' ) );\n\n\t\t\t\t\t\t\t\t// Reject the promise.\n\t\t\t\t\t\t\t\treject( false );\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.finally( (): void => {\n\t\t\t\t\t\t\t\t// Clean up.\n\t\t\t\t\t\t\t\tthis.removeAttribute( 'suspense' );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Return.\n\t\t\t\t\treturn false;\n\t\t\t\t} else if ( false === isValid ) {\n\t\t\t\t\t// Not a Promise, but looks like we found an error!\n\t\t\t\t\tvalid = false;\n\n\t\t\t\t\t// Return.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// No error found, all good.\n\t\t\treturn true;\n\t\t} );\n\n\t\t// Check if the field is valid or not.\n\t\tif ( valid ) {\n\t\t\tthis.setAttribute( 'valid', 'yes' );\n\t\t\tthis.removeAttribute( 'error' );\n\t\t\tthis.removeAttribute( 'suspense' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'valid' );\n\n\t\t\t// Check for suspense.\n\t\t\tif ( suspense ) {\n\t\t\t\tthis.setAttribute( 'suspense', error );\n\t\t\t\tthis.removeAttribute( 'error' );\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute( 'suspense' );\n\t\t\t\tthis.setAttribute( 'error', error );\n\t\t\t}\n\t\t}\n\n\t\t// Do we have a suspense?\n\t\tif ( suspense ) {\n\t\t\t// Yes we do, return the promise.\n\t\t\treturn suspense;\n\t\t}\n\n\t\t// No we don't, return a resolved promise.\n\t\treturn valid;\n\t}\n\n\t/**\n\t * Set the error message.\n\t *\n\t * @param {string} message Error message.\n\t */\n\tsetErrorMessage( message: string = '' ): void {\n\t\t// Look for an existing tp-form-error element.\n\t\tlet error: TPFormErrorElement | null = this.querySelector( 'tp-form-error' );\n\n\t\t// If found, update its textContent with the error message. Otherwise, create a new tp-form-error element and append it to the component.\n\t\tif ( error ) {\n\t\t\terror.textContent = message;\n\t\t} else {\n\t\t\terror = document.createElement( 'tp-form-error' );\n\t\t\terror.textContent = message;\n\t\t\terror.setAttribute( 'role', 'alert' );\n\t\t\tthis.appendChild( error );\n\t\t}\n\n\t\t// Set up accessibility for the error message.\n\t\tconst field = this.getField();\n\n\t\t// Set aria-invalid on the field.\n\t\tif ( field ) {\n\t\t\tfield.setAttribute( 'aria-invalid', 'true' );\n\n\t\t\t// Generate ID for error element if not present.\n\t\t\tif ( ! error.id ) {\n\t\t\t\terror.id = `tp-error-${ Math.random().toString( 36 ).substring( 2, 9 ) }`;\n\t\t\t}\n\n\t\t\t// Link field to error via aria-describedby.\n\t\t\tfield.setAttribute( 'aria-describedby', error.id );\n\t\t}\n\n\t\t// Dispatch a custom 'validation-error' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validation-error' ) );\n\t}\n\n\t/**\n\t * Remove the error message.\n\t */\n\tremoveErrorMessage(): void {\n\t\t// Find and remove the tp-form-error element.\n\t\tthis.querySelector( 'tp-form-error' )?.remove();\n\n\t\t// Remove accessibility attributes from the field.\n\t\tconst field = this.getField();\n\n\t\t// Remove aria-invalid and aria-describedby.\n\t\tif ( field ) {\n\t\t\tfield.removeAttribute( 'aria-invalid' );\n\t\t\tfield.removeAttribute( 'aria-describedby' );\n\t\t}\n\n\t\t// Dispatch a custom 'validation-success' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validation-success' ) );\n\t}\n\n\t/**\n\t * Set the suspense message.\n\t *\n\t * @param {string} message Suspense message.\n\t */\n\tsetSuspenseMessage( message: string = '' ): void {\n\t\t// Look for an existing tp-form-error element.\n\t\tconst suspense: TPFormSuspenseElement | null = this.querySelector( 'tp-form-suspense' );\n\n\t\t// If found, update its textContent with the suspense message. Otherwise, create a new tp-form-suspense element and append it to the component.\n\t\tif ( suspense ) {\n\t\t\tsuspense.textContent = message;\n\t\t} else {\n\t\t\tconst suspenseElement: TPFormSuspenseElement = document.createElement( 'tp-form-suspense' );\n\t\t\tsuspenseElement.textContent = message;\n\t\t\tsuspenseElement.setAttribute( 'aria-live', 'polite' );\n\t\t\tthis.appendChild( suspenseElement );\n\t\t}\n\t}\n\n\t/**\n\t * Remove the suspense message.\n\t */\n\tremoveSuspenseMessage(): void {\n\t\t// Find and remove the tp-form-suspense element.\n\t\tthis.querySelector( 'tp-form-suspense' )?.remove();\n\t}\n}\n","/**\n * TP Form Error.\n */\nexport class TPFormErrorElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormErrorsHeadingElement } from './tp-form-errors-heading';\nimport { TPFormErrorsListElement } from './tp-form-errors-list';\n\n/**\n * TP Form Errors.\n */\nexport class TPFormErrorsElement extends HTMLElement {\n\t/**\n\t * Update the error summary with the given invalid fields.\n\t *\n\t * @param {TPFormFieldElement[]} invalidFields Array of invalid form fields.\n\t */\n\tupdate( invalidFields: TPFormFieldElement[] ): void {\n\t\t// Get child components.\n\t\tconst heading = this.querySelector( 'tp-form-errors-heading' ) as TPFormErrorsHeadingElement | null;\n\t\tconst list = this.querySelector( 'tp-form-errors-list' ) as TPFormErrorsListElement | null;\n\n\t\t// If no errors, remove active state.\n\t\tif ( 0 === invalidFields.length ) {\n\t\t\tthis.removeAttribute( 'active' );\n\t\t\tthis.removeAttribute( 'tabindex' );\n\t\t\theading?.update( 0 );\n\t\t\tlist?.clear();\n\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set active state and make focusable.\n\t\tthis.setAttribute( 'active', 'yes' );\n\t\tthis.setAttribute( 'tabindex', '-1' );\n\n\t\t// Update child components.\n\t\theading?.update( invalidFields.length );\n\t\tlist?.update( invalidFields );\n\t}\n\n\t/**\n\t * Clear the error summary.\n\t */\n\tclear(): void {\n\t\t// Clear attributes.\n\t\tthis.removeAttribute( 'active' );\n\t\tthis.removeAttribute( 'tabindex' );\n\n\t\t// Get heading and list.\n\t\tconst heading = this.querySelector( 'tp-form-errors-heading' ) as TPFormErrorsHeadingElement | null;\n\t\tconst list = this.querySelector( 'tp-form-errors-list' ) as TPFormErrorsListElement | null;\n\n\t\t// Update them.\n\t\theading?.update( 0 );\n\t\tlist?.clear();\n\t}\n}\n","/**\n * TP Form Errors Heading.\n *\n * Displays the error count. User controls the heading element wrapper.\n */\nexport class TPFormErrorsHeadingElement extends HTMLElement {\n\t/**\n\t * Get format.\n\t *\n\t * @return {string} Format with $count placeholder.\n\t */\n\tget format(): string {\n\t\t// Get format.\n\t\treturn this.getAttribute( 'format' ) ?? '';\n\t}\n\n\t/**\n\t * Set format.\n\t *\n\t * @param {string} format Format string.\n\t */\n\tset format( format: string ) {\n\t\t// Set format.\n\t\tthis.setAttribute( 'format', format );\n\t}\n\n\t/**\n\t * Update the heading with the error count.\n\t *\n\t * @param {number} count Number of errors.\n\t */\n\tupdate( count: number ): void {\n\t\t// Update count.\n\t\tthis.textContent = this.format.replace( '$count', count.toString() );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\n\n/**\n * TP Form Errors List.\n *\n * Displays the list of error links using tp-form-errors-error elements.\n */\nexport class TPFormErrorsListElement extends HTMLElement {\n\t/**\n\t * Update the list with error links.\n\t *\n\t * @param {TPFormFieldElement[]} invalidFields Array of invalid form fields.\n\t */\n\tupdate( invalidFields: TPFormFieldElement[] ): void {\n\t\t// Clear existing content.\n\t\tthis.textContent = '';\n\n\t\t// Get validators for summary messages.\n\t\tconst { tpFormValidators } = window;\n\t\tinvalidFields.forEach( ( field: TPFormFieldElement ): void => {\n\t\t\t// Get field ID for the link.\n\t\t\tconst inputField = field.getField();\n\t\t\tconst fieldId = inputField?.id ?? '';\n\n\t\t\t// Skip if no field ID.\n\t\t\tif ( ! fieldId ) {\n\t\t\t\t// Bail.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get the error type from the field's error attribute.\n\t\t\tconst errorType = field.getAttribute( 'error' ) ?? '';\n\n\t\t\t// Get the summary message.\n\t\t\tlet message = '';\n\n\t\t\t// Check if we have everything.\n\t\t\tif ( errorType && tpFormValidators && errorType in tpFormValidators ) {\n\t\t\t\tconst validator = tpFormValidators[ errorType ];\n\n\t\t\t\t// Try getSummaryMessage first, fall back to getErrorMessage.\n\t\t\t\tif ( 'function' === typeof validator.getSummaryMessage ) {\n\t\t\t\t\tmessage = validator.getSummaryMessage( field );\n\t\t\t\t} else if ( 'function' === typeof validator.getErrorMessage ) {\n\t\t\t\t\tmessage = validator.getErrorMessage( field );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Skip if no message.\n\t\t\tif ( ! message ) {\n\t\t\t\t// Bail.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Create error element with link.\n\t\t\tconst errorElement = document.createElement( 'tp-form-errors-error' );\n\t\t\terrorElement.setAttribute( 'role', 'listitem' );\n\t\t\tconst link = document.createElement( 'a' );\n\t\t\tlink.href = `#${ fieldId }`;\n\t\t\tlink.textContent = message;\n\t\t\terrorElement.appendChild( link );\n\t\t\tthis.appendChild( errorElement );\n\t\t} );\n\t}\n\n\t/**\n\t * Clear the list.\n\t */\n\tclear(): void {\n\t\t// Clear.\n\t\tthis.textContent = '';\n\t}\n}\n","/**\n * TP Form Errors Error.\n */\nexport class TPFormErrorsErrorElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Use event delegation to handle clicks on dynamically added anchors.\n\t\tthis.addEventListener( 'click', this.handleClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle click on error link.\n\t *\n\t * @param {Event} event Click event.\n\t */\n\tprotected handleClick( event: Event ): void {\n\t\t// Find the anchor element.\n\t\tconst target = event.target as HTMLElement;\n\t\tconst anchor = target.closest( 'a' );\n\n\t\t// Only handle clicks on anchors.\n\t\tif ( ! anchor ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prevent default to avoid hash in URL.\n\t\tevent.preventDefault();\n\n\t\t// Get the field ID from href.\n\t\tconst href = anchor.getAttribute( 'href' ) ?? '';\n\t\tconst fieldId = href.replace( '#', '' );\n\n\t\t// Focus the target field.\n\t\tif ( fieldId ) {\n\t\t\tconst targetField = document.getElementById( fieldId );\n\t\t\ttargetField?.focus();\n\t\t}\n\t}\n}\n","/**\n * TP Form Suspense.\n */\nexport class TPFormSuspenseElement extends HTMLElement {\n}\n","/**\n * TP Form Submit.\n */\nexport class TPFormSubmitElement 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 observed in the TPFormSubmitElement web-component.\n\t\treturn [ 'submitting-text', 'original-text', 'submitting' ];\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 if attribute has changed.\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 submit button.\n\t\tconst submitButton: HTMLButtonElement | null = this.querySelector( 'button[type=\"submit\"]' );\n\n\t\t// Check if we have a submit button.\n\t\tif ( ! submitButton ) {\n\t\t\t// No, we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prepare submit button text.\n\t\tconst submittingText: string = this.getAttribute( 'submitting-text' ) ?? '';\n\t\tconst originalText: string = this.getAttribute( 'original-text' ) ?? submitButton.innerHTML;\n\n\t\t// Check if we are submitting.\n\t\tif ( 'yes' === this.getAttribute( 'submitting' ) ) {\n\t\t\tsubmitButton.setAttribute( 'disabled', 'disabled' );\n\t\t\tthis.setAttribute( 'original-text', originalText );\n\t\t\tsubmitButton.textContent = submittingText;\n\t\t} else {\n\t\t\tsubmitButton.removeAttribute( 'disabled' );\n\t\t\tthis.removeAttribute( 'submitting' );\n\t\t\tthis.removeAttribute( 'original-text' );\n\t\t\tsubmitButton.innerHTML = originalText;\n\t\t}\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Validators.\n */\n\n// Import validators.\nimport { TPFormValidator } from './definitions';\nimport * as required from './validators/required';\nimport * as email from './validators/email';\nimport * as minLength from './validators/min-length';\nimport * as maxLength from './validators/max-length';\nimport * as noEmptySpaces from './validators/no-empty-spaces';\nimport * as zip from './validators/zip';\n\n// Prepare validators.\nconst validators = [\n\trequired,\n\temail,\n\tminLength,\n\tmaxLength,\n\tnoEmptySpaces,\n\tzip,\n];\n\n/**\n * Register Validators and Errors.\n */\nwindow.tpFormValidators = {};\nwindow.tpFormErrors = {};\nwindow.tpFormSummaryErrors = {};\nwindow.tpFormSuspenseMessages = {};\n\n// Register validators.\nvalidators.forEach( (\n\t{ name, validator, errorMessage, summaryErrorMessage }: { name: string, validator: TPFormValidator, errorMessage: string, summaryErrorMessage?: string }\n): void => {\n\t// Assigning validators and error messages to various fields.\n\twindow.tpFormValidators[ name ] = validator;\n\twindow.tpFormErrors[ name ] = errorMessage;\n\n\t// Register summary error message if provided.\n\tif ( summaryErrorMessage ) {\n\t\twindow.tpFormSummaryErrors[ name ] = summaryErrorMessage;\n\t}\n} );\n\n/**\n * Components.\n */\nimport { TPFormElement } from './tp-form';\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormErrorElement } from './tp-form-error';\nimport { TPFormErrorsElement } from './tp-form-errors';\nimport { TPFormErrorsHeadingElement } from './tp-form-errors-heading';\nimport { TPFormErrorsListElement } from './tp-form-errors-list';\nimport { TPFormErrorsErrorElement } from './tp-form-errors-error';\nimport { TPFormSuspenseElement } from './tp-form-suspense';\nimport { TPFormSubmitElement } from './tp-form-submit';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-form', TPFormElement );\ncustomElements.define( 'tp-form-field', TPFormFieldElement );\ncustomElements.define( 'tp-form-error', TPFormErrorElement );\ncustomElements.define( 'tp-form-errors', TPFormErrorsElement );\ncustomElements.define( 'tp-form-errors-heading', TPFormErrorsHeadingElement );\ncustomElements.define( 'tp-form-errors-list', TPFormErrorsListElement );\ncustomElements.define( 'tp-form-errors-error', TPFormErrorsErrorElement );\ncustomElements.define( 'tp-form-suspense', TPFormSuspenseElement );\ncustomElements.define( 'tp-form-submit', TPFormSubmitElement );\n"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","getErrorMessage","error","tpFormErrors","window","getSummaryErrorMessage","field","tpFormSummaryErrors","template","label","querySelector","textContent","trim","getFieldLabel","replace","errorMessage","summaryErrorMessage","validator","validate","getField","getSummaryMessage","test","minLength","parseInt","getAttribute","length","message","maxLength","inputField","customPattern","RegExp","TPFormElement","HTMLElement","constructor","super","this","form","addEventListener","handleFormSubmit","bind","e","preventDefault","stopImmediatePropagation","submit","setAttribute","dispatchEvent","CustomEvent","bubbles","removeAttribute","fields","querySelectorAll","formValid","validationPromises","Array","from","map","Promise","all","then","results","every","isValid","catch","finally","clearErrorSummary","handleValidationError","invalidFields","filter","hasAttribute","offsetWidth","offsetHeight","errorSummary","update","setTimeout","focus","firstInvalidField","clear","validateField","fieldValid","resetValidation","forEach","TPFormFieldElement","handleFieldChanged","setupAccessibility","id","Math","random","toString","substring","closest","observedAttributes","attributeChangedCallback","name","oldValue","newValue","tpFormValidators","setErrorMessage","removeErrorMessage","suspense","getSuspenseMessage","setSuspenseMessage","removeSuspenseMessage","valid","getAttributeNames","attributeName","resolve","reject","suspenseIsValid","document","createElement","appendChild","remove","suspenseElement","TPFormErrorElement","TPFormErrorsElement","heading","list","TPFormErrorsHeadingElement","format","count","TPFormErrorsListElement","fieldId","errorType","errorElement","link","href","TPFormErrorsErrorElement","handleClick","event","anchor","target","targetField","getElementById","TPFormSuspenseElement","TPFormSubmitElement","_name","submitButton","submittingText","originalText","innerHTML","validators","tpFormSuspenseMessages","customElements","define"],"ignoreList":[],"sourceRoot":""}
@@ -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.previouslyFocusedElement=null,this.boundHandleKeyDown=this.handleKeyDown.bind(this),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())}isAriaEnabled(){return"no"!==this.getAttribute("aria")}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&&("no"!==this.getAttribute("manage-focus")&&(this.previouslyFocusedElement=this.ownerDocument.activeElement),""===this.group||this.allGroups||this.updateAllGroups(),t.showModal(),this.setAttribute("open","yes"),document.addEventListener("keydown",this.boundHandleKeyDown),"no"!==this.getAttribute("manage-focus")&&this.setInitialFocus())}close(){document.removeEventListener("keydown",this.boundHandleKeyDown);const t=this.querySelector("dialog");null==t||t.close(),this.removeAttribute("open"),"no"!==this.getAttribute("manage-focus")&&this.previouslyFocusedElement&&(this.previouslyFocusedElement.focus(),this.previouslyFocusedElement=null),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(){var t,e;const i=this.querySelector("tp-lightbox-count");null==i||i.update();const s=this.querySelector("tp-lightbox-previous"),r=this.querySelector("tp-lightbox-next");if(!s&&!r)return;const n=null!==(t=null==s?void 0:s.querySelector("button"))&&void 0!==t?t:null,l=null!==(e=null==r?void 0:r.querySelector("button"))&&void 0!==e?e:null,o=this.isAriaEnabled();if(""===this.group)return null==s||s.setAttribute("disabled","yes"),null==r||r.setAttribute("disabled","yes"),void(o&&(null==n||n.setAttribute("aria-disabled","true"),null==l||l.setAttribute("aria-disabled","true")));const u=this.getAllGroups();if(!u)return null==s||s.setAttribute("disabled","yes"),null==r||r.setAttribute("disabled","yes"),void(o&&(null==n||n.setAttribute("aria-disabled","true"),null==l||l.setAttribute("aria-disabled","true")));this.currentIndex<=1?(null==s||s.setAttribute("disabled","yes"),o&&(null==n||n.setAttribute("aria-disabled","true"))):(null==s||s.removeAttribute("disabled"),o&&(null==n||n.removeAttribute("aria-disabled"))),this.currentIndex<u.length?(null==r||r.removeAttribute("disabled"),o&&(null==l||l.removeAttribute("aria-disabled"))):(null==r||r.setAttribute("disabled","yes"),o&&(null==l||l.setAttribute("aria-disabled","true")))}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(){if(!this.lightboxNavItems)return;const t=this.isAriaEnabled();this.lightboxNavItems.forEach(((e,i)=>{const s=e.querySelector("button");this.currentIndex-1===i?(e.setAttribute("current","yes"),t&&s&&s.setAttribute("aria-current","true")):(e.removeAttribute("current"),t&&s&&s.removeAttribute("aria-current"))}))}setInitialFocus(){var t;const e=this.querySelector("[autofocus]");e?e.focus():null===(t=this.dialogElement)||void 0===t||t.focus()}handleKeyDown(t){"yes"===this.getAttribute("arrow-navigation")&&("ArrowLeft"===t.key?(t.preventDefault(),this.previous()):"ArrowRight"===t.key&&(t.preventDefault(),this.next()))}}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.textContent=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{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",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,s;super(),this.currentTemplate=null,this.currentGroup="",this.allGroups=null,this.touchStartX=0,this.touchStartY=0,this.swipeThreshold=200,this.previouslyFocusedElement=null,this.boundHandleKeyDown=this.handleKeyDown.bind(this),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)),null===(s=this.dialogElement)||void 0===s||s.addEventListener("close",this.handleDialogClose.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())}isAriaEnabled(){return"no"!==this.getAttribute("aria")}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&&("no"!==this.getAttribute("manage-focus")&&(this.previouslyFocusedElement=this.ownerDocument.activeElement),""===this.group||this.allGroups||this.updateAllGroups(),t.showModal(),this.setAttribute("open","yes"),document.addEventListener("keydown",this.boundHandleKeyDown),"no"!==this.getAttribute("manage-focus")&&this.setInitialFocus())}close(){document.removeEventListener("keydown",this.boundHandleKeyDown);const t=this.querySelector("dialog");null==t||t.close(),this.removeAttribute("open"),"no"!==this.getAttribute("manage-focus")&&this.previouslyFocusedElement&&(this.previouslyFocusedElement.focus(),this.previouslyFocusedElement=null),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(){var t,e;this.querySelectorAll("tp-lightbox-count").forEach(t=>t.update());const i=this.querySelector("tp-lightbox-previous"),s=this.querySelector("tp-lightbox-next");if(!i&&!s)return;const r=null!==(t=null==i?void 0:i.querySelector("button"))&&void 0!==t?t:null,l=null!==(e=null==s?void 0:s.querySelector("button"))&&void 0!==e?e:null,n=this.isAriaEnabled();if(""===this.group)return null==i||i.setAttribute("disabled","yes"),null==s||s.setAttribute("disabled","yes"),void(n&&(null==r||r.setAttribute("aria-disabled","true"),null==l||l.setAttribute("aria-disabled","true")));const o=this.getAllGroups();if(!o)return null==i||i.setAttribute("disabled","yes"),null==s||s.setAttribute("disabled","yes"),void(n&&(null==r||r.setAttribute("aria-disabled","true"),null==l||l.setAttribute("aria-disabled","true")));this.currentIndex<=1?(null==i||i.setAttribute("disabled","yes"),n&&(null==r||r.setAttribute("aria-disabled","true"))):(null==i||i.removeAttribute("disabled"),n&&(null==r||r.removeAttribute("aria-disabled"))),this.currentIndex<o.length?(null==s||s.removeAttribute("disabled"),n&&(null==l||l.removeAttribute("aria-disabled"))):(null==s||s.setAttribute("disabled","yes"),n&&(null==l||l.setAttribute("aria-disabled","true")))}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()}handleDialogClose(){this.hasAttribute("open")&&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(){if(!this.lightboxNavItems)return;const t=this.isAriaEnabled();this.lightboxNavItems.forEach((e,i)=>{const s=e.querySelector("button");this.currentIndex-1===i?(e.setAttribute("current","yes"),t&&s&&s.setAttribute("aria-current","true")):(e.removeAttribute("current"),t&&s&&s.removeAttribute("aria-current"))})}setInitialFocus(){var t;const e=this.querySelector("[autofocus]");e?e.focus():null===(t=this.dialogElement)||void 0===t||t.focus()}handleKeyDown(t){"yes"===this.getAttribute("arrow-navigation")&&("ArrowLeft"===t.key?(t.preventDefault(),this.previous()):"ArrowRight"===t.key&&(t.preventDefault(),this.next()))}}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.textContent=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