@travelopia/web-components 0.9.7 → 0.9.8

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 +1 @@
1
- {"version":3,"file":"dist/multi-select/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/multi-select/tp-multi-select.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-field.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-placeholder.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-status.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-options.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-option.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-search.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pill.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pills.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-select-all.ts","webpack://@travelopia/web-components/./src/multi-select/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\n\n/**\n * TP Multi Select.\n */\nexport class TPMultiSelectElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tcurrentlyHighlightedOption: number = -1;\n\tprotected keyboardEventListener: EventListener;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.keyboardEventListener = this.handleKeyboardInputs.bind( this ) as EventListener;\n\t\tdocument.addEventListener( 'click', this.handleDocumentClick.bind( this ) );\n\t\tthis.addEventListener( 'change', this.update.bind( this ) );\n\n\t\t// Get options.\n\t\tconst options: TPMultiSelectOptionsElement | null = this.querySelector( 'tp-multi-select-options' );\n\n\t\t// Listen for dynamic changes to the option values.\n\t\tif ( options ) {\n\t\t\tconst mutationObserver: MutationObserver = new MutationObserver( this.initialize.bind( this ) );\n\t\t\tmutationObserver.observe( options, { childList: true, subtree: true } );\n\t\t}\n\n\t\t// Initialize component.\n\t\tthis.initialize();\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'open' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// If no changes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Changed attribute name is 'open'.\n\t\tif ( 'open' === name ) {\n\t\t\t// If new value is 'yes' then open the dropdown.\n\t\t\tif ( 'yes' === newValue ) {\n\t\t\t\tdocument.addEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'open', { bubbles: true } ) );\n\t\t\t} else {\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tdocument.removeEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'close', { bubbles: true } ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set the value of this component.\n\t *\n\t * @param {Array} value Value.\n\t */\n\tset value( value: string[] ) {\n\t\t// Bail if value is not an array.\n\t\tif ( ! value || ! Array.isArray( value ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value of the select field.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Check if the value is in the array.\n\t\t\tif ( value.includes( option.getAttribute( 'value' ) ?? '' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t} else {\n\t\t\t\toption.removeAttribute( 'selected' );\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch change event.\n\t\tthis.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n\n\t/**\n\t * Get the value of this component.\n\t *\n\t * @return {Array} Value of this component.\n\t */\n\tget value(): string[] {\n\t\t// Get the value of the select field.\n\t\tconst value: string[] = [];\n\n\t\t// Get selected options.\n\t\tconst selectedOptions: NodeListOf<HTMLOptionElement> | null = this.querySelectorAll( 'select option[selected]' );\n\t\tselectedOptions?.forEach( ( option: HTMLOptionElement ) => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' );\n\n\t\t\t// Add value to array.\n\t\t\tif ( optionValue ) {\n\t\t\t\tvalue.push( optionValue );\n\t\t\t}\n\t\t} );\n\n\t\t// Return value.\n\t\treturn value;\n\t}\n\n\t/**\n\t * Update the value of the select field.\n\t */\n\tprotected updateFormFieldValue(): void {\n\t\t// Get options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option` );\n\t\tconst selectField: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Bail if there's no styled selected options or select field.\n\t\tif ( ! styledSelectedOptions || ! selectField ) {\n\t\t\t// Bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get selected options.\n\t\tconst selectOptions: HTMLOptionElement[] = Array.from( selectField.options );\n\n\t\t// Traverse options.\n\t\tstyledSelectedOptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' ) ?? '';\n\n\t\t\t// If option value is present.\n\t\t\tif ( optionValue ) {\n\t\t\t\tconst matchingSelectOption: HTMLOptionElement | undefined = selectOptions.find( ( selectOption ) => selectOption.value === optionValue );\n\n\t\t\t\t// Update select field.\n\t\t\t\tif ( 'yes' === option.getAttribute( 'selected' ) ) {\n\t\t\t\t\t// Update select field.\n\t\t\t\t\tif ( matchingSelectOption ) {\n\t\t\t\t\t\tmatchingSelectOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst newOption: HTMLOptionElement = document.createElement( 'option' );\n\t\t\t\t\t\tnewOption.setAttribute( 'value', option.getAttribute( 'value' ) ?? '' );\n\t\t\t\t\t\tnewOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t\tselectField?.append( newOption );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmatchingSelectOption?.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch events.\n\t\tselectField.dispatchEvent( new Event( 'change' ) );\n\t}\n\n\t/**\n\t * Update component and sub-components.\n\t */\n\tupdate(): void {\n\t\t// First, update field value.\n\t\tthis.updateFormFieldValue();\n\n\t\t// Get value.\n\t\tconst value: string[] = this.value;\n\n\t\t// Toggle selected attribute.\n\t\tif ( 0 !== value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t}\n\n\t\t// Get status.\n\t\tconst status: TPMultiSelectStatusElement | null = this.querySelector( 'tp-multi-select-status' );\n\n\t\t// Update status.\n\t\tif ( status ) {\n\t\t\t// Update status.\n\t\t\tif ( value.length > 0 ) {\n\t\t\t\tstatus.setAttribute( 'total', value.length.toString() );\n\t\t\t} else {\n\t\t\t\tstatus.removeAttribute( 'total' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle clicking the document.\n\t *\n\t * @param {Event} e Event.\n\t */\n\tprotected handleDocumentClick( e: Event ): void {\n\t\t// Close on click outside.\n\t\tif ( this !== e.target && ! this.contains( e.target as Node ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\t}\n\n\t/**\n\t * Initialize component.\n\t */\n\tinitialize(): void {\n\t\t// Get select element.\n\t\tlet selectElement: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Create select element (if it doesn't already exist).\n\t\tif ( ! selectElement ) {\n\t\t\tselectElement = document.createElement( 'select' );\n\t\t\tselectElement.setAttribute( 'name', this.getAttribute( 'name' ) ?? '' );\n\n\t\t\t// Get form reference.\n\t\t\tconst formReference = this.getAttribute( 'form' );\n\n\t\t\t// Add form reference.\n\t\t\tif ( formReference ) {\n\t\t\t\tselectElement.setAttribute( 'form', formReference );\n\t\t\t}\n\n\t\t\t// Set multiple.\n\t\t\tif ( 'no' !== this.getAttribute( 'multiple' ) ) {\n\t\t\t\tselectElement.setAttribute( 'multiple', 'multiple' );\n\t\t\t}\n\n\t\t\t// Append.\n\t\t\tthis.append( selectElement );\n\t\t} else {\n\t\t\tselectElement.innerHTML = '';\n\t\t}\n\n\t\t// Update components for selected options.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select a value.\n\t *\n\t * @param {string} value Value to select.\n\t */\n\tselect( value: string = '' ): void {\n\t\t// Stuff for single-select.\n\t\tif ( 'no' === this.getAttribute( 'multiple' ) ) {\n\t\t\t// First, unselect everything.\n\t\t\tthis.unSelectAll();\n\n\t\t\t// If the value is blank, don't do anything else.\n\t\t\tif ( '' === value ) {\n\t\t\t\t// Close the field, if applicable.\n\t\t\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\t}\n\n\t\t\t\t// Exit.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Select all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Search stuff.\n\t\tconst search: TPMultiSelectSearchElement | null = this.querySelector( 'tp-multi-select-search' );\n\t\tsearch?.clear();\n\t\tsearch?.focus();\n\n\t\t// Close the field, if applicable.\n\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select all values.\n\t */\n\tselectAll(): void {\n\t\t// Get all options.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select a value.\n\t *\n\t * @param {string} value Value to unselect.\n\t */\n\tunSelect( value: string = '' ): void {\n\t\t// Get all options with the specified value.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select all values.\n\t */\n\tunSelectAll(): void {\n\t\t// Get all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Keyboard events.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightNextOption();\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightPreviousOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Enter':\n\t\t\t\tthis.toggleHighlightedOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Escape':\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Highlight the next option.\n\t */\n\thighlightNextOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the next option to be highlighted. Assume next option is the favorable option.\n\t\tlet nextToBeHighlighted = this.currentlyHighlightedOption + 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( nextToBeHighlighted < options.length && options[ nextToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tnextToBeHighlighted++;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit. Here, the last highlighted option keeps highlighted.\n\t\tif ( nextToBeHighlighted === options.length ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== -1 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ nextToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ nextToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = nextToBeHighlighted;\n\t}\n\n\t/**\n\t * Highlight previous option.\n\t */\n\thighlightPreviousOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the previous option to be highlighted. Assume previous option is the favorable option.\n\t\tlet previousToBeHighlighted = this.currentlyHighlightedOption - 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( previousToBeHighlighted >= 0 && options[ previousToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tpreviousToBeHighlighted--;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit.\n\t\tif ( previousToBeHighlighted < 0 ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== 0 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ previousToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ previousToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = previousToBeHighlighted;\n\t}\n\n\t/**\n\t * Toggle highlighted option.\n\t */\n\ttoggleHighlightedOption(): void {\n\t\t// Get option and if it exists set it to null.\n\t\tconst option: TPMultiSelectOptionElement | null = this.querySelector( `tp-multi-select-option[highlighted=\"yes\"]` );\n\t\toption?.toggle( null );\n\t}\n\n\t/**\n\t * Un-highlight all options.\n\t */\n\tunHighlightAllOptions(): void {\n\t\t// Reset the currentlyHighlightedOption.\n\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// If there are options, un-highlight them.\n\t\tif ( options ) {\n\t\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t\t// Remove highlighted attribute.\n\t\t\t\toption.removeAttribute( 'highlighted' );\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Field.\n */\nexport class TPMultiSelectFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.addEventListener( 'click', this.toggleOpen.bind( this ) );\n\t}\n\n\t/**\n\t * Toggle opening this component.\n\t */\n\ttoggleOpen(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail early if we don't have a multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle open.\n\t\tif ( 'yes' === multiSelect.getAttribute( 'open' ) ) {\n\t\t\tmultiSelect.removeAttribute( 'open' );\n\t\t} else {\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\t}\n}\n","/**\n * TP Multi Select Placeholder.\n */\nexport class TPMultiSelectPlaceholderElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Status.\n */\nexport class TPMultiSelectStatusElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'total', 'format' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} _name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( _name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Update component.\n\t\tif ( oldValue !== newValue ) {\n\t\t\tthis.update();\n\t\t}\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get format attribute.\n\t\tconst format: string = this.getAttribute( 'format' ) ?? '$total Selected';\n\t\tlet html: string = format.replace( '$total', this.getAttribute( 'total' ) ?? '' );\n\n\t\t// Format string includes $value.\n\t\tif ( format.includes( '$value' ) ) {\n\t\t\t// Get multi-select.\n\t\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t\t// Check if multi-select exists.\n\t\t\tif ( multiSelect ) {\n\t\t\t\t// Get value if present or create an empty array.\n\t\t\t\tconst value: string[] = multiSelect.value ?? [];\n\t\t\t\tlet replace: string = '';\n\n\t\t\t\t// Check if value array is not empty.\n\t\t\t\tif ( value.length > 0 ) {\n\t\t\t\t\t// Get first value.\n\t\t\t\t\tconst option: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ value[ 0 ] }\"]` );\n\n\t\t\t\t\t// Check if option exists.\n\t\t\t\t\tif ( option ) {\n\t\t\t\t\t\treplace = option.getAttribute( 'label' ) ?? '';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Replace $value.\n\t\t\t\thtml = html.replace( '$value', replace );\n\t\t\t}\n\t\t}\n\n\t\t// Set inner HTML.\n\t\tthis.innerHTML = html;\n\t}\n}\n","/**\n * TP Multi Select Options.\n */\nexport class TPMultiSelectOptionsElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Option.\n */\nexport class TPMultiSelectOptionElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener to toggle the selected state.\n\t\tthis.addEventListener( 'click', this.toggle.bind( this ) );\n\t}\n\n\t/**\n\t * Select / un-select this option.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\ttoggle( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Get multi-select element and value of option.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst value: string = this.getAttribute( 'value' ) ?? '';\n\n\t\t// Toggle selected state. Dispatch custom events accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect?.select( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'select', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t} else {\n\t\t\tmultiSelect?.unSelect( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'unselect', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\n\n/**\n * TP Multi Select Search.\n */\nexport class TPMultiSelectSearchElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// get input.\n\t\tconst input: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if input exists.\n\t\tif ( ! input ) {\n\t\t\t// No, its not. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Add event listeners.\n\t\tinput.addEventListener( 'keydown', this.handleKeyboardInputs.bind( this ) );\n\t\tinput.addEventListener( 'keyup', this.handleSearchChange.bind( this ) );\n\t\tinput.addEventListener( 'input', this.handleSearchChange.bind( this ) );\n\t\tthis.addEventListener( 'click', this.handleClick.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'open', this.focus.bind( this ) );\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Get multi select and search field.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if multi select and search field exists.\n\t\tif ( ! multiSelect || ! search ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle keyboard inputs.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'Enter':\n\t\t\t\te.preventDefault(); // Prevent inadvertent form submits.\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowDown':\n\t\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t\t\tbreak;\n\t\t\tcase 'Backspace': // Remove last pill if search is empty.\n\t\t\t\tif ( 0 === search.value.length ) {\n\t\t\t\t\tconst pill: TPMultiSelectPillElement | null = multiSelect.querySelector( 'tp-multi-select-pill:last-of-type' );\n\n\t\t\t\t\t// Check if pill exists, remove it.\n\t\t\t\t\tif ( pill ) {\n\t\t\t\t\t\tpill.removePill();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Handle search field value changed.\n\t */\n\tprotected handleSearchChange(): void {\n\t\t// Get search field and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | undefined = this.closest( 'tp-multi-select' )?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select, search, and options field exists.\n\t\tif ( ! multiSelect || ! search || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize matched option count.\n\t\tlet matchedOptionCount = 0;\n\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Hide and show options based on search.\n\t\t\tif ( option.getAttribute( 'label' )?.toLowerCase().match( new RegExp( `.*${ search.value.toLowerCase().replace( /\\s/g, '.*' ) }.*` ) ) ) {\n\t\t\t\toption.removeAttribute( 'hidden' );\n\t\t\t\tmatchedOptionCount++;\n\t\t\t} else {\n\t\t\t\toption.setAttribute( 'hidden', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Resize input width.\n\t\tif ( '' === search.value ) {\n\t\t\tsearch.removeAttribute( 'style' );\n\t\t} else {\n\t\t\tsearch.style.width = `${ search.value.length + 2 }ch`;\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\n\t\t// Show matched option count.\n\t\tmultiSelect.setAttribute( 'visible-options', matchedOptionCount.toString() );\n\t}\n\n\t/**\n\t * Handle click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\tprotected handleClick( e: Event ): void {\n\t\t// First, prevent propagation to avoid document.click set on `tp-multi-select`.\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\t// Now send the event so other stuff can work as per normal, and another event for good measure.\n\t\tthis.dispatchEvent( new CustomEvent( 'multi-select-opened' ) );\n\t\tdocument.dispatchEvent( new Event( 'click' ) );\n\n\t\t// Open multi select.\n\t\tthis.closest( 'tp-multi-select' )?.setAttribute( 'open', 'yes' );\n\t}\n\n\t/**\n\t * Clear the search field.\n\t */\n\tclear(): void {\n\t\t// Clear search field.\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if search field exists.\n\t\tif ( search ) {\n\t\t\t// Set value to empty string and dispatch change event.\n\t\t\tsearch.value = '';\n\t\t\tsearch.dispatchEvent( new Event( 'change' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Set focus on the search field.\n\t */\n\tfocus(): void {\n\t\t// When it's focused, use search change to ensure the results are refreshed.\n\t\tthis.handleSearchChange();\n\n\t\t// Focus on input.\n\t\tthis.querySelector( 'input' )?.focus();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Pill.\n */\nexport class TPMultiSelectPillElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleButtonClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle button click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\thandleButtonClick( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Remove pill.\n\t\tthis.removePill();\n\t}\n\n\t/**\n\t * Remove this pill.\n\t */\n\tremovePill(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Unselect value.\n\t\tif ( multiSelect && this.getAttribute( 'value' ) ) {\n\t\t\tmultiSelect.unSelect( this.getAttribute( 'value' ) ?? '' );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect', { bubbles: true } ) );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Pills.\n */\nexport class TPMultiSelectPillsElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.update.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.querySelector( 'select' )?.addEventListener( 'change', ( () => this.update() ) as EventListener );\n\n\t\t// Update.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail if there's no multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine pills.\n\t\tconst pills: NodeListOf<TPMultiSelectPillElement> | null = this.querySelectorAll( 'tp-multi-select-pill' );\n\t\tconst values: string[] = [ ...new Set( multiSelect.value ) ] ?? [];\n\t\tconst pillValues: string[] = [];\n\n\t\t// Remove pills that shouldn't exist.\n\t\tpills.forEach( ( pill: TPMultiSelectPillElement ): void => {\n\t\t\t// Get pill value.\n\t\t\tconst pillValue: string = pill.getAttribute( 'value' ) ?? '';\n\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill value to the array.\n\t\t\tpillValues.push( pillValue );\n\n\t\t\t// Remove pill if it doesn't exist in the values.\n\t\t\tif ( ! values.includes( pillValue ) ) {\n\t\t\t\tpill.remove();\n\t\t\t}\n\t\t} );\n\n\t\t// Create new pills.\n\t\tconst pillsToCreate: string[] = values.filter( ( value: string ) => ! pillValues.includes( value ) );\n\n\t\t// Create pills.\n\t\tpillsToCreate.forEach( ( pillValue: string ): void => {\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get multi-select option.\n\t\t\tconst multiSelectOption: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ pillValue }\"]` );\n\n\t\t\t// Bail early if there's no multi-select option.\n\t\t\tif ( ! multiSelectOption ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill.\n\t\t\tthis.appendChild( this.createPill( pillValue, multiSelectOption.getAttribute( 'label' ) ?? '' ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Create a new pill.\n\t *\n\t * @param {string} value Pill value.\n\t * @param {string} label Pill label.\n\t *\n\t * @return {TPMultiSelectPillElement} New pill.\n\t */\n\tcreatePill( value: string, label: string ): TPMultiSelectPillElement {\n\t\t// Create pill and set value attribute.\n\t\tconst newPill = document.createElement( 'tp-multi-select-pill' ) as TPMultiSelectPillElement;\n\t\tnewPill.setAttribute( 'value', value );\n\n\t\t// Create pill label.\n\t\tconst pillLabel: HTMLElement = document.createElement( 'span' );\n\t\tpillLabel.textContent = label;\n\n\t\t// Create pill close button.\n\t\tconst pillCloseButton: HTMLElement = document.createElement( 'button' );\n\t\tpillCloseButton.setAttribute( 'type', 'button' );\n\t\tpillCloseButton.textContent = 'x';\n\n\t\t// Add event listener.\n\t\tpillCloseButton.addEventListener( 'click', () => {\n\t\t\t// On click, run removePill method.\n\t\t\tnewPill.removePill();\n\t\t} );\n\n\t\t// Append label and close button to pill.\n\t\tnewPill.appendChild( pillLabel );\n\t\tnewPill.appendChild( pillCloseButton );\n\n\t\t// Return newPill element.\n\t\treturn newPill;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Select All.\n */\nexport class TPMultiSelectSelectAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listeners.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.handleValueChanged.bind( this ) );\n\t\tthis.addEventListener( 'click', this.toggleSelectAll.bind( this ) );\n\t}\n\n\t/**\n\t * Handle value changed.\n\t */\n\thandleValueChanged(): void {\n\t\t// Get multi select and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null | undefined = multiSelect?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select and options exists.\n\t\tif ( ! multiSelect || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if all options are selected.\n\t\tif ( Array.from( options ).filter( ( optionNode ) => optionNode.getAttribute( 'disabled' ) !== 'yes' ).length === multiSelect.value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t\tthis.innerHTML = this.getAttribute( 'unselect-text' ) ?? '';\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t\tthis.innerHTML = this.getAttribute( 'select-text' ) ?? '';\n\t\t}\n\t}\n\n\t/**\n\t * Toggle select all.\n\t */\n\ttoggleSelectAll(): void {\n\t\t// Get multi select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if multi select exists.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if select all is yes. Apply selectAll and unselectAll methods accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect.selectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'select-all', { bubbles: true } ) );\n\t\t} else {\n\t\t\tmultiSelect.unSelectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect-all', { bubbles: true } ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectFieldElement } from './tp-multi-select-field';\nimport { TPMultiSelectPlaceholderElement } from './tp-multi-select-placeholder';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectPillsElement } from './tp-multi-select-pills';\nimport { TPMultiSelectSelectAllElement } from './tp-multi-select-select-all';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-multi-select', TPMultiSelectElement );\ncustomElements.define( 'tp-multi-select-field', TPMultiSelectFieldElement );\ncustomElements.define( 'tp-multi-select-placeholder', TPMultiSelectPlaceholderElement );\ncustomElements.define( 'tp-multi-select-status', TPMultiSelectStatusElement );\ncustomElements.define( 'tp-multi-select-options', TPMultiSelectOptionsElement );\ncustomElements.define( 'tp-multi-select-option', TPMultiSelectOptionElement );\ncustomElements.define( 'tp-multi-select-search', TPMultiSelectSearchElement );\ncustomElements.define( 'tp-multi-select-pill', TPMultiSelectPillElement );\ncustomElements.define( 'tp-multi-select-pills', TPMultiSelectPillsElement );\ncustomElements.define( 'tp-multi-select-select-all', TPMultiSelectSelectAllElement );\n"],"names":["TPMultiSelectElement","HTMLElement","constructor","super","currentlyHighlightedOption","this","keyboardEventListener","handleKeyboardInputs","bind","document","addEventListener","handleDocumentClick","update","options","querySelector","MutationObserver","initialize","observe","childList","subtree","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","bubbles","unHighlightAllOptions","removeEventListener","value","Array","isArray","styledOptions","querySelectorAll","forEach","option","includes","getAttribute","setAttribute","removeAttribute","selectedOptions","optionValue","push","updateFormFieldValue","styledSelectedOptions","selectField","selectOptions","from","matchingSelectOption","find","selectOption","newOption","createElement","append","remove","Event","length","status","toString","e","target","contains","selectElement","innerHTML","formReference","select","unSelectAll","search","clear","focus","selectAll","unSelect","key","preventDefault","highlightNextOption","highlightPreviousOption","toggleHighlightedOption","nextToBeHighlighted","scrollIntoView","behavior","block","previousToBeHighlighted","toggle","TPMultiSelectFieldElement","toggleOpen","multiSelect","closest","TPMultiSelectPlaceholderElement","TPMultiSelectStatusElement","_name","format","html","replace","TPMultiSelectOptionsElement","TPMultiSelectOptionElement","stopPropagation","detail","TPMultiSelectSearchElement","input","handleSearchChange","handleClick","pill","removePill","matchedOptionCount","toLowerCase","match","RegExp","style","width","TPMultiSelectPillElement","handleButtonClick","TPMultiSelectPillsElement","pills","values","Set","pillValues","pillValue","filter","multiSelectOption","appendChild","createPill","label","newPill","pillLabel","textContent","pillCloseButton","TPMultiSelectSelectAllElement","handleValueChanged","toggleSelectAll","optionNode","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/multi-select/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/multi-select/tp-multi-select.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-field.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-placeholder.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-status.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-options.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-option.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-search.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-search-status.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pill.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pills.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-select-all.ts","webpack://@travelopia/web-components/./src/multi-select/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\n\n/**\n * TP Multi Select.\n */\nexport class TPMultiSelectElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tcurrentlyHighlightedOption: number = -1;\n\tprotected keyboardEventListener: EventListener;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.keyboardEventListener = this.handleKeyboardInputs.bind( this ) as EventListener;\n\t\tdocument.addEventListener( 'click', this.handleDocumentClick.bind( this ) );\n\t\tthis.addEventListener( 'change', this.update.bind( this ) );\n\t\tthis.addEventListener( 'focusout', this.handleFocusOut.bind( this ) );\n\n\t\t// Get options.\n\t\tconst options: TPMultiSelectOptionsElement | null = this.querySelector( 'tp-multi-select-options' );\n\n\t\t// Listen for dynamic changes to the option values.\n\t\tif ( options ) {\n\t\t\tconst mutationObserver: MutationObserver = new MutationObserver( this.initialize.bind( this ) );\n\t\t\tmutationObserver.observe( options, { childList: true, subtree: true } );\n\t\t}\n\n\t\t// Initialize component.\n\t\tthis.initialize();\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'open', 'aria' ];\n\t}\n\n\t/**\n\t * Check if ARIA management is enabled.\n\t *\n\t * @return {boolean} Whether ARIA is enabled.\n\t */\n\tisAriaEnabled(): boolean {\n\t\t// Return whether ARIA management is enabled (default: yes).\n\t\treturn 'no' !== this.getAttribute( 'aria' );\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// If no changes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Changed attribute name is 'open'.\n\t\tif ( 'open' === name ) {\n\t\t\t// If new value is 'yes' then open the dropdown.\n\t\t\tif ( 'yes' === newValue ) {\n\t\t\t\tdocument.addEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.updateAriaExpanded( true );\n\t\t\t\tthis.highlightNextOption();\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'open', { bubbles: true } ) );\n\t\t\t} else {\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tdocument.removeEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.updateAriaExpanded( false );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'close', { bubbles: true } ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set the value of this component.\n\t *\n\t * @param {Array} value Value.\n\t */\n\tset value( value: string[] ) {\n\t\t// Bail if value is not an array.\n\t\tif ( ! value || ! Array.isArray( value ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value of the select field.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Check if the value is in the array.\n\t\t\tif ( value.includes( option.getAttribute( 'value' ) ?? '' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t} else {\n\t\t\t\toption.removeAttribute( 'selected' );\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch change event.\n\t\tthis.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n\n\t/**\n\t * Get the value of this component.\n\t *\n\t * @return {Array} Value of this component.\n\t */\n\tget value(): string[] {\n\t\t// Get the value of the select field.\n\t\tconst value: string[] = [];\n\n\t\t// Get selected options.\n\t\tconst selectedOptions: NodeListOf<HTMLOptionElement> | null = this.querySelectorAll( 'select option[selected]' );\n\t\tselectedOptions?.forEach( ( option: HTMLOptionElement ) => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' );\n\n\t\t\t// Add value to array.\n\t\t\tif ( optionValue ) {\n\t\t\t\tvalue.push( optionValue );\n\t\t\t}\n\t\t} );\n\n\t\t// Return value.\n\t\treturn value;\n\t}\n\n\t/**\n\t * Update the value of the select field.\n\t */\n\tprotected updateFormFieldValue(): void {\n\t\t// Get options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option` );\n\t\tconst selectField: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Bail if there's no styled selected options or select field.\n\t\tif ( ! styledSelectedOptions || ! selectField ) {\n\t\t\t// Bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get selected options.\n\t\tconst selectOptions: HTMLOptionElement[] = Array.from( selectField.options );\n\n\t\t// Traverse options.\n\t\tstyledSelectedOptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' ) ?? '';\n\n\t\t\t// If option value is present.\n\t\t\tif ( optionValue ) {\n\t\t\t\tconst matchingSelectOption: HTMLOptionElement | undefined = selectOptions.find( ( selectOption ) => selectOption.value === optionValue );\n\n\t\t\t\t// Update select field.\n\t\t\t\tif ( 'yes' === option.getAttribute( 'selected' ) ) {\n\t\t\t\t\t// Update select field.\n\t\t\t\t\tif ( matchingSelectOption ) {\n\t\t\t\t\t\tmatchingSelectOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst newOption: HTMLOptionElement = document.createElement( 'option' );\n\t\t\t\t\t\tnewOption.setAttribute( 'value', option.getAttribute( 'value' ) ?? '' );\n\t\t\t\t\t\tnewOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t\tselectField?.append( newOption );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmatchingSelectOption?.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch events.\n\t\tselectField.dispatchEvent( new Event( 'change' ) );\n\t}\n\n\t/**\n\t * Update component and sub-components.\n\t */\n\tupdate(): void {\n\t\t// First, update field value.\n\t\tthis.updateFormFieldValue();\n\n\t\t// Get value.\n\t\tconst value: string[] = this.value;\n\n\t\t// Toggle selected attribute.\n\t\tif ( 0 !== value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t}\n\n\t\t// Get status.\n\t\tconst status: TPMultiSelectStatusElement | null = this.querySelector( 'tp-multi-select-status' );\n\n\t\t// Update status.\n\t\tif ( status ) {\n\t\t\t// Update status.\n\t\t\tif ( value.length > 0 ) {\n\t\t\t\tstatus.setAttribute( 'total', value.length.toString() );\n\t\t\t} else {\n\t\t\t\tstatus.removeAttribute( 'total' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle clicking the document.\n\t *\n\t * @param {Event} e Event.\n\t */\n\tprotected handleDocumentClick( e: Event ): void {\n\t\t// Close on click outside.\n\t\tif ( this !== e.target && ! this.contains( e.target as Node ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\t}\n\n\t/**\n\t * Initialize component.\n\t */\n\tinitialize(): void {\n\t\t// Get select element.\n\t\tlet selectElement: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Create select element (if it doesn't already exist).\n\t\tif ( ! selectElement ) {\n\t\t\tselectElement = document.createElement( 'select' );\n\t\t\tselectElement.setAttribute( 'name', this.getAttribute( 'name' ) ?? '' );\n\n\t\t\t// Get form reference.\n\t\t\tconst formReference = this.getAttribute( 'form' );\n\n\t\t\t// Add form reference.\n\t\t\tif ( formReference ) {\n\t\t\t\tselectElement.setAttribute( 'form', formReference );\n\t\t\t}\n\n\t\t\t// Set multiple.\n\t\t\tif ( 'no' !== this.getAttribute( 'multiple' ) ) {\n\t\t\t\tselectElement.setAttribute( 'multiple', 'multiple' );\n\t\t\t}\n\n\t\t\t// Append.\n\t\t\tthis.append( selectElement );\n\t\t} else {\n\t\t\tselectElement.innerHTML = '';\n\t\t}\n\n\t\t// Update components for selected options.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select a value.\n\t *\n\t * @param {string} value Value to select.\n\t */\n\tselect( value: string = '' ): void {\n\t\t// Stuff for single-select.\n\t\tif ( 'no' === this.getAttribute( 'multiple' ) ) {\n\t\t\t// First, unselect everything.\n\t\t\tthis.unSelectAll();\n\n\t\t\t// If the value is blank, don't do anything else.\n\t\t\tif ( '' === value ) {\n\t\t\t\t// Close the field, if applicable.\n\t\t\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\t}\n\n\t\t\t\t// Exit.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Select all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Search stuff.\n\t\tconst search: TPMultiSelectSearchElement | null = this.querySelector( 'tp-multi-select-search' );\n\t\tsearch?.clear();\n\t\tsearch?.focus();\n\n\t\t// Close the field, if applicable.\n\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select all values.\n\t */\n\tselectAll(): void {\n\t\t// Get all options.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select a value.\n\t *\n\t * @param {string} value Value to unselect.\n\t */\n\tunSelect( value: string = '' ): void {\n\t\t// Get all options with the specified value.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select all values.\n\t */\n\tunSelectAll(): void {\n\t\t// Get all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Keyboard events.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightNextOption();\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightPreviousOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Enter':\n\t\t\t\tthis.toggleHighlightedOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Escape':\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Highlight the next option.\n\t */\n\thighlightNextOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the next option to be highlighted. Assume next option is the favorable option.\n\t\tlet nextToBeHighlighted = this.currentlyHighlightedOption + 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( nextToBeHighlighted < options.length && options[ nextToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tnextToBeHighlighted++;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit. Here, the last highlighted option keeps highlighted.\n\t\tif ( nextToBeHighlighted === options.length ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== -1 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ nextToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ nextToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update aria-activedescendant.\n\t\tthis.updateAriaActiveDescendant( options[ nextToBeHighlighted ].id || null );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = nextToBeHighlighted;\n\t}\n\n\t/**\n\t * Highlight previous option.\n\t */\n\thighlightPreviousOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the previous option to be highlighted. Assume previous option is the favorable option.\n\t\tlet previousToBeHighlighted = this.currentlyHighlightedOption - 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( previousToBeHighlighted >= 0 && options[ previousToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tpreviousToBeHighlighted--;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit.\n\t\tif ( previousToBeHighlighted < 0 ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== 0 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ previousToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ previousToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update aria-activedescendant.\n\t\tthis.updateAriaActiveDescendant( options[ previousToBeHighlighted ].id || null );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = previousToBeHighlighted;\n\t}\n\n\t/**\n\t * Toggle highlighted option.\n\t */\n\ttoggleHighlightedOption(): void {\n\t\t// Get option and if it exists set it to null.\n\t\tconst option: TPMultiSelectOptionElement | null = this.querySelector( `tp-multi-select-option[highlighted=\"yes\"]` );\n\t\toption?.toggle( null );\n\t}\n\n\t/**\n\t * Un-highlight all options.\n\t */\n\tunHighlightAllOptions(): void {\n\t\t// Reset the currentlyHighlightedOption.\n\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// If there are options, un-highlight them.\n\t\tif ( options ) {\n\t\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t\t// Remove highlighted attribute.\n\t\t\t\toption.removeAttribute( 'highlighted' );\n\t\t\t} );\n\t\t}\n\n\t\t// Clear aria-activedescendant.\n\t\tthis.updateAriaActiveDescendant( null );\n\t}\n\n\t/**\n\t * Get the combobox element (search input or field).\n\t *\n\t * @return {HTMLElement | null} The combobox element.\n\t */\n\tgetComboboxElement(): HTMLElement | null {\n\t\t// If search input exists, it's the combobox.\n\t\tconst searchInput: HTMLInputElement | null = this.querySelector( 'tp-multi-select-search input' );\n\n\t\t// Return search input if it exists.\n\t\tif ( searchInput ) {\n\t\t\t// Return search input.\n\t\t\treturn searchInput;\n\t\t}\n\n\t\t// Otherwise, the field is the combobox.\n\t\treturn this.querySelector( 'tp-multi-select-field' );\n\t}\n\n\t/**\n\t * Update aria-expanded on the combobox element.\n\t *\n\t * @param {boolean} isOpen Whether the dropdown is open.\n\t */\n\tupdateAriaExpanded( isOpen: boolean ): void {\n\t\t// Check if ARIA 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 combobox element.\n\t\tconst combobox = this.getComboboxElement();\n\n\t\t// Update aria-expanded if combobox exists.\n\t\tif ( combobox ) {\n\t\t\tcombobox.setAttribute( 'aria-expanded', isOpen ? 'true' : 'false' );\n\t\t}\n\t}\n\n\t/**\n\t * Update aria-activedescendant on the combobox element.\n\t *\n\t * @param {string | null} optionId The ID of the highlighted option, or null to clear.\n\t */\n\tupdateAriaActiveDescendant( optionId: string | null ): void {\n\t\t// Check if ARIA 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 combobox element.\n\t\tconst combobox = this.getComboboxElement();\n\n\t\t// Update aria-activedescendant if combobox exists.\n\t\tif ( combobox ) {\n\t\t\t// Set or remove aria-activedescendant based on optionId.\n\t\t\tif ( optionId ) {\n\t\t\t\tcombobox.setAttribute( 'aria-activedescendant', optionId );\n\t\t\t} else {\n\t\t\t\tcombobox.removeAttribute( 'aria-activedescendant' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle focus out events to close the dropdown.\n\t *\n\t * @param {FocusEvent} e Focus event.\n\t */\n\thandleFocusOut( e: FocusEvent ): void {\n\t\t// Don't close if focus is moving within the multi-select.\n\t\tif ( e.relatedTarget && this.contains( e.relatedTarget as Node ) ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Close the dropdown.\n\t\tthis.removeAttribute( 'open' );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\n\n/**\n * TP Multi Select Field.\n */\nexport class TPMultiSelectFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listeners.\n\t\tthis.addEventListener( 'click', this.toggleOpen.bind( this ) );\n\t\tthis.addEventListener( 'keydown', this.handleKeydown.bind( this ) );\n\t}\n\n\t/**\n\t * Handle keydown events to open the dropdown.\n\t *\n\t * @param {KeyboardEvent} e Keyboard event.\n\t */\n\thandleKeydown( e: KeyboardEvent ): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail if no multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Open on Enter, Space, or ArrowDown (only if dropdown is closed).\n\t\tif ( 'Enter' === e.key || ' ' === e.key || 'ArrowDown' === e.key ) {\n\t\t\t// Check if dropdown is currently closed.\n\t\t\tif ( 'yes' !== multiSelect.getAttribute( 'open' ) ) {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback(): void {\n\t\t// Setup ARIA attributes.\n\t\tthis.setupAriaAttributes();\n\n\t\t// Wire up label click.\n\t\tthis.setupLabelClick();\n\t}\n\n\t/**\n\t * Setup label click to focus this field.\n\t * Enables clicking the label to focus the field when aria-labelledby is present.\n\t */\n\tsetupLabelClick(): void {\n\t\t// Get aria-labelledby attribute.\n\t\tconst labelledBy: string | null = this.getAttribute( 'aria-labelledby' );\n\n\t\t// Bail if no labelledby attribute.\n\t\tif ( ! labelledBy ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the label element.\n\t\tconst label: HTMLElement | null = document.getElementById( labelledBy );\n\n\t\t// Bail if no label found.\n\t\tif ( ! label ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Add click listener to focus this field.\n\t\tlabel.addEventListener( 'click', () => {\n\t\t\t// Focus this field.\n\t\t\tthis.focus();\n\t\t} );\n\t}\n\n\t/**\n\t * Setup ARIA attributes for the field element.\n\t * Only applies when there is no search input (field acts as combobox).\n\t */\n\tsetupAriaAttributes(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if ARIA is enabled.\n\t\tif ( ! multiSelect?.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// If search input exists, it will be the combobox - don't set attributes on field.\n\t\tconst searchInput: HTMLInputElement | null = multiSelect.querySelector( 'tp-multi-select-search input' );\n\n\t\t// Bail if search input exists.\n\t\tif ( searchInput ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get options container.\n\t\tconst options: TPMultiSelectOptionsElement | null = multiSelect.querySelector( 'tp-multi-select-options' );\n\n\t\t// Set combobox role and attributes.\n\t\tthis.setAttribute( 'role', 'combobox' );\n\t\tthis.setAttribute( 'aria-haspopup', 'listbox' );\n\t\tthis.setAttribute( 'aria-expanded', 'false' );\n\n\t\t// Set tabindex only if not already present.\n\t\tif ( ! this.hasAttribute( 'tabindex' ) ) {\n\t\t\tthis.setAttribute( 'tabindex', '0' );\n\t\t}\n\n\t\t// Set aria-controls pointing to options ID.\n\t\tif ( options ) {\n\t\t\tthis.setAttribute( 'aria-controls', options.id );\n\t\t}\n\t}\n\n\t/**\n\t * Toggle opening this component.\n\t */\n\ttoggleOpen(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail early if we don't have a multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle open.\n\t\tif ( 'yes' === multiSelect.getAttribute( 'open' ) ) {\n\t\t\tmultiSelect.removeAttribute( 'open' );\n\t\t} else {\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\t}\n}\n","/**\n * TP Multi Select Placeholder.\n */\nexport class TPMultiSelectPlaceholderElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Status.\n */\nexport class TPMultiSelectStatusElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'total', 'format' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} _name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( _name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Update component.\n\t\tif ( oldValue !== newValue ) {\n\t\t\tthis.update();\n\t\t}\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get format attribute.\n\t\tconst format: string = this.getAttribute( 'format' ) ?? '$total Selected';\n\t\tlet html: string = format.replace( '$total', this.getAttribute( 'total' ) ?? '' );\n\n\t\t// Format string includes $value.\n\t\tif ( format.includes( '$value' ) ) {\n\t\t\t// Get multi-select.\n\t\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t\t// Check if multi-select exists.\n\t\t\tif ( multiSelect ) {\n\t\t\t\t// Get value if present or create an empty array.\n\t\t\t\tconst value: string[] = multiSelect.value ?? [];\n\t\t\t\tlet replace: string = '';\n\n\t\t\t\t// Check if value array is not empty.\n\t\t\t\tif ( value.length > 0 ) {\n\t\t\t\t\t// Get first value.\n\t\t\t\t\tconst option: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ value[ 0 ] }\"]` );\n\n\t\t\t\t\t// Check if option exists.\n\t\t\t\t\tif ( option ) {\n\t\t\t\t\t\treplace = option.getAttribute( 'label' ) ?? '';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Replace $value.\n\t\t\t\thtml = html.replace( '$value', replace );\n\t\t\t}\n\t\t}\n\n\t\t// Set inner HTML.\n\t\tthis.innerHTML = html;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * Counter for generating unique IDs.\n */\nlet optionsIdCounter = 0;\n\n/**\n * TP Multi Select Options.\n */\nexport class TPMultiSelectOptionsElement extends HTMLElement {\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback(): void {\n\t\t// Setup ARIA attributes.\n\t\tthis.setupAriaAttributes();\n\t}\n\n\t/**\n\t * Setup ARIA attributes for the listbox.\n\t */\n\tsetupAriaAttributes(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if ARIA is enabled.\n\t\tif ( ! multiSelect?.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Auto-generate ID if not present.\n\t\tif ( ! this.id ) {\n\t\t\tthis.id = `tp-multi-select-listbox-${ ++optionsIdCounter }`;\n\t\t}\n\n\t\t// Set listbox role.\n\t\tthis.setAttribute( 'role', 'listbox' );\n\n\t\t// Set aria-multiselectable if multiple selection is enabled.\n\t\tif ( 'no' !== multiSelect.getAttribute( 'multiple' ) ) {\n\t\t\tthis.setAttribute( 'aria-multiselectable', 'true' );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * Counter for generating unique IDs.\n */\nlet optionIdCounter = 0;\n\n/**\n * TP Multi Select Option.\n */\nexport class TPMultiSelectOptionElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener to toggle the selected state.\n\t\tthis.addEventListener( 'click', this.toggle.bind( this ) );\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes to observe.\n\t\treturn [ 'selected' ];\n\t}\n\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback(): void {\n\t\t// Setup ARIA attributes.\n\t\tthis.setupAriaAttributes();\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// If no changes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update ARIA state when selected changes.\n\t\tif ( 'selected' === name ) {\n\t\t\tthis.updateAriaState();\n\t\t}\n\t}\n\n\t/**\n\t * Setup ARIA attributes for the option.\n\t */\n\tsetupAriaAttributes(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if ARIA is enabled.\n\t\tif ( ! multiSelect?.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Auto-generate ID if not present.\n\t\tif ( ! this.id ) {\n\t\t\tthis.id = `tp-multi-select-option-${ ++optionIdCounter }`;\n\t\t}\n\n\t\t// Set option role.\n\t\tthis.setAttribute( 'role', 'option' );\n\n\t\t// Set tabindex only if not already present (needed for relatedTarget to work on focusout).\n\t\tif ( ! this.hasAttribute( 'tabindex' ) ) {\n\t\t\tthis.setAttribute( 'tabindex', '-1' );\n\t\t}\n\n\t\t// Set initial ARIA state.\n\t\tthis.updateAriaState();\n\t}\n\n\t/**\n\t * Update ARIA state based on selected attribute.\n\t */\n\tupdateAriaState(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if ARIA is enabled.\n\t\tif ( ! multiSelect?.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update aria-selected.\n\t\tconst isSelected = 'yes' === this.getAttribute( 'selected' );\n\t\tthis.setAttribute( 'aria-selected', isSelected ? 'true' : 'false' );\n\t}\n\n\t/**\n\t * Select / un-select this option.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\ttoggle( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Get multi-select element and value of option.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst value: string = this.getAttribute( 'value' ) ?? '';\n\n\t\t// Toggle selected state. Dispatch custom events accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect?.select( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'select', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t} else {\n\t\t\tmultiSelect?.unSelect( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'unselect', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\n\n/**\n * TP Multi Select Search.\n */\nexport class TPMultiSelectSearchElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listeners.\n\t\tconst input = this.querySelector( 'input' );\n\t\tinput?.addEventListener( 'keydown', this.handleKeyboardInputs.bind( this ) );\n\t\tinput?.addEventListener( 'keyup', this.handleSearchChange.bind( this ) );\n\t\tinput?.addEventListener( 'input', this.handleSearchChange.bind( this ) );\n\t\tthis.addEventListener( 'click', this.handleClick.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'open', this.focus.bind( this ) );\n\t}\n\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback(): void {\n\t\t// Setup ARIA attributes.\n\t\tthis.setupAriaAttributes();\n\t}\n\n\t/**\n\t * Setup ARIA attributes for the search input (combobox).\n\t */\n\tsetupAriaAttributes(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if ARIA is enabled.\n\t\tif ( ! multiSelect?.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get input.\n\t\tconst input: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Bail if no input.\n\t\tif ( ! input ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get options container.\n\t\tconst options: TPMultiSelectOptionsElement | null = multiSelect.querySelector( 'tp-multi-select-options' );\n\n\t\t// Set combobox role and attributes on the input.\n\t\tinput.setAttribute( 'role', 'combobox' );\n\t\tinput.setAttribute( 'aria-haspopup', 'listbox' );\n\t\tinput.setAttribute( 'aria-expanded', 'false' );\n\t\tinput.setAttribute( 'aria-autocomplete', 'list' );\n\n\t\t// Set aria-controls if options has an ID.\n\t\tif ( options?.id ) {\n\t\t\tinput.setAttribute( 'aria-controls', options.id );\n\t\t}\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Get multi select and search field.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if multi select and search field exists.\n\t\tif ( ! multiSelect || ! search ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle keyboard inputs.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'Enter':\n\t\t\t\te.preventDefault(); // Prevent inadvertent form submits.\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowDown':\n\n\t\t\t\t// Only handle when dropdown is closed.\n\t\t\t\tif ( 'yes' !== multiSelect.getAttribute( 'open' ) ) {\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Backspace': // Remove last pill if search is empty.\n\t\t\t\tif ( 0 === search.value.length ) {\n\t\t\t\t\tconst pill: TPMultiSelectPillElement | null = multiSelect.querySelector( 'tp-multi-select-pill:last-of-type' );\n\n\t\t\t\t\t// Check if pill exists, remove it.\n\t\t\t\t\tif ( pill ) {\n\t\t\t\t\t\tpill.removePill();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Handle search field value changed.\n\t */\n\tprotected handleSearchChange(): void {\n\t\t// Get search field and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | undefined = this.closest( 'tp-multi-select' )?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select, search, and options field exists.\n\t\tif ( ! multiSelect || ! search || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize matched option count.\n\t\tlet matchedOptionCount = 0;\n\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Hide and show options based on search.\n\t\t\tif ( option.getAttribute( 'label' )?.toLowerCase().match( new RegExp( `.*${ search.value.toLowerCase().replace( /\\s/g, '.*' ) }.*` ) ) ) {\n\t\t\t\toption.removeAttribute( 'hidden' );\n\t\t\t\tmatchedOptionCount++;\n\t\t\t} else {\n\t\t\t\toption.setAttribute( 'hidden', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Resize input width.\n\t\tif ( '' === search.value ) {\n\t\t\tsearch.removeAttribute( 'style' );\n\t\t} else {\n\t\t\tsearch.style.width = `${ search.value.length + 2 }ch`;\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\n\t\t// Show matched option count.\n\t\tmultiSelect.setAttribute( 'visible-options', matchedOptionCount.toString() );\n\t}\n\n\t/**\n\t * Handle click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\tprotected handleClick( e: Event ): void {\n\t\t// First, prevent propagation to avoid document.click set on `tp-multi-select`.\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\t// Now send the event so other stuff can work as per normal, and another event for good measure.\n\t\tthis.dispatchEvent( new CustomEvent( 'multi-select-opened' ) );\n\t\tdocument.dispatchEvent( new Event( 'click' ) );\n\n\t\t// Open multi select.\n\t\tthis.closest( 'tp-multi-select' )?.setAttribute( 'open', 'yes' );\n\t}\n\n\t/**\n\t * Clear the search field.\n\t */\n\tclear(): void {\n\t\t// Clear search field.\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if search field exists.\n\t\tif ( search ) {\n\t\t\t// Set value to empty string and dispatch change event.\n\t\t\tsearch.value = '';\n\t\t\tsearch.dispatchEvent( new Event( 'change' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Set focus on the search field.\n\t */\n\tfocus(): void {\n\t\t// When it's focused, use search change to ensure the results are refreshed.\n\t\tthis.handleSearchChange();\n\n\t\t// Focus on input.\n\t\tthis.querySelector( 'input' )?.focus();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Search Status.\n */\nexport class TPMultiSelectSearchStatusElement extends HTMLElement {\n\t/**\n\t * Store the default role from markup.\n\t */\n\tprotected defaultRole: string | null = null;\n\n\t/**\n\t * Store the default aria-live from markup.\n\t */\n\tprotected defaultAriaLive: string | null = null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Listen for search input changes.\n\t\tthis.closest( 'tp-multi-select' )?.querySelector( 'tp-multi-select-search input' )?.addEventListener( 'input', this.update.bind( this ) );\n\t}\n\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback(): void {\n\t\t// Store the default role and aria-live from markup.\n\t\tthis.defaultRole = this.getAttribute( 'role' );\n\t\tthis.defaultAriaLive = this.getAttribute( 'aria-live' );\n\n\t\t// Initial update.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail if no multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get visible options count.\n\t\tconst visibleOptions: NodeListOf<TPMultiSelectOptionElement> = multiSelect.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\t\tconst count: number = visibleOptions.length;\n\n\t\t// Get format attributes.\n\t\tconst format: string = this.getAttribute( 'format' ) ?? '$count results';\n\t\tconst noResultsFormat: string = this.getAttribute( 'no-results-format' ) ?? 'No results found';\n\n\t\t// Get role and aria-live attributes for no-results state.\n\t\tconst noResultsRole: string | null = this.getAttribute( 'no-results-role' );\n\t\tconst noResultsAriaLive: string | null = this.getAttribute( 'no-results-aria-live' );\n\n\t\t// Update text content, role, and aria-live based on count.\n\t\tif ( 0 === count ) {\n\t\t\tthis.textContent = noResultsFormat;\n\n\t\t\t// Switch to no-results role if specified.\n\t\t\tif ( noResultsRole ) {\n\t\t\t\tthis.setAttribute( 'role', noResultsRole );\n\t\t\t}\n\n\t\t\t// Switch to no-results aria-live if specified.\n\t\t\tif ( noResultsAriaLive ) {\n\t\t\t\tthis.setAttribute( 'aria-live', noResultsAriaLive );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.textContent = format.replace( '$count', count.toString() );\n\n\t\t\t// Restore default role.\n\t\t\tif ( this.defaultRole ) {\n\t\t\t\tthis.setAttribute( 'role', this.defaultRole );\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute( 'role' );\n\t\t\t}\n\n\t\t\t// Restore default aria-live.\n\t\t\tif ( this.defaultAriaLive ) {\n\t\t\t\tthis.setAttribute( 'aria-live', this.defaultAriaLive );\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute( 'aria-live' );\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Pill.\n */\nexport class TPMultiSelectPillElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleButtonClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle button click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\thandleButtonClick( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Remove pill.\n\t\tthis.removePill();\n\t}\n\n\t/**\n\t * Remove this pill.\n\t */\n\tremovePill(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Unselect value.\n\t\tif ( multiSelect && this.getAttribute( 'value' ) ) {\n\t\t\tmultiSelect.unSelect( this.getAttribute( 'value' ) ?? '' );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect', { bubbles: true } ) );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Pills.\n */\nexport class TPMultiSelectPillsElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.update.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.querySelector( 'select' )?.addEventListener( 'change', ( () => this.update() ) as EventListener );\n\n\t\t// Update.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail if there's no multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine pills.\n\t\tconst pills: NodeListOf<TPMultiSelectPillElement> | null = this.querySelectorAll( 'tp-multi-select-pill' );\n\t\tconst values: string[] = [ ...new Set( multiSelect.value ) ] ?? [];\n\t\tconst pillValues: string[] = [];\n\n\t\t// Remove pills that shouldn't exist.\n\t\tpills.forEach( ( pill: TPMultiSelectPillElement ): void => {\n\t\t\t// Get pill value.\n\t\t\tconst pillValue: string = pill.getAttribute( 'value' ) ?? '';\n\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill value to the array.\n\t\t\tpillValues.push( pillValue );\n\n\t\t\t// Remove pill if it doesn't exist in the values.\n\t\t\tif ( ! values.includes( pillValue ) ) {\n\t\t\t\tpill.remove();\n\t\t\t}\n\t\t} );\n\n\t\t// Create new pills.\n\t\tconst pillsToCreate: string[] = values.filter( ( value: string ) => ! pillValues.includes( value ) );\n\n\t\t// Create pills.\n\t\tpillsToCreate.forEach( ( pillValue: string ): void => {\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get multi-select option.\n\t\t\tconst multiSelectOption: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ pillValue }\"]` );\n\n\t\t\t// Bail early if there's no multi-select option.\n\t\t\tif ( ! multiSelectOption ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill.\n\t\t\tthis.appendChild( this.createPill( pillValue, multiSelectOption.getAttribute( 'label' ) ?? '' ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Create a new pill.\n\t *\n\t * @param {string} value Pill value.\n\t * @param {string} label Pill label.\n\t *\n\t * @return {TPMultiSelectPillElement} New pill.\n\t */\n\tcreatePill( value: string, label: string ): TPMultiSelectPillElement {\n\t\t// Create pill and set value attribute.\n\t\tconst newPill = document.createElement( 'tp-multi-select-pill' ) as TPMultiSelectPillElement;\n\t\tnewPill.setAttribute( 'value', value );\n\n\t\t// Create pill label.\n\t\tconst pillLabel: HTMLElement = document.createElement( 'span' );\n\t\tpillLabel.textContent = label;\n\n\t\t// Create pill close button.\n\t\tconst pillCloseButton: HTMLElement = document.createElement( 'button' );\n\t\tpillCloseButton.setAttribute( 'type', 'button' );\n\n\t\t// Use remove-format for button text, falling back to 'x'.\n\t\tconst removeFormat = this.getAttribute( 'remove-format' );\n\t\tpillCloseButton.textContent = removeFormat ? removeFormat.replace( '$label', label ) : 'x';\n\n\t\t// Add event listener.\n\t\tpillCloseButton.addEventListener( 'click', () => {\n\t\t\t// On click, run removePill method.\n\t\t\tnewPill.removePill();\n\t\t} );\n\n\t\t// Stop propagation on keydown to prevent parent handlers from intercepting.\n\t\tpillCloseButton.addEventListener( 'keydown', ( e: KeyboardEvent ) => {\n\t\t\t// Check if Enter or Space was pressed.\n\t\t\tif ( 'Enter' === e.key || ' ' === e.key ) {\n\t\t\t\te.stopPropagation();\n\t\t\t}\n\t\t} );\n\n\t\t// Append label and close button to pill.\n\t\tnewPill.appendChild( pillLabel );\n\t\tnewPill.appendChild( pillCloseButton );\n\n\t\t// Return newPill element.\n\t\treturn newPill;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * Counter for generating unique IDs.\n */\nlet selectAllIdCounter = 0;\n\n/**\n * TP Multi Select Select All.\n */\nexport class TPMultiSelectSelectAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listeners.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.handleValueChanged.bind( this ) );\n\t\tthis.addEventListener( 'click', this.toggleSelectAll.bind( this ) );\n\t}\n\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback(): void {\n\t\t// Setup ARIA attributes.\n\t\tthis.setupAriaAttributes();\n\t}\n\n\t/**\n\t * Setup ARIA attributes for the select all option.\n\t */\n\tsetupAriaAttributes(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if ARIA is enabled.\n\t\tif ( ! multiSelect?.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Auto-generate ID if not present.\n\t\tif ( ! this.id ) {\n\t\t\tthis.id = `tp-multi-select-all-${ ++selectAllIdCounter }`;\n\t\t}\n\n\t\t// Set option role.\n\t\tthis.setAttribute( 'role', 'option' );\n\n\t\t// Set initial aria-selected state.\n\t\tthis.updateAriaState();\n\t}\n\n\t/**\n\t * Update ARIA state based on selected attribute.\n\t */\n\tupdateAriaState(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if ARIA is enabled.\n\t\tif ( ! multiSelect?.isAriaEnabled() ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update aria-selected.\n\t\tconst isSelected = 'yes' === this.getAttribute( 'selected' );\n\t\tthis.setAttribute( 'aria-selected', isSelected ? 'true' : 'false' );\n\t}\n\n\t/**\n\t * Handle value changed.\n\t */\n\thandleValueChanged(): void {\n\t\t// Get multi select and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null | undefined = multiSelect?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select and options exists.\n\t\tif ( ! multiSelect || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if all options are selected.\n\t\tif ( Array.from( options ).filter( ( optionNode ) => optionNode.getAttribute( 'disabled' ) !== 'yes' ).length === multiSelect.value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t\tthis.innerHTML = this.getAttribute( 'unselect-text' ) ?? '';\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t\tthis.innerHTML = this.getAttribute( 'select-text' ) ?? '';\n\t\t}\n\n\t\t// Update ARIA state.\n\t\tthis.updateAriaState();\n\t}\n\n\t/**\n\t * Toggle select all.\n\t */\n\ttoggleSelectAll(): void {\n\t\t// Get multi select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if multi select exists.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if select all is yes. Apply selectAll and unselectAll methods accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect.selectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'select-all', { bubbles: true } ) );\n\t\t} else {\n\t\t\tmultiSelect.unSelectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect-all', { bubbles: true } ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectFieldElement } from './tp-multi-select-field';\nimport { TPMultiSelectPlaceholderElement } from './tp-multi-select-placeholder';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\nimport { TPMultiSelectSearchStatusElement } from './tp-multi-select-search-status';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectPillsElement } from './tp-multi-select-pills';\nimport { TPMultiSelectSelectAllElement } from './tp-multi-select-select-all';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-multi-select', TPMultiSelectElement );\ncustomElements.define( 'tp-multi-select-field', TPMultiSelectFieldElement );\ncustomElements.define( 'tp-multi-select-placeholder', TPMultiSelectPlaceholderElement );\ncustomElements.define( 'tp-multi-select-status', TPMultiSelectStatusElement );\ncustomElements.define( 'tp-multi-select-options', TPMultiSelectOptionsElement );\ncustomElements.define( 'tp-multi-select-option', TPMultiSelectOptionElement );\ncustomElements.define( 'tp-multi-select-search', TPMultiSelectSearchElement );\ncustomElements.define( 'tp-multi-select-search-status', TPMultiSelectSearchStatusElement );\ncustomElements.define( 'tp-multi-select-pill', TPMultiSelectPillElement );\ncustomElements.define( 'tp-multi-select-pills', TPMultiSelectPillsElement );\ncustomElements.define( 'tp-multi-select-select-all', TPMultiSelectSelectAllElement );\n"],"names":["TPMultiSelectElement","HTMLElement","constructor","super","currentlyHighlightedOption","this","keyboardEventListener","handleKeyboardInputs","bind","document","addEventListener","handleDocumentClick","update","handleFocusOut","options","querySelector","MutationObserver","initialize","observe","childList","subtree","observedAttributes","isAriaEnabled","getAttribute","attributeChangedCallback","name","oldValue","newValue","updateAriaExpanded","highlightNextOption","dispatchEvent","CustomEvent","bubbles","unHighlightAllOptions","removeEventListener","value","Array","isArray","styledOptions","querySelectorAll","forEach","option","includes","setAttribute","removeAttribute","selectedOptions","optionValue","push","updateFormFieldValue","styledSelectedOptions","selectField","selectOptions","from","matchingSelectOption","find","selectOption","newOption","createElement","append","remove","Event","length","status","toString","e","target","contains","selectElement","innerHTML","formReference","select","unSelectAll","search","clear","focus","selectAll","unSelect","key","preventDefault","highlightPreviousOption","toggleHighlightedOption","nextToBeHighlighted","scrollIntoView","behavior","block","updateAriaActiveDescendant","id","previousToBeHighlighted","toggle","getComboboxElement","isOpen","combobox","optionId","relatedTarget","TPMultiSelectFieldElement","toggleOpen","handleKeydown","multiSelect","closest","stopPropagation","connectedCallback","setupAriaAttributes","setupLabelClick","labelledBy","label","getElementById","hasAttribute","TPMultiSelectPlaceholderElement","TPMultiSelectStatusElement","_name","format","html","replace","optionsIdCounter","TPMultiSelectOptionsElement","optionIdCounter","TPMultiSelectOptionElement","updateAriaState","isSelected","detail","TPMultiSelectSearchElement","input","handleSearchChange","handleClick","pill","removePill","matchedOptionCount","toLowerCase","match","RegExp","style","width","TPMultiSelectSearchStatusElement","defaultRole","defaultAriaLive","count","noResultsFormat","noResultsRole","noResultsAriaLive","textContent","TPMultiSelectPillElement","handleButtonClick","TPMultiSelectPillsElement","pills","values","Set","pillValues","pillValue","filter","multiSelectOption","appendChild","createPill","newPill","pillLabel","pillCloseButton","removeFormat","selectAllIdCounter","TPMultiSelectSelectAllElement","handleValueChanged","toggleSelectAll","optionNode","customElements","define"],"sourceRoot":""}
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";class t extends HTMLElement{}class e extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.increment.bind(this))}increment(){const t=this.closest("tp-number-spinner");null==t||t.increment()}}class n extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.decrement.bind(this))}decrement(){const t=this.closest("tp-number-spinner");null==t||t.decrement()}}class s extends HTMLElement{get min(){const t=this.getAttribute("min");return t?parseInt(t):null}set min(t){this.setAttribute("min",t.toString())}get max(){const t=this.getAttribute("max");return t?parseInt(t):null}set max(t){this.setAttribute("max",t.toString())}get step(){var t;return parseInt(null!==(t=this.getAttribute("step"))&&void 0!==t?t:"1")}set step(t){this.setAttribute("step",t.toString())}get value(){var t,e;return parseInt(null!==(e=null===(t=this.querySelector("tp-number-spinner-input input"))||void 0===t?void 0:t.getAttribute("value"))&&void 0!==e?e:"0")}set value(t){var e;null===(e=this.querySelector("tp-number-spinner-input input"))||void 0===e||e.setAttribute("value",t.toString())}increment(){const t=this.value,e=this.max,n=t+this.step;e&&n>e||(this.value=n)}decrement(){const t=this.value,e=this.min,n=t-this.step;e&&n<e||(this.value=n)}}customElements.define("tp-number-spinner-input",t),customElements.define("tp-number-spinner-increment",e),customElements.define("tp-number-spinner-decrement",n),customElements.define("tp-number-spinner",s)})();
1
+ (()=>{"use strict";class t extends HTMLElement{}class e extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.increment.bind(this))}increment(){const t=this.closest("tp-number-spinner");null==t||t.increment()}}class n extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.decrement.bind(this))}decrement(){const t=this.closest("tp-number-spinner");null==t||t.decrement()}}class i extends HTMLElement{connectedCallback(){this.setupAria()}isAriaEnabled(){return"no"!==this.getAttribute("aria")}getInput(){return this.querySelector("tp-number-spinner-input input")}setupAria(){if(!this.isAriaEnabled())return;const t=this.getInput();t&&(t.hasAttribute("role")||t.setAttribute("role","spinbutton"),this.setupButtonTabindex(),t.addEventListener("keydown",this.handleInputKeydown.bind(this)),this.updateAriaAttributes())}setupButtonTabindex(){const t=this.querySelector("tp-number-spinner-decrement button"),e=this.querySelector("tp-number-spinner-increment button");t&&!t.hasAttribute("tabindex")&&t.setAttribute("tabindex","-1"),e&&!e.hasAttribute("tabindex")&&e.setAttribute("tabindex","-1")}handleInputKeydown(t){switch(t.key){case"ArrowUp":t.preventDefault(),this.increment();break;case"ArrowDown":t.preventDefault(),this.decrement();break;case"Home":null!==this.min&&(t.preventDefault(),this.value=this.min);break;case"End":null!==this.max&&(t.preventDefault(),this.value=this.max)}}updateAriaAttributes(){if(!this.isAriaEnabled())return;const t=this.getInput();if(!t)return;const e=this.value,n=this.min,i=this.max;t.setAttribute("aria-valuenow",e.toString()),null!==n&&t.setAttribute("aria-valuemin",n.toString()),null!==i&&t.setAttribute("aria-valuemax",i.toString()),this.updateButtonStates(e,n,i)}updateButtonStates(t,e,n){const i=this.querySelector("tp-number-spinner-decrement button"),r=this.querySelector("tp-number-spinner-increment button");i&&(null!==e&&t<=e?i.setAttribute("aria-disabled","true"):i.removeAttribute("aria-disabled")),r&&(null!==n&&t>=n?r.setAttribute("aria-disabled","true"):r.removeAttribute("aria-disabled"))}get min(){const t=this.getAttribute("min");return t?parseInt(t):null}set min(t){this.setAttribute("min",t.toString())}get max(){const t=this.getAttribute("max");return t?parseInt(t):null}set max(t){this.setAttribute("max",t.toString())}get step(){var t;return parseInt(null!==(t=this.getAttribute("step"))&&void 0!==t?t:"1")}set step(t){this.setAttribute("step",t.toString())}get value(){var t,e;return parseInt(null!==(e=null===(t=this.querySelector("tp-number-spinner-input input"))||void 0===t?void 0:t.getAttribute("value"))&&void 0!==e?e:"0")}set value(t){var e;null===(e=this.querySelector("tp-number-spinner-input input"))||void 0===e||e.setAttribute("value",t.toString()),this.updateAriaAttributes()}increment(){const t=this.value,e=this.max,n=t+this.step;e&&n>e||(this.value=n)}decrement(){const t=this.value,e=this.min,n=t-this.step;e&&n<e||(this.value=n)}}customElements.define("tp-number-spinner-input",t),customElements.define("tp-number-spinner-increment",e),customElements.define("tp-number-spinner-decrement",n),customElements.define("tp-number-spinner",i)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/number-spinner/index.js","mappings":"mBAGO,MAAMA,UAA6BC,aCKnC,MAAMC,UAAiCD,YAI7C,WAAAE,G,MAECC,QAG8B,QAA9B,EAAAC,KAAKC,cAAe,iBAAU,SAAEC,iBAAkB,QAASF,KAAKG,UAAUC,KAAMJ,MACjF,CAKA,SAAAG,GAEC,MAAME,EAAwCL,KAAKM,QAAS,qBAC5DD,SAAAA,EAAeF,WAChB,ECnBM,MAAMI,UAAiCX,YAI7C,WAAAE,G,MAECC,QAG8B,QAA9B,EAAAC,KAAKC,cAAe,iBAAU,SAAEC,iBAAkB,QAASF,KAAKQ,UAAUJ,KAAMJ,MACjF,CAKA,SAAAQ,GAEC,MAAMH,EAAwCL,KAAKM,QAAS,qBAC5DD,SAAAA,EAAeG,WAChB,ECxBM,MAAMC,UAAwBb,YAMpC,OAAIc,GAEH,MAAMA,EAAqBV,KAAKW,aAAc,OAG9C,OAAKD,EAEGE,SAAUF,GAIX,IACR,CAOA,OAAIA,CAAKA,GAERV,KAAKa,aAAc,MAAOH,EAAII,WAC/B,CAOA,OAAIC,GAEH,MAAMA,EAAqBf,KAAKW,aAAc,OAG9C,OAAKI,EAEGH,SAAUG,GAIX,IACR,CAOA,OAAIA,CAAKA,GAERf,KAAKa,aAAc,MAAOE,EAAID,WAC/B,CAOA,QAAIE,G,MAEH,OAAOJ,SAAqC,QAA3B,EAAAZ,KAAKW,aAAc,eAAQ,QAAI,IACjD,CAOA,QAAIK,CAAMA,GAEThB,KAAKa,aAAc,OAAQG,EAAKF,WACjC,CAOA,SAAIG,G,QAEH,OAAOL,SAAwF,QAA9E,EAAqD,QAArD,EAAAZ,KAAKC,cAAe,wCAAiC,eAAEU,aAAc,gBAAS,QAAI,IACpG,CAOA,SAAIM,CAAOA,G,MAE2C,QAArD,EAAAjB,KAAKC,cAAe,wCAAiC,SAAEY,aAAc,QAASI,EAAMH,WACrF,CAKA,SAAAX,GAEC,MAAMe,EAAuBlB,KAAKiB,MAC5BF,EAAqBf,KAAKe,IAC1BI,EAAmBD,EAAelB,KAAKgB,KAGxCD,GAAOI,EAAWJ,IAMvBf,KAAKiB,MAAQE,EACd,CAKA,SAAAX,GAEC,MAAMU,EAAuBlB,KAAKiB,MAC5BP,EAAqBV,KAAKU,IAC1BS,EAAmBD,EAAelB,KAAKgB,KAGxCN,GAAOS,EAAWT,IAMvBV,KAAKiB,MAAQE,EACd,EC1HDC,eAAeC,OAAQ,0BAA2B1B,GAClDyB,eAAeC,OAAQ,8BAA+BxB,GACtDuB,eAAeC,OAAQ,8BAA+Bd,GACtDa,eAAeC,OAAQ,oBAAqBZ,E","sources":["webpack://@travelopia/web-components/./src/number-spinner/tp-number-spinner-input.ts","webpack://@travelopia/web-components/./src/number-spinner/tp-number-spinner-increment.ts","webpack://@travelopia/web-components/./src/number-spinner/tp-number-spinner-decrement.ts","webpack://@travelopia/web-components/./src/number-spinner/tp-number-spinner.ts","webpack://@travelopia/web-components/./src/number-spinner/index.ts"],"sourcesContent":["/**\n * TP Number Spinner Input.\n */\nexport class TPNumberSpinnerInput extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPNumberSpinner } from './tp-number-spinner';\n\n/**\n * TP Number Spinner Increment Element.\n */\nexport class TPNumberSpinnerIncrement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Attach click event for increment.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.increment.bind( this ) );\n\t}\n\n\t/**\n\t * Increment the value.\n\t */\n\tincrement(): void {\n\t\t// Run function on parent.\n\t\tconst numberSpinner: TPNumberSpinner | null = this.closest( 'tp-number-spinner' );\n\t\tnumberSpinner?.increment();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPNumberSpinner } from './tp-number-spinner';\n\n/**\n * TP Number Spinner Decrement Element.\n */\nexport class TPNumberSpinnerDecrement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Attach click event for decrement.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.decrement.bind( this ) );\n\t}\n\n\t/**\n\t * Decrement the value.\n\t */\n\tdecrement(): void {\n\t\t// Run function on parent.\n\t\tconst numberSpinner: TPNumberSpinner | null = this.closest( 'tp-number-spinner' );\n\t\tnumberSpinner?.decrement();\n\t}\n}\n","/**\n * TP Number Spinner Element.\n */\nexport class TPNumberSpinner extends HTMLElement {\n\t/**\n\t * Get minimum value.\n\t *\n\t * @return {number|null} The minimum value.\n\t */\n\tget min(): number | null {\n\t\t// Get minimum attribute.\n\t\tconst min: string | null = this.getAttribute( 'min' );\n\n\t\t// Check if we have an attribute.\n\t\tif ( min ) {\n\t\t\t// Yep, return its value.\n\t\t\treturn parseInt( min );\n\t\t}\n\n\t\t// Nope, return null.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Set minimum value.\n\t *\n\t * @param {number} min Minimum value.\n\t */\n\tset min( min: number ) {\n\t\t// Set attribute.\n\t\tthis.setAttribute( 'min', min.toString() );\n\t}\n\n\t/**\n\t * Get maximum value.\n\t *\n\t * @return {number|null} The maximum value.\n\t */\n\tget max(): number | null {\n\t\t// Get maximum attribute.\n\t\tconst max: string | null = this.getAttribute( 'max' );\n\n\t\t// Check if we have an attribute.\n\t\tif ( max ) {\n\t\t\t// Yep, return its value.\n\t\t\treturn parseInt( max );\n\t\t}\n\n\t\t// Nope, return null.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Set maximum value.\n\t *\n\t * @param {number} max Maximum value.\n\t */\n\tset max( max: number ) {\n\t\t// Set attribute.\n\t\tthis.setAttribute( 'max', max.toString() );\n\t}\n\n\t/**\n\t * Get current step.\n\t *\n\t * @return {number} Current step.\n\t */\n\tget step(): number {\n\t\t// Get step from attribute.\n\t\treturn parseInt( this.getAttribute( 'step' ) ?? '1' );\n\t}\n\n\t/**\n\t * Set current step.\n\t *\n\t * @param {number} step Current step.\n\t */\n\tset step( step: number ) {\n\t\t// Set attribute.\n\t\tthis.setAttribute( 'step', step.toString() );\n\t}\n\n\t/**\n\t * Get value.\n\t *\n\t * @return {number} The value.\n\t */\n\tget value(): number {\n\t\t// Get value from input.\n\t\treturn parseInt( this.querySelector( 'tp-number-spinner-input input' )?.getAttribute( 'value' ) ?? '0' );\n\t}\n\n\t/**\n\t * Set current value.\n\t *\n\t * @param {number} value Current value.\n\t */\n\tset value( value: number ) {\n\t\t// Set input's value.\n\t\tthis.querySelector( 'tp-number-spinner-input input' )?.setAttribute( 'value', value.toString() );\n\t}\n\n\t/**\n\t * Increment.\n\t */\n\tincrement(): void {\n\t\t// Calculate new value.\n\t\tconst currentValue: number = this.value;\n\t\tconst max: number | null = this.max;\n\t\tconst newValue: number = currentValue + this.step;\n\n\t\t// Check if new value is greater than the maximum.\n\t\tif ( max && newValue > max ) {\n\t\t\t// Yes, that's not allowed.\n\t\t\treturn;\n\t\t}\n\n\t\t// No, set its value.\n\t\tthis.value = newValue;\n\t}\n\n\t/**\n\t * Decrement.\n\t */\n\tdecrement(): void {\n\t\t// Calculate new value.\n\t\tconst currentValue: number = this.value;\n\t\tconst min: number | null = this.min;\n\t\tconst newValue: number = currentValue - this.step;\n\n\t\t// Check if new value is less than the minumum.\n\t\tif ( min && newValue < min ) {\n\t\t\t// Yes, that's not allowed.\n\t\t\treturn;\n\t\t}\n\n\t\t// No, set its value.\n\t\tthis.value = newValue;\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPNumberSpinnerInput } from './tp-number-spinner-input';\nimport { TPNumberSpinnerIncrement } from './tp-number-spinner-increment';\nimport { TPNumberSpinnerDecrement } from './tp-number-spinner-decrement';\nimport { TPNumberSpinner } from './tp-number-spinner';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-number-spinner-input', TPNumberSpinnerInput );\ncustomElements.define( 'tp-number-spinner-increment', TPNumberSpinnerIncrement );\ncustomElements.define( 'tp-number-spinner-decrement', TPNumberSpinnerDecrement );\ncustomElements.define( 'tp-number-spinner', TPNumberSpinner );\n"],"names":["TPNumberSpinnerInput","HTMLElement","TPNumberSpinnerIncrement","constructor","super","this","querySelector","addEventListener","increment","bind","numberSpinner","closest","TPNumberSpinnerDecrement","decrement","TPNumberSpinner","min","getAttribute","parseInt","setAttribute","toString","max","step","value","currentValue","newValue","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/number-spinner/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/number-spinner/tp-number-spinner-input.ts","webpack://@travelopia/web-components/./src/number-spinner/tp-number-spinner-increment.ts","webpack://@travelopia/web-components/./src/number-spinner/tp-number-spinner-decrement.ts","webpack://@travelopia/web-components/./src/number-spinner/tp-number-spinner.ts","webpack://@travelopia/web-components/./src/number-spinner/index.ts"],"sourcesContent":["/**\n * TP Number Spinner Input.\n */\nexport class TPNumberSpinnerInput extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPNumberSpinner } from './tp-number-spinner';\n\n/**\n * TP Number Spinner Increment Element.\n */\nexport class TPNumberSpinnerIncrement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Attach click event for increment.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.increment.bind( this ) );\n\t}\n\n\t/**\n\t * Increment the value.\n\t */\n\tincrement(): void {\n\t\t// Run function on parent.\n\t\tconst numberSpinner: TPNumberSpinner | null = this.closest( 'tp-number-spinner' );\n\t\tnumberSpinner?.increment();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPNumberSpinner } from './tp-number-spinner';\n\n/**\n * TP Number Spinner Decrement Element.\n */\nexport class TPNumberSpinnerDecrement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Attach click event for decrement.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.decrement.bind( this ) );\n\t}\n\n\t/**\n\t * Decrement the value.\n\t */\n\tdecrement(): void {\n\t\t// Run function on parent.\n\t\tconst numberSpinner: TPNumberSpinner | null = this.closest( 'tp-number-spinner' );\n\t\tnumberSpinner?.decrement();\n\t}\n}\n","/**\n * TP Number Spinner Element.\n */\nexport class TPNumberSpinner extends HTMLElement {\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback(): void {\n\t\t// Set up ARIA attributes.\n\t\tthis.setupAria();\n\t}\n\n\t/**\n\t * Check if ARIA management is enabled.\n\t *\n\t * @return {boolean} Whether ARIA is enabled.\n\t */\n\tisAriaEnabled(): boolean {\n\t\t// Return whether ARIA management is enabled (default: yes).\n\t\treturn 'no' !== this.getAttribute( 'aria' );\n\t}\n\n\t/**\n\t * Get the input element.\n\t *\n\t * @return {HTMLInputElement|null} The input element.\n\t */\n\tgetInput(): HTMLInputElement | null {\n\t\t// Return the input element.\n\t\treturn this.querySelector( 'tp-number-spinner-input input' );\n\t}\n\n\t/**\n\t * Set up ARIA attributes on the input.\n\t */\n\tsetupAria(): void {\n\t\t// Check if ARIA 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 the input element.\n\t\tconst input: HTMLInputElement | null = this.getInput();\n\n\t\t// Bail if no input.\n\t\tif ( ! input ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set role=\"spinbutton\" on input if not already set.\n\t\tif ( ! input.hasAttribute( 'role' ) ) {\n\t\t\tinput.setAttribute( 'role', 'spinbutton' );\n\t\t}\n\n\t\t// Set tabindex=\"-1\" on buttons if not already set.\n\t\tthis.setupButtonTabindex();\n\n\t\t// Add keyboard event listener for arrow keys and Home/End.\n\t\tinput.addEventListener( 'keydown', this.handleInputKeydown.bind( this ) );\n\n\t\t// Set initial ARIA attributes.\n\t\tthis.updateAriaAttributes();\n\t}\n\n\t/**\n\t * Set tabindex=\"-1\" on buttons if not already set by consumer.\n\t */\n\tsetupButtonTabindex(): void {\n\t\t// Get buttons.\n\t\tconst decrementButton: HTMLButtonElement | null = this.querySelector( 'tp-number-spinner-decrement button' );\n\t\tconst incrementButton: HTMLButtonElement | null = this.querySelector( 'tp-number-spinner-increment button' );\n\n\t\t// Set tabindex on decrement button if not already set.\n\t\tif ( decrementButton && ! decrementButton.hasAttribute( 'tabindex' ) ) {\n\t\t\tdecrementButton.setAttribute( 'tabindex', '-1' );\n\t\t}\n\n\t\t// Set tabindex on increment button if not already set.\n\t\tif ( incrementButton && ! incrementButton.hasAttribute( 'tabindex' ) ) {\n\t\t\tincrementButton.setAttribute( 'tabindex', '-1' );\n\t\t}\n\t}\n\n\t/**\n\t * Handle keydown events on the input.\n\t *\n\t * @param {KeyboardEvent} event The keyboard event.\n\t */\n\thandleInputKeydown( event: KeyboardEvent ): void {\n\t\t// Handle arrow keys and Home/End.\n\t\tswitch ( event.key ) {\n\t\t\t// Arrow Up: Increment value.\n\t\t\tcase 'ArrowUp':\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.increment();\n\t\t\t\tbreak;\n\n\t\t\t// Arrow Down: Decrement value.\n\t\t\tcase 'ArrowDown':\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.decrement();\n\t\t\t\tbreak;\n\n\t\t\t// Home: Go to minimum value.\n\t\t\tcase 'Home':\n\n\t\t\t\t// Check if min is defined.\n\t\t\t\tif ( null !== this.min ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tthis.value = this.min;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\t// End: Go to maximum value.\n\t\t\tcase 'End':\n\n\t\t\t\t// Check if max is defined.\n\t\t\t\tif ( null !== this.max ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tthis.value = this.max;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Update ARIA attributes on input and buttons.\n\t */\n\tupdateAriaAttributes(): void {\n\t\t// Check if ARIA 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 the input element.\n\t\tconst input: HTMLInputElement | null = this.getInput();\n\n\t\t// Bail if no input.\n\t\tif ( ! input ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current value and limits.\n\t\tconst currentValue: number = this.value;\n\t\tconst min: number | null = this.min;\n\t\tconst max: number | null = this.max;\n\n\t\t// Set aria-valuenow.\n\t\tinput.setAttribute( 'aria-valuenow', currentValue.toString() );\n\n\t\t// Set aria-valuemin if min is defined.\n\t\tif ( null !== min ) {\n\t\t\tinput.setAttribute( 'aria-valuemin', min.toString() );\n\t\t}\n\n\t\t// Set aria-valuemax if max is defined.\n\t\tif ( null !== max ) {\n\t\t\tinput.setAttribute( 'aria-valuemax', max.toString() );\n\t\t}\n\n\t\t// Update button states.\n\t\tthis.updateButtonStates( currentValue, min, max );\n\t}\n\n\t/**\n\t * Update aria-disabled state on buttons.\n\t *\n\t * @param {number} currentValue Current value.\n\t * @param {number|null} min Minimum value.\n\t * @param {number|null} max Maximum value.\n\t */\n\tupdateButtonStates( currentValue: number, min: number | null, max: number | null ): void {\n\t\t// Get buttons.\n\t\tconst decrementButton: HTMLButtonElement | null = this.querySelector( 'tp-number-spinner-decrement button' );\n\t\tconst incrementButton: HTMLButtonElement | null = this.querySelector( 'tp-number-spinner-increment button' );\n\n\t\t// Update decrement button.\n\t\tif ( decrementButton ) {\n\t\t\t// Check if at minimum.\n\t\t\tif ( null !== min && currentValue <= min ) {\n\t\t\t\tdecrementButton.setAttribute( 'aria-disabled', 'true' );\n\t\t\t} else {\n\t\t\t\tdecrementButton.removeAttribute( 'aria-disabled' );\n\t\t\t}\n\t\t}\n\n\t\t// Update increment button.\n\t\tif ( incrementButton ) {\n\t\t\t// Check if at maximum.\n\t\t\tif ( null !== max && currentValue >= max ) {\n\t\t\t\tincrementButton.setAttribute( 'aria-disabled', 'true' );\n\t\t\t} else {\n\t\t\t\tincrementButton.removeAttribute( 'aria-disabled' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get minimum value.\n\t *\n\t * @return {number|null} The minimum value.\n\t */\n\tget min(): number | null {\n\t\t// Get minimum attribute.\n\t\tconst min: string | null = this.getAttribute( 'min' );\n\n\t\t// Check if we have an attribute.\n\t\tif ( min ) {\n\t\t\t// Yep, return its value.\n\t\t\treturn parseInt( min );\n\t\t}\n\n\t\t// Nope, return null.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Set minimum value.\n\t *\n\t * @param {number} min Minimum value.\n\t */\n\tset min( min: number ) {\n\t\t// Set attribute.\n\t\tthis.setAttribute( 'min', min.toString() );\n\t}\n\n\t/**\n\t * Get maximum value.\n\t *\n\t * @return {number|null} The maximum value.\n\t */\n\tget max(): number | null {\n\t\t// Get maximum attribute.\n\t\tconst max: string | null = this.getAttribute( 'max' );\n\n\t\t// Check if we have an attribute.\n\t\tif ( max ) {\n\t\t\t// Yep, return its value.\n\t\t\treturn parseInt( max );\n\t\t}\n\n\t\t// Nope, return null.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Set maximum value.\n\t *\n\t * @param {number} max Maximum value.\n\t */\n\tset max( max: number ) {\n\t\t// Set attribute.\n\t\tthis.setAttribute( 'max', max.toString() );\n\t}\n\n\t/**\n\t * Get current step.\n\t *\n\t * @return {number} Current step.\n\t */\n\tget step(): number {\n\t\t// Get step from attribute.\n\t\treturn parseInt( this.getAttribute( 'step' ) ?? '1' );\n\t}\n\n\t/**\n\t * Set current step.\n\t *\n\t * @param {number} step Current step.\n\t */\n\tset step( step: number ) {\n\t\t// Set attribute.\n\t\tthis.setAttribute( 'step', step.toString() );\n\t}\n\n\t/**\n\t * Get value.\n\t *\n\t * @return {number} The value.\n\t */\n\tget value(): number {\n\t\t// Get value from input.\n\t\treturn parseInt( this.querySelector( 'tp-number-spinner-input input' )?.getAttribute( 'value' ) ?? '0' );\n\t}\n\n\t/**\n\t * Set current value.\n\t *\n\t * @param {number} value Current value.\n\t */\n\tset value( value: number ) {\n\t\t// Set input's value.\n\t\tthis.querySelector( 'tp-number-spinner-input input' )?.setAttribute( 'value', value.toString() );\n\n\t\t// Update ARIA attributes.\n\t\tthis.updateAriaAttributes();\n\t}\n\n\t/**\n\t * Increment.\n\t */\n\tincrement(): void {\n\t\t// Calculate new value.\n\t\tconst currentValue: number = this.value;\n\t\tconst max: number | null = this.max;\n\t\tconst newValue: number = currentValue + this.step;\n\n\t\t// Check if new value is greater than the maximum.\n\t\tif ( max && newValue > max ) {\n\t\t\t// Yes, that's not allowed.\n\t\t\treturn;\n\t\t}\n\n\t\t// No, set its value.\n\t\tthis.value = newValue;\n\t}\n\n\t/**\n\t * Decrement.\n\t */\n\tdecrement(): void {\n\t\t// Calculate new value.\n\t\tconst currentValue: number = this.value;\n\t\tconst min: number | null = this.min;\n\t\tconst newValue: number = currentValue - this.step;\n\n\t\t// Check if new value is less than the minumum.\n\t\tif ( min && newValue < min ) {\n\t\t\t// Yes, that's not allowed.\n\t\t\treturn;\n\t\t}\n\n\t\t// No, set its value.\n\t\tthis.value = newValue;\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPNumberSpinnerInput } from './tp-number-spinner-input';\nimport { TPNumberSpinnerIncrement } from './tp-number-spinner-increment';\nimport { TPNumberSpinnerDecrement } from './tp-number-spinner-decrement';\nimport { TPNumberSpinner } from './tp-number-spinner';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-number-spinner-input', TPNumberSpinnerInput );\ncustomElements.define( 'tp-number-spinner-increment', TPNumberSpinnerIncrement );\ncustomElements.define( 'tp-number-spinner-decrement', TPNumberSpinnerDecrement );\ncustomElements.define( 'tp-number-spinner', TPNumberSpinner );\n"],"names":["TPNumberSpinnerInput","HTMLElement","TPNumberSpinnerIncrement","constructor","super","this","querySelector","addEventListener","increment","bind","numberSpinner","closest","TPNumberSpinnerDecrement","decrement","TPNumberSpinner","connectedCallback","setupAria","isAriaEnabled","getAttribute","getInput","input","hasAttribute","setAttribute","setupButtonTabindex","handleInputKeydown","updateAriaAttributes","decrementButton","incrementButton","event","key","preventDefault","min","value","max","currentValue","toString","updateButtonStates","removeAttribute","parseInt","step","newValue","customElements","define"],"sourceRoot":""}
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";class t extends HTMLElement{constructor(){super();const t=this.querySelector("a");null==t||t.addEventListener("click",this.handleLinkClick.bind(this))}handleLinkClick(t){var e;const r=this.closest("tp-tabs"),s=this.querySelector("a"),n=null!==(e=null==s?void 0:s.getAttribute("href"))&&void 0!==e?e:"";r&&s&&""!==n&&("yes"!==r.getAttribute("update-url")&&t.preventDefault(),r.setAttribute("current-tab",n.replace("#","")))}isCurrentTab(t=""){const e=this.querySelector("a");return`#${t}`===(null==e?void 0:e.getAttribute("href"))}}class e extends HTMLElement{}class r extends HTMLElement{}class s extends HTMLElement{constructor(){super(),this.updateTabFromUrlHash(),window.addEventListener("hashchange",this.updateTabFromUrlHash.bind(this))}static get observedAttributes(){return["current-tab","update-url","overflow"]}attributeChangedCallback(t="",e="",r=""){e!==r&&(this.update(),"current-tab"===t&&this.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}update(){var t;const e=null!==(t=this.getAttribute("current-tab"))&&void 0!==t?t:"";if(!this.querySelector(`tp-tabs-tab[id="${e}"]`))return;const r=this.getCurrentNestedTab(e),s=this.querySelectorAll("tp-tabs-nav-item");s&&s.forEach((t=>{t.isCurrentTab(e)||r&&t.isCurrentTab(r)?t.setAttribute("active","yes"):t.removeAttribute("active")}));const n=this.querySelectorAll("tp-tabs-tab");n&&n.forEach((t=>{e===t.getAttribute("id")||r&&r===t.getAttribute("id")?t.setAttribute("open","yes"):t.removeAttribute("open")}))}updateTabFromUrlHash(){"yes"===this.getAttribute("update-url")&&this.setCurrentTab()}setCurrentTab(t=""){""!==t&&this.setAttribute("current-tab",t);const e=window.location.hash;if(""!==e){const t=this.querySelector(`a[href="${e}"]`),r=null==t?void 0:t.closest("tp-tabs");null==r||r.setAttribute("current-tab",e.replace("#",""))}}getCurrentNestedTab(t=""){if(""===t)return"";const e=this.querySelector(`tp-tabs-tab[id="${t}"]`),r=null==e?void 0:e.querySelector("tp-tabs"),s=null==r?void 0:r.getAttribute("current-tab");return null!=s?s:""}}customElements.define("tp-tabs-nav-item",t),customElements.define("tp-tabs-nav",e),customElements.define("tp-tabs-tab",r),customElements.define("tp-tabs",s)})();
1
+ (()=>{"use strict";class t extends HTMLElement{constructor(){super();const t=this.getTrigger();null==t||t.addEventListener("click",this.handleTriggerClick.bind(this)),this.setupAriaAttributes()}getTrigger(){return this.querySelector("button")||this.querySelector("a")}static get observedAttributes(){return["active"]}attributeChangedCallback(t,e,r){e!==r&&"active"===t&&this.updateAriaState("yes"===r)}isAriaEnabled(){var t;const e=this.closest("tp-tabs");return null===(t=null==e?void 0:e.isAriaEnabled())||void 0===t||t}setupAriaAttributes(){if(!this.isAriaEnabled())return;const t=this.getTrigger();if(!t)return;t.id||(t.id=`tp-tab-${Math.random().toString(36).substring(2,9)}`);const e=this.getPanelId();e&&!t.hasAttribute("aria-controls")&&t.setAttribute("aria-controls",e);const r="yes"===this.getAttribute("active");this.updateAriaState(r)}getPanelId(){var t,e;const r=this.getTrigger();return r?r instanceof HTMLAnchorElement?null!==(e=null===(t=r.getAttribute("href"))||void 0===t?void 0:t.replace("#",""))&&void 0!==e?e:"":r.getAttribute("aria-controls")||r.getAttribute("data-controls")||"":""}updateAriaState(t){if(!this.isAriaEnabled())return;const e=this.getTrigger();e&&(e.setAttribute("aria-selected",t?"true":"false"),e.setAttribute("tabindex",t?"0":"-1"))}handleTriggerClick(t){const e=this.closest("tp-tabs"),r=this.getTrigger(),i=this.getPanelId();e&&r&&""!==i&&(r instanceof HTMLAnchorElement&&"yes"!==e.getAttribute("update-url")&&t.preventDefault(),e.setAttribute("current-tab",i))}isCurrentTab(t=""){return t===this.getPanelId()}}class e extends HTMLElement{constructor(){super(),this.addEventListener("keydown",this.handleKeyDown.bind(this))}isAriaEnabled(){var t;const e=this.closest("tp-tabs");return null===(t=null==e?void 0:e.isAriaEnabled())||void 0===t||t}getTabTriggers(){const t=this.querySelectorAll("tp-tabs-nav-item"),e=[];return t.forEach((t=>{const r=t.querySelector("button")||t.querySelector("a");r&&e.push(r)})),e}handleKeyDown(t){if(!this.isAriaEnabled())return;const e=this.getTabTriggers();if(0===e.length)return;const r=e.findIndex((t=>t===this.ownerDocument.activeElement));if(-1===r)return;let i=r;switch(t.key){case"ArrowLeft":i=0===r?e.length-1:r-1;break;case"ArrowRight":i=r===e.length-1?0:r+1;break;case"Home":i=0;break;case"End":i=e.length-1;break;default:return}t.preventDefault();const s=e[i];s.click(),s.focus()}}class r extends HTMLElement{constructor(){super(),this.setupAriaAttributes()}static get observedAttributes(){return["open"]}attributeChangedCallback(t,e,r){e!==r&&"open"===t&&this.updateAriaState("yes"===r)}isAriaEnabled(){var t;const e=this.closest("tp-tabs");return null===(t=null==e?void 0:e.isAriaEnabled())||void 0===t||t}setupAriaAttributes(){if(!this.isAriaEnabled())return;const t=this.getAttribute("id");if(t){const e=this.closest("tp-tabs"),r=null==e?void 0:e.querySelector(`a[href="#${t}"]`);(null==r?void 0:r.id)&&!this.hasAttribute("aria-labelledby")&&this.setAttribute("aria-labelledby",r.id)}const e="yes"===this.getAttribute("open");this.updateAriaState(e)}updateAriaState(t){this.isAriaEnabled()&&(t?(this.removeAttribute("aria-hidden"),this.removeAttribute("inert"),this.setAttribute("tabindex","0")):(this.setAttribute("aria-hidden","true"),this.setAttribute("inert",""),this.removeAttribute("tabindex")))}}class i extends HTMLElement{constructor(){super(),this.updateTabFromUrlHash(),window.addEventListener("hashchange",this.updateTabFromUrlHash.bind(this))}static get observedAttributes(){return["current-tab","update-url","overflow","aria"]}isAriaEnabled(){return"no"!==this.getAttribute("aria")}attributeChangedCallback(t="",e="",r=""){e!==r&&(this.update(),"current-tab"===t&&this.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}update(){var t;const e=null!==(t=this.getAttribute("current-tab"))&&void 0!==t?t:"";if(!this.querySelector(`tp-tabs-tab[id="${e}"]`))return;const r=this.getCurrentNestedTab(e),i=this.querySelectorAll("tp-tabs-nav-item");i&&i.forEach((t=>{t.isCurrentTab(e)||r&&t.isCurrentTab(r)?t.setAttribute("active","yes"):t.removeAttribute("active")}));const s=this.querySelectorAll("tp-tabs-tab");s&&s.forEach((t=>{e===t.getAttribute("id")||r&&r===t.getAttribute("id")?t.setAttribute("open","yes"):t.removeAttribute("open")}))}updateTabFromUrlHash(){"yes"===this.getAttribute("update-url")&&this.setCurrentTab()}setCurrentTab(t=""){""!==t&&this.setAttribute("current-tab",t);const e=window.location.hash;if(""!==e){const t=this.querySelector(`a[href="${e}"]`),r=null==t?void 0:t.closest("tp-tabs");null==r||r.setAttribute("current-tab",e.replace("#",""))}}getCurrentNestedTab(t=""){if(""===t)return"";const e=this.querySelector(`tp-tabs-tab[id="${t}"]`),r=null==e?void 0:e.querySelector("tp-tabs"),i=null==r?void 0:r.getAttribute("current-tab");return null!=i?i:""}}customElements.define("tp-tabs",i),customElements.define("tp-tabs-nav",e),customElements.define("tp-tabs-nav-item",t),customElements.define("tp-tabs-tab",r)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/tabs/index.js","mappings":"mBAQO,MAAMA,UAA6BC,YAIzC,WAAAC,GAECC,QAGA,MAAMC,EAAiCC,KAAKC,cAAe,KAC3DF,SAAAA,EAAMG,iBAAkB,QAASF,KAAKG,gBAAgBC,KAAMJ,MAC7D,CASU,eAAAG,CAAiBE,G,MAE1B,MAAMC,EAA6BN,KAAKO,QAAS,WAC3CR,EAAiCC,KAAKC,cAAe,KACrDO,EAA6C,QAA5B,EAAAT,aAAI,EAAJA,EAAMU,aAAc,eAAQ,QAAI,GAGhDH,GAAUP,GAAQ,KAAOS,IAM3B,QAAUF,EAAKG,aAAc,eACjCJ,EAAEK,iBAIHJ,EAAKK,aAAc,cAAeH,EAAOI,QAAS,IAAK,KACxD,CASA,YAAAC,CAAcC,EAAqB,IAElC,MAAMf,EAAiCC,KAAKC,cAAe,KAG3D,MAAO,IAAKa,OAAkBf,aAAI,EAAJA,EAAMU,aAAc,QACnD,EC3DM,MAAMM,UAAyBnB,aCA/B,MAAMoB,UAAyBpB,aCM/B,MAAMqB,UAAsBrB,YAIlC,WAAAC,GAECC,QAGAE,KAAKkB,uBAGLC,OAAOjB,iBAAkB,aAAcF,KAAKkB,qBAAqBd,KAAMJ,MACxE,CAOA,6BAAWoB,GAEV,MAAO,CAAE,cAAe,aAAc,WACvC,CASA,wBAAAC,CAA0BC,EAAe,GAAIC,EAAmB,GAAIC,EAAmB,IAEjFD,IAAaC,IAMlBxB,KAAKyB,SAGA,gBAAkBH,GACtBtB,KAAK0B,cAAe,IAAIC,YAAa,SAAU,CAAEC,SAAS,KAE5D,CAKA,MAAAH,G,MAEC,MAAMX,EAAuD,QAAlC,EAAAd,KAAKS,aAAc,sBAAe,QAAI,GAGjE,IAAOT,KAAKC,cAAe,mBAAoBa,OAE9C,OAID,MAAMe,EAAmB7B,KAAK8B,oBAAqBhB,GAG7CiB,EAA6C/B,KAAKgC,iBAAkB,oBAGrED,GACJA,EAASE,SAAWC,IAEdA,EAAQrB,aAAcC,IAAkBe,GAAoBK,EAAQrB,aAAcgB,GACtFK,EAAQvB,aAAc,SAAU,OAEhCuB,EAAQC,gBAAiB,S,IAM5B,MAAM7B,EAAqCN,KAAKgC,iBAAkB,eAG7D1B,GACJA,EAAK2B,SAAWG,IAEVtB,IAAesB,EAAI3B,aAAc,OAAYoB,GAAoBA,IAAqBO,EAAI3B,aAAc,MAC5G2B,EAAIzB,aAAc,OAAQ,OAE1ByB,EAAID,gBAAiB,O,GAIzB,CAKA,oBAAAjB,GAEM,QAAUlB,KAAKS,aAAc,eAMlCT,KAAKqC,eACN,CAOA,aAAAA,CAAeC,EAAgB,IAEzB,KAAOA,GACXtC,KAAKW,aAAc,cAAe2B,GAInC,MAAMC,EAAkBpB,OAAOqB,SAASC,KAGxC,GAAK,KAAOF,EAAU,CACrB,MAAMG,EAAwC1C,KAAKC,cAAe,WAAYsC,OACxEzB,EAAa4B,aAAW,EAAXA,EAAanC,QAAS,WACzCO,SAAAA,EAAYH,aAAc,cAAe4B,EAAQ3B,QAAS,IAAK,I,CAEjE,CASA,mBAAAkB,CAAqBhB,EAAqB,IAEzC,GAAK,KAAOA,EAEX,MAAO,GAIR,MAAM6B,EAAoB3C,KAAKC,cAAe,mBAAoBa,OAG5D8B,EAA0BD,aAAiB,EAAjBA,EAAmB1C,cAAe,WAG5D4B,EAAmBe,aAAuB,EAAvBA,EAAyBnC,aAAc,eAGhE,OAAOoB,QAAAA,EAAoB,EAC5B,ECnJDgB,eAAeC,OAAQ,mBAAoBnD,GAC3CkD,eAAeC,OAAQ,cAAe/B,GACtC8B,eAAeC,OAAQ,cAAe9B,GACtC6B,eAAeC,OAAQ,UAAW7B,E","sources":["webpack://@travelopia/web-components/./src/tabs/tp-tabs-nav-item.ts","webpack://@travelopia/web-components/./src/tabs/tp-tabs-nav.ts","webpack://@travelopia/web-components/./src/tabs/tp-tabs-tab.ts","webpack://@travelopia/web-components/./src/tabs/tp-tabs.ts","webpack://@travelopia/web-components/./src/tabs/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPTabsElement } from './tp-tabs';\n\n/**\n * TP Tabs Nav Item Element.\n */\nexport class TPTabsNavItemElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Constructor function.\n\t\tsuper();\n\n\t\t// Find the anchor element within this component and add a click event listener.\n\t\tconst link: HTMLAnchorElement | null = this.querySelector( 'a' );\n\t\tlink?.addEventListener( 'click', this.handleLinkClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle link click.\n\t *\n\t * @param {Event} e Click event.\n\t *\n\t * @protected\n\t */\n\tprotected handleLinkClick( e: Event ): void {\n\t\t// Find the closest tp-tabs element and the anchor element within this component.\n\t\tconst tabs: TPTabsElement | null = this.closest( 'tp-tabs' );\n\t\tconst link: HTMLAnchorElement | null = this.querySelector( 'a' );\n\t\tconst anchor: string = link?.getAttribute( 'href' ) ?? '';\n\n\t\t// If the tabs component, link, or anchor is missing, do nothing.\n\t\tif ( ! tabs || ! link || '' === anchor ) {\n\t\t\t// Exit if the tabs component or the link is not found.\n\t\t\treturn;\n\t\t}\n\n\t\t// If the 'update-url' attribute is not set to 'yes', prevent the default link behavior.\n\t\tif ( 'yes' !== tabs.getAttribute( 'update-url' ) ) {\n\t\t\te.preventDefault();\n\t\t}\n\n\t\t// Update the 'current-tab' attribute on the tabs component with the anchor's ID.\n\t\ttabs.setAttribute( 'current-tab', anchor.replace( '#', '' ) );\n\t}\n\n\t/**\n\t * Check if this component contains the link to the current tab.\n\t *\n\t * @param {string} currentTab Current tab ID.\n\t *\n\t * @return {boolean} Whether it is the current tab or not.\n\t */\n\tisCurrentTab( currentTab: string = '' ): boolean {\n\t\t// Find the anchor element within this component.\n\t\tconst link: HTMLAnchorElement | null = this.querySelector( 'a' );\n\n\t\t// Return true if the anchor's href matches the current tab ID.\n\t\treturn `#${ currentTab }` === link?.getAttribute( 'href' );\n\t}\n}\n","/**\n * TP Tabs Nav Element.\n */\nexport class TPTabsNavElement extends HTMLElement {\n}\n","/**\n * TP Tabs Tab Element.\n */\nexport class TPTabsTabElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPTabsNavItemElement } from './tp-tabs-nav-item';\nimport { TPTabsTabElement } from './tp-tabs-tab';\n\n/**\n * TP Tabs.\n */\nexport class TPTabsElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Update the current tab based on the URL hash.\n\t\tthis.updateTabFromUrlHash();\n\n\t\t// Listen for hash changes in the URL and update the tab accordingly.\n\t\twindow.addEventListener( 'hashchange', this.updateTabFromUrlHash.bind( this ) );\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes observed in the TPTabsElement web-component.\n\t\treturn [ 'current-tab', 'update-url', 'overflow' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// If the attribute value hasn't changed, do nothing.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update the component whenever an observed attribute changes.\n\t\tthis.update();\n\n\t\t// If the 'current-tab' attribute has changed, dispatch a 'change' event.\n\t\tif ( 'current-tab' === name ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t\t}\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get current tab.\n\t\tconst currentTab: string = this.getAttribute( 'current-tab' ) ?? '';\n\n\t\t// Check if current tab exists.\n\t\tif ( ! this.querySelector( `tp-tabs-tab[id=\"${ currentTab }\"]` ) ) {\n\t\t\t// Exit if no matching tab is found.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current nested tab if has.\n\t\tconst currentNestedTab = this.getCurrentNestedTab( currentTab );\n\n\t\t// Update nav items.\n\t\tconst navItems: NodeListOf<TPTabsNavItemElement> = this.querySelectorAll( 'tp-tabs-nav-item' );\n\n\t\t// Update the navigation items based on the current tab.\n\t\tif ( navItems ) {\n\t\t\tnavItems.forEach( ( navItem: TPTabsNavItemElement ): void => {\n\t\t\t\t// If the nav item corresponds to the current tab or nested tab, set it as active.\n\t\t\t\tif ( navItem.isCurrentTab( currentTab ) || ( currentNestedTab && navItem.isCurrentTab( currentNestedTab ) ) ) {\n\t\t\t\t\tnavItem.setAttribute( 'active', 'yes' );\n\t\t\t\t} else {\n\t\t\t\t\tnavItem.removeAttribute( 'active' );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Update tabs.\n\t\tconst tabs: NodeListOf<TPTabsTabElement> = this.querySelectorAll( 'tp-tabs-tab' );\n\n\t\t// Update the tab panels based on the current tab.\n\t\tif ( tabs ) {\n\t\t\ttabs.forEach( ( tab: TPTabsTabElement ): void => {\n\t\t\t\t// If the tab corresponds to the current tab or nested tab, open it.\n\t\t\t\tif ( currentTab === tab.getAttribute( 'id' ) || ( currentNestedTab && currentNestedTab === tab.getAttribute( 'id' ) ) ) {\n\t\t\t\t\ttab.setAttribute( 'open', 'yes' );\n\t\t\t\t} else {\n\t\t\t\t\ttab.removeAttribute( 'open' );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Update tab from URL hash.\n\t */\n\tupdateTabFromUrlHash(): void {\n\t\t// If 'update-url' attribute is not set to 'yes', do nothing.\n\t\tif ( 'yes' !== this.getAttribute( 'update-url' ) ) {\n\t\t\t// Exit if the 'update-url' attribute is not enabled.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set current associated tab.\n\t\tthis.setCurrentTab();\n\t}\n\n\t/**\n\t * Set current tab.\n\t *\n\t * @param {string} tabId Tab ID.\n\t */\n\tsetCurrentTab( tabId: string = '' ): void {\n\t\t// If a tab ID is provided, set it as the current tab.\n\t\tif ( '' !== tabId ) {\n\t\t\tthis.setAttribute( 'current-tab', tabId );\n\t\t}\n\n\t\t// Set current tab based on current url hash.\n\t\tconst urlHash: string = window.location.hash;\n\n\t\t// Find the link that matches the URL hash.\n\t\tif ( '' !== urlHash ) {\n\t\t\tconst currentLink: HTMLAnchorElement | null = this.querySelector( `a[href=\"${ urlHash }\"]` );\n\t\t\tconst currentTab = currentLink?.closest( 'tp-tabs' );\n\t\t\tcurrentTab?.setAttribute( 'current-tab', urlHash.replace( '#', '' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Get current nested tab.\n\t *\n\t * @param {string} currentTab Tab ID.\n\t *\n\t * @return {string} If has Nested current tab or empty.\n\t */\n\tgetCurrentNestedTab( currentTab: string = '' ): string {\n\t\t// If no current tab is provided, return an empty string.\n\t\tif ( '' === currentTab ) {\n\t\t\t// Exit if no current tab is provided.\n\t\t\treturn '';\n\t\t}\n\n\t\t// Find the element corresponding to the current tab ID.\n\t\tconst currentTabElement = this.querySelector( `tp-tabs-tab[id=\"${ currentTab }\"]` );\n\n\t\t// Find the nested tp-tabs element within the current tab.\n\t\tconst currentNestedTabElement = currentTabElement?.querySelector( 'tp-tabs' );\n\n\t\t// Get the ID of the current nested tab, if any.\n\t\tconst currentNestedTab = currentNestedTabElement?.getAttribute( 'current-tab' );\n\n\t\t// Return the nested tab ID, or an empty string if none exists.\n\t\treturn currentNestedTab ?? '';\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPTabsNavItemElement } from './tp-tabs-nav-item';\nimport { TPTabsNavElement } from './tp-tabs-nav';\nimport { TPTabsTabElement } from './tp-tabs-tab';\nimport { TPTabsElement } from './tp-tabs';\n\n/**\n * Register Components.\n */\n\n// Register components.\ncustomElements.define( 'tp-tabs-nav-item', TPTabsNavItemElement );\ncustomElements.define( 'tp-tabs-nav', TPTabsNavElement );\ncustomElements.define( 'tp-tabs-tab', TPTabsTabElement );\ncustomElements.define( 'tp-tabs', TPTabsElement );\n"],"names":["TPTabsNavItemElement","HTMLElement","constructor","super","link","this","querySelector","addEventListener","handleLinkClick","bind","e","tabs","closest","anchor","getAttribute","preventDefault","setAttribute","replace","isCurrentTab","currentTab","TPTabsNavElement","TPTabsTabElement","TPTabsElement","updateTabFromUrlHash","window","observedAttributes","attributeChangedCallback","name","oldValue","newValue","update","dispatchEvent","CustomEvent","bubbles","currentNestedTab","getCurrentNestedTab","navItems","querySelectorAll","forEach","navItem","removeAttribute","tab","setCurrentTab","tabId","urlHash","location","hash","currentLink","currentTabElement","currentNestedTabElement","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/tabs/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/tabs/tp-tabs-nav-item.ts","webpack://@travelopia/web-components/./src/tabs/tp-tabs-nav.ts","webpack://@travelopia/web-components/./src/tabs/tp-tabs-tab.ts","webpack://@travelopia/web-components/./src/tabs/tp-tabs.ts","webpack://@travelopia/web-components/./src/tabs/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPTabsElement } from './tp-tabs';\n\n/**\n * TP Tabs Nav Item Element.\n */\nexport class TPTabsNavItemElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Constructor function.\n\t\tsuper();\n\n\t\t// Get the trigger element (button or anchor).\n\t\tconst trigger = this.getTrigger();\n\n\t\t// Add click event listener to the trigger.\n\t\ttrigger?.addEventListener( 'click', this.handleTriggerClick.bind( this ) );\n\n\t\t// Set up ARIA attributes.\n\t\tthis.setupAriaAttributes();\n\t}\n\n\t/**\n\t * Get the trigger element (button or anchor).\n\t *\n\t * @return {HTMLButtonElement | HTMLAnchorElement | null} The trigger element.\n\t */\n\tgetTrigger(): HTMLButtonElement | HTMLAnchorElement | null {\n\t\t// Look for button first, then anchor.\n\t\treturn this.querySelector( 'button' ) || this.querySelector( 'a' );\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// Observe the active attribute to update ARIA state.\n\t\treturn [ 'active' ];\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// Early return if no change.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// No change.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update ARIA state when active attribute changes.\n\t\tif ( 'active' === name ) {\n\t\t\tthis.updateAriaState( 'yes' === newValue );\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 tabs component.\n\t\tconst tabs: TPTabsElement | null = this.closest( 'tp-tabs' );\n\n\t\t// Return whether aria management is enabled.\n\t\treturn tabs?.isAriaEnabled() ?? true;\n\t}\n\n\t/**\n\t * Set up ARIA attributes on the trigger element.\n\t */\n\tprivate setupAriaAttributes(): 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 the trigger element.\n\t\tconst trigger = this.getTrigger();\n\n\t\t// Bail if no trigger.\n\t\tif ( ! trigger ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Generate ID for the trigger if not present.\n\t\tif ( ! trigger.id ) {\n\t\t\ttrigger.id = `tp-tab-${ Math.random().toString( 36 ).substring( 2, 9 ) }`;\n\t\t}\n\n\t\t// Get the panel ID from href (anchor) or aria-controls (button).\n\t\tconst panelId = this.getPanelId();\n\n\t\t// Set aria-controls if we have a panel ID and it's not already set.\n\t\tif ( panelId && ! trigger.hasAttribute( 'aria-controls' ) ) {\n\t\t\ttrigger.setAttribute( 'aria-controls', panelId );\n\t\t}\n\n\t\t// Set initial ARIA state.\n\t\tconst isActive = 'yes' === this.getAttribute( 'active' );\n\t\tthis.updateAriaState( isActive );\n\t}\n\n\t/**\n\t * Get the panel ID that this nav item controls.\n\t *\n\t * @return {string} The panel ID.\n\t */\n\tgetPanelId(): string {\n\t\t// Get the trigger.\n\t\tconst trigger = this.getTrigger();\n\n\t\t// Bail if no trigger.\n\t\tif ( ! trigger ) {\n\t\t\t// Bail.\n\t\t\treturn '';\n\t\t}\n\n\t\t// Check if trigger is a link.\n\t\tif ( trigger instanceof HTMLAnchorElement ) {\n\t\t\t// For anchors, get from href. For buttons, get from aria-controls or data-controls.\n\t\t\treturn trigger.getAttribute( 'href' )?.replace( '#', '' ) ?? '';\n\t\t}\n\n\t\t// For buttons, check aria-controls or data-controls.\n\t\treturn trigger.getAttribute( 'aria-controls' ) || trigger.getAttribute( 'data-controls' ) || '';\n\t}\n\n\t/**\n\t * Update ARIA state on the trigger element.\n\t *\n\t * @param {boolean} isActive Whether this tab is active.\n\t */\n\tprivate updateAriaState( isActive: 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 the trigger element.\n\t\tconst trigger = this.getTrigger();\n\n\t\t// Bail if no trigger.\n\t\tif ( ! trigger ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update aria-selected.\n\t\ttrigger.setAttribute( 'aria-selected', isActive ? 'true' : 'false' );\n\n\t\t// Update tabindex for roving tabindex pattern.\n\t\ttrigger.setAttribute( 'tabindex', isActive ? '0' : '-1' );\n\t}\n\n\t/**\n\t * Handle trigger click.\n\t *\n\t * @param {Event} e Click event.\n\t *\n\t * @protected\n\t */\n\tprotected handleTriggerClick( e: Event ): void {\n\t\t// Find the closest tp-tabs element.\n\t\tconst tabs: TPTabsElement | null = this.closest( 'tp-tabs' );\n\t\tconst trigger = this.getTrigger();\n\t\tconst panelId = this.getPanelId();\n\n\t\t// If the tabs component, trigger, or panel ID is missing, do nothing.\n\t\tif ( ! tabs || ! trigger || '' === panelId ) {\n\t\t\t// Exit if required elements are not found.\n\t\t\treturn;\n\t\t}\n\n\t\t// For anchors, prevent default if update-url is not enabled.\n\t\tif ( trigger instanceof HTMLAnchorElement && 'yes' !== tabs.getAttribute( 'update-url' ) ) {\n\t\t\te.preventDefault();\n\t\t}\n\n\t\t// Update the 'current-tab' attribute on the tabs component.\n\t\ttabs.setAttribute( 'current-tab', panelId );\n\t}\n\n\t/**\n\t * Check if this component contains the trigger for the current tab.\n\t *\n\t * @param {string} currentTab Current tab ID.\n\t *\n\t * @return {boolean} Whether it is the current tab or not.\n\t */\n\tisCurrentTab( currentTab: string = '' ): boolean {\n\t\t// Return true if this nav item's panel ID matches the current tab.\n\t\treturn currentTab === this.getPanelId();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPTabsElement } from './tp-tabs';\n\n/**\n * TP Tabs Nav Element.\n */\nexport class TPTabsNavElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add keyboard event listener for arrow key navigation.\n\t\tthis.addEventListener( 'keydown', this.handleKeyDown.bind( this ) );\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 tabs component.\n\t\tconst tabs: TPTabsElement | null = this.closest( 'tp-tabs' );\n\n\t\t// Return whether aria management is enabled.\n\t\treturn tabs?.isAriaEnabled() ?? true;\n\t}\n\n\t/**\n\t * Get all tab trigger elements (buttons or anchors).\n\t *\n\t * @return {Array<HTMLButtonElement | HTMLAnchorElement>} Array of trigger elements.\n\t */\n\tprivate getTabTriggers(): Array<HTMLButtonElement | HTMLAnchorElement> {\n\t\t// Get all nav items and collect their triggers.\n\t\tconst navItems = this.querySelectorAll( 'tp-tabs-nav-item' );\n\t\tconst triggers: Array<HTMLButtonElement | HTMLAnchorElement> = [];\n\n\t\t// Iterate over nav items to find triggers.\n\t\tnavItems.forEach( ( navItem ) => {\n\t\t\t// Look for button first, then anchor.\n\t\t\tconst trigger = navItem.querySelector( 'button' ) || navItem.querySelector( 'a' );\n\n\t\t\t// Add trigger to array if found.\n\t\t\tif ( trigger ) {\n\t\t\t\ttriggers.push( trigger );\n\t\t\t}\n\t\t} );\n\n\t\t// Return all triggers.\n\t\treturn triggers;\n\t}\n\n\t/**\n\t * Handle keydown events for keyboard navigation.\n\t *\n\t * @param {KeyboardEvent} e Keyboard event.\n\t */\n\tprivate handleKeyDown( e: KeyboardEvent ): void {\n\t\t// Only handle if aria management is enabled.\n\t\tif ( ! this.isAriaEnabled() ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get all tab triggers.\n\t\tconst triggers = this.getTabTriggers();\n\n\t\t// Bail if no triggers.\n\t\tif ( triggers.length === 0 ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find current focused trigger index using ownerDocument.\n\t\tconst currentIndex = triggers.findIndex( ( trigger ) => trigger === this.ownerDocument.activeElement );\n\n\t\t// Only handle if focus is on a trigger.\n\t\tif ( currentIndex === -1 ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get new index.\n\t\tlet newIndex = currentIndex;\n\n\t\t// Handle arrow keys, Home, and End.\n\t\tswitch ( e.key ) {\n\t\t\t// Move to previous tab, wrap to end if at start.\n\t\t\tcase 'ArrowLeft':\n\t\t\t\tnewIndex = currentIndex === 0 ? triggers.length - 1 : currentIndex - 1;\n\t\t\t\tbreak;\n\n\t\t\t// Move to next tab, wrap to start if at end.\n\t\t\tcase 'ArrowRight':\n\t\t\t\tnewIndex = currentIndex === triggers.length - 1 ? 0 : currentIndex + 1;\n\t\t\t\tbreak;\n\n\t\t\t// Move to first tab.\n\t\t\tcase 'Home':\n\t\t\t\tnewIndex = 0;\n\t\t\t\tbreak;\n\n\t\t\t// Move to last tab.\n\t\t\tcase 'End':\n\t\t\t\tnewIndex = triggers.length - 1;\n\t\t\t\tbreak;\n\n\t\t\t// Not a navigation key, bail.\n\t\t\tdefault:\n\n\t\t\t\t// Not a navigation key, bail.\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Prevent default browser behavior.\n\t\te.preventDefault();\n\n\t\t// Activate the new tab first (updates tabindex), then focus.\n\t\tconst newTrigger = triggers[ newIndex ];\n\t\tnewTrigger.click();\n\t\tnewTrigger.focus();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPTabsElement } from './tp-tabs';\n\n/**\n * TP Tabs Tab Element.\n */\nexport class TPTabsTabElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Set up ARIA attributes.\n\t\tthis.setupAriaAttributes();\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// Observe the open attribute to update ARIA state.\n\t\treturn [ 'open' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string, oldValue: string, newValue: string ): void {\n\t\t// Early return if no change.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// No change.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update ARIA state when open attribute changes.\n\t\tif ( 'open' === name ) {\n\t\t\tthis.updateAriaState( 'yes' === newValue );\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 tabs component.\n\t\tconst tabs: TPTabsElement | null = this.closest( 'tp-tabs' );\n\n\t\t// Return whether aria management is enabled.\n\t\treturn tabs?.isAriaEnabled() ?? true;\n\t}\n\n\t/**\n\t * Set up ARIA attributes on this tab panel.\n\t */\n\tprivate setupAriaAttributes(): 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 the panel ID.\n\t\tconst panelId = this.getAttribute( 'id' );\n\n\t\t// Find the corresponding tab trigger by matching href.\n\t\tif ( panelId ) {\n\t\t\tconst tabs: TPTabsElement | null = this.closest( 'tp-tabs' );\n\t\t\tconst trigger = tabs?.querySelector( `a[href=\"#${ panelId }\"]` );\n\n\t\t\t// Set aria-labelledby if trigger has an ID.\n\t\t\tif ( trigger?.id && ! this.hasAttribute( 'aria-labelledby' ) ) {\n\t\t\t\tthis.setAttribute( 'aria-labelledby', trigger.id );\n\t\t\t}\n\t\t}\n\n\t\t// Set initial ARIA state.\n\t\tconst isOpen = 'yes' === this.getAttribute( 'open' );\n\t\tthis.updateAriaState( isOpen );\n\t}\n\n\t/**\n\t * Update ARIA state on this tab panel.\n\t *\n\t * @param {boolean} isOpen Whether this panel 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// Update aria-hidden, inert, and tabindex based on open state.\n\t\tif ( isOpen ) {\n\t\t\tthis.removeAttribute( 'aria-hidden' );\n\t\t\tthis.removeAttribute( 'inert' );\n\t\t\tthis.setAttribute( 'tabindex', '0' );\n\t\t} else {\n\t\t\tthis.setAttribute( 'aria-hidden', 'true' );\n\t\t\tthis.setAttribute( 'inert', '' );\n\t\t\tthis.removeAttribute( 'tabindex' );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPTabsNavItemElement } from './tp-tabs-nav-item';\nimport { TPTabsTabElement } from './tp-tabs-tab';\n\n/**\n * TP Tabs.\n */\nexport class TPTabsElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Update the current tab based on the URL hash.\n\t\tthis.updateTabFromUrlHash();\n\n\t\t// Listen for hash changes in the URL and update the tab accordingly.\n\t\twindow.addEventListener( 'hashchange', this.updateTabFromUrlHash.bind( this ) );\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes observed in the TPTabsElement web-component.\n\t\treturn [ 'current-tab', 'update-url', 'overflow', 'aria' ];\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\tisAriaEnabled(): boolean {\n\t\t// Return whether aria management is enabled (default: yes).\n\t\treturn 'no' !== this.getAttribute( 'aria' );\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// If the attribute value hasn't changed, do nothing.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Update the component whenever an observed attribute changes.\n\t\tthis.update();\n\n\t\t// If the 'current-tab' attribute has changed, dispatch a 'change' event.\n\t\tif ( 'current-tab' === name ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t\t}\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get current tab.\n\t\tconst currentTab: string = this.getAttribute( 'current-tab' ) ?? '';\n\n\t\t// Check if current tab exists.\n\t\tif ( ! this.querySelector( `tp-tabs-tab[id=\"${ currentTab }\"]` ) ) {\n\t\t\t// Exit if no matching tab is found.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current nested tab if has.\n\t\tconst currentNestedTab = this.getCurrentNestedTab( currentTab );\n\n\t\t// Update nav items.\n\t\tconst navItems: NodeListOf<TPTabsNavItemElement> = this.querySelectorAll( 'tp-tabs-nav-item' );\n\n\t\t// Update the navigation items based on the current tab.\n\t\tif ( navItems ) {\n\t\t\tnavItems.forEach( ( navItem: TPTabsNavItemElement ): void => {\n\t\t\t\t// If the nav item corresponds to the current tab or nested tab, set it as active.\n\t\t\t\tif ( navItem.isCurrentTab( currentTab ) || ( currentNestedTab && navItem.isCurrentTab( currentNestedTab ) ) ) {\n\t\t\t\t\tnavItem.setAttribute( 'active', 'yes' );\n\t\t\t\t} else {\n\t\t\t\t\tnavItem.removeAttribute( 'active' );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Update tabs.\n\t\tconst tabs: NodeListOf<TPTabsTabElement> = this.querySelectorAll( 'tp-tabs-tab' );\n\n\t\t// Update the tab panels based on the current tab.\n\t\tif ( tabs ) {\n\t\t\ttabs.forEach( ( tab: TPTabsTabElement ): void => {\n\t\t\t\t// If the tab corresponds to the current tab or nested tab, open it.\n\t\t\t\tif ( currentTab === tab.getAttribute( 'id' ) || ( currentNestedTab && currentNestedTab === tab.getAttribute( 'id' ) ) ) {\n\t\t\t\t\ttab.setAttribute( 'open', 'yes' );\n\t\t\t\t} else {\n\t\t\t\t\ttab.removeAttribute( 'open' );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Update tab from URL hash.\n\t */\n\tupdateTabFromUrlHash(): void {\n\t\t// If 'update-url' attribute is not set to 'yes', do nothing.\n\t\tif ( 'yes' !== this.getAttribute( 'update-url' ) ) {\n\t\t\t// Exit if the 'update-url' attribute is not enabled.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set current associated tab.\n\t\tthis.setCurrentTab();\n\t}\n\n\t/**\n\t * Set current tab.\n\t *\n\t * @param {string} tabId Tab ID.\n\t */\n\tsetCurrentTab( tabId: string = '' ): void {\n\t\t// If a tab ID is provided, set it as the current tab.\n\t\tif ( '' !== tabId ) {\n\t\t\tthis.setAttribute( 'current-tab', tabId );\n\t\t}\n\n\t\t// Set current tab based on current url hash.\n\t\tconst urlHash: string = window.location.hash;\n\n\t\t// Find the link that matches the URL hash.\n\t\tif ( '' !== urlHash ) {\n\t\t\tconst currentLink: HTMLAnchorElement | null = this.querySelector( `a[href=\"${ urlHash }\"]` );\n\t\t\tconst currentTab = currentLink?.closest( 'tp-tabs' );\n\t\t\tcurrentTab?.setAttribute( 'current-tab', urlHash.replace( '#', '' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Get current nested tab.\n\t *\n\t * @param {string} currentTab Tab ID.\n\t *\n\t * @return {string} If has Nested current tab or empty.\n\t */\n\tgetCurrentNestedTab( currentTab: string = '' ): string {\n\t\t// If no current tab is provided, return an empty string.\n\t\tif ( '' === currentTab ) {\n\t\t\t// Exit if no current tab is provided.\n\t\t\treturn '';\n\t\t}\n\n\t\t// Find the element corresponding to the current tab ID.\n\t\tconst currentTabElement = this.querySelector( `tp-tabs-tab[id=\"${ currentTab }\"]` );\n\n\t\t// Find the nested tp-tabs element within the current tab.\n\t\tconst currentNestedTabElement = currentTabElement?.querySelector( 'tp-tabs' );\n\n\t\t// Get the ID of the current nested tab, if any.\n\t\tconst currentNestedTab = currentNestedTabElement?.getAttribute( 'current-tab' );\n\n\t\t// Return the nested tab ID, or an empty string if none exists.\n\t\treturn currentNestedTab ?? '';\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPTabsNavItemElement } from './tp-tabs-nav-item';\nimport { TPTabsNavElement } from './tp-tabs-nav';\nimport { TPTabsTabElement } from './tp-tabs-tab';\nimport { TPTabsElement } from './tp-tabs';\n\n/**\n * Register Components.\n */\n\n// Register parent first so children can find it during their constructor.\ncustomElements.define( 'tp-tabs', TPTabsElement );\ncustomElements.define( 'tp-tabs-nav', TPTabsNavElement );\ncustomElements.define( 'tp-tabs-nav-item', TPTabsNavItemElement );\ncustomElements.define( 'tp-tabs-tab', TPTabsTabElement );\n"],"names":["TPTabsNavItemElement","HTMLElement","constructor","super","trigger","this","getTrigger","addEventListener","handleTriggerClick","bind","setupAriaAttributes","querySelector","observedAttributes","attributeChangedCallback","name","oldValue","newValue","updateAriaState","isAriaEnabled","tabs","closest","id","Math","random","toString","substring","panelId","getPanelId","hasAttribute","setAttribute","isActive","getAttribute","HTMLAnchorElement","replace","e","preventDefault","isCurrentTab","currentTab","TPTabsNavElement","handleKeyDown","getTabTriggers","navItems","querySelectorAll","triggers","forEach","navItem","push","length","currentIndex","findIndex","ownerDocument","activeElement","newIndex","key","newTrigger","click","focus","TPTabsTabElement","isOpen","removeAttribute","TPTabsElement","updateTabFromUrlHash","window","update","dispatchEvent","CustomEvent","bubbles","currentNestedTab","getCurrentNestedTab","tab","setCurrentTab","tabId","urlHash","location","hash","currentLink","currentTabElement","currentNestedTabElement","customElements","define"],"sourceRoot":""}
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.trigger=null,this.makePopover()}get offset(){var t;return parseInt(null!==(t=this.getAttribute("offset"))&&void 0!==t?t:"0")}set offset(t){t?this.setAttribute("offset",t.toString()):this.removeAttribute("offset")}makePopover(){this.getAttribute("popover")||this.setAttribute("popover","")}setTrigger(t){this.trigger=t}setContent(){var t,e,i;const o=null!==(e=null===(t=this.trigger)||void 0===t?void 0:t.getContent())&&void 0!==e?e:null;o&&(null===(i=this.querySelector("slot"))||void 0===i||i.replaceChildren(o))}setPosition(){if(!this.trigger)return;const{height:t,width:e}=this.getBoundingClientRect(),{x:i,y:o,width:s,height:n}=this.trigger.getBoundingClientRect(),r=i+s/2;let l=0;const h=this.querySelector("tp-tooltip-arrow");h&&({height:l}=h.getBoundingClientRect()),o>t+this.offset+l?(this.style.marginTop=o-t-this.offset-l/2+"px",null==h||h.setAttribute("position","bottom")):(this.style.marginTop=`${o+n+this.offset+l/2}px`,null==h||h.setAttribute("position","top")),r<e/2?this.style.marginLeft="0px":window.innerWidth-r<e/2?this.style.marginLeft=window.innerWidth-e+"px":this.style.marginLeft=i+s/2-e/2+"px";const{left:u}=this.getBoundingClientRect(),d=(r-u)/e*100;h&&(h.style.left=`${d}%`)}show(){this.setContent(),this.showPopover(),this.setPosition(),this.setAttribute("show","yes"),this.dispatchEvent(new CustomEvent("show"))}hide(){this.hidePopover(),this.removeAttribute("show"),this.dispatchEvent(new CustomEvent("hide"))}}class e extends HTMLElement{constructor(){super(),navigator.maxTouchPoints>0?this.addEventListener("click",this.toggleTooltip.bind(this)):(this.addEventListener("mouseenter",this.showTooltip.bind(this)),this.addEventListener("mouseleave",this.hideTooltip.bind(this))),window.addEventListener("scroll",this.handleWindowScroll.bind(this),!0)}toggleTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";if(""===e)return;const i=document.querySelector(`#${e}`);"yes"===(null==i?void 0:i.getAttribute("show"))?null==i||i.hide():(null==i||i.setTrigger(this),null==i||i.show())}showTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";if(""===e)return;const i=document.querySelector(`#${e}`);null==i||i.setTrigger(this),null==i||i.show()}hideTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";if(""===e)return;const i=document.querySelector(`#${e}`);null==i||i.hide()}getContent(){const t=this.querySelector("template");return t?t.content.cloneNode(!0):null}handleWindowScroll(t){var e;const i=null!==(e=this.getAttribute("tooltip"))&&void 0!==e?e:"",o=document.querySelector(`#${i}`);t.target!==o&&this.hideTooltip()}}class i extends HTMLElement{}customElements.define("tp-tooltip",t),customElements.define("tp-tooltip-trigger",e),customElements.define("tp-tooltip-arrow",i)})();
1
+ (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.trigger=null,this.makePopover()}connectedCallback(){this.setupAria()}isAriaEnabled(){return"no"!==this.getAttribute("aria")}setupAria(){this.isAriaEnabled()&&(this.id||(this.id=`tp-tooltip-${crypto.randomUUID()}`),this.hasAttribute("role")||this.setAttribute("role","tooltip"))}get offset(){var t;return parseInt(null!==(t=this.getAttribute("offset"))&&void 0!==t?t:"0")}set offset(t){t?this.setAttribute("offset",t.toString()):this.removeAttribute("offset")}makePopover(){this.getAttribute("popover")||this.setAttribute("popover","")}setTrigger(t){this.trigger=t}setContent(){var t,e,i;const o=null!==(e=null===(t=this.trigger)||void 0===t?void 0:t.getContent())&&void 0!==e?e:null;o&&(null===(i=this.querySelector("slot"))||void 0===i||i.replaceChildren(o))}setPosition(){if(!this.trigger)return;const{height:t,width:e}=this.getBoundingClientRect(),{x:i,y:o,width:s,height:n}=this.trigger.getBoundingClientRect(),r=i+s/2;let l=0;const h=this.querySelector("tp-tooltip-arrow");h&&({height:l}=h.getBoundingClientRect()),o>t+this.offset+l?(this.style.marginTop=o-t-this.offset-l/2+"px",null==h||h.setAttribute("position","bottom")):(this.style.marginTop=`${o+n+this.offset+l/2}px`,null==h||h.setAttribute("position","top")),r<e/2?this.style.marginLeft="0px":window.innerWidth-r<e/2?this.style.marginLeft=window.innerWidth-e+"px":this.style.marginLeft=i+s/2-e/2+"px";const{left:u}=this.getBoundingClientRect(),d=(r-u)/e*100;h&&(h.style.left=`${d}%`)}show(){this.setContent(),this.showPopover(),this.setPosition(),this.setAttribute("show","yes"),this.dispatchEvent(new CustomEvent("show"))}hide(){this.hidePopover(),this.removeAttribute("show"),this.dispatchEvent(new CustomEvent("hide"))}}class e extends HTMLElement{constructor(){super(),navigator.maxTouchPoints>0?this.addEventListener("click",this.toggleTooltip.bind(this)):(this.addEventListener("mouseenter",this.showTooltip.bind(this)),this.addEventListener("mouseleave",this.hideTooltip.bind(this))),this.addEventListener("focusin",this.showTooltip.bind(this)),this.addEventListener("focusout",this.hideTooltip.bind(this)),this.addEventListener("keydown",this.handleKeyDown.bind(this)),window.addEventListener("scroll",this.handleWindowScroll.bind(this),!0)}connectedCallback(){this.setupAria()}isAriaEnabled(){const t=this.getTooltip();return"no"!==(null==t?void 0:t.getAttribute("aria"))}getTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";return""===e?null:document.querySelector(`#${e}`)}getTriggerElement(){return this.querySelector("a, button, [tabindex]")}setupAria(){if(!this.isAriaEnabled())return;const t=this.getTooltip(),e=this.getTriggerElement();t&&e&&!e.hasAttribute("aria-describedby")&&e.setAttribute("aria-describedby",t.id)}handleKeyDown(t){"Escape"===t.key&&this.hideTooltip()}toggleTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";if(""===e)return;const i=document.querySelector(`#${e}`);"yes"===(null==i?void 0:i.getAttribute("show"))?null==i||i.hide():(null==i||i.setTrigger(this),null==i||i.show())}showTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";if(""===e)return;const i=document.querySelector(`#${e}`);null==i||i.setTrigger(this),null==i||i.show()}hideTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";if(""===e)return;const i=document.querySelector(`#${e}`);null==i||i.hide()}getContent(){const t=this.querySelector("template");return t?t.content.cloneNode(!0):null}handleWindowScroll(t){var e;const i=null!==(e=this.getAttribute("tooltip"))&&void 0!==e?e:"",o=document.querySelector(`#${i}`);t.target!==o&&this.hideTooltip()}}class i extends HTMLElement{}customElements.define("tp-tooltip",t),customElements.define("tp-tooltip-trigger",e),customElements.define("tp-tooltip-arrow",i)})();
2
2
  //# sourceMappingURL=index.js.map