Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Cart i2: view switcher shared to children #4817

Merged
merged 5 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 6 additions & 14 deletions assets/js/blocks/cart-checkout/cart-i2/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,14 @@ import { createContext, useContext } from '@wordpress/element';
/**
* Context consumed by inner blocks.
*/
export type CartBlockControlsContextProps = {
viewSwitcher: {
component: () => JSX.Element | null;
currentView: string;
};
export type CartBlockContextProps = {
currentView: string;
};

export const CartBlockControlsContext = createContext<
CartBlockControlsContextProps
>( {
viewSwitcher: {
component: () => null,
currentView: 'filledCart',
},
export const CartBlockContext = createContext< CartBlockContextProps >( {
currentView: '',
} );

export const useCartBlockControlsContext = (): CartBlockControlsContextProps => {
return useContext( CartBlockControlsContext );
export const useCartBlockContext = (): CartBlockContextProps => {
return useContext( CartBlockContext );
};
48 changes: 26 additions & 22 deletions assets/js/blocks/cart-checkout/cart-i2/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import classnames from 'classnames';
import { __ } from '@wordpress/i18n';
import { CartCheckoutFeedbackPrompt } from '@woocommerce/editor-components/feedback-prompt';
import {
InnerBlocks,
useBlockProps,
InnerBlocks,
InspectorControls,
BlockControls,
} from '@wordpress/block-editor';
import { PanelBody, ToggleControl, Notice } from '@wordpress/components';
import { CartCheckoutCompatibilityNotice } from '@woocommerce/editor-components/compatibility-notices';
Expand All @@ -31,7 +32,7 @@ import './editor.scss';
import { addClassToBody, useBlockPropsWithLocking } from './hacks';
import { useViewSwitcher } from './use-view-switcher';
import type { Attributes } from './types';
import { CartBlockControlsContext } from './context';
import { CartBlockContext } from './context';

// This is adds a class to body to signal if the selected block is locked
addClassToBody();
Expand Down Expand Up @@ -140,24 +141,28 @@ export const Edit = ( {
className,
attributes,
setAttributes,
clientId,
}: {
className: string;
attributes: Attributes;
setAttributes: ( attributes: Record< string, unknown > ) => undefined;
clientId: string;
} ): JSX.Element => {
const { currentView, component: ViewSwitcherComponent } = useViewSwitcher( [
{
view: 'emptyCart',
label: __( 'Empty Cart', 'woo-gutenberg-products-block' ),
icon: <Icon srcElement={ removeCart } />,
},
{
view: 'filledCart',
label: __( 'Filled Cart', 'woo-gutenberg-products-block' ),
icon: <Icon srcElement={ filledCart } />,
default: true,
},
] );
const { currentView, component: ViewSwitcherComponent } = useViewSwitcher(
clientId,
[
{
view: 'woocommerce/filled-cart-block',
label: __( 'Filled Cart', 'woo-gutenberg-products-block' ),
icon: <Icon srcElement={ filledCart } />,
},
{
view: 'woocommerce/empty-cart-block',
label: __( 'Empty Cart', 'woo-gutenberg-products-block' ),
icon: <Icon srcElement={ removeCart } />,
},
]
);
const cartClassName = classnames( {
'has-dark-controls': attributes.hasDarkControls,
} );
Expand Down Expand Up @@ -212,13 +217,12 @@ export const Edit = ( {
attributes={ attributes }
setAttributes={ setAttributes }
/>
<ViewSwitcherComponent />
<CartBlockControlsContext.Provider
<BlockControls __experimentalShareWithChildBlocks>
<ViewSwitcherComponent />
</BlockControls>
<CartBlockContext.Provider
value={ {
viewSwitcher: {
component: ViewSwitcherComponent,
currentView,
},
currentView,
} }
>
<CartProvider>
Expand All @@ -230,7 +234,7 @@ export const Edit = ( {
/>
</div>
</CartProvider>
</CartBlockControlsContext.Provider>
</CartBlockContext.Provider>
</EditorProvider>
</BlockErrorBoundary>
<CartCheckoutCompatibilityNotice blockName="cart" />
Expand Down
1 change: 1 addition & 0 deletions assets/js/blocks/cart-checkout/cart-i2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const settings = {
align: false,
html: false,
multiple: false,
__experimentalExposeControlsToChildren: true,
},
example: {
attributes: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,28 @@ import { innerBlockAreas } from '@woocommerce/blocks-checkout';
*/
import { useForcedLayout } from '../../use-forced-layout';
import { getAllowedBlocks } from '../../editor-utils';
import { useCartBlockControlsContext } from '../../context';
import { useCartBlockContext } from '../../context';

export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
const blockProps = useBlockProps();
const { currentView } = useCartBlockContext();
const allowedBlocks = getAllowedBlocks( innerBlockAreas.EMPTY_CART );

useForcedLayout( {
clientId,
template: allowedBlocks,
} );

const {
viewSwitcher: { currentView, component: ViewSwitcherComponent },
} = useCartBlockControlsContext();

return (
<div { ...blockProps } hidden={ currentView !== 'emptyCart' }>
<div
{ ...blockProps }
hidden={ currentView !== 'woocommerce/empty-cart-block' }
>
This is the empty cart block.
<InnerBlocks
allowedBlocks={ allowedBlocks }
templateLock={ false }
/>
<ViewSwitcherComponent />
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@ import { useForcedLayout } from '../../use-forced-layout';
import { getAllowedBlocks } from '../../editor-utils';
import { Columns } from './../../columns';
import './editor.scss';
import { useCartBlockControlsContext } from '../../context';
import { useCartBlockContext } from '../../context';

export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
const blockProps = useBlockProps();
const { currentView } = useCartBlockContext();
const allowedBlocks = getAllowedBlocks( innerBlockAreas.FILLED_CART );

useForcedLayout( {
clientId,
template: allowedBlocks,
} );

const {
viewSwitcher: { currentView, component: ViewSwitcherComponent },
} = useCartBlockControlsContext();

return (
<div { ...blockProps } hidden={ currentView !== 'filledCart' }>
<div
{ ...blockProps }
hidden={ currentView !== 'woocommerce/filled-cart-block' }
>
<Columns>
<SidebarLayout className={ 'wc-block-cart' }>
<InnerBlocks
Expand All @@ -37,7 +36,6 @@ export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
/>
</SidebarLayout>
</Columns>
<ViewSwitcherComponent />
</div>
);
};
Expand Down
54 changes: 28 additions & 26 deletions assets/js/blocks/cart-checkout/cart-i2/use-view-switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,52 @@
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { useDispatch, select } from '@wordpress/data';
import { Toolbar, ToolbarDropdownMenu } from '@wordpress/components';
import { BlockControls } from '@wordpress/block-editor';
import { Icon, eye } from '@woocommerce/icons';
import { store as blockEditorStore } from '@wordpress/block-editor';

interface View {
view: string;
label: string;
icon: string | JSX.Element;
default?: boolean;
}

export const useViewSwitcher = (
clientId: string,
views: View[]
): {
currentView: string;
component: () => JSX.Element;
} => {
const initialView =
views?.find( ( view ) => view.default === true ) || views[ 0 ];
const initialView = views[ 0 ];
const [ currentView, setCurrentView ] = useState( initialView );
const { selectBlock } = useDispatch( 'core/block-editor' );
const { getBlock } = select( blockEditorStore );

const ViewSwitcherComponent = () => (
<BlockControls>
<Toolbar>
<ToolbarDropdownMenu
label={ __(
'Switch view',
'woo-gutenberg-products-block'
) }
text={ currentView.label }
icon={
<Icon
srcElement={ eye }
style={ { marginRight: '8px' } }
/>
}
controls={ views.map( ( view ) => ( {
...view,
title: view.label,
onClick: () => setCurrentView( view ),
} ) ) }
/>
</Toolbar>
</BlockControls>
<Toolbar>
<ToolbarDropdownMenu
label={ __( 'Switch view', 'woo-gutenberg-products-block' ) }
text={ currentView.label }
icon={
<Icon srcElement={ eye } style={ { marginRight: '8px' } } />
}
controls={ views.map( ( view ) => ( {
...view,
title: view.label,
onClick: () => {
setCurrentView( view );
selectBlock(
getBlock( clientId ).innerBlocks.find(
( block: { name: string } ) =>
block.name === view.view
)?.clientId || clientId
);
},
} ) ) }
/>
</Toolbar>
);

return {
Expand Down