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:
parent
e32fc79aec
commit
4e581a4825
|
@ -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 );
|
||||
},
|
||||
} ) ) }
|
||||
/>
|
||||
|
|
|
@ -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: '',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 );
|
Loading…
Reference in New Issue