Allow view switcher to toggle view when using Gutenberg list view (https://github.com/woocommerce/woocommerce-blocks/pull/8429)

* Remove old view switcher component (not used)

* Switch in list view

* useSelect

* Optional selection of parent block on changing view

---------

Co-authored-by: Seghir Nadir <nadir.seghir@gmail.com>
This commit is contained in:
Mike Jolley 2023-03-07 11:21:13 +00:00 committed by GitHub
parent e32fc79aec
commit 4e581a4825
4 changed files with 82 additions and 120 deletions

View File

@ -2,7 +2,8 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { useDispatch, select as dataSelect } from '@wordpress/data';
import { useLayoutEffect } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { ToolbarGroup, ToolbarDropdownMenu } from '@wordpress/components';
import { BlockControls } from '@wordpress/block-editor';
import { Icon } from '@wordpress/icons';
@ -12,7 +13,7 @@ import { eye } from '@woocommerce/icons';
* Internal dependencies
*/
import type { View } from './types';
import { getView } from './utils';
import { getView, selectView } from './utils';
export const Switcher = ( {
currentView,
@ -23,10 +24,64 @@ export const Switcher = ( {
views: View[];
clientId: string;
} ): JSX.Element | null => {
const {
getBlockName,
getSelectedBlockClientId,
getBlockParentsByBlockName,
} = useSelect( ( select ) => {
const blockEditor = select( 'core/block-editor' );
return {
getBlockName: blockEditor.getBlockName,
getSelectedBlockClientId: blockEditor.getSelectedBlockClientId,
getBlockParentsByBlockName: blockEditor.getBlockParentsByBlockName,
};
}, [] );
const selectedBlockClientId = getSelectedBlockClientId();
const currentViewObject = getView( currentView, views ) || views[ 0 ];
const currentViewLabel = currentViewObject.label;
const { updateBlockAttributes, selectBlock } =
useDispatch( 'core/block-editor' );
useLayoutEffect( () => {
const selectedBlock = selectedBlockClientId
? getBlockName( selectedBlockClientId )
: null;
// If there is no selected block, or the selected block is the current view, do nothing.
if ( ! selectedBlock || currentView === selectedBlock ) {
return;
}
const viewNames = views.map( ( view ) => view.view );
if ( viewNames.includes( selectedBlock ) ) {
selectView( clientId, selectedBlock );
return;
}
// Look at the parent blocks to see if any of them are a view we can select.
const parentBlockClientIds = getBlockParentsByBlockName(
selectedBlockClientId,
viewNames
);
const parentBlock =
parentBlockClientIds.length === 1
? getBlockName( parentBlockClientIds[ 0 ] )
: null;
// If there is no parent block, or the parent block is the current view, do nothing.
if ( ! parentBlock || currentView === parentBlock ) {
return;
}
selectView( clientId, parentBlock, false );
}, [
clientId,
currentView,
getBlockName,
getBlockParentsByBlockName,
selectedBlockClientId,
views,
] );
return (
<BlockControls>
@ -49,17 +104,7 @@ export const Switcher = ( {
),
isActive: view.view === currentView,
onClick: () => {
updateBlockAttributes( clientId, {
currentView: view.view,
} );
selectBlock(
dataSelect( 'core/block-editor' )
.getBlock( clientId )
?.innerBlocks.find(
( block: { name: string } ) =>
block.name === view.view
)?.clientId || clientId
);
selectView( clientId, view.view );
},
} ) ) }
/>

View File

@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { select } from '@wordpress/data';
import { select, dispatch } from '@wordpress/data';
/**
* Internal dependencies
@ -15,6 +15,27 @@ export const getView = (
return views.find( ( view ) => view.view === viewName );
};
export const selectView = (
clientId: string,
viewName: string,
selectParent = true
) => {
const { updateBlockAttributes, selectBlock } =
dispatch( 'core/block-editor' );
updateBlockAttributes( clientId, {
currentView: viewName,
} );
if ( selectParent ) {
selectBlock(
select( 'core/block-editor' )
.getBlock( clientId )
?.innerBlocks.find(
( block: { name: string } ) => block.name === viewName
)?.clientId || clientId
);
}
};
const defaultView = {
views: [],
currentView: '',

View File

@ -1,14 +0,0 @@
.wc-block-view-switch-control {
text-align: left;
background: #f0f2f3;
box-shadow: 0 0 0 13px #f0f2f3;
margin: 0 0 27px;
visibility: hidden;
color: $gray-700;
}
.has-child-selected,
.is-selected {
.wc-block-view-switch-control {
visibility: visible;
}
}

View File

@ -1,90 +0,0 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { ButtonGroup, Button } from '@wordpress/components';
import { useState } from '@wordpress/element';
import { withInstanceId } from '@wordpress/compose';
/**
* Internal dependencies
*/
import './editor.scss';
const ViewSwitcher = ( {
className,
label = __( 'View', 'woo-gutenberg-products-block' ),
views,
defaultView,
instanceId,
render,
} ) => {
const [ currentView, setCurrentView ] = useState( defaultView );
const classes = classnames( className, 'wc-block-view-switch-control' );
const htmlId = 'wc-block-view-switch-control-' + instanceId;
return (
<>
<div className={ classes }>
<label
htmlFor={ htmlId }
className="wc-block-view-switch-control__label"
>
{ label + ': ' }
</label>
<ButtonGroup id={ htmlId }>
{ views.map( ( view ) => (
<Button
key={ view.value }
isPrimary={ currentView === view.value }
aria-pressed={ currentView === view.value }
onMouseDown={ () => {
if ( currentView !== view.value ) {
setCurrentView( view.value );
}
} }
onClick={ () => {
if ( currentView !== view.value ) {
setCurrentView( view.value );
}
} }
>
{ view.name }
</Button>
) ) }
</ButtonGroup>
</div>
{ render( currentView ) }
</>
);
};
ViewSwitcher.propTypes = {
/**
* Custom class name to add to component.
*/
className: PropTypes.string,
/**
* List of views.
*/
views: PropTypes.arrayOf(
PropTypes.shape( {
name: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
} )
).isRequired,
/**
* The default selected view.
*/
defaultView: PropTypes.string.isRequired,
/**
* Render prop for selected views.
*/
render: PropTypes.func.isRequired,
// from withInstanceId
instanceId: PropTypes.number.isRequired,
};
export default withInstanceId( ViewSwitcher );