@travelopia/web-components 0.9.11 → 0.9.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"dist/slider/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/slider/tp-slider.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-track.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-slides.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-slide.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-arrow.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-nav.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-nav-item.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-count.ts","webpack://@travelopia/web-components/./src/slider/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPSliderSlidesElement } from './tp-slider-slides';\nimport { TPSliderSlideElement } from './tp-slider-slide';\nimport { TPSliderCountElement } from './tp-slider-count';\nimport { TPSliderNavElement } from './tp-slider-nav';\nimport { TPSliderNavItemElement } from './tp-slider-nav-item';\nimport { TPSliderArrowElement } from './tp-slider-arrow';\n\n/**\n * TP Slider.\n */\nexport class TPSliderElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected touchStartX: number = 0;\n\tprotected touchStartY: number = 0;\n\tprotected swipeThreshold: number = 200;\n\tprotected responsiveSettings: { [ key: string ]: any };\n\tprotected allowedResponsiveKeys: string[] = [\n\t\t'flexible-height',\n\t\t'infinite',\n\t\t'swipe',\n\t\t'behaviour',\n\t\t'auto-slide-interval',\n\t\t'per-view',\n\t\t'step',\n\t\t'responsive',\n\t];\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Set current slide.\n\t\tif ( ! this.getAttribute( 'current-slide' ) ) {\n\t\t\tthis.setAttribute( 'current-slide', '1' );\n\t\t}\n\n\t\t// Threshold Setting.\n\t\tthis.swipeThreshold = Number( this?.getAttribute( 'swipe-threshold' ) ?? '200' );\n\n\t\t// Initialize slider.\n\t\tthis.slide();\n\t\tthis.autoSlide();\n\t\tthis.setAttribute( 'initialized', 'yes' );\n\n\t\t// Responsive Settings.\n\t\tconst responsiveSettingsJSON: string = this.getAttribute( 'responsive' ) || '';\n\t\tthis.responsiveSettings = responsiveSettingsJSON ? JSON.parse( responsiveSettingsJSON ) : [];\n\n\t\t// Event listeners.\n\t\tif ( ! ( 'ResizeObserver' in window ) ) {\n\t\t\t/**\n\t\t\t * We set the resize observer in `tp-slider-slides`\n\t\t\t * because These are just fallbacks for browsers that don't support ResizeObserver.\n\t\t\t */\n\n\t\t\t// @ts-ignore\n\t\t\twindow.addEventListener( 'resize', this.handleResize.bind( this ) );\n\t\t\tdocument.fonts.ready.then( () => this.handleResize() );\n\t\t}\n\n\t\t// Touch listeners.\n\t\tthis.addEventListener( 'touchstart', this.handleTouchStart.bind( this ), { passive: true } );\n\t\tthis.addEventListener( 'touchend', this.handleTouchEnd.bind( this ) );\n\n\t\t// Keyboard listener for arrow key navigation.\n\t\tthis.addEventListener( 'keydown', this.handleKeyDown.bind( this ) );\n\t}\n\n\t/**\n\t * Handle keydown events for arrow key navigation.\n\t *\n\t * @param {KeyboardEvent} e Keyboard event.\n\t */\n\tprotected handleKeyDown( e: KeyboardEvent ): void {\n\t\t// Only handle if arrow-navigation is enabled (disabled by default).\n\t\tif ( 'yes' !== this.getAttribute( 'arrow-navigation' ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Only handle arrow keys.\n\t\tif ( 'ArrowLeft' !== e.key && 'ArrowRight' !== e.key ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prevent default scrolling behavior.\n\t\te.preventDefault();\n\n\t\t// Navigate based on arrow direction.\n\t\tif ( 'ArrowLeft' === e.key ) {\n\t\t\tthis.previous();\n\t\t} else if ( 'ArrowRight' === e.key ) {\n\t\t\tthis.next();\n\t\t}\n\t}\n\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback() {\n\t\t/**\n\t\t * Update on initial render.\n\t\t *\n\t\t * This is so that the disabled values of the navigation arrows\n\t\t * can be set because attributeChangedCallback does not get fired when\n\t\t * no attributes are passed to the slider.\n\t\t */\n\t\tthis.update();\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// Observed attributes.\n\t\treturn [ 'current-slide', 'flexible-height', 'infinite', 'swipe', 'per-view', 'step' ];\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// Keep an eye on current slide.\n\t\tif ( 'current-slide' === name && oldValue !== newValue ) {\n\t\t\tthis.slide();\n\t\t\tthis.dispatchEvent( new CustomEvent( 'slide-complete', { bubbles: true } ) );\n\t\t}\n\n\t\t// Update the component after the attribute change.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Get current slide index.\n\t *\n\t * @return {number} Current slide index.\n\t */\n\tget currentSlideIndex(): number {\n\t\t// To get the current slide index.\n\t\treturn parseInt( this.getAttribute( 'current-slide' ) ?? '1' );\n\t}\n\n\t/**\n\t * Set current slide index.\n\t *\n\t * @param {number} index Slide index.\n\t */\n\tset currentSlideIndex( index: number ) {\n\t\t// Set the current slide index.\n\t\tthis.setCurrentSlide( index );\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// To get the current step.\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 Step.\n\t */\n\tset step( step: number ) {\n\t\t// Set the current step.\n\t\tthis.setAttribute( 'step', step.toString() );\n\t}\n\n\t/**\n\t * Get per view.\n\t *\n\t * @return {number} Current step.\n\t */\n\tget perView(): number {\n\t\t// To get number of slides per view.\n\t\treturn parseInt( this.getAttribute( 'per-view' ) ?? '1' );\n\t}\n\n\t/**\n\t * Set per view.\n\t *\n\t * @param {number} perView Per view.\n\t */\n\tset perView( perView: number ) {\n\t\t// Set the number of slides per view.\n\t\tthis.setAttribute( 'per-view', perView.toString() );\n\t}\n\n\t/**\n\t * Get total number of slides.\n\t *\n\t * @return {number} Total slides.\n\t */\n\tgetTotalSlides(): number {\n\t\t// To get the total number of slides.\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = this.getSlideElements();\n\n\t\t// Check if slides are available.\n\t\tif ( slides ) {\n\t\t\t// Tell the total number of slides.\n\t\t\treturn slides.length;\n\t\t}\n\n\t\t// Else return 0.\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Get Slide Elements.\n\t */\n\tgetSlideElements() {\n\t\t// Get slides.\n\t\tconst slidesElement: TPSliderSlidesElement | null = this.querySelector( 'tp-slider-slides' );\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = slidesElement?.querySelectorAll( ':scope > tp-slider-slide' );\n\n\t\t// Return array of slides.\n\t\treturn slides;\n\t}\n\n\t/**\n\t * Navigate to the next slide.\n\t */\n\tnext(): void {\n\t\t// Initialize total slides variable.\n\t\tconst totalSlides: number = this.getTotalSlides();\n\n\t\t// Check if we are at the last slide considering per view attribute.\n\t\tif ( this.currentSlideIndex >= totalSlides - this.perView + 1 ) {\n\t\t\t// Check if we are in infinite mode.\n\t\t\tif ( 'yes' === this.getAttribute( 'infinite' ) ) {\n\t\t\t\t// Yes, we are, and go back to first slide.\n\t\t\t\tthis.setCurrentSlide( 1 );\n\t\t\t}\n\n\t\t\t// Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get next slide index by adding minimum of step or remaining number of slides.\n\t\tconst nextSlideIndex: number = Math.min( this.currentSlideIndex + this.step, totalSlides - this.perView + 1 );\n\n\t\t// Check if the next slide step is not taking it beyond the last slide.\n\t\tif ( nextSlideIndex > ( totalSlides - this.perView + 1 ) ) {\n\t\t\t// Yes, it is.\n\t\t\treturn;\n\t\t}\n\n\t\t// Everything is good, go to next slide.\n\t\tthis.setCurrentSlide( nextSlideIndex );\n\t}\n\n\t/**\n\t * Navigate to the previous slide.\n\t */\n\tprevious(): void {\n\t\t// Check if we are at the first slide.\n\t\tif ( this.currentSlideIndex <= 1 ) {\n\t\t\t// Check if we are in infinite mode.\n\t\t\tif ( 'yes' === this.getAttribute( 'infinite' ) ) {\n\t\t\t\tthis.setCurrentSlide( this.getTotalSlides() - this.perView + 1 );\n\t\t\t}\n\n\t\t\t// Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize total slides variable.\n\t\tconst totalSlides: number = this.getTotalSlides();\n\n\t\t// Total Possible groups.\n\t\tconst totalPossibleGroups: number = Math.ceil( totalSlides / this.step );\n\n\t\t// Initialize previous slide number.\n\t\tlet previousSlideNumber: number = 0;\n\n\t\t// Checking if total slides are not divisible by step.\n\t\tif ( totalSlides / this.step !== Math.round( totalSlides / this.step ) ) {\n\t\t\t// Initialize current group.\n\t\t\tlet currentGroup: number;\n\n\t\t\t// Check if we are in the last group or in any other.\n\t\t\tif ( this.currentSlideIndex + this.step - 1 >= totalSlides ) {\n\t\t\t\tcurrentGroup = totalPossibleGroups;\n\t\t\t} else {\n\t\t\t\tcurrentGroup = Math.ceil( this.currentSlideIndex / this.step );\n\t\t\t}\n\n\t\t\t// Update previous slide number based on which group we are in.\n\t\t\tif ( currentGroup === totalPossibleGroups ) {\n\t\t\t\tpreviousSlideNumber = this.currentSlideIndex - this.step + 1;\n\t\t\t} else {\n\t\t\t\tpreviousSlideNumber = this.currentSlideIndex - this.step;\n\t\t\t}\n\t\t} else {\n\t\t\t// Check if we are in the last group.\n\t\t\tpreviousSlideNumber = this.currentSlideIndex - this.step;\n\t\t}\n\n\t\t// Check if the previous slide step is not taking it beyond the first slide.\n\t\tif ( previousSlideNumber > 1 ) {\n\t\t\tthis.setCurrentSlide( previousSlideNumber );\n\t\t} else {\n\t\t\tthis.setCurrentSlide( 1 );\n\t\t}\n\t}\n\n\t/**\n\t * Get current slide index.\n\t *\n\t * @return {number} Current slide index.\n\t */\n\tgetCurrentSlide(): number {\n\t\t// Get current slide index.\n\t\treturn this.currentSlideIndex;\n\t}\n\n\t/**\n\t * Set the current slide index.\n\t *\n\t * @param {number} index Slide index.\n\t */\n\tsetCurrentSlide( index: number ): void {\n\t\t// Check if slide index is valid.\n\t\tif ( index > this.getTotalSlides() || index <= 0 ) {\n\t\t\t// Stop! It's not valid.\n\t\t\treturn;\n\t\t}\n\n\t\t// dispatch slide-set event.\n\t\tthis.dispatchEvent( new CustomEvent( 'slide-set', {\n\t\t\tbubbles: true,\n\t\t\tdetail: {\n\t\t\t\tslideIndex: index,\n\t\t\t},\n\t\t} ) );\n\n\t\t// Set current slide index.\n\t\tthis.setAttribute( 'current-slide', index.toString() );\n\t}\n\n\t/**\n\t * Slide to the current slide.\n\t *\n\t * @protected\n\t */\n\tprotected slide(): void {\n\t\t// Check if slider is disabled.\n\t\tif ( 'yes' === this.getAttribute( 'disabled' ) ) {\n\t\t\t// Yes, it is. So stop.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get slides.\n\t\tconst slidesContainer: TPSliderSlidesElement | null = this.querySelector( 'tp-slider-slides' );\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = this.getSlideElements();\n\n\t\t// Check if we have slide container and slides.\n\t\tif ( ! slidesContainer || ! slides ) {\n\t\t\t// No, we don't. Either one of them or both are missing. So stop.\n\t\t\treturn;\n\t\t}\n\n\t\t// First, update the height.\n\n\t\t// Yield to main thread to fix a bug in Safari 16.\n\t\tsetTimeout( () => this.updateHeight(), 0 );\n\n\t\t// Now lets slide!\n\t\tconst behaviour: string = this.getAttribute( 'behaviour' ) || '';\n\n\t\t// Check if behaviour is set to fade and slide on the current slide index is present in the slides array.\n\t\tif ( 'fade' !== behaviour && slides[ this.currentSlideIndex - 1 ] ) {\n\t\t\t// Yes, it is. So slide to the current slide.\n\t\t\tslidesContainer.style.left = `-${ slides[ this.currentSlideIndex - 1 ].offsetLeft }px`;\n\t\t}\n\t}\n\n\t/**\n\t * Get the arrow element by selector.\n\t *\n\t * In case of nested sliders, it difficult to find the correct arrow\n\t * because arrows can be placed anywhere.\n\t * This function checks if the parent tp-slider belongs to this component,\n\t * then return that arrow element, using 'this'.\n\t *\n\t * @param {string} selector Selector.\n\t */\n\tgetArrow( selector: string ) {\n\t\t// Get all arrows.\n\t\tconst arrows: NodeListOf<TPSliderArrowElement> | null = this.querySelectorAll( selector );\n\t\tconst parentSliderElement: TPSliderElement = this;\n\t\tlet theArrow: TPSliderArrowElement | null = this.querySelector( selector );\n\n\t\t// Loop through all the arrows including the one's inside nested slider.\n\t\tarrows.forEach( ( arrow ) => {\n\t\t\t/**\n\t\t\t * If the closest tp-slider is the same as the parentSliderElement, that means we have found\n\t\t\t * the correct arrow.\n\t\t\t */\n\t\t\tif ( parentSliderElement === arrow.closest( 'tp-slider' ) ) {\n\t\t\t\ttheArrow = arrow;\n\t\t\t}\n\t\t} );\n\n\t\t// Return arrow.\n\t\treturn theArrow;\n\t}\n\n\t/**\n\t * Update stuff when any attribute has changed.\n\t * Example: Update sub-components.\n\t */\n\tasync update(): Promise<void> {\n\t\t// Get sub-components.\n\t\tconst sliderNav: TPSliderNavElement | null = this.querySelector( 'tp-slider-nav' );\n\t\tconst sliderCounts: NodeListOf<TPSliderCountElement> | null = this.querySelectorAll( 'tp-slider-count' );\n\t\tconst leftArrow: TPSliderArrowElement | null = this.getArrow( 'tp-slider-arrow[direction=\"previous\"]' );\n\t\tconst rightArrow: TPSliderArrowElement | null = this.getArrow( 'tp-slider-arrow[direction=\"next\"]' );\n\n\t\t// Wait for initialization - done to avoid updateNavItems undefined error.\n\t\tawait customElements.whenDefined( 'tp-slider-nav' );\n\t\tawait customElements.whenDefined( 'tp-slider-nav-item' );\n\t\tawait customElements.whenDefined( 'tp-slider-count' );\n\t\tawait customElements.whenDefined( 'tp-slider-arrow' );\n\n\t\t// Total slides variable and Total possible group.\n\t\tconst totalSlides: number = this.getTotalSlides();\n\t\tconst totalPossibleGroups: number = Math.ceil( totalSlides / this.step );\n\n\t\t// Set active slide.\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = this.getSlideElements();\n\n\t\t// Check if slides are available.\n\t\tif ( slides ) {\n\t\t\t// Check if aria management is enabled (default: yes).\n\t\t\tconst manageAria = 'no' !== this.getAttribute( 'aria' );\n\n\t\t\t// Calculate visible slide range (0-indexed).\n\t\t\tconst firstVisibleIndex = this.currentSlideIndex - 1;\n\t\t\tconst lastVisibleIndex = firstVisibleIndex + this.perView - 1;\n\n\t\t\t// Traverse slides.\n\t\t\tslides.forEach( ( slide: TPSliderSlideElement, index: number ): void => {\n\t\t\t\t// Update active attribute.\n\t\t\t\tif ( this.currentSlideIndex - 1 === index ) {\n\t\t\t\t\tslide.setAttribute( 'active', 'yes' );\n\t\t\t\t} else {\n\t\t\t\t\tslide.removeAttribute( 'active' );\n\t\t\t\t}\n\n\t\t\t\t// Update aria-hidden and inert for non-visible slides.\n\t\t\t\tif ( manageAria ) {\n\t\t\t\t\t// Check index.\n\t\t\t\t\tif ( index >= firstVisibleIndex && index <= lastVisibleIndex ) {\n\t\t\t\t\t\tslide.removeAttribute( 'aria-hidden' );\n\t\t\t\t\t\tslide.removeAttribute( 'inert' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tslide.setAttribute( 'aria-hidden', 'true' );\n\t\t\t\t\t\tslide.setAttribute( 'inert', '' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// First, set the template for the slider nav.\n\t\tsliderNav?.updateNavItems();\n\n\t\t// Once the template has been set, query the slider nav items.\n\t\tconst sliderNavItems: NodeListOf<TPSliderNavItemElement> | null = this.querySelectorAll( 'tp-slider-nav-item' );\n\n\t\t// Set current slider nav item.\n\t\tif ( sliderNavItems ) {\n\t\t\t// Add current attribute.\n\t\t\tsliderNavItems.forEach( ( navItem: TPSliderNavItemElement, index: number, allItems: NodeListOf<TPSliderNavItemElement> ): void => {\n\t\t\t\t// Remove current attribute.\n\t\t\t\tnavItem.removeAttribute( 'current' );\n\n\t\t\t\t// Get Round of Index.\n\t\t\t\tconst groupIndex = Math.round( ( this.currentSlideIndex - 1 ) / this.step );\n\n\t\t\t\t// Check if index and groups are equal to update active dot.\n\t\t\t\tif ( groupIndex === index ) {\n\t\t\t\t\tnavItem.setAttribute( 'current', 'yes' );\n\t\t\t\t} else if ( ( index === totalPossibleGroups - 1 && this.currentSlideIndex + this.step - 1 >= totalSlides ) ) {\n\t\t\t\t\tnavItem.setAttribute( 'current', 'yes' );\n\n\t\t\t\t\t// Remove current index from last 2nd item.\n\t\t\t\t\tallItems[ index - 1 ]?.removeAttribute( 'current' );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Update slider count.\n\t\tif ( sliderCounts ) {\n\t\t\t// Set total attribute.\n\t\t\tthis.setAttribute( 'total', this.getTotalSlides().toString() );\n\n\t\t\t// Update slider counts.\n\t\t\tsliderCounts.forEach( ( slideCount: TPSliderCountElement ) => {\n\t\t\t\t// Check if the slideCount.update is a function.\n\t\t\t\tif ( 'function' === typeof slideCount.update ) {\n\t\t\t\t\t// Update slide count.\n\t\t\t\t\tslideCount.update();\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Enable / disable arrows.\n\t\tif ( 'yes' !== this.getAttribute( 'infinite' ) ) {\n\t\t\t// For the last slide.\n\t\t\tif ( this.getCurrentSlide() === this.getTotalSlides() - this.perView + 1 ) {\n\t\t\t\trightArrow?.setAttribute( 'disabled', 'yes' );\n\t\t\t} else {\n\t\t\t\trightArrow?.removeAttribute( 'disabled' );\n\t\t\t}\n\n\t\t\t// For the first slide.\n\t\t\tif ( 1 === this.getCurrentSlide() ) {\n\t\t\t\tleftArrow?.setAttribute( 'disabled', 'yes' );\n\t\t\t} else {\n\t\t\t\tleftArrow?.removeAttribute( 'disabled' );\n\t\t\t}\n\t\t} else {\n\t\t\trightArrow?.removeAttribute( 'disabled' );\n\t\t\tleftArrow?.removeAttribute( 'disabled' );\n\t\t}\n\t}\n\n\t/**\n\t * Update the height of the slider based on current slide.\n\t */\n\tupdateHeight(): void {\n\t\t// Get slides container to resize.\n\t\tconst slidesContainer: TPSliderSlidesElement | null = this.querySelector( 'tp-slider-slides' );\n\n\t\t// Check if slides container is available.\n\t\tif ( ! slidesContainer ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Bail early if we don't want it to be flexible height - as long as it doesn't fade.\n\t\tif ( 'yes' !== this.getAttribute( 'flexible-height' ) && 'fade' !== this.getAttribute( 'behaviour' ) ) {\n\t\t\t// Remove height property for good measure!\n\t\t\tslidesContainer.style.removeProperty( 'height' );\n\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get slides.\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = this.getSlideElements();\n\n\t\t// Check if slides are available.\n\t\tif ( ! slides ) {\n\t\t\t// No slides to resize.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have a flexible height.\n\t\tif ( 'yes' === this.getAttribute( 'flexible-height' ) ) {\n\t\t\t// Check if per-view is greater than 1.\n\t\t\tif ( this.perView > 1 ) {\n\t\t\t\tconst currentIndex: number = this.currentSlideIndex - 1;\n\t\t\t\tconst slidesOnCurrentView: number = currentIndex + this.perView;\n\t\t\t\tlet maxHeight: number = 0;\n\n\t\t\t\t// Traverse all slides in the current view and add their height to the array.\n\t\t\t\tfor ( let i: number = currentIndex; i < slidesOnCurrentView; i++ ) {\n\t\t\t\t\t// Check if the slide exists.\n\t\t\t\t\tif ( slides[ i ].scrollHeight > maxHeight ) {\n\t\t\t\t\t\tmaxHeight = slides[ i ].scrollHeight;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Set the height of the container to be the max height of the slides in the current view.\n\t\t\t\tslidesContainer.style.height = `${ maxHeight }px`;\n\t\t\t} else {\n\t\t\t\t// Set the height of the container to be the height of the current slide.\n\t\t\t\tconst height: number = slides[ this.currentSlideIndex - 1 ].scrollHeight;\n\t\t\t\tslidesContainer.style.height = `${ height }px`;\n\t\t\t}\n\t\t} else {\n\t\t\t// Set the height of the container to be the height of the tallest slide.\n\t\t\tlet height: number = 0;\n\n\t\t\t// Traverse all slides and add their height to the array.\n\t\t\tslides.forEach( ( slide: TPSliderSlideElement ): void => {\n\t\t\t\t// Set the height of the container to be the height of the tallest slide.\n\t\t\t\tif ( slide.scrollHeight > height ) {\n\t\t\t\t\theight = slide.scrollHeight;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Set the height of the container to be the height of the tallest slide.\n\t\t\tslidesContainer.style.height = `${ height }px`;\n\t\t}\n\t}\n\n\t/**\n\t * Resize the slider when the window is resized.\n\t *\n\t * @protected\n\t */\n\thandleResize(): void {\n\t\t// Update responsive settings. We are using setTimeout for INP( Interaction for Next Paint ).\n\t\tsetTimeout( () => {\n\t\t\t// Update attributes responsive settings.\n\t\t\tthis.updateAttributesResponsively();\n\t\t}, 0 );\n\n\t\t// Check if we're already resizing.\n\t\tif ( this.getAttribute( 'resizing' ) ) {\n\t\t\t// Yes we are, early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// First, lets flag this component as resizing.\n\t\tthis.setAttribute( 'resizing', 'yes' );\n\n\t\t// Run the slide (so height can be resized).\n\t\tthis.slide();\n\n\t\t// Done, let's remove the flag.\n\t\tthis.removeAttribute( 'resizing' );\n\t}\n\n\t/**\n\t * Update attributes responsive settings.\n\t */\n\tupdateAttributesResponsively(): void {\n\t\t// Check if responsiveSettings exist.\n\t\tif ( ! this.responsiveSettings.length ) {\n\t\t\t// Early Return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Step 2: First remove all the allowed responsive keys.\n\t\tthis.allowedResponsiveKeys.forEach( ( key: string ) => {\n\t\t\t// Remove.\n\t\t\tthis.removeAttribute( key );\n\t\t} );\n\n\t\t// Step 3: Loop through responsiveSettings and check if the media query is matched.\n\t\tthis.responsiveSettings.every( ( settings: { [ key: string ]: any } ) => {\n\t\t\t// Check if media query is matched.\n\t\t\tif ( window.matchMedia( settings.media ).matches ) {\n\t\t\t\t// If yes, loop through the settings at this media breakpoint.\n\t\t\t\tfor ( const settingKey in settings ) {\n\t\t\t\t\t// Check if the setting key is not media.\n\t\t\t\t\tif ( 'media' !== settingKey && this.allowedResponsiveKeys.includes( settingKey ) ) {\n\t\t\t\t\t\t// Set those keys as attributes.\n\t\t\t\t\t\tthis.setAttribute( settingKey, settings[ settingKey ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Return false to break out of the loop.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Return true so that the loop continues, if it does not break above.\n\t\t\treturn true;\n\t\t} );\n\t}\n\n\t/**\n\t * Detect touch start event, and store the starting location.\n\t *\n\t * @param {Event} e Touch event.\n\t *\n\t * @protected\n\t */\n\tprotected handleTouchStart( e: TouchEvent ): void {\n\t\t// initialize touch start coordinates\n\t\tif ( 'yes' === this.getAttribute( 'swipe' ) ) {\n\t\t\tthis.touchStartX = e.touches[ 0 ].clientX;\n\t\t\tthis.touchStartY = e.touches[ 0 ].clientY;\n\t\t}\n\t}\n\n\t/**\n\t * Detect touch end event, and check if it was a left or right swipe.\n\t *\n\t * @param {Event} e Touch event.\n\t *\n\t * @protected\n\t */\n\tprotected handleTouchEnd( e: TouchEvent ): void {\n\t\t// Early return if swipe is not enabled.\n\t\tif ( 'yes' !== this.getAttribute( 'swipe' ) ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Calculate the horizontal and vertical distance moved.\n\t\tconst touchEndX: number = e.changedTouches[ 0 ].clientX;\n\t\tconst touchEndY: number = e.changedTouches[ 0 ].clientY;\n\t\tconst swipeDistanceX: number = touchEndX - this.touchStartX;\n\t\tconst swipeDistanceY: number = touchEndY - this.touchStartY;\n\n\t\t// Determine if the swipe is predominantly horizontal or vertical.\n\t\tconst isHorizontalSwipe: boolean = Math.abs( swipeDistanceX ) > Math.abs( swipeDistanceY );\n\n\t\t// If it's not horizontal swipe, return\n\t\tif ( ! isHorizontalSwipe ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if it's a right or left swipe.\n\t\tif ( swipeDistanceX > 0 ) {\n\t\t\t// Right-Swipe: Check if horizontal swipe distance is less than the threshold.\n\t\t\tif ( swipeDistanceX < this.swipeThreshold ) {\n\t\t\t\tthis.previous();\n\t\t\t}\n\t\t} else if ( swipeDistanceX < 0 ) {\n\t\t\t// Left-Swipe: Check if horizontal swipe distance is less than the threshold.\n\t\t\tif ( swipeDistanceX > -this.swipeThreshold ) {\n\t\t\t\tthis.next();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Auto slide.\n\t */\n\tprotected autoSlide(): void {\n\t\t// Auto Slide.\n\t\tconst autoSlideInterval: string | null = this.getAttribute( 'auto-slide-interval' );\n\n\t\t// Check if we have an auto slider interval.\n\t\tif ( ! autoSlideInterval ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for a valid interval.\n\t\tconst interval: number = parseInt( autoSlideInterval );\n\n\t\t// Check if interval is valid.\n\t\tif ( interval <= 0 ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Run this on a timeout, rather than interval, so the interval can be controlled after the component is initialized.\n\t\tsetTimeout( (): void => {\n\t\t\t// Run the next slide.\n\t\t\tthis.next();\n\t\t\tthis.autoSlide();\n\t\t\tthis.dispatchEvent( new CustomEvent( 'auto-slide-complete' ) );\n\t\t}, interval );\n\t}\n}\n","/**\n * TP Slider Track.\n */\nexport class TPSliderTrackElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\n\n/**\n * TP Slider Slides.\n */\nexport class TPSliderSlidesElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Resize observer.\n\t\tif ( 'ResizeObserver' in window ) {\n\t\t\tnew ResizeObserver( this.handleHeightChange.bind( this ) ).observe( this );\n\t\t}\n\t}\n\n\t/**\n\t * Handle slide height change.\n\t */\n\tprotected handleHeightChange(): void {\n\t\t// Get the parent tp-slider element.\n\t\tconst slider: TPSliderElement | null = this.closest( 'tp-slider' );\n\n\t\t// Bail if not found.\n\t\tif ( ! slider ) {\n\t\t\t// Bail early if not found.\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Yield to main thread to avoid observation errors.\n\t\t *\n\t\t * @see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#observation_errors\n\t\t */\n\t\tsetTimeout( (): void => {\n\t\t\t// Handle resize.\n\t\t\tslider.handleResize();\n\t\t}, 0 );\n\t}\n}\n","/**\n * TP Slider Slide.\n */\nexport class TPSliderSlideElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\n\n/**\n * TP Slider Arrow.\n */\nexport class TPSliderArrowElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get the button and add event listener.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle when the button is clicked.\n\t */\n\thandleClick(): void {\n\t\t// If disabled, do nothing.\n\t\tif ( 'yes' === this.getAttribute( 'disabled' ) ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the slider.\n\t\tconst slider: TPSliderElement | null = this.closest( 'tp-slider' );\n\n\t\t// If no slider, early return.\n\t\tif ( ! slider ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initiate slider according to the direction of the button clicked.\n\t\tif ( 'previous' === this.getAttribute( 'direction' ) ) {\n\t\t\tslider.previous();\n\t\t} else if ( 'next' === this.getAttribute( 'direction' ) ) {\n\t\t\tslider.next();\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\n\n/**\n * TP Slider Nav.\n */\nexport class TPSliderNavElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected template: HTMLTemplateElement | null = null;\n\tprotected slider: TPSliderElement | null = null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get elements.\n\t\tthis.template = this.querySelector( 'template' );\n\t\tthis.slider = this.closest( 'tp-slider' );\n\t}\n\n\t/**\n\t * Update nav items based on template.\n\t */\n\tpublic updateNavItems(): void {\n\t\t// Bail if no template.\n\t\tif ( ! this.template || ! this.slider ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Total slides.\n\t\tconst totalSlides: number = this.slider?.getTotalSlides();\n\n\t\t// Initialise the total number of navigation items.\n\t\tconst totalNavItems: number = Math.ceil( ( totalSlides - this.slider?.perView ) / this.slider?.step ) + 1;\n\n\t\t// Clear the navigation.\n\t\tthis.innerHTML = '';\n\n\t\t// Append the navigation items.\n\t\tfor ( let i = 1; i <= totalNavItems; i++ ) {\n\t\t\t// Clone the template.\n\t\t\tconst navItem: Node = this.template.content.cloneNode( true );\n\t\t\tconst div: HTMLDivElement = document.createElement( 'div' );\n\t\t\tdiv.appendChild( navItem );\n\n\t\t\t// Append the navigation item.\n\t\t\tthis.innerHTML += div.innerHTML.replace( '$index', i.toString() );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\nimport { TPSliderNavElement } from './tp-slider-nav';\n\n/**\n * TP Slider Nav Item.\n */\nexport class TPSliderNavItemElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected slider : TPSliderElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.slider = this.closest( 'tp-slider' );\n\n\t\t// Get the nav-item button.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleClick.bind( this ) );\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Get observed attributes.\n\t\treturn [ 'current' ];\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 aria-current on the button when current attribute changes.\n\t\tif ( 'current' === name && 'no' !== this.slider?.getAttribute( 'aria' ) ) {\n\t\t\tconst button = this.querySelector( 'button' );\n\n\t\t\t// Check if button exists.\n\t\t\tif ( button ) {\n\t\t\t\t// Check value.\n\t\t\t\tif ( 'yes' === newValue ) {\n\t\t\t\t\tbutton.setAttribute( 'aria-current', 'true' );\n\t\t\t\t} else {\n\t\t\t\t\tbutton.removeAttribute( 'aria-current' );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle when the button is clicked.\n\t */\n\thandleClick(): void {\n\t\t// Check if slider exists.\n\t\tif ( ! this.slider ) {\n\t\t\t// No its not! Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set current slide.\n\t\tthis.slider.setCurrentSlide( this.getIndex() );\n\t}\n\n\t/**\n\t * Get index of this item inside the navigation.\n\t *\n\t * @return {number} Index.\n\t */\n\tgetIndex(): number {\n\t\t// Check if we have an index.\n\t\tif ( this.getAttribute( 'index' ) ) {\n\t\t\t// Yes, return it.\n\t\t\treturn parseInt( this.getAttribute( 'index' ) ?? '0' );\n\t\t}\n\n\t\t// Initialize variables.\n\t\tconst slideNav: TPSliderNavElement | null = this.closest( 'tp-slider-nav' );\n\t\tconst step = this.slider?.step ?? 1;\n\t\tconst perView = this.slider?.perView ?? 1;\n\t\tconst totalSlides = this.slider?.getTotalSlides() ?? 1;\n\t\tconst index = Array.from( slideNav?.children ?? [] ).indexOf( this );\n\n\t\t// Find posible position of the slide.\n\t\tconst lastItem = ( totalSlides - perView ) + 1;\n\t\tconst targetSlide = ( index * step ) + 1;\n\n\t\t// Get the new slide number.\n\t\tconst currentSlideIndex = Math.min( lastItem, targetSlide );\n\n\t\t// return the index.\n\t\treturn currentSlideIndex;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\n\n/**\n * TP Slider Count.\n */\nexport class TPSliderCountElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} Observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes observed by this component.\n\t\treturn [ 'format' ];\n\t}\n\n\t/**\n\t * Get format.\n\t *\n\t * @return {string} Format.\n\t */\n\tget format(): string {\n\t\t// Get the 'format' attribute value.\n\t\treturn this.getAttribute( 'format' ) ?? '$current / $total';\n\t}\n\n\t/**\n\t * Set format.\n\t *\n\t * @param {string} format Format.\n\t */\n\tset format( format: string ) {\n\t\t// Set the 'format' attribute value.\n\t\tthis.setAttribute( 'format', format );\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t */\n\tattributeChangedCallback(): void {\n\t\t// On change of format attribute, update the component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update component.\n\t */\n\tupdate(): void {\n\t\t// Get slider.\n\t\tconst slider: TPSliderElement | null = this.closest( 'tp-slider' );\n\n\t\t// Check if slider exists.\n\t\tif ( ! slider ) {\n\t\t\t// No its not! Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initializing current variable including per view. Along with initializing total variable.\n\t\tconst current: number = Math.min( slider.currentSlideIndex - 1 + slider.perView, slider.getTotalSlides() );\n\t\tconst total: string = slider.getAttribute( 'total' ) ?? '';\n\n\t\t// Updating variables in format attribute.\n\t\tthis.innerHTML =\n\t\t\tthis.format\n\t\t\t\t.replace( '$current', current.toString() )\n\t\t\t\t.replace( '$total', total || '' );\n\n\t\t// Updating current and total attributes.\n\t\tthis.setAttribute( 'current', current.toString() );\n\t\tthis.setAttribute( 'total', total || '' );\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPSliderElement } from './tp-slider';\nimport { TPSliderTrackElement } from './tp-slider-track';\nimport { TPSliderSlidesElement } from './tp-slider-slides';\nimport { TPSliderSlideElement } from './tp-slider-slide';\nimport { TPSliderArrowElement } from './tp-slider-arrow';\nimport { TPSliderNavElement } from './tp-slider-nav';\nimport { TPSliderNavItemElement } from './tp-slider-nav-item';\nimport { TPSliderCountElement } from './tp-slider-count';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-slider-nav', TPSliderNavElement );\ncustomElements.define( 'tp-slider', TPSliderElement );\ncustomElements.define( 'tp-slider-count', TPSliderCountElement );\ncustomElements.define( 'tp-slider-track', TPSliderTrackElement );\ncustomElements.define( 'tp-slider-slides', TPSliderSlidesElement );\ncustomElements.define( 'tp-slider-slide', TPSliderSlideElement );\ncustomElements.define( 'tp-slider-arrow', TPSliderArrowElement );\ncustomElements.define( 'tp-slider-nav-item', TPSliderNavItemElement );\n"],"names":["TPSliderElement","HTMLElement","constructor","super","touchStartX","touchStartY","swipeThreshold","allowedResponsiveKeys","this","getAttribute","setAttribute","Number","slide","autoSlide","responsiveSettingsJSON","responsiveSettings","JSON","parse","window","addEventListener","handleResize","bind","document","fonts","ready","then","handleTouchStart","passive","handleTouchEnd","handleKeyDown","e","key","preventDefault","previous","next","connectedCallback","update","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","bubbles","currentSlideIndex","parseInt","index","setCurrentSlide","step","toString","perView","getTotalSlides","slides","getSlideElements","length","slidesElement","querySelector","querySelectorAll","totalSlides","nextSlideIndex","Math","min","totalPossibleGroups","ceil","previousSlideNumber","round","currentGroup","getCurrentSlide","detail","slideIndex","slidesContainer","setTimeout","updateHeight","style","left","offsetLeft","getArrow","selector","arrows","parentSliderElement","theArrow","forEach","arrow","closest","sliderNav","sliderCounts","leftArrow","rightArrow","customElements","whenDefined","manageAria","firstVisibleIndex","lastVisibleIndex","removeAttribute","updateNavItems","sliderNavItems","navItem","allItems","slideCount","removeProperty","currentIndex","slidesOnCurrentView","maxHeight","i","scrollHeight","height","updateAttributesResponsively","every","settings","matchMedia","media","matches","settingKey","includes","touches","clientX","clientY","touchEndX","changedTouches","touchEndY","swipeDistanceX","swipeDistanceY","abs","autoSlideInterval","interval","TPSliderTrackElement","TPSliderSlidesElement","ResizeObserver","handleHeightChange","observe","slider","TPSliderSlideElement","TPSliderArrowElement","handleClick","TPSliderNavElement","template","totalNavItems","innerHTML","content","cloneNode","div","createElement","appendChild","replace","TPSliderNavItemElement","_oldValue","button","getIndex","slideNav","lastItem","targetSlide","Array","from","children","indexOf","TPSliderCountElement","format","current","total","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/slider/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/slider/tp-slider.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-track.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-slides.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-slide.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-arrow.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-nav.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-nav-item.ts","webpack://@travelopia/web-components/./src/slider/tp-slider-count.ts","webpack://@travelopia/web-components/./src/slider/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPSliderSlidesElement } from './tp-slider-slides';\nimport { TPSliderSlideElement } from './tp-slider-slide';\nimport { TPSliderCountElement } from './tp-slider-count';\nimport { TPSliderNavElement } from './tp-slider-nav';\nimport { TPSliderNavItemElement } from './tp-slider-nav-item';\nimport { TPSliderArrowElement } from './tp-slider-arrow';\n\n/**\n * TP Slider.\n */\nexport class TPSliderElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected touchStartX: number = 0;\n\tprotected touchStartY: number = 0;\n\tprotected swipeThreshold: number = 200;\n\tprotected responsiveSettings: { [ key: string ]: any };\n\tprotected allowedResponsiveKeys: string[] = [\n\t\t'flexible-height',\n\t\t'infinite',\n\t\t'swipe',\n\t\t'behaviour',\n\t\t'auto-slide-interval',\n\t\t'per-view',\n\t\t'step',\n\t\t'responsive',\n\t];\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Set current slide.\n\t\tif ( ! this.getAttribute( 'current-slide' ) ) {\n\t\t\tthis.setAttribute( 'current-slide', '1' );\n\t\t}\n\n\t\t// Threshold Setting.\n\t\tthis.swipeThreshold = Number( this?.getAttribute( 'swipe-threshold' ) ?? '200' );\n\n\t\t// Initialize slider.\n\t\tthis.slide();\n\t\tthis.autoSlide();\n\t\tthis.setAttribute( 'initialized', 'yes' );\n\n\t\t// Responsive Settings.\n\t\tconst responsiveSettingsJSON: string = this.getAttribute( 'responsive' ) || '';\n\t\tthis.responsiveSettings = responsiveSettingsJSON ? JSON.parse( responsiveSettingsJSON ) : [];\n\n\t\t// Event listeners.\n\t\tif ( ! ( 'ResizeObserver' in window ) ) {\n\t\t\t/**\n\t\t\t * We set the resize observer in `tp-slider-slides`\n\t\t\t * because These are just fallbacks for browsers that don't support ResizeObserver.\n\t\t\t */\n\n\t\t\t// @ts-ignore\n\t\t\twindow.addEventListener( 'resize', this.handleResize.bind( this ) );\n\t\t\tdocument.fonts.ready.then( () => this.handleResize() );\n\t\t}\n\n\t\t// Touch listeners.\n\t\tthis.addEventListener( 'touchstart', this.handleTouchStart.bind( this ), { passive: true } );\n\t\tthis.addEventListener( 'touchend', this.handleTouchEnd.bind( this ) );\n\n\t\t// Keyboard listener for arrow key navigation.\n\t\tthis.addEventListener( 'keydown', this.handleKeyDown.bind( this ) );\n\t}\n\n\t/**\n\t * Handle keydown events for arrow key navigation.\n\t *\n\t * @param {KeyboardEvent} e Keyboard event.\n\t */\n\tprotected handleKeyDown( e: KeyboardEvent ): void {\n\t\t// Only handle if arrow-navigation is enabled (disabled by default).\n\t\tif ( 'yes' !== this.getAttribute( 'arrow-navigation' ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Only handle arrow keys.\n\t\tif ( 'ArrowLeft' !== e.key && 'ArrowRight' !== e.key ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prevent default scrolling behavior.\n\t\te.preventDefault();\n\n\t\t// Navigate based on arrow direction.\n\t\tif ( 'ArrowLeft' === e.key ) {\n\t\t\tthis.previous();\n\t\t} else if ( 'ArrowRight' === e.key ) {\n\t\t\tthis.next();\n\t\t}\n\t}\n\n\t/**\n\t * Connected callback.\n\t */\n\tconnectedCallback() {\n\t\t/**\n\t\t * Update on initial render.\n\t\t *\n\t\t * This is so that the disabled values of the navigation arrows\n\t\t * can be set because attributeChangedCallback does not get fired when\n\t\t * no attributes are passed to the slider.\n\t\t */\n\t\tthis.update();\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// Observed attributes.\n\t\treturn [ 'current-slide', 'flexible-height', 'infinite', 'swipe', 'per-view', 'step' ];\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// Keep an eye on current slide.\n\t\tif ( 'current-slide' === name && oldValue !== newValue ) {\n\t\t\tthis.slide();\n\t\t\tthis.dispatchEvent( new CustomEvent( 'slide-complete', { bubbles: true } ) );\n\t\t}\n\n\t\t// Update the component after the attribute change.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Get current slide index.\n\t *\n\t * @return {number} Current slide index.\n\t */\n\tget currentSlideIndex(): number {\n\t\t// To get the current slide index.\n\t\treturn parseInt( this.getAttribute( 'current-slide' ) ?? '1' );\n\t}\n\n\t/**\n\t * Set current slide index.\n\t *\n\t * @param {number} index Slide index.\n\t */\n\tset currentSlideIndex( index: number ) {\n\t\t// Set the current slide index.\n\t\tthis.setCurrentSlide( index );\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// To get the current step.\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 Step.\n\t */\n\tset step( step: number ) {\n\t\t// Set the current step.\n\t\tthis.setAttribute( 'step', step.toString() );\n\t}\n\n\t/**\n\t * Get per view.\n\t *\n\t * @return {number} Current step.\n\t */\n\tget perView(): number {\n\t\t// To get number of slides per view.\n\t\treturn parseInt( this.getAttribute( 'per-view' ) ?? '1' );\n\t}\n\n\t/**\n\t * Set per view.\n\t *\n\t * @param {number} perView Per view.\n\t */\n\tset perView( perView: number ) {\n\t\t// Set the number of slides per view.\n\t\tthis.setAttribute( 'per-view', perView.toString() );\n\t}\n\n\t/**\n\t * Get total number of slides.\n\t *\n\t * @return {number} Total slides.\n\t */\n\tgetTotalSlides(): number {\n\t\t// To get the total number of slides.\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = this.getSlideElements();\n\n\t\t// Check if slides are available.\n\t\tif ( slides ) {\n\t\t\t// Tell the total number of slides.\n\t\t\treturn slides.length;\n\t\t}\n\n\t\t// Else return 0.\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Get Slide Elements.\n\t */\n\tgetSlideElements() {\n\t\t// Get slides.\n\t\tconst slidesElement: TPSliderSlidesElement | null = this.querySelector( 'tp-slider-slides' );\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = slidesElement?.querySelectorAll( ':scope > tp-slider-slide' );\n\n\t\t// Return array of slides.\n\t\treturn slides;\n\t}\n\n\t/**\n\t * Navigate to the next slide.\n\t */\n\tnext(): void {\n\t\t// Initialize total slides variable.\n\t\tconst totalSlides: number = this.getTotalSlides();\n\n\t\t// Check if we are at the last slide considering per view attribute.\n\t\tif ( this.currentSlideIndex >= totalSlides - this.perView + 1 ) {\n\t\t\t// Check if we are in infinite mode.\n\t\t\tif ( 'yes' === this.getAttribute( 'infinite' ) ) {\n\t\t\t\t// Yes, we are, and go back to first slide.\n\t\t\t\tthis.setCurrentSlide( 1 );\n\t\t\t}\n\n\t\t\t// Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get next slide index by adding minimum of step or remaining number of slides.\n\t\tconst nextSlideIndex: number = Math.min( this.currentSlideIndex + this.step, totalSlides - this.perView + 1 );\n\n\t\t// Check if the next slide step is not taking it beyond the last slide.\n\t\tif ( nextSlideIndex > ( totalSlides - this.perView + 1 ) ) {\n\t\t\t// Yes, it is.\n\t\t\treturn;\n\t\t}\n\n\t\t// Everything is good, go to next slide.\n\t\tthis.setCurrentSlide( nextSlideIndex );\n\t}\n\n\t/**\n\t * Navigate to the previous slide.\n\t */\n\tprevious(): void {\n\t\t// Check if we are at the first slide.\n\t\tif ( this.currentSlideIndex <= 1 ) {\n\t\t\t// Check if we are in infinite mode.\n\t\t\tif ( 'yes' === this.getAttribute( 'infinite' ) ) {\n\t\t\t\tthis.setCurrentSlide( this.getTotalSlides() - this.perView + 1 );\n\t\t\t}\n\n\t\t\t// Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize total slides variable.\n\t\tconst totalSlides: number = this.getTotalSlides();\n\n\t\t// Total Possible groups.\n\t\tconst totalPossibleGroups: number = Math.ceil( totalSlides / this.step );\n\n\t\t// Initialize previous slide number.\n\t\tlet previousSlideNumber: number = 0;\n\n\t\t// Checking if total slides are not divisible by step.\n\t\tif ( totalSlides / this.step !== Math.round( totalSlides / this.step ) ) {\n\t\t\t// Initialize current group.\n\t\t\tlet currentGroup: number;\n\n\t\t\t// Check if we are in the last group or in any other.\n\t\t\tif ( this.currentSlideIndex + this.step - 1 >= totalSlides ) {\n\t\t\t\tcurrentGroup = totalPossibleGroups;\n\t\t\t} else {\n\t\t\t\tcurrentGroup = Math.ceil( this.currentSlideIndex / this.step );\n\t\t\t}\n\n\t\t\t// Update previous slide number based on which group we are in.\n\t\t\tif ( currentGroup === totalPossibleGroups ) {\n\t\t\t\tpreviousSlideNumber = this.currentSlideIndex - this.step + 1;\n\t\t\t} else {\n\t\t\t\tpreviousSlideNumber = this.currentSlideIndex - this.step;\n\t\t\t}\n\t\t} else {\n\t\t\t// Check if we are in the last group.\n\t\t\tpreviousSlideNumber = this.currentSlideIndex - this.step;\n\t\t}\n\n\t\t// Check if the previous slide step is not taking it beyond the first slide.\n\t\tif ( previousSlideNumber > 1 ) {\n\t\t\tthis.setCurrentSlide( previousSlideNumber );\n\t\t} else {\n\t\t\tthis.setCurrentSlide( 1 );\n\t\t}\n\t}\n\n\t/**\n\t * Get current slide index.\n\t *\n\t * @return {number} Current slide index.\n\t */\n\tgetCurrentSlide(): number {\n\t\t// Get current slide index.\n\t\treturn this.currentSlideIndex;\n\t}\n\n\t/**\n\t * Set the current slide index.\n\t *\n\t * @param {number} index Slide index.\n\t */\n\tsetCurrentSlide( index: number ): void {\n\t\t// Check if slide index is valid.\n\t\tif ( index > this.getTotalSlides() || index <= 0 ) {\n\t\t\t// Stop! It's not valid.\n\t\t\treturn;\n\t\t}\n\n\t\t// dispatch slide-set event.\n\t\tthis.dispatchEvent( new CustomEvent( 'slide-set', {\n\t\t\tbubbles: true,\n\t\t\tdetail: {\n\t\t\t\tslideIndex: index,\n\t\t\t},\n\t\t} ) );\n\n\t\t// Set current slide index.\n\t\tthis.setAttribute( 'current-slide', index.toString() );\n\t}\n\n\t/**\n\t * Slide to the current slide.\n\t *\n\t * @protected\n\t */\n\tprotected slide(): void {\n\t\t// Check if slider is disabled.\n\t\tif ( 'yes' === this.getAttribute( 'disabled' ) ) {\n\t\t\t// Yes, it is. So stop.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get slides.\n\t\tconst slidesContainer: TPSliderSlidesElement | null = this.querySelector( 'tp-slider-slides' );\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = this.getSlideElements();\n\n\t\t// Check if we have slide container and slides.\n\t\tif ( ! slidesContainer || ! slides ) {\n\t\t\t// No, we don't. Either one of them or both are missing. So stop.\n\t\t\treturn;\n\t\t}\n\n\t\t// First, update the height.\n\n\t\t// Yield to main thread to fix a bug in Safari 16.\n\t\tsetTimeout( () => this.updateHeight(), 0 );\n\n\t\t// Now lets slide!\n\t\tconst behaviour: string = this.getAttribute( 'behaviour' ) || '';\n\n\t\t// Check if behaviour is set to fade and slide on the current slide index is present in the slides array.\n\t\tif ( 'fade' !== behaviour && slides[ this.currentSlideIndex - 1 ] ) {\n\t\t\t// Yes, it is. So slide to the current slide.\n\t\t\tslidesContainer.style.left = `-${ slides[ this.currentSlideIndex - 1 ].offsetLeft }px`;\n\t\t}\n\t}\n\n\t/**\n\t * Get the arrow element by selector.\n\t *\n\t * In case of nested sliders, it difficult to find the correct arrow\n\t * because arrows can be placed anywhere.\n\t * This function checks if the parent tp-slider belongs to this component,\n\t * then return that arrow element, using 'this'.\n\t *\n\t * @param {string} selector Selector.\n\t */\n\tgetArrow( selector: string ) {\n\t\t// Get all arrows.\n\t\tconst arrows: NodeListOf<TPSliderArrowElement> | null = this.querySelectorAll( selector );\n\t\tconst parentSliderElement: TPSliderElement = this;\n\t\tlet theArrow: TPSliderArrowElement | null = this.querySelector( selector );\n\n\t\t// Loop through all the arrows including the one's inside nested slider.\n\t\tarrows.forEach( ( arrow ) => {\n\t\t\t/**\n\t\t\t * If the closest tp-slider is the same as the parentSliderElement, that means we have found\n\t\t\t * the correct arrow.\n\t\t\t */\n\t\t\tif ( parentSliderElement === arrow.closest( 'tp-slider' ) ) {\n\t\t\t\ttheArrow = arrow;\n\t\t\t}\n\t\t} );\n\n\t\t// Return arrow.\n\t\treturn theArrow;\n\t}\n\n\t/**\n\t * Update stuff when any attribute has changed.\n\t * Example: Update sub-components.\n\t */\n\tasync update(): Promise<void> {\n\t\t// Get sub-components.\n\t\tconst sliderNav: TPSliderNavElement | null = this.querySelector( 'tp-slider-nav' );\n\t\tconst sliderCounts: NodeListOf<TPSliderCountElement> | null = this.querySelectorAll( 'tp-slider-count' );\n\t\tconst leftArrow: TPSliderArrowElement | null = this.getArrow( 'tp-slider-arrow[direction=\"previous\"]' );\n\t\tconst rightArrow: TPSliderArrowElement | null = this.getArrow( 'tp-slider-arrow[direction=\"next\"]' );\n\n\t\t// Wait for initialization - done to avoid updateNavItems undefined error.\n\t\tawait customElements.whenDefined( 'tp-slider-nav' );\n\t\tawait customElements.whenDefined( 'tp-slider-nav-item' );\n\t\tawait customElements.whenDefined( 'tp-slider-count' );\n\t\tawait customElements.whenDefined( 'tp-slider-arrow' );\n\n\t\t// Total slides variable and Total possible group.\n\t\tconst totalSlides: number = this.getTotalSlides();\n\t\tconst totalPossibleGroups: number = Math.ceil( totalSlides / this.step );\n\n\t\t// Set active slide.\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = this.getSlideElements();\n\n\t\t// Check if slides are available.\n\t\tif ( slides ) {\n\t\t\t// Check if aria management is enabled (default: yes).\n\t\t\tconst manageAria = 'no' !== this.getAttribute( 'aria' );\n\n\t\t\t// Calculate visible slide range (0-indexed).\n\t\t\tconst firstVisibleIndex = this.currentSlideIndex - 1;\n\t\t\tconst lastVisibleIndex = firstVisibleIndex + this.perView - 1;\n\n\t\t\t// Traverse slides.\n\t\t\tslides.forEach( ( slide: TPSliderSlideElement, index: number ): void => {\n\t\t\t\t// Update active attribute.\n\t\t\t\tif ( this.currentSlideIndex - 1 === index ) {\n\t\t\t\t\tslide.setAttribute( 'active', 'yes' );\n\t\t\t\t} else {\n\t\t\t\t\tslide.removeAttribute( 'active' );\n\t\t\t\t}\n\n\t\t\t\t// Update aria-hidden and inert for non-visible slides.\n\t\t\t\tif ( manageAria ) {\n\t\t\t\t\t// Check index.\n\t\t\t\t\tif ( index >= firstVisibleIndex && index <= lastVisibleIndex ) {\n\t\t\t\t\t\tslide.removeAttribute( 'aria-hidden' );\n\t\t\t\t\t\tslide.removeAttribute( 'inert' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tslide.setAttribute( 'aria-hidden', 'true' );\n\t\t\t\t\t\tslide.setAttribute( 'inert', '' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// First, set the template for the slider nav.\n\t\tsliderNav?.updateNavItems();\n\n\t\t// Once the template has been set, query the slider nav items.\n\t\tconst sliderNavItems: NodeListOf<TPSliderNavItemElement> | null = this.querySelectorAll( 'tp-slider-nav-item' );\n\n\t\t// Set current slider nav item.\n\t\tif ( sliderNavItems ) {\n\t\t\t// Add current attribute.\n\t\t\tsliderNavItems.forEach( ( navItem: TPSliderNavItemElement, index: number, allItems: NodeListOf<TPSliderNavItemElement> ): void => {\n\t\t\t\t// Remove current attribute.\n\t\t\t\tnavItem.removeAttribute( 'current' );\n\n\t\t\t\t// Get Round of Index.\n\t\t\t\tconst groupIndex = Math.round( ( this.currentSlideIndex - 1 ) / this.step );\n\n\t\t\t\t// Check if index and groups are equal to update active dot.\n\t\t\t\tif ( groupIndex === index ) {\n\t\t\t\t\tnavItem.setAttribute( 'current', 'yes' );\n\t\t\t\t} else if ( ( index === totalPossibleGroups - 1 && this.currentSlideIndex + this.step - 1 >= totalSlides ) ) {\n\t\t\t\t\tnavItem.setAttribute( 'current', 'yes' );\n\n\t\t\t\t\t// Remove current index from last 2nd item.\n\t\t\t\t\tallItems[ index - 1 ]?.removeAttribute( 'current' );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Update slider count.\n\t\tif ( sliderCounts ) {\n\t\t\t// Set total attribute.\n\t\t\tthis.setAttribute( 'total', this.getTotalSlides().toString() );\n\n\t\t\t// Update slider counts.\n\t\t\tsliderCounts.forEach( ( slideCount: TPSliderCountElement ) => {\n\t\t\t\t// Check if the slideCount.update is a function.\n\t\t\t\tif ( 'function' === typeof slideCount.update ) {\n\t\t\t\t\t// Update slide count.\n\t\t\t\t\tslideCount.update();\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Enable / disable arrows.\n\t\tif ( 'yes' !== this.getAttribute( 'infinite' ) ) {\n\t\t\t// For the last slide.\n\t\t\tif ( this.getCurrentSlide() === this.getTotalSlides() - this.perView + 1 ) {\n\t\t\t\trightArrow?.setAttribute( 'disabled', 'yes' );\n\t\t\t} else {\n\t\t\t\trightArrow?.removeAttribute( 'disabled' );\n\t\t\t}\n\n\t\t\t// For the first slide.\n\t\t\tif ( 1 === this.getCurrentSlide() ) {\n\t\t\t\tleftArrow?.setAttribute( 'disabled', 'yes' );\n\t\t\t} else {\n\t\t\t\tleftArrow?.removeAttribute( 'disabled' );\n\t\t\t}\n\t\t} else {\n\t\t\trightArrow?.removeAttribute( 'disabled' );\n\t\t\tleftArrow?.removeAttribute( 'disabled' );\n\t\t}\n\t}\n\n\t/**\n\t * Update the height of the slider based on current slide.\n\t */\n\tupdateHeight(): void {\n\t\t// Get slides container to resize.\n\t\tconst slidesContainer: TPSliderSlidesElement | null = this.querySelector( 'tp-slider-slides' );\n\n\t\t// Check if slides container is available.\n\t\tif ( ! slidesContainer ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Bail early if we don't want it to be flexible height - as long as it doesn't fade.\n\t\tif ( 'yes' !== this.getAttribute( 'flexible-height' ) && 'fade' !== this.getAttribute( 'behaviour' ) ) {\n\t\t\t// Remove height property for good measure!\n\t\t\tslidesContainer.style.removeProperty( 'height' );\n\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get slides.\n\t\tconst slides: NodeListOf<TPSliderSlideElement> | null | undefined = this.getSlideElements();\n\n\t\t// Check if slides are available.\n\t\tif ( ! slides ) {\n\t\t\t// No slides to resize.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if we have a flexible height.\n\t\tif ( 'yes' === this.getAttribute( 'flexible-height' ) ) {\n\t\t\t// Check if per-view is greater than 1.\n\t\t\tif ( this.perView > 1 ) {\n\t\t\t\tconst currentIndex: number = this.currentSlideIndex - 1;\n\t\t\t\tconst slidesOnCurrentView: number = currentIndex + this.perView;\n\t\t\t\tlet maxHeight: number = 0;\n\n\t\t\t\t// Traverse all slides in the current view and add their height to the array.\n\t\t\t\tfor ( let i: number = currentIndex; i < slidesOnCurrentView; i++ ) {\n\t\t\t\t\t// Check if the slide exists.\n\t\t\t\t\tif ( slides[ i ].scrollHeight > maxHeight ) {\n\t\t\t\t\t\tmaxHeight = slides[ i ].scrollHeight;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Set the height of the container to be the max height of the slides in the current view.\n\t\t\t\tslidesContainer.style.height = `${ maxHeight }px`;\n\t\t\t} else {\n\t\t\t\t// Set the height of the container to be the height of the current slide.\n\t\t\t\tconst height: number = slides[ this.currentSlideIndex - 1 ].scrollHeight;\n\t\t\t\tslidesContainer.style.height = `${ height }px`;\n\t\t\t}\n\t\t} else {\n\t\t\t// Set the height of the container to be the height of the tallest slide.\n\t\t\tlet height: number = 0;\n\n\t\t\t// Traverse all slides and add their height to the array.\n\t\t\tslides.forEach( ( slide: TPSliderSlideElement ): void => {\n\t\t\t\t// Set the height of the container to be the height of the tallest slide.\n\t\t\t\tif ( slide.scrollHeight > height ) {\n\t\t\t\t\theight = slide.scrollHeight;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Set the height of the container to be the height of the tallest slide.\n\t\t\tslidesContainer.style.height = `${ height }px`;\n\t\t}\n\t}\n\n\t/**\n\t * Resize the slider when the window is resized.\n\t *\n\t * @protected\n\t */\n\thandleResize(): void {\n\t\t// Update responsive settings. We are using setTimeout for INP( Interaction for Next Paint ).\n\t\tsetTimeout( () => {\n\t\t\t// Update attributes responsive settings.\n\t\t\tthis.updateAttributesResponsively();\n\t\t}, 0 );\n\n\t\t// Check if we're already resizing.\n\t\tif ( this.getAttribute( 'resizing' ) ) {\n\t\t\t// Yes we are, early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// First, lets flag this component as resizing.\n\t\tthis.setAttribute( 'resizing', 'yes' );\n\n\t\t// Run the slide (so height can be resized).\n\t\tthis.slide();\n\n\t\t// Done, let's remove the flag.\n\t\tthis.removeAttribute( 'resizing' );\n\t}\n\n\t/**\n\t * Update attributes responsive settings.\n\t */\n\tupdateAttributesResponsively(): void {\n\t\t// Check if responsiveSettings exist.\n\t\tif ( ! this.responsiveSettings.length ) {\n\t\t\t// Early Return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Step 2: First remove all the allowed responsive keys.\n\t\tthis.allowedResponsiveKeys.forEach( ( key: string ) => {\n\t\t\t// Remove.\n\t\t\tthis.removeAttribute( key );\n\t\t} );\n\n\t\t// Step 3: Loop through responsiveSettings and check if the media query is matched.\n\t\tthis.responsiveSettings.every( ( settings: { [ key: string ]: any } ) => {\n\t\t\t// Check if media query is matched.\n\t\t\tif ( window.matchMedia( settings.media ).matches ) {\n\t\t\t\t// If yes, loop through the settings at this media breakpoint.\n\t\t\t\tfor ( const settingKey in settings ) {\n\t\t\t\t\t// Check if the setting key is not media.\n\t\t\t\t\tif ( 'media' !== settingKey && this.allowedResponsiveKeys.includes( settingKey ) ) {\n\t\t\t\t\t\t// Set those keys as attributes.\n\t\t\t\t\t\tthis.setAttribute( settingKey, settings[ settingKey ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Return false to break out of the loop.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Return true so that the loop continues, if it does not break above.\n\t\t\treturn true;\n\t\t} );\n\t}\n\n\t/**\n\t * Detect touch start event, and store the starting location.\n\t *\n\t * @param {Event} e Touch event.\n\t *\n\t * @protected\n\t */\n\tprotected handleTouchStart( e: TouchEvent ): void {\n\t\t// initialize touch start coordinates\n\t\tif ( 'yes' === this.getAttribute( 'swipe' ) ) {\n\t\t\tthis.touchStartX = e.touches[ 0 ].clientX;\n\t\t\tthis.touchStartY = e.touches[ 0 ].clientY;\n\t\t}\n\t}\n\n\t/**\n\t * Detect touch end event, and check if it was a left or right swipe.\n\t *\n\t * @param {Event} e Touch event.\n\t *\n\t * @protected\n\t */\n\tprotected handleTouchEnd( e: TouchEvent ): void {\n\t\t// Early return if swipe is not enabled.\n\t\tif ( 'yes' !== this.getAttribute( 'swipe' ) ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Calculate the horizontal and vertical distance moved.\n\t\tconst touchEndX: number = e.changedTouches[ 0 ].clientX;\n\t\tconst touchEndY: number = e.changedTouches[ 0 ].clientY;\n\t\tconst swipeDistanceX: number = touchEndX - this.touchStartX;\n\t\tconst swipeDistanceY: number = touchEndY - this.touchStartY;\n\n\t\t// Determine if the swipe is predominantly horizontal or vertical.\n\t\tconst isHorizontalSwipe: boolean = Math.abs( swipeDistanceX ) > Math.abs( swipeDistanceY );\n\n\t\t// If it's not horizontal swipe, return\n\t\tif ( ! isHorizontalSwipe ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if it's a right or left swipe.\n\t\tif ( swipeDistanceX > 0 ) {\n\t\t\t// Right-Swipe: Check if horizontal swipe distance is less than the threshold.\n\t\t\tif ( swipeDistanceX < this.swipeThreshold ) {\n\t\t\t\tthis.previous();\n\t\t\t}\n\t\t} else if ( swipeDistanceX < 0 ) {\n\t\t\t// Left-Swipe: Check if horizontal swipe distance is less than the threshold.\n\t\t\tif ( swipeDistanceX > -this.swipeThreshold ) {\n\t\t\t\tthis.next();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Auto slide.\n\t */\n\tprotected autoSlide(): void {\n\t\t// Auto Slide.\n\t\tconst autoSlideInterval: string | null = this.getAttribute( 'auto-slide-interval' );\n\n\t\t// Check if we have an auto slider interval.\n\t\tif ( ! autoSlideInterval ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for a valid interval.\n\t\tconst interval: number = parseInt( autoSlideInterval );\n\n\t\t// Check if interval is valid.\n\t\tif ( interval <= 0 ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Run this on a timeout, rather than interval, so the interval can be controlled after the component is initialized.\n\t\tsetTimeout( (): void => {\n\t\t\t// Run the next slide.\n\t\t\tthis.next();\n\t\t\tthis.autoSlide();\n\t\t\tthis.dispatchEvent( new CustomEvent( 'auto-slide-complete' ) );\n\t\t}, interval );\n\t}\n}\n","/**\n * TP Slider Track.\n */\nexport class TPSliderTrackElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\n\n/**\n * TP Slider Slides.\n */\nexport class TPSliderSlidesElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Resize observer.\n\t\tif ( 'ResizeObserver' in window ) {\n\t\t\tnew ResizeObserver( this.handleHeightChange.bind( this ) ).observe( this );\n\t\t}\n\t}\n\n\t/**\n\t * Handle slide height change.\n\t */\n\tprotected handleHeightChange(): void {\n\t\t// Get the parent tp-slider element.\n\t\tconst slider: TPSliderElement | null = this.closest( 'tp-slider' );\n\n\t\t// Bail if not found.\n\t\tif ( ! slider ) {\n\t\t\t// Bail early if not found.\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Yield to main thread to avoid observation errors.\n\t\t *\n\t\t * @see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#observation_errors\n\t\t */\n\t\tsetTimeout( (): void => {\n\t\t\t// Handle resize.\n\t\t\tslider.handleResize();\n\t\t}, 0 );\n\t}\n}\n","/**\n * TP Slider Slide.\n */\nexport class TPSliderSlideElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\n\n/**\n * TP Slider Arrow.\n */\nexport class TPSliderArrowElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get the button and add event listener.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle when the button is clicked.\n\t */\n\thandleClick(): void {\n\t\t// If disabled, do nothing.\n\t\tif ( 'yes' === this.getAttribute( 'disabled' ) ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the slider.\n\t\tconst slider: TPSliderElement | null = this.closest( 'tp-slider' );\n\n\t\t// If no slider, early return.\n\t\tif ( ! slider ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initiate slider according to the direction of the button clicked.\n\t\tif ( 'previous' === this.getAttribute( 'direction' ) ) {\n\t\t\tslider.previous();\n\t\t} else if ( 'next' === this.getAttribute( 'direction' ) ) {\n\t\t\tslider.next();\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\n\n/**\n * TP Slider Nav.\n */\nexport class TPSliderNavElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected template: HTMLTemplateElement | null = null;\n\tprotected slider: TPSliderElement | null = null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get elements.\n\t\tthis.template = this.querySelector( 'template' );\n\t\tthis.slider = this.closest( 'tp-slider' );\n\t}\n\n\t/**\n\t * Update nav items based on template.\n\t */\n\tpublic updateNavItems(): void {\n\t\t// Bail if no template.\n\t\tif ( ! this.template || ! this.slider ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Total slides.\n\t\tconst totalSlides: number = this.slider?.getTotalSlides();\n\n\t\t// Initialise the total number of navigation items.\n\t\tconst totalNavItems: number = Math.ceil( ( totalSlides - this.slider?.perView ) / this.slider?.step ) + 1;\n\n\t\t// Clear the navigation.\n\t\tthis.innerHTML = '';\n\n\t\t// Append the navigation items.\n\t\tfor ( let i = 1; i <= totalNavItems; i++ ) {\n\t\t\t// Clone the template.\n\t\t\tconst navItem: Node = this.template.content.cloneNode( true );\n\t\t\tconst div: HTMLDivElement = document.createElement( 'div' );\n\t\t\tdiv.appendChild( navItem );\n\n\t\t\t// Append the navigation item.\n\t\t\tthis.innerHTML += div.innerHTML.replace( '$index', i.toString() );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\nimport { TPSliderNavElement } from './tp-slider-nav';\n\n/**\n * TP Slider Nav Item.\n */\nexport class TPSliderNavItemElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected slider : TPSliderElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.slider = this.closest( 'tp-slider' );\n\n\t\t// Get the nav-item button.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleClick.bind( this ) );\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Get observed attributes.\n\t\treturn [ 'current' ];\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 aria-current on the button when current attribute changes.\n\t\tif ( 'current' === name && 'no' !== this.slider?.getAttribute( 'aria' ) ) {\n\t\t\tconst button = this.querySelector( 'button' );\n\n\t\t\t// Check if button exists.\n\t\t\tif ( button ) {\n\t\t\t\t// Check value.\n\t\t\t\tif ( 'yes' === newValue ) {\n\t\t\t\t\tbutton.setAttribute( 'aria-current', 'true' );\n\t\t\t\t} else {\n\t\t\t\t\tbutton.removeAttribute( 'aria-current' );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle when the button is clicked.\n\t */\n\thandleClick(): void {\n\t\t// Check if slider exists.\n\t\tif ( ! this.slider ) {\n\t\t\t// No its not! Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set current slide.\n\t\tthis.slider.setCurrentSlide( this.getIndex() );\n\t}\n\n\t/**\n\t * Get index of this item inside the navigation.\n\t *\n\t * @return {number} Index.\n\t */\n\tgetIndex(): number {\n\t\t// Check if we have an index.\n\t\tif ( this.getAttribute( 'index' ) ) {\n\t\t\t// Yes, return it.\n\t\t\treturn parseInt( this.getAttribute( 'index' ) ?? '0' );\n\t\t}\n\n\t\t// Initialize variables.\n\t\tconst slideNav: TPSliderNavElement | null = this.closest( 'tp-slider-nav' );\n\t\tconst step = this.slider?.step ?? 1;\n\t\tconst perView = this.slider?.perView ?? 1;\n\t\tconst totalSlides = this.slider?.getTotalSlides() ?? 1;\n\t\tconst index = Array.from( slideNav?.children ?? [] ).indexOf( this );\n\n\t\t// Find posible position of the slide.\n\t\tconst lastItem = ( totalSlides - perView ) + 1;\n\t\tconst targetSlide = ( index * step ) + 1;\n\n\t\t// Get the new slide number.\n\t\tconst currentSlideIndex = Math.min( lastItem, targetSlide );\n\n\t\t// return the index.\n\t\treturn currentSlideIndex;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPSliderElement } from './tp-slider';\n\n/**\n * TP Slider Count.\n */\nexport class TPSliderCountElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} Observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes observed by this component.\n\t\treturn [ 'format' ];\n\t}\n\n\t/**\n\t * Get format.\n\t *\n\t * @return {string} Format.\n\t */\n\tget format(): string {\n\t\t// Get the 'format' attribute value.\n\t\treturn this.getAttribute( 'format' ) ?? '$current / $total';\n\t}\n\n\t/**\n\t * Set format.\n\t *\n\t * @param {string} format Format.\n\t */\n\tset format( format: string ) {\n\t\t// Set the 'format' attribute value.\n\t\tthis.setAttribute( 'format', format );\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t */\n\tattributeChangedCallback(): void {\n\t\t// On change of format attribute, update the component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update component.\n\t */\n\tupdate(): void {\n\t\t// Get slider.\n\t\tconst slider: TPSliderElement | null = this.closest( 'tp-slider' );\n\n\t\t// Check if slider exists.\n\t\tif ( ! slider ) {\n\t\t\t// No its not! Terminate.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initializing current variable including per view. Along with initializing total variable.\n\t\tconst current: number = Math.min( slider.currentSlideIndex - 1 + slider.perView, slider.getTotalSlides() );\n\t\tconst total: string = slider.getAttribute( 'total' ) ?? '';\n\n\t\t// Updating variables in format attribute.\n\t\tthis.innerHTML =\n\t\t\tthis.format\n\t\t\t\t.replace( '$current', current.toString() )\n\t\t\t\t.replace( '$total', total || '' );\n\n\t\t// Updating current and total attributes.\n\t\tthis.setAttribute( 'current', current.toString() );\n\t\tthis.setAttribute( 'total', total || '' );\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPSliderElement } from './tp-slider';\nimport { TPSliderTrackElement } from './tp-slider-track';\nimport { TPSliderSlidesElement } from './tp-slider-slides';\nimport { TPSliderSlideElement } from './tp-slider-slide';\nimport { TPSliderArrowElement } from './tp-slider-arrow';\nimport { TPSliderNavElement } from './tp-slider-nav';\nimport { TPSliderNavItemElement } from './tp-slider-nav-item';\nimport { TPSliderCountElement } from './tp-slider-count';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-slider-nav', TPSliderNavElement );\ncustomElements.define( 'tp-slider', TPSliderElement );\ncustomElements.define( 'tp-slider-count', TPSliderCountElement );\ncustomElements.define( 'tp-slider-track', TPSliderTrackElement );\ncustomElements.define( 'tp-slider-slides', TPSliderSlidesElement );\ncustomElements.define( 'tp-slider-slide', TPSliderSlideElement );\ncustomElements.define( 'tp-slider-arrow', TPSliderArrowElement );\ncustomElements.define( 'tp-slider-nav-item', TPSliderNavItemElement );\n"],"names":["TPSliderElement","HTMLElement","constructor","super","touchStartX","touchStartY","swipeThreshold","allowedResponsiveKeys","this","getAttribute","setAttribute","Number","slide","autoSlide","responsiveSettingsJSON","responsiveSettings","JSON","parse","window","addEventListener","handleResize","bind","document","fonts","ready","then","handleTouchStart","passive","handleTouchEnd","handleKeyDown","e","key","preventDefault","previous","next","connectedCallback","update","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","bubbles","currentSlideIndex","parseInt","index","setCurrentSlide","step","toString","perView","getTotalSlides","slides","getSlideElements","length","slidesElement","querySelector","querySelectorAll","totalSlides","nextSlideIndex","Math","min","totalPossibleGroups","ceil","previousSlideNumber","round","currentGroup","getCurrentSlide","detail","slideIndex","slidesContainer","setTimeout","updateHeight","style","left","offsetLeft","getArrow","selector","arrows","parentSliderElement","theArrow","forEach","arrow","closest","sliderNav","sliderCounts","leftArrow","rightArrow","customElements","whenDefined","manageAria","firstVisibleIndex","lastVisibleIndex","removeAttribute","updateNavItems","sliderNavItems","navItem","allItems","slideCount","removeProperty","currentIndex","slidesOnCurrentView","maxHeight","i","scrollHeight","height","updateAttributesResponsively","every","settings","matchMedia","media","matches","settingKey","includes","touches","clientX","clientY","touchEndX","changedTouches","touchEndY","swipeDistanceX","swipeDistanceY","abs","autoSlideInterval","interval","TPSliderTrackElement","TPSliderSlidesElement","ResizeObserver","handleHeightChange","observe","slider","TPSliderSlideElement","TPSliderArrowElement","handleClick","TPSliderNavElement","template","totalNavItems","innerHTML","content","cloneNode","div","createElement","appendChild","replace","TPSliderNavItemElement","_oldValue","button","getIndex","slideNav","lastItem","targetSlide","Array","from","children","indexOf","TPSliderCountElement","format","current","total","define"],"ignoreList":[],"sourceRoot":""}
@@ -1,2 +1,2 @@
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();if(!e||!r||""===i)return;r instanceof HTMLAnchorElement&&"yes"!==e.getAttribute("update-url")&&t.preventDefault();const s=document.getElementById(i);if(s){const t=s.closest("tp-tabs");if(t&&t!==e){t.setAttribute("current-tab",i);const r=t.closest("tp-tabs-tab");return void(r&&r.id&&(e.getAttribute("current-tab")===r.id?e.update():e.setAttribute("current-tab",r.id)))}}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(){setTimeout((()=>{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")}))}),0)}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)})();
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();if(!e||!r||""===i)return;r instanceof HTMLAnchorElement&&"yes"!==e.getAttribute("update-url")&&t.preventDefault();const s=document.getElementById(i);if(s){const t=s.closest("tp-tabs");if(t&&t!==e){t.setAttribute("current-tab",i);const r=t.closest("tp-tabs-tab");return void(r&&r.id&&(e.getAttribute("current-tab")===r.id?e.update():e.setAttribute("current-tab",r.id)))}}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(){setTimeout(()=>{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")})},0)}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":"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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// Find the target panel.\n\t\tconst targetPanel: HTMLElement | null = document.getElementById( panelId );\n\n\t\t// Check if the target panel belongs to a nested tp-tabs.\n\t\tif ( targetPanel ) {\n\t\t\tconst panelTabs: TPTabsElement | null = targetPanel.closest( 'tp-tabs' );\n\n\t\t\t// If the panel belongs to a different (nested) tp-tabs, update that instead.\n\t\t\tif ( panelTabs && panelTabs !== tabs ) {\n\t\t\t\t// Update the nested tp-tabs.\n\t\t\t\tpanelTabs.setAttribute( 'current-tab', panelId );\n\n\t\t\t\t// Also ensure the parent tab containing the nested tp-tabs is open.\n\t\t\t\tconst parentTab = panelTabs.closest( 'tp-tabs-tab' );\n\n\t\t\t\t// Check if found a parent tab.\n\t\t\t\tif ( parentTab && parentTab.id ) {\n\t\t\t\t\t// Check if parent's current-tab is already the same value.\n\t\t\t\t\tif ( tabs.getAttribute( 'current-tab' ) === parentTab.id ) {\n\t\t\t\t\t\t// Force update since setAttribute won't trigger attributeChangedCallback.\n\t\t\t\t\t\ttabs.update();\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttabs.setAttribute( 'current-tab', parentTab.id );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Exit early since we've handled the nested case.\n\t\t\t\treturn;\n\t\t\t}\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// Wrap inside setTimeout to avoid high INP.\n\t\tsetTimeout( () => {\n\t\t\t// Get current tab.\n\t\t\tconst currentTab: string = this.getAttribute( 'current-tab' ) ?? '';\n\n\t\t\t// Check if current tab exists.\n\t\t\tif ( ! this.querySelector( `tp-tabs-tab[id=\"${ currentTab }\"]` ) ) {\n\t\t\t\t// Exit if no matching tab is found.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get current nested tab if has.\n\t\t\tconst currentNestedTab = this.getCurrentNestedTab( currentTab );\n\n\t\t\t// Update nav items.\n\t\t\tconst navItems: NodeListOf<TPTabsNavItemElement> = this.querySelectorAll( 'tp-tabs-nav-item' );\n\n\t\t\t// Update the navigation items based on the current tab.\n\t\t\tif ( navItems ) {\n\t\t\t\tnavItems.forEach( ( navItem: TPTabsNavItemElement ): void => {\n\t\t\t\t\t// If the nav item corresponds to the current tab or nested tab, set it as active.\n\t\t\t\t\tif ( navItem.isCurrentTab( currentTab ) || ( currentNestedTab && navItem.isCurrentTab( currentNestedTab ) ) ) {\n\t\t\t\t\t\tnavItem.setAttribute( 'active', 'yes' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnavItem.removeAttribute( 'active' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Update tabs.\n\t\t\tconst tabs: NodeListOf<TPTabsTabElement> = this.querySelectorAll( 'tp-tabs-tab' );\n\n\t\t\t// Update the tab panels based on the current tab.\n\t\t\tif ( tabs ) {\n\t\t\t\ttabs.forEach( ( tab: TPTabsTabElement ): void => {\n\t\t\t\t\t// If the tab corresponds to the current tab or nested tab, open it.\n\t\t\t\t\tif ( currentTab === tab.getAttribute( 'id' ) || ( currentNestedTab && currentNestedTab === tab.getAttribute( 'id' ) ) ) {\n\t\t\t\t\t\ttab.setAttribute( 'open', 'yes' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttab.removeAttribute( 'open' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t}, 0 );\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","targetPanel","document","getElementById","panelTabs","parentTab","update","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","dispatchEvent","CustomEvent","bubbles","setTimeout","currentNestedTab","getCurrentNestedTab","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// Find the target panel.\n\t\tconst targetPanel: HTMLElement | null = document.getElementById( panelId );\n\n\t\t// Check if the target panel belongs to a nested tp-tabs.\n\t\tif ( targetPanel ) {\n\t\t\tconst panelTabs: TPTabsElement | null = targetPanel.closest( 'tp-tabs' );\n\n\t\t\t// If the panel belongs to a different (nested) tp-tabs, update that instead.\n\t\t\tif ( panelTabs && panelTabs !== tabs ) {\n\t\t\t\t// Update the nested tp-tabs.\n\t\t\t\tpanelTabs.setAttribute( 'current-tab', panelId );\n\n\t\t\t\t// Also ensure the parent tab containing the nested tp-tabs is open.\n\t\t\t\tconst parentTab = panelTabs.closest( 'tp-tabs-tab' );\n\n\t\t\t\t// Check if found a parent tab.\n\t\t\t\tif ( parentTab && parentTab.id ) {\n\t\t\t\t\t// Check if parent's current-tab is already the same value.\n\t\t\t\t\tif ( tabs.getAttribute( 'current-tab' ) === parentTab.id ) {\n\t\t\t\t\t\t// Force update since setAttribute won't trigger attributeChangedCallback.\n\t\t\t\t\t\ttabs.update();\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttabs.setAttribute( 'current-tab', parentTab.id );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Exit early since we've handled the nested case.\n\t\t\t\treturn;\n\t\t\t}\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// Wrap inside setTimeout to avoid high INP.\n\t\tsetTimeout( () => {\n\t\t\t// Get current tab.\n\t\t\tconst currentTab: string = this.getAttribute( 'current-tab' ) ?? '';\n\n\t\t\t// Check if current tab exists.\n\t\t\tif ( ! this.querySelector( `tp-tabs-tab[id=\"${ currentTab }\"]` ) ) {\n\t\t\t\t// Exit if no matching tab is found.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get current nested tab if has.\n\t\t\tconst currentNestedTab = this.getCurrentNestedTab( currentTab );\n\n\t\t\t// Update nav items.\n\t\t\tconst navItems: NodeListOf<TPTabsNavItemElement> = this.querySelectorAll( 'tp-tabs-nav-item' );\n\n\t\t\t// Update the navigation items based on the current tab.\n\t\t\tif ( navItems ) {\n\t\t\t\tnavItems.forEach( ( navItem: TPTabsNavItemElement ): void => {\n\t\t\t\t\t// If the nav item corresponds to the current tab or nested tab, set it as active.\n\t\t\t\t\tif ( navItem.isCurrentTab( currentTab ) || ( currentNestedTab && navItem.isCurrentTab( currentNestedTab ) ) ) {\n\t\t\t\t\t\tnavItem.setAttribute( 'active', 'yes' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnavItem.removeAttribute( 'active' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Update tabs.\n\t\t\tconst tabs: NodeListOf<TPTabsTabElement> = this.querySelectorAll( 'tp-tabs-tab' );\n\n\t\t\t// Update the tab panels based on the current tab.\n\t\t\tif ( tabs ) {\n\t\t\t\ttabs.forEach( ( tab: TPTabsTabElement ): void => {\n\t\t\t\t\t// If the tab corresponds to the current tab or nested tab, open it.\n\t\t\t\t\tif ( currentTab === tab.getAttribute( 'id' ) || ( currentNestedTab && currentNestedTab === tab.getAttribute( 'id' ) ) ) {\n\t\t\t\t\t\ttab.setAttribute( 'open', 'yes' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttab.removeAttribute( 'open' );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t}, 0 );\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","targetPanel","document","getElementById","panelTabs","parentTab","update","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","dispatchEvent","CustomEvent","bubbles","setTimeout","currentNestedTab","getCurrentNestedTab","tab","setCurrentTab","tabId","urlHash","location","hash","currentLink","currentTabElement","currentNestedTabElement","customElements","define"],"ignoreList":[],"sourceRoot":""}
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.update()}update(){var t;const e=null!==(t=this.getAttribute("trigger"))&&void 0!==t?t:":scope > *",i=this.querySelectorAll(e);i&&i.forEach((t=>t.addEventListener(this.getEvent(),(()=>{let e=null;["INPUT","SELECT","TEXTAREA"].includes(t.tagName)&&"value"in t&&"string"==typeof t.value&&(e=t.value),this.triggerFired(t,e)}))))}triggerFired(t,e=null){t&&(this.dispatchEvent(new CustomEvent("triggered")),e||""===e?this.hasAttribute("value")||this.hasAttribute("non-empty-value")?this.toggleByValueAttribute(e):this.toggleByTargetDataValue(e):this.toggleWithoutValue())}toggleByValueAttribute(t=""){const e=this.getTargetElements();if(!e)return;let i=[];const r=this.getAttribute("value"),g=this.hasAttribute("non-empty-value");(r||g)&&(r&&(i=r.split(",")),e.forEach((e=>{i.length&&i.includes(t)||g&&t?this.toggleTargetAttribute(e,"on"):this.toggleTargetAttribute(e,"off")})))}toggleByTargetDataValue(t=""){const e=this.getTargetElements();e&&e.forEach((e=>{const i=e.getAttribute("data-toggle-value"),r=e.hasAttribute("data-toggle-non-empty-value");if(!i&&!r)return;let g=[];i&&(g=i.split(",")),g.length&&g.includes(t)||r&&t?this.toggleTargetAttribute(e,"on"):this.toggleTargetAttribute(e,"off")}))}toggleWithoutValue(){const t=this.getTargetElements();t&&t.forEach((t=>{this.toggleTargetAttribute(t)}))}toggleTargetAttribute(t=null,e=""){t&&("on"===e?(t.setAttribute(this.getAttributeName(),this.getAttributeValue()),this.dispatchEvent(new CustomEvent("toggled-on"))):"off"===e?(t.removeAttribute(this.getAttributeName()),this.dispatchEvent(new CustomEvent("toggled-off"))):(t.toggleAttribute(this.getAttributeName()),this.dispatchEvent(new CustomEvent("toggled"))))}getTargetElements(){var t;const e=null!==(t=this.getAttribute("target"))&&void 0!==t?t:"";return""===e?null:this.getAncestorContext().querySelectorAll(e)}getAttributeName(){var t;return null!==(t=this.getAttribute("attribute"))&&void 0!==t?t:"toggled"}getAttributeValue(){var t;return null!==(t=this.getAttribute("attribute-value"))&&void 0!==t?t:"yes"}getEvent(){var t;return null!==(t=this.getAttribute("event"))&&void 0!==t?t:"change"}getAncestorContext(){var t;let e=document;const i=null!==(t=this.getAttribute("closest-ancestor"))&&void 0!==t?t:"";if(""!==i){const t=this.closest(i);t&&(e=t)}return e}}customElements.define("tp-toggle-attribute",t)})();
1
+ (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.update()}update(){var t;const e=null!==(t=this.getAttribute("trigger"))&&void 0!==t?t:":scope > *",i=this.querySelectorAll(e);i&&i.forEach(t=>t.addEventListener(this.getEvent(),()=>{let e=null;["INPUT","SELECT","TEXTAREA"].includes(t.tagName)&&"value"in t&&"string"==typeof t.value&&(e=t.value),this.triggerFired(t,e)}))}triggerFired(t,e=null){t&&(this.dispatchEvent(new CustomEvent("triggered")),e||""===e?this.hasAttribute("value")||this.hasAttribute("non-empty-value")?this.toggleByValueAttribute(e):this.toggleByTargetDataValue(e):this.toggleWithoutValue())}toggleByValueAttribute(t=""){const e=this.getTargetElements();if(!e)return;let i=[];const r=this.getAttribute("value"),g=this.hasAttribute("non-empty-value");(r||g)&&(r&&(i=r.split(",")),e.forEach(e=>{i.length&&i.includes(t)||g&&t?this.toggleTargetAttribute(e,"on"):this.toggleTargetAttribute(e,"off")}))}toggleByTargetDataValue(t=""){const e=this.getTargetElements();e&&e.forEach(e=>{const i=e.getAttribute("data-toggle-value"),r=e.hasAttribute("data-toggle-non-empty-value");if(!i&&!r)return;let g=[];i&&(g=i.split(",")),g.length&&g.includes(t)||r&&t?this.toggleTargetAttribute(e,"on"):this.toggleTargetAttribute(e,"off")})}toggleWithoutValue(){const t=this.getTargetElements();t&&t.forEach(t=>{this.toggleTargetAttribute(t)})}toggleTargetAttribute(t=null,e=""){t&&("on"===e?(t.setAttribute(this.getAttributeName(),this.getAttributeValue()),this.dispatchEvent(new CustomEvent("toggled-on"))):"off"===e?(t.removeAttribute(this.getAttributeName()),this.dispatchEvent(new CustomEvent("toggled-off"))):(t.toggleAttribute(this.getAttributeName()),this.dispatchEvent(new CustomEvent("toggled"))))}getTargetElements(){var t;const e=null!==(t=this.getAttribute("target"))&&void 0!==t?t:"";return""===e?null:this.getAncestorContext().querySelectorAll(e)}getAttributeName(){var t;return null!==(t=this.getAttribute("attribute"))&&void 0!==t?t:"toggled"}getAttributeValue(){var t;return null!==(t=this.getAttribute("attribute-value"))&&void 0!==t?t:"yes"}getEvent(){var t;return null!==(t=this.getAttribute("event"))&&void 0!==t?t:"change"}getAncestorContext(){var t;let e=document;const i=null!==(t=this.getAttribute("closest-ancestor"))&&void 0!==t?t:"";if(""!==i){const t=this.closest(i);t&&(e=t)}return e}}customElements.define("tp-toggle-attribute",t)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/toggle-attribute/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/toggle-attribute/tp-toggle-attribute.ts","webpack://@travelopia/web-components/./src/toggle-attribute/index.ts"],"sourcesContent":["/**\n * TP Toggle Attribute.\n */\nexport class TPToggleAttributeElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Call the parent constructor.\n\t\tsuper();\n\n\t\t// Call the update function to set up event listeners.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update.\n\t */\n\tupdate(): void {\n\t\t// Get trigger elements.\n\t\tconst triggerSelector: string = this.getAttribute( 'trigger' ) ?? ':scope > *';\n\t\tconst triggers: NodeListOf<HTMLElement> = this.querySelectorAll( triggerSelector );\n\n\t\t// Exit the function if no triggers are found.\n\t\tif ( ! triggers ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for value.\n\t\ttriggers.forEach( ( trigger: HTMLElement ) => trigger.addEventListener( this.getEvent(), (): void => {\n\t\t\t// Set value.\n\t\t\tlet value: string | null = null;\n\n\t\t\t// Check if we have a value.\n\t\t\tif ( [ 'INPUT', 'SELECT', 'TEXTAREA' ].includes( trigger.tagName ) && ( 'value' in trigger ) && 'string' === typeof trigger.value ) {\n\t\t\t\tvalue = trigger.value;\n\t\t\t}\n\n\t\t\t// Call the triggerFired function with the trigger element and its value.\n\t\t\tthis.triggerFired( trigger, value );\n\t\t} ) );\n\t}\n\n\t/**\n\t * Trigger has fired the event.\n\t *\n\t * @param {HTMLElement} trigger Trigger element.\n\t * @param {string} value The value of the trigger.\n\t */\n\ttriggerFired( trigger: HTMLElement, value: string | null = null ): void {\n\t\t// Check if we have a trigger.\n\t\tif ( ! trigger ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Dispatch event.\n\t\tthis.dispatchEvent( new CustomEvent( 'triggered' ) );\n\n\t\t// Check if trigger has a value, example: form inputs.\n\t\tif ( value || '' === value ) {\n\t\t\t// Check if we have a value.\n\t\t\tif ( this.hasAttribute( 'value' ) || this.hasAttribute( 'non-empty-value' ) ) {\n\t\t\t\tthis.toggleByValueAttribute( value );\n\t\t\t} else {\n\t\t\t\tthis.toggleByTargetDataValue( value );\n\t\t\t}\n\t\t} else {\n\t\t\t// Trigger does not have a value, example: buttons.\n\t\t\tthis.toggleWithoutValue();\n\t\t}\n\t}\n\n\t/**\n\t * Toggle target based on value attribute set on this component.\n\t *\n\t * @param {string} value Trigger's value.\n\t */\n\ttoggleByValueAttribute( value: string = '' ): void {\n\t\t// Get the target elements.\n\t\tconst targetElements = this.getTargetElements();\n\n\t\t// Check if we can continue\n\t\tif ( ! targetElements ) {\n\t\t\t// We can't.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize values.\n\t\tlet values: string[] = [];\n\n\t\t// Get value to listen for.\n\t\tconst valuesAttribute = this.getAttribute( 'value' );\n\t\tconst nonEmptyValuesAttribute = this.hasAttribute( 'non-empty-value' );\n\n\t\t// Can we proceed?\n\t\tif ( ! valuesAttribute && ! nonEmptyValuesAttribute ) {\n\t\t\t// Nope.\n\t\t\treturn;\n\t\t}\n\n\t\t// Do we have the values attribute?\n\t\tif ( valuesAttribute ) {\n\t\t\t// Yes, split it.\n\t\t\tvalues = valuesAttribute.split( ',' );\n\t\t}\n\n\t\t// Toggle the target elements.\n\t\ttargetElements.forEach( ( target ) => {\n\t\t\t// Toggle the target's attribute if the target and trigger have the same value.\n\t\t\tif ( ( values.length && values.includes( value ) ) || ( nonEmptyValuesAttribute && value ) ) {\n\t\t\t\tthis.toggleTargetAttribute( target, 'on' );\n\t\t\t} else {\n\t\t\t\tthis.toggleTargetAttribute( target, 'off' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Toggle target based on `data-toggle-value` set on target.\n\t *\n\t * @param {string} value Trigger's value.\n\t */\n\ttoggleByTargetDataValue( value: string = '' ): void {\n\t\t// Get the target elements.\n\t\tconst targetElements = this.getTargetElements();\n\n\t\t// Check if we can continue\n\t\tif ( ! targetElements ) {\n\t\t\t// We can't.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle the target elements.\n\t\ttargetElements.forEach( ( target: HTMLElement ): void => {\n\t\t\t// Get values and split them. Set an empty array otherwise.\n\t\t\tconst valuesAttribute = target.getAttribute( 'data-toggle-value' );\n\t\t\tconst nonEmptyValuesAttribute = target.hasAttribute( 'data-toggle-non-empty-value' );\n\n\t\t\t// Can we proceed?\n\t\t\tif ( ! valuesAttribute && ! nonEmptyValuesAttribute ) {\n\t\t\t\t// Nope, bail.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Initialize values.\n\t\t\tlet values: string[] = [];\n\n\t\t\t// Null check.\n\t\t\tif ( valuesAttribute ) {\n\t\t\t\t// Assign the values.\n\t\t\t\tvalues = valuesAttribute.split( ',' );\n\t\t\t}\n\n\t\t\t// Toggle on element attribute if it matches value or it does not have a data-toggle-value attribute in which case it will match with all non empty values.\n\t\t\tif ( ( values.length && values.includes( value ) ) || ( nonEmptyValuesAttribute && value ) ) {\n\t\t\t\tthis.toggleTargetAttribute( target, 'on' );\n\t\t\t} else {\n\t\t\t\tthis.toggleTargetAttribute( target, 'off' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Toggle the target without any value.\n\t */\n\ttoggleWithoutValue(): void {\n\t\t// Get the target elements.\n\t\tconst targetElements = this.getTargetElements();\n\n\t\t// Check if we can continue\n\t\tif ( ! targetElements ) {\n\t\t\t// We can't.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle the target elements.\n\t\ttargetElements.forEach( ( target: HTMLElement ): void => {\n\t\t\t// Toggle on element attribute if it matches the value.\n\t\t\tthis.toggleTargetAttribute( target );\n\t\t} );\n\t}\n\n\t/**\n\t * Toggle the target's value on or off.\n\t *\n\t * @param {HTMLElement} target The target element.\n\t * @param {string} type Either `on` or `off`.\n\t */\n\ttoggleTargetAttribute( target: HTMLElement | null = null, type: string = '' ): void {\n\t\t// Check if target exists.\n\t\tif ( ! target ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Next toggle attribute on or off.\n\t\tif ( 'on' === type ) {\n\t\t\ttarget.setAttribute( this.getAttributeName(), this.getAttributeValue() );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'toggled-on' ) );\n\t\t} else if ( 'off' === type ) {\n\t\t\ttarget.removeAttribute( this.getAttributeName() );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'toggled-off' ) );\n\t\t} else {\n\t\t\ttarget.toggleAttribute( this.getAttributeName() );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'toggled' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Get target element.\n\t */\n\tgetTargetElements(): NodeListOf<HTMLElement> | null {\n\t\t// Get target selector.\n\t\tconst targetSelector: string = this.getAttribute( 'target' ) ?? '';\n\n\t\t// Check if we have a target selector.\n\t\tif ( '' === targetSelector ) {\n\t\t\t// Return null if no target selector is provided.\n\t\t\treturn null;\n\t\t}\n\n\t\t// Return the target.\n\t\treturn this.getAncestorContext().querySelectorAll( targetSelector );\n\t}\n\n\t/**\n\t * Get attribute name to toggle.\n\t *\n\t * @return {string} The attribute name.\n\t */\n\tgetAttributeName(): string {\n\t\t// Return the attribute name from the 'attribute' attribute or default to 'toggled'.\n\t\treturn this.getAttribute( 'attribute' ) ?? 'toggled';\n\t}\n\n\t/**\n\t * Get attribute value once it is toggled.\n\t *\n\t * @return {string} The attribute value.\n\t */\n\tgetAttributeValue(): string {\n\t\t// Return the attribute value from the 'attribute-value' attribute or default to 'yes'.\n\t\treturn this.getAttribute( 'attribute-value' ) ?? 'yes';\n\t}\n\n\t/**\n\t * Get event.\n\t *\n\t * @return {string} The event.\n\t */\n\tgetEvent(): string {\n\t\t// Return the event type from the 'event' attribute or default to 'change'.\n\t\treturn this.getAttribute( 'event' ) ?? 'change';\n\t}\n\n\t/**\n\t * Get ancestor context.\n\t */\n\tgetAncestorContext(): Document | HTMLElement {\n\t\t// Set default context.\n\t\tlet context: Document | HTMLElement = document;\n\n\t\t// Check for closest ancestor attribute.\n\n\t\t// If set, the context will be the closest target ancestor.\n\n\t\t// Note: The target's ancestor must also be this element's ancestor!\n\t\tconst closestSelector: string = this.getAttribute( 'closest-ancestor' ) ?? '';\n\n\t\t// Find the closest ancestor matching the selector.\n\t\tif ( '' !== closestSelector ) {\n\t\t\tconst closestContext: HTMLElement | null = this.closest( closestSelector );\n\n\t\t\t// Check if we can continue\n\t\t\tif ( closestContext ) {\n\t\t\t\tcontext = closestContext;\n\t\t\t}\n\t\t}\n\n\t\t// Return context.\n\t\treturn context;\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPToggleAttributeElement } from './tp-toggle-attribute';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-toggle-attribute', TPToggleAttributeElement );\n"],"names":["TPToggleAttributeElement","HTMLElement","constructor","super","this","update","triggerSelector","getAttribute","triggers","querySelectorAll","forEach","trigger","addEventListener","getEvent","value","includes","tagName","triggerFired","dispatchEvent","CustomEvent","hasAttribute","toggleByValueAttribute","toggleByTargetDataValue","toggleWithoutValue","targetElements","getTargetElements","values","valuesAttribute","nonEmptyValuesAttribute","split","target","length","toggleTargetAttribute","type","setAttribute","getAttributeName","getAttributeValue","removeAttribute","toggleAttribute","targetSelector","getAncestorContext","context","document","closestSelector","closestContext","closest","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/toggle-attribute/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/toggle-attribute/tp-toggle-attribute.ts","webpack://@travelopia/web-components/./src/toggle-attribute/index.ts"],"sourcesContent":["/**\n * TP Toggle Attribute.\n */\nexport class TPToggleAttributeElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Call the parent constructor.\n\t\tsuper();\n\n\t\t// Call the update function to set up event listeners.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update.\n\t */\n\tupdate(): void {\n\t\t// Get trigger elements.\n\t\tconst triggerSelector: string = this.getAttribute( 'trigger' ) ?? ':scope > *';\n\t\tconst triggers: NodeListOf<HTMLElement> = this.querySelectorAll( triggerSelector );\n\n\t\t// Exit the function if no triggers are found.\n\t\tif ( ! triggers ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for value.\n\t\ttriggers.forEach( ( trigger: HTMLElement ) => trigger.addEventListener( this.getEvent(), (): void => {\n\t\t\t// Set value.\n\t\t\tlet value: string | null = null;\n\n\t\t\t// Check if we have a value.\n\t\t\tif ( [ 'INPUT', 'SELECT', 'TEXTAREA' ].includes( trigger.tagName ) && ( 'value' in trigger ) && 'string' === typeof trigger.value ) {\n\t\t\t\tvalue = trigger.value;\n\t\t\t}\n\n\t\t\t// Call the triggerFired function with the trigger element and its value.\n\t\t\tthis.triggerFired( trigger, value );\n\t\t} ) );\n\t}\n\n\t/**\n\t * Trigger has fired the event.\n\t *\n\t * @param {HTMLElement} trigger Trigger element.\n\t * @param {string} value The value of the trigger.\n\t */\n\ttriggerFired( trigger: HTMLElement, value: string | null = null ): void {\n\t\t// Check if we have a trigger.\n\t\tif ( ! trigger ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Dispatch event.\n\t\tthis.dispatchEvent( new CustomEvent( 'triggered' ) );\n\n\t\t// Check if trigger has a value, example: form inputs.\n\t\tif ( value || '' === value ) {\n\t\t\t// Check if we have a value.\n\t\t\tif ( this.hasAttribute( 'value' ) || this.hasAttribute( 'non-empty-value' ) ) {\n\t\t\t\tthis.toggleByValueAttribute( value );\n\t\t\t} else {\n\t\t\t\tthis.toggleByTargetDataValue( value );\n\t\t\t}\n\t\t} else {\n\t\t\t// Trigger does not have a value, example: buttons.\n\t\t\tthis.toggleWithoutValue();\n\t\t}\n\t}\n\n\t/**\n\t * Toggle target based on value attribute set on this component.\n\t *\n\t * @param {string} value Trigger's value.\n\t */\n\ttoggleByValueAttribute( value: string = '' ): void {\n\t\t// Get the target elements.\n\t\tconst targetElements = this.getTargetElements();\n\n\t\t// Check if we can continue\n\t\tif ( ! targetElements ) {\n\t\t\t// We can't.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize values.\n\t\tlet values: string[] = [];\n\n\t\t// Get value to listen for.\n\t\tconst valuesAttribute = this.getAttribute( 'value' );\n\t\tconst nonEmptyValuesAttribute = this.hasAttribute( 'non-empty-value' );\n\n\t\t// Can we proceed?\n\t\tif ( ! valuesAttribute && ! nonEmptyValuesAttribute ) {\n\t\t\t// Nope.\n\t\t\treturn;\n\t\t}\n\n\t\t// Do we have the values attribute?\n\t\tif ( valuesAttribute ) {\n\t\t\t// Yes, split it.\n\t\t\tvalues = valuesAttribute.split( ',' );\n\t\t}\n\n\t\t// Toggle the target elements.\n\t\ttargetElements.forEach( ( target ) => {\n\t\t\t// Toggle the target's attribute if the target and trigger have the same value.\n\t\t\tif ( ( values.length && values.includes( value ) ) || ( nonEmptyValuesAttribute && value ) ) {\n\t\t\t\tthis.toggleTargetAttribute( target, 'on' );\n\t\t\t} else {\n\t\t\t\tthis.toggleTargetAttribute( target, 'off' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Toggle target based on `data-toggle-value` set on target.\n\t *\n\t * @param {string} value Trigger's value.\n\t */\n\ttoggleByTargetDataValue( value: string = '' ): void {\n\t\t// Get the target elements.\n\t\tconst targetElements = this.getTargetElements();\n\n\t\t// Check if we can continue\n\t\tif ( ! targetElements ) {\n\t\t\t// We can't.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle the target elements.\n\t\ttargetElements.forEach( ( target: HTMLElement ): void => {\n\t\t\t// Get values and split them. Set an empty array otherwise.\n\t\t\tconst valuesAttribute = target.getAttribute( 'data-toggle-value' );\n\t\t\tconst nonEmptyValuesAttribute = target.hasAttribute( 'data-toggle-non-empty-value' );\n\n\t\t\t// Can we proceed?\n\t\t\tif ( ! valuesAttribute && ! nonEmptyValuesAttribute ) {\n\t\t\t\t// Nope, bail.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Initialize values.\n\t\t\tlet values: string[] = [];\n\n\t\t\t// Null check.\n\t\t\tif ( valuesAttribute ) {\n\t\t\t\t// Assign the values.\n\t\t\t\tvalues = valuesAttribute.split( ',' );\n\t\t\t}\n\n\t\t\t// Toggle on element attribute if it matches value or it does not have a data-toggle-value attribute in which case it will match with all non empty values.\n\t\t\tif ( ( values.length && values.includes( value ) ) || ( nonEmptyValuesAttribute && value ) ) {\n\t\t\t\tthis.toggleTargetAttribute( target, 'on' );\n\t\t\t} else {\n\t\t\t\tthis.toggleTargetAttribute( target, 'off' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Toggle the target without any value.\n\t */\n\ttoggleWithoutValue(): void {\n\t\t// Get the target elements.\n\t\tconst targetElements = this.getTargetElements();\n\n\t\t// Check if we can continue\n\t\tif ( ! targetElements ) {\n\t\t\t// We can't.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle the target elements.\n\t\ttargetElements.forEach( ( target: HTMLElement ): void => {\n\t\t\t// Toggle on element attribute if it matches the value.\n\t\t\tthis.toggleTargetAttribute( target );\n\t\t} );\n\t}\n\n\t/**\n\t * Toggle the target's value on or off.\n\t *\n\t * @param {HTMLElement} target The target element.\n\t * @param {string} type Either `on` or `off`.\n\t */\n\ttoggleTargetAttribute( target: HTMLElement | null = null, type: string = '' ): void {\n\t\t// Check if target exists.\n\t\tif ( ! target ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Next toggle attribute on or off.\n\t\tif ( 'on' === type ) {\n\t\t\ttarget.setAttribute( this.getAttributeName(), this.getAttributeValue() );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'toggled-on' ) );\n\t\t} else if ( 'off' === type ) {\n\t\t\ttarget.removeAttribute( this.getAttributeName() );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'toggled-off' ) );\n\t\t} else {\n\t\t\ttarget.toggleAttribute( this.getAttributeName() );\n\t\t\tthis.dispatchEvent( new CustomEvent( 'toggled' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Get target element.\n\t */\n\tgetTargetElements(): NodeListOf<HTMLElement> | null {\n\t\t// Get target selector.\n\t\tconst targetSelector: string = this.getAttribute( 'target' ) ?? '';\n\n\t\t// Check if we have a target selector.\n\t\tif ( '' === targetSelector ) {\n\t\t\t// Return null if no target selector is provided.\n\t\t\treturn null;\n\t\t}\n\n\t\t// Return the target.\n\t\treturn this.getAncestorContext().querySelectorAll( targetSelector );\n\t}\n\n\t/**\n\t * Get attribute name to toggle.\n\t *\n\t * @return {string} The attribute name.\n\t */\n\tgetAttributeName(): string {\n\t\t// Return the attribute name from the 'attribute' attribute or default to 'toggled'.\n\t\treturn this.getAttribute( 'attribute' ) ?? 'toggled';\n\t}\n\n\t/**\n\t * Get attribute value once it is toggled.\n\t *\n\t * @return {string} The attribute value.\n\t */\n\tgetAttributeValue(): string {\n\t\t// Return the attribute value from the 'attribute-value' attribute or default to 'yes'.\n\t\treturn this.getAttribute( 'attribute-value' ) ?? 'yes';\n\t}\n\n\t/**\n\t * Get event.\n\t *\n\t * @return {string} The event.\n\t */\n\tgetEvent(): string {\n\t\t// Return the event type from the 'event' attribute or default to 'change'.\n\t\treturn this.getAttribute( 'event' ) ?? 'change';\n\t}\n\n\t/**\n\t * Get ancestor context.\n\t */\n\tgetAncestorContext(): Document | HTMLElement {\n\t\t// Set default context.\n\t\tlet context: Document | HTMLElement = document;\n\n\t\t// Check for closest ancestor attribute.\n\n\t\t// If set, the context will be the closest target ancestor.\n\n\t\t// Note: The target's ancestor must also be this element's ancestor!\n\t\tconst closestSelector: string = this.getAttribute( 'closest-ancestor' ) ?? '';\n\n\t\t// Find the closest ancestor matching the selector.\n\t\tif ( '' !== closestSelector ) {\n\t\t\tconst closestContext: HTMLElement | null = this.closest( closestSelector );\n\n\t\t\t// Check if we can continue\n\t\t\tif ( closestContext ) {\n\t\t\t\tcontext = closestContext;\n\t\t\t}\n\t\t}\n\n\t\t// Return context.\n\t\treturn context;\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPToggleAttributeElement } from './tp-toggle-attribute';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-toggle-attribute', TPToggleAttributeElement );\n"],"names":["TPToggleAttributeElement","HTMLElement","constructor","super","this","update","triggerSelector","getAttribute","triggers","querySelectorAll","forEach","trigger","addEventListener","getEvent","value","includes","tagName","triggerFired","dispatchEvent","CustomEvent","hasAttribute","toggleByValueAttribute","toggleByTargetDataValue","toggleWithoutValue","targetElements","getTargetElements","values","valuesAttribute","nonEmptyValuesAttribute","split","target","length","toggleTargetAttribute","type","setAttribute","getAttributeName","getAttributeValue","removeAttribute","toggleAttribute","targetSelector","getAncestorContext","context","document","closestSelector","closestContext","closest","customElements","define"],"ignoreList":[],"sourceRoot":""}