Untitled
import { assignEventAction } from '../utils/analytics'; import { getSelectedStateFromLocalStorage } from '../utils/local-storage'; /** * Tabs */ export default class BlackstonePerformanceData { /** * Component Constructor. */ constructor() { this.blocks = Array.from( document.querySelectorAll( '.performance-data' ) ); this.selectedState = getSelectedStateFromLocalStorage(); // Bail if tabs block is not on page if ( ! this.blocks.length ) { return; } this.blocks.forEach( block => this.initBlock( block ) ); } /** * Initialize the block. */ initBlock( block ) { const select = block.querySelector( '.performance-data__select' ); const dropdownHeader = block.querySelector( '.dropdown-header' ); const dropdownButton = block.querySelector( '.dropdown-button' ); const dropdownOptions = Array.from( block.querySelectorAll( '.dropdown-option' ) ); const windowhashdata = window.location.hash ? window.location.hash : ''; // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment if ( select ) { const options = Array.from( select.querySelectorAll( 'option' ) ); select.addEventListener( 'change', ( e ) => this.selectTab( e, block ) ); document.addEventListener( 'setGatingState', () => { this.selectedState = getSelectedStateFromLocalStorage(); this.updateTabs( select, options, windowhashdata ); } ); this.updateTabs( select, options, windowhashdata ); this.selectTabOnload( block, windowhashdata ); block.dataset.initiallyHidden = false; if ( block.querySelector( '.is-sticky' ) ) { this.positionSelectDropdown( block ); } } else { if ( dropdownHeader ) { dropdownHeader.addEventListener( 'click', ( e ) => this.toggleDropdown( e, block ) ); } if ( dropdownButton ) { dropdownButton.addEventListener( 'click', ( e ) => this.toggleDropdown( e, block ) ); } if ( 0 < dropdownOptions.length ) { dropdownOptions.forEach( option => { option.addEventListener( 'click', ( e ) => this.selectDropdownOption( e, block, true ) ); // Add event listener to remove highlighted on hover option.addEventListener( 'mouseenter', () => { dropdownOptions.forEach( opt => opt.classList.remove( 'selected' ) ); } ); } ); } dropdownOptions.forEach( option => { option.addEventListener( 'mouseenter', ( e ) => this.handleHover( e ) ); } ); document.addEventListener( 'click', ( event ) => { if ( !event.target.closest( '.dropdown-container' ) ) { this.closeDropdown( block ); } } ); document.addEventListener( 'setGatingState', () => { this.selectedState = getSelectedStateFromLocalStorage(); this.updateTabsForDropdown( dropdownOptions, windowhashdata, block, false ); } ); block.dataset.initiallyHidden = false; this.updateTabsForDropdown( dropdownOptions, windowhashdata, block, true ); this.selectTabOnloadForDropdown( block, windowhashdata ); window.addEventListener( 'scroll', () => this.handleScroll( block ) ); } // Set the initial value of the dropdown button based on priority: hash value, gating state, or default option const hashValue = windowhashdata ? windowhashdata.replace( '#', '' ).toLowerCase() : null; let selectedOption = null; if ( hashValue ) { selectedOption = dropdownOptions.find( option => option.getAttribute( 'value' ) === hashValue ); } if ( !selectedOption && this.selectedState ) { selectedOption = dropdownOptions.find( option => { const defaultInStates = option.dataset.defaultInStates?.split( ' ' ); return defaultInStates && defaultInStates.includes( this.selectedState ); } ); } if ( !selectedOption ) { selectedOption = dropdownOptions[0]; } if ( selectedOption && dropdownButton ) { dropdownButton.innerText = selectedOption.innerText; this.selectDropdownOption( { target: selectedOption, stopPropagation: () => {} }, block, false ); } } toggleDropdown( e, block ) { e.stopPropagation(); const dropdownOptions = block.querySelector( '.dropdown-options' ); const dropdownContainer = block.querySelector( '.dropdown-container' ); dropdownOptions.classList.toggle( 'show' ); dropdownContainer.classList.toggle( 'selected' ); } closeDropdown( block ) { const dropdownOptions = block.querySelector( '.dropdown-options' ); const dropdownContainer = block.querySelector( '.dropdown-container' ); dropdownOptions.classList.remove( 'show' ); dropdownContainer.classList.remove( 'selected' ); } selectDropdownOption( e, block, sendToGA = true ) { e.stopPropagation(); const selected = e.target.getAttribute( 'value' ); const dropdownButton = block.querySelector( '.dropdown-button' ); const target = block.querySelector( `.performance-data-${selected}` ); const items = Array.from( block.querySelectorAll( '.performance-data__item' ) ); const dropdownOptions = Array.from( block.querySelectorAll( '.dropdown-option' ) ); dropdownOptions.forEach( option => { option.classList.remove( 'selected' ); option.classList.remove( 'hovered' ); } ); // Mark the clicked option as selected e.target.classList.add( 'selected' ); if ( dropdownButton ) { dropdownButton.innerText = e.target.innerText; } items.forEach( item => item.setAttribute( 'aria-selected', false ) ); if ( target ) { target.setAttribute( 'aria-selected', true ); } this.closeDropdown( block ); if (sendToGA) { assignEventAction( e ); } } /** * Update the tabs (for state change); */ updateTabs( select, options, windowhashdata ) { let defaultOption = null; if ( this.selectedState ) { const defaultOptions = options.filter( option => { const defaultInStates = option.dataset.defaultInStates?.split( ' ' ); return defaultInStates.includes( this.selectedState ); } ); if ( defaultOptions.length && ! windowhashdata ) { [defaultOption] = defaultOptions; select.value = defaultOption.value; const changeEvent = new Event( 'change' ); select.dispatchEvent( changeEvent ); } } } updateTabsForDropdown( dropdownOptions, windowhashdata, block, sendToGA = true ) { let defaultOption = null; if ( this.selectedState ) { const defaultOptions = dropdownOptions.filter( option => { const defaultInStates = option.dataset.defaultInStates?.split( ' ' ); return defaultInStates && defaultInStates.includes( this.selectedState ); } ); if ( defaultOptions.length && !windowhashdata ) { [defaultOption] = defaultOptions; const event= new Event( 'click', { bubbles: true } ); defaultOption.dispatchEvent( event ); const dropdownButton = block.querySelector( '.dropdown-button' ); if( dropdownButton ) { dropdownButton.innerText = defaultOption.innerText; } // Ensure the selected option is highlighted dropdownOptions.forEach( option => option.classList.remove( 'selected' ) ); defaultOption.classList.add( 'selected' ); } } } /** * Select Tab Logic. */ selectTab( e, block ) { const selected = e.target.options[ e.target.selectedIndex ].value; const target = block.querySelector( `.performance-data-${ selected }` ); const items = Array.from( block.querySelectorAll( '.performance-data__item' ) ); // Unselect selected items. items.forEach( item => item.setAttribute( 'aria-selected', false ) ); // Select target one. if ( target ) { target.setAttribute( 'aria-selected', true ); // Remove focus to prevent ipad issue with chart selection. e.target.blur(); } /** * Reset the first performance item chart tab to first. * 10up/component-tabs does not provide an api for targetting each instance, * therefore all tabs are updated on the page. `e.isTrusted` ensures it is * an user action and not occuring as a result of `updateTabs` region updates, * which causes onload issues. */ if ( e.isTrusted ) { const firstChartTab = target.querySelector( '.tab-item a[role=tab]' ); if ( firstChartTab ) { firstChartTab.click(); } } assignEventAction( e ); } /** * On page load, select the appropriate tab based on hash value or the first item. */ selectTabOnload( block, windowhashdata ) { const select = block.querySelector( '.performance-data__select' ); const options = Array.from( select.querySelectorAll( 'option' ) ); const hashValue = windowhashdata ? windowhashdata.replace( '#', '' ).toLowerCase() : null; let selectedOption = null; if ( hashValue ) { selectedOption = options.find( option => option.value === hashValue ); } if ( ! selectedOption && this.selectedState ) { selectedOption = options.find( option => { const defaultInStates = option.dataset.defaultInStates?.split( ' ' ); return defaultInStates && defaultInStates.includes( this.selectedState ); } ); } if ( ! selectedOption ) { selectedOption = options[0]; } select.value = selectedOption.value; const changeEvent = new Event( 'change' ); select.dispatchEvent( changeEvent ); } selectTabOnloadForDropdown( block, windowhashdata ) { const dropdownOptions = Array.from( block.querySelectorAll( '.dropdown-option' ) ); const hashValue = windowhashdata ? windowhashdata.replace( '#', '' ).toLowerCase() : null; let selectedOption = null; if ( hashValue ) { selectedOption = dropdownOptions.find( option => option.getAttribute( 'value' ) === hashValue ); } if ( ! selectedOption && this.selectedState ) { selectedOption = dropdownOptions.find( option => { const defaultInStates = option.dataset.defaultInStates?.split( ' ' ); return defaultInStates && defaultInStates.includes( this.selectedState ); } ); } if ( ! selectedOption ) { selectedOption = dropdownOptions[0]; } const event= new Event( 'click', { bubbles: true } ); selectedOption.dispatchEvent( event ); // Ensure the selected option is highlighted dropdownOptions.forEach( option => option.classList.remove( 'selected' ) ); selectedOption.classList.add( 'selected' ); } handleScroll( block ) { const dropdownButton = block.querySelector( '.dropdown-button' ); const dropdownContainer = block.querySelector( '.dropdown-container' ); const dropdownOptions = block.querySelector( '.dropdown-options' ); const isSticky = dropdownButton && dropdownButton.classList.contains( 'sticky' ); if ( ! isSticky ) { return; } if ( window.scrollY > dropdownButton.offsetTop ) { dropdownContainer.classList.add( 'stuck' ); dropdownOptions.classList.add( 'stuck' ); } else { dropdownContainer.classList.remove( 'stuck' ); dropdownOptions.classList.remove( 'stuck' ); } } handleHover( e ) { const dropdownOption = e.target; // Ensure hover is removed from any previously hovered option const dropdownOptions = Array.from( dropdownOption.parentElement.querySelectorAll( '.dropdown-option' ) ); dropdownOptions.forEach( option => option.classList.remove( 'hovered' ) ); // Highlight the hovered option dropdownOption.classList.add( 'hovered' ); } positionSelectDropdown( block ) { const stickyContainer = block.querySelector( '.sticky-container' ); const dropdownContainer = block.querySelector( '.dropdown-container' ); const topOfStickyContainer = stickyContainer.getBoundingClientRect().top + window.scrollY; const topOfDropdownContainer = dropdownContainer.getBoundingClientRect().top + window.scrollY; if ( topOfDropdownContainer > topOfStickyContainer ) { dropdownContainer.classList.add( 'above-sticky' ); } else { dropdownContainer.classList.remove( 'above-sticky' ); } } }
Leave a Comment