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

Commit

Permalink
Cart i2: Toolbar based view switcher (#4811)
Browse files Browse the repository at this point in the history
* New icons

* Add new view switcher

* Context to pass down component controls

* Implement switcher
  • Loading branch information
mikejolley authored Sep 22, 2021
1 parent df51e2f commit 410eb43
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 14 deletions.
27 changes: 27 additions & 0 deletions assets/js/blocks/cart-checkout/cart-i2/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* External dependencies
*/
import { createContext, useContext } from '@wordpress/element';

/**
* Context consumed by inner blocks.
*/
export type CartBlockControlsContextProps = {
viewSwitcher: {
component: () => JSX.Element | null;
currentView: string;
};
};

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

export const useCartBlockControlsContext = (): CartBlockControlsContextProps => {
return useContext( CartBlockControlsContext );
};
44 changes: 35 additions & 9 deletions assets/js/blocks/cart-checkout/cart-i2/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ import {
import { createInterpolateElement } from '@wordpress/element';
import { getAdminLink, getSetting } from '@woocommerce/settings';
import { previewCart } from '@woocommerce/resource-previews';
import { Icon, filledCart, removeCart } from '@woocommerce/icons';

/**
* Internal dependencies
*/
import './editor.scss';
import { addClassToBody } from './hacks';
import { useViewSwitcher } from './use-view-switcher';
import type { Attributes } from './types';
import { CartBlockControlsContext } from './context';

// This is adds a class to body to signal if the selected block is locked
addClassToBody();
Expand Down Expand Up @@ -142,6 +145,19 @@ export const Edit = ( {
attributes: Attributes;
setAttributes: ( attributes: Record< string, unknown > ) => undefined;
} ): 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 cartClassName = classnames( {
'has-dark-controls': attributes.hasDarkControls,
} );
Expand Down Expand Up @@ -194,15 +210,25 @@ export const Edit = ( {
attributes={ attributes }
setAttributes={ setAttributes }
/>
<CartProvider>
<div className={ cartClassName }>
<InnerBlocks
allowedBlocks={ ALLOWED_BLOCKS }
template={ defaultInnerBlocksTemplate }
templateLock="insert"
/>
</div>
</CartProvider>
<ViewSwitcherComponent />
<CartBlockControlsContext.Provider
value={ {
viewSwitcher: {
component: ViewSwitcherComponent,
currentView,
},
} }
>
<CartProvider>
<div className={ cartClassName }>
<InnerBlocks
allowedBlocks={ ALLOWED_BLOCKS }
template={ defaultInnerBlocksTemplate }
templateLock="insert"
/>
</div>
</CartProvider>
</CartBlockControlsContext.Provider>
</EditorProvider>
</BlockErrorBoundary>
<CartCheckoutCompatibilityNotice blockName="cart" />
Expand Down
2 changes: 1 addition & 1 deletion assets/js/blocks/cart-checkout/cart-i2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const settings = {
keywords: [ __( 'WooCommerce', 'woo-gutenberg-products-block' ) ],
description: __( 'Shopping cart.', 'woo-gutenberg-products-block' ),
supports: {
align: [ 'wide', 'full' ],
align: false,
html: false,
multiple: false,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { innerBlockAreas } from '@woocommerce/blocks-checkout';
*/
import { useForcedLayout } from '../../use-forced-layout';
import { getAllowedBlocks } from '../../editor-utils';
import { useCartBlockControlsContext } from '../../context';

export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
const blockProps = useBlockProps();
Expand All @@ -18,13 +19,19 @@ export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
clientId,
template: allowedBlocks,
} );

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

return (
<div { ...blockProps }>
<div { ...blockProps } hidden={ currentView !== 'emptyCart' }>
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,6 +12,7 @@ import { useForcedLayout } from '../../use-forced-layout';
import { getAllowedBlocks } from '../../editor-utils';
import { Columns } from './../../columns';
import './editor.scss';
import { useCartBlockControlsContext } from '../../context';

export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
const blockProps = useBlockProps();
Expand All @@ -21,8 +22,13 @@ export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
clientId,
template: allowedBlocks,
} );

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

return (
<div { ...blockProps }>
<div { ...blockProps } hidden={ currentView !== 'filledCart' }>
<Columns>
<SidebarLayout className={ 'wc-block-cart' }>
<InnerBlocks
Expand All @@ -31,6 +37,7 @@ export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
/>
</SidebarLayout>
</Columns>
<ViewSwitcherComponent />
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { Icon, cart } from '@woocommerce/icons';
import { Icon, filledCart } from '@woocommerce/icons';
import { registerFeaturePluginBlockType } from '@woocommerce/block-settings';

/**
Expand All @@ -12,7 +12,7 @@ import metadata from './block.json';

registerFeaturePluginBlockType( metadata, {
icon: {
src: <Icon srcElement={ cart } />,
src: <Icon srcElement={ filledCart } />,
foreground: '#874FB9',
},
edit: Edit,
Expand Down
58 changes: 58 additions & 0 deletions assets/js/blocks/cart-checkout/cart-i2/use-view-switcher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { Toolbar, ToolbarDropdownMenu } from '@wordpress/components';
import { BlockControls } from '@wordpress/block-editor';
import { Icon, eye } from '@woocommerce/icons';

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

export const useViewSwitcher = (
views: View[]
): {
currentView: string;
component: () => JSX.Element;
} => {
const initialView =
views?.find( ( view ) => view.default === true ) || views[ 0 ];
const [ currentView, setCurrentView ] = useState( initialView );

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>
);

return {
currentView: currentView.view,
component: ViewSwitcherComponent,
};
};

export default useViewSwitcher;
2 changes: 2 additions & 0 deletions assets/js/icons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ export { default as comment } from './library/comment';
export { default as contact } from './library/contact';
export { default as done } from './library/done';
export { default as discussion } from './library/discussion';
export { default as eye } from './library/eye';
export { default as exclamation } from './library/exclamation';
export { default as external } from './library/external';
export { default as fields } from './library/fields';
export { default as filledCart } from './library/filled-cart';
export { default as folderStarred } from './library/folder-starred';
export { default as folder } from './library/folder';
export { default as formStep } from './library/form-step';
Expand Down
13 changes: 13 additions & 0 deletions assets/js/icons/library/eye.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* External dependencies
*/
import { SVG } from 'wordpress-components';

const eye = (
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="none" d="M0 0h24v24H0V0z" />
<path d="M12 6a9.77 9.77 0 0 1 8.82 5.5C19.17 14.87 15.79 17 12 17s-7.17-2.13-8.82-5.5A9.77 9.77 0 0 1 12 6m0-2C7 4 2.73 7.11 1 11.5 2.73 15.89 7 19 12 19s9.27-3.11 11-7.5C21.27 7.11 17 4 12 4zm0 5a2.5 2.5 0 0 1 0 5 2.5 2.5 0 0 1 0-5m0-2c-2.48 0-4.5 2.02-4.5 4.5S9.52 16 12 16s4.5-2.02 4.5-4.5S14.48 7 12 7z" />
</SVG>
);

export default eye;
19 changes: 19 additions & 0 deletions assets/js/icons/library/filled-cart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* External dependencies
*/
import { SVG } from 'wordpress-components';

const filledCart = (
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g fill="none" fillRule="evenodd">
<path d="M0 0h24v24H0z" />
<path
fill="currentColor"
fillRule="nonzero"
d="M15.55 13c.75 0 1.41-.41 1.75-1.03l3.58-6.49A.996.996 0 0 0 20.01 4H5.21l-.94-2H1v2h2l3.6 7.59-1.35 2.44C4.52 15.37 5.48 17 7 17h12v-2H7l1.1-2h7.45ZM7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2Zm10 0c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2Z"
/>
</g>{ ' ' }
</SVG>
);

export default filledCart;

0 comments on commit 410eb43

Please sign in to comment.