Untitled
unknown
plain_text
a year ago
11 kB
8
Indexable
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 options = Array.from( select.querySelectorAll( 'option' ) );
const windowhashdata = window.location.hash ? window.location.hash : ''; // phpcs:ignore
select.addEventListener( 'change', ( e ) => this.selectTab( e, block ) );
document.addEventListener( 'setGatingState', () => {
this.selectedState = getSelectedStateFromLocalStorage();
this.updateTabs( select, options, windowhashdata );
} );
this.updateTabs( select, options );
this.selectTabOnload( block, windowhashdata );
block.dataset.initiallyHidden = false;
if ( block.querySelector( '.is-sticky' ) ) {
this.positionSelectDropdown( block );
}
}
/**
* 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 );
}
}
}
/**
* 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();
}
}
// Send GTM data
assignEventAction( e );
}
/**
* Scroll to selected class when hash is present .
*/
selectTabOnload( block, windowhashdata ) {
if ( windowhashdata ) {
if ( window.history.scrollRestoration ) {
window.history.scrollRestoration = 'manual';
}
const selecteddata = windowhashdata.replace( '#', '' ).toLowerCase();
const targetdata = block.querySelector( `.performance-data-${ selecteddata }` );
const itemsdata = Array.from( block.querySelectorAll( '.performance-data__item' ) );
const elem = document.querySelector( '.performance-data' );
const isAnchorAvailable = [...document.querySelector( '.performance-data__select' ).options]
.filter( x => x.value === selecteddata )[0];
if ( isAnchorAvailable ) {
isAnchorAvailable.setAttribute( 'selected', true );
//Unselect selected itemsdata.
itemsdata.forEach( item => item.setAttribute( 'aria-selected', false ) );
// Select target one.
if ( targetdata ) {
targetdata.setAttribute( 'aria-selected', true );
}
if ( elem ) {
const yOffset = -100;
const y = elem.getBoundingClientRect().top + window.scrollY + yOffset;
window.scrollTo( {top: y, behavior: 'smooth'} );
}
}
}
}
/**
* Just triggers a null change event on select dropdown when the page is scrolled without any change in class selector.
*
* @return void
*/
positionSelectDropdown( block ){
const selectElement = block.querySelector( '.performance-data__select' );
document.addEventListener( 'scroll', () => {
const isFocused = ( document.activeElement === selectElement );
if ( isFocused ) {
selectElement.dispatchEvent( new Event( 'change' ) );
}
} );
}
}
add_filter(
'render_block',
function( $block_content, $block ) {
if ( 'blackstone/performance-data' === $block['blockName'] ) {
if ( $block['innerBlocks'] ) {
$groupTitles = array();
foreach( $block['innerBlocks'] as $inner_block ) {
$groupTitle = $inner_block['attrs']['groupTitle'];
if ( ! empty( $groupTitle ) && ! in_array( $groupTitle, $groupTitles, true ) ) {
$groupTitles[] = $groupTitle;
}
}
if ( empty( $groupTitles ) ) {
$tabs = '<div class="performance-data__action">';
$tabs .= '<div class="custom-select">';
$tabs .= '<select name="performance-class" class="performance-data__select">';
$has_default_states = ! empty(
array_filter(
array_map(
function( $inner_block ) {
return ! empty( $inner_block['attrs']['states'] );
},
$block['innerBlocks']
)
)
);
if ( is_array( $block['innerBlocks'] ) ) {
foreach ( $block['innerBlocks'] as $inner_block ) {
$title = $inner_block['attrs']['title'];
$states = ! empty( $inner_block['attrs']['states'] ) ? $inner_block['attrs']['states'] : [];
$id = sanitize_title_with_dashes( $title );
$gtm_atts = setup_multiple_gtm_attributes(array("category"=>"Page Engagement", "action"=>"Filter Click", "label"=>'Performance Filter | ' . esc_attr( $title ), "component_type"=>"Chart tabs", "click_text"=>esc_attr( $title ), "tag_name"=>"Page Engagement Click"), false);
$tabs .= '<option ' . $gtm_atts . ' value="' . esc_attr( $id ) . '" data-default-in-states="' . esc_attr( implode( ' ', $states ) ) . '">' . esc_html( $title ) . '</option>';
}
}
$tabs .= '</select>';
$tabs .= '</div>';
$tabs .= '</div>';
} else {
$shareClass = __( 'Share Class', 'blackstone' );
$tabs = '<div class="dropdown-container">';
$tabs .= '<div class="dropdown-header" onclick="toggleDropdown()">';
$tabs .= '<div class="share">'. $shareClass .'</div>';
$tabs .= '<div class="dropdown-button">Select an option</div>';
$tabs .= '</div>';
$has_default_states = ! empty(
array_filter(
array_map(
function( $inner_block ) {
return ! empty( $inner_block['attrs']['states'] );
},
$block['innerBlocks']
)
)
);
if ( is_array( $block['innerBlocks'] ) ) {
$groupsPerforamcenBars = array();
foreach( $block['innerBlocks'] as $inner_block ) {
$groupTitle = trim( $inner_block['attrs']['groupTitle'] );
if ( ! isset( $groupsPerforamcenBars[ $groupTitle ] ) ) {
$groupsPerforamcenBars[ $groupTitle ] = array();
}
$groupsPerforamcenBars[ $groupTitle ][] = $inner_block;
}
$tabs .= '<div class="dropdown-options" id="dropdown-options">';
foreach ( $groupsPerforamcenBars as $groupTitle => $group_tabs ) {
$tabs .= '<div class="dropdown-group">';
$tabs .= '<div class="dropdown-group-title">'. $groupTitle .'</div>';
foreach ( $group_tabs as $inner_block ) {
$title = $inner_block['attrs']['title'];
$states = ! empty( $inner_block['attrs']['states'] ) ? $inner_block['attrs']['states'] : [];
$id = sanitize_title_with_dashes( $title );
$groupTitles = $inner_block['attrs']['groupTitle'] ? explode("\n", $inner_block['attrs']['groupTitle']) : [];
$gtm_atts = setup_multiple_gtm_attributes(array("category"=>"Page Engagement", "action"=>"Filter Click", "label"=>'Performance Filter | ' . esc_attr( $title ), "component_type"=>"Chart tabs", "click_text"=>esc_attr( $title ), "tag_name"=>"Page Engagement Click"), false);
$tabs .= '<div class="dropdown-option" onclick="selectOption(\'' . esc_js( $title ) . '\')" ' . $gtm_atts . ' value="' . esc_attr( $id ) . '" data-default-in-states="' . esc_attr( implode( ' ', $states ) ) . '">' . esc_html( $title ) . '</div>';
}
$tabs .= '</div>';
}
$tabs .= '</div>';
}
$tabs .= '</div>';
$tabs .='<script>
document.addEventListener("DOMContentLoaded", function() {
// Set the initial value of the dropdown button to the first option
var firstOption = document.querySelector(".dropdown-option");
var dropdownButton = document.querySelector(".dropdown-button");
if (firstOption) {
dropdownButton.innerText = firstOption.innerText;
}
});
function toggleDropdown() {
var dropdownOptions = document.getElementById("dropdown-options");
var dropdownContainer = document.querySelector(".dropdown-container");
dropdownOptions.classList.toggle("show");
dropdownContainer.classList.toggle("selected");
}
function selectOption(value) {
document.querySelector(".dropdown-button").innerText = value;
document.getElementById("dropdown-options").classList.remove("show");
document.querySelector(".dropdown-container").classList.remove("selected");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
var dropdownContainer = document.querySelector(".dropdown-container");
var dropdownOptions = document.getElementById("dropdown-options");
if (!event.target.closest(".dropdown-container")) {
if (dropdownOptions.classList.contains("show")) {
dropdownOptions.classList.remove("show");
dropdownContainer.classList.remove("selected");
}
}
}
</script>';
}
// Add custom select.
$block_content = str_replace( '<!-- Tabs Placeholder -->', $tabs, $block_content );
$block_content = str_replace( 'data-component="chart-tabs-tab-item-link"', 'data-component="chart-tabs-tab-item-link" data-disable-ga-auto-tracking="true"', $block_content );
if ( $has_default_states ) {
$block_content = str_replace( 'data-initially-hidden="false"', 'data-initially-hidden="true"', $block_content );
}
// Make first item visible.
$block_content = preg_replace( '/role=\"tabpanel\" aria-selected=\"false\"/', 'role="tabpanel" aria-selected="true"', $block_content, 1 );
}
}
return $block_content;
},
10,
2
);Editor is loading...
Leave a Comment