/** * External dependencies */ import { __ } from '@wordpress/i18n'; import { useState, useEffect } from '@wordpress/element'; import { useDispatch, select } from '@wordpress/data'; import { ToolbarGroup, ToolbarDropdownMenu } from '@wordpress/components'; import { eye } from '@woocommerce/icons'; import { Icon } from '@wordpress/icons'; import { store as blockEditorStore } from '@wordpress/block-editor'; interface View { view: string; label: string; icon: string | JSX.Element; } function getView( viewName: string, views: View[] ) { return views.find( ( view ) => view.view === viewName ); } export const useViewSwitcher = ( clientId: string, views: View[] ): { currentView: string; component: JSX.Element; } => { const initialView = views[ 0 ]; const [ currentView, setCurrentView ] = useState( initialView ); const { selectBlock } = useDispatch( 'core/block-editor' ); const { getBlock, getSelectedBlockClientId, getBlockParentsByBlockName } = select( blockEditorStore ); const selectedBlockClientId = getSelectedBlockClientId(); useEffect( () => { const selectedBlock = getBlock( selectedBlockClientId ); if ( ! selectedBlock ) { return; } if ( currentView.view === selectedBlock.name ) { return; } const viewNames = views.map( ( { view } ) => view ); if ( viewNames.includes( selectedBlock.name ) ) { const newView = getView( selectedBlock.name, views ); if ( newView ) { return setCurrentView( newView ); } } const parentBlockIds = getBlockParentsByBlockName( selectedBlockClientId, viewNames ); if ( parentBlockIds.length !== 1 ) { return; } const parentBlock = getBlock( parentBlockIds[ 0 ] ); if ( currentView.view === parentBlock.name ) { return; } const newView = getView( parentBlock.name, views ); if ( newView ) { setCurrentView( newView ); } }, [ getBlockParentsByBlockName, selectedBlockClientId, getBlock, currentView.view, views, ] ); const ViewSwitcherComponent = ( } controls={ views.map( ( view ) => ( { ...view, title: { view.label }, isActive: view.view === currentView.view, onClick: () => { setCurrentView( view ); selectBlock( getBlock( clientId ).innerBlocks.find( ( block: { name: string } ) => block.name === view.view )?.clientId || clientId ); }, } ) ) } /> ); return { currentView: currentView.view, component: ViewSwitcherComponent, }; };