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

Commit 2caa016

Browse files
authored
Show Cart and Checkout blocks in Style Book (#8888)
* Update forced layout * Track isPreview in editor context * Add preview to checkout * Add preview to cart
1 parent d24aa8f commit 2caa016

File tree

9 files changed

+137
-95
lines changed

9 files changed

+137
-95
lines changed

assets/js/base/context/providers/editor-context.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ interface EditorContextType {
1919

2020
// Get data by name.
2121
getPreviewData: ( name: string ) => Record< string, unknown >;
22+
23+
// Indicates whether in the preview context.
24+
isPreview?: boolean;
2225
}
2326

2427
const EditorContext = createContext( {
@@ -38,11 +41,13 @@ export const EditorProvider = ( {
3841
currentPostId = 0,
3942
previewData = {},
4043
currentView = '',
44+
isPreview = false,
4145
}: {
4246
children: React.ReactChildren;
4347
currentPostId?: number | undefined;
4448
previewData?: Record< string, unknown > | undefined;
4549
currentView?: string | undefined;
50+
isPreview?: boolean | undefined;
4651
} ) => {
4752
const editingPostId = useSelect(
4853
( select ): number =>
@@ -68,6 +73,7 @@ export const EditorProvider = ( {
6873
currentView,
6974
previewData,
7075
getPreviewData,
76+
isPreview,
7177
};
7278

7379
return (

assets/js/blocks/cart-checkout-shared/use-forced-layout.ts renamed to assets/js/blocks/cart-checkout-shared/use-forced-layout/index.ts

Lines changed: 13 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -7,93 +7,14 @@ import {
77
createBlock,
88
getBlockType,
99
createBlocksFromInnerBlocksTemplate,
10-
BlockInstance,
10+
TemplateArray,
1111
} from '@wordpress/blocks';
12-
import type { Block, TemplateArray } from '@wordpress/blocks';
13-
import type { MutableRefObject } from 'react';
14-
15-
interface LockableBlock extends Block {
16-
attributes: {
17-
lock?: {
18-
type: 'object';
19-
remove?: boolean;
20-
move: boolean;
21-
default?: {
22-
remove?: boolean;
23-
move?: boolean;
24-
};
25-
};
26-
};
27-
}
28-
const isBlockLocked = ( {
29-
attributes,
30-
}: {
31-
attributes: LockableBlock[ 'attributes' ];
32-
} ) => Boolean( attributes.lock?.remove || attributes.lock?.default?.remove );
12+
import { useEditorContext } from '@woocommerce/base-context';
3313

3414
/**
35-
* This hook is used to determine which blocks are missing from a block. Given the list of inner blocks of a block, we
36-
* can check for any registered blocks that:
37-
* a) Are locked,
38-
* b) Have the parent set as the current block, and
39-
* c) Are not present in the list of inner blocks.
15+
* Internal dependencies
4016
*/
41-
const getMissingBlocks = (
42-
innerBlocks: BlockInstance[],
43-
registeredBlockTypes: ( LockableBlock | undefined )[]
44-
) => {
45-
const lockedBlockTypes = registeredBlockTypes.filter(
46-
( block: LockableBlock | undefined ) => block && isBlockLocked( block )
47-
);
48-
const missingBlocks: LockableBlock[] = [];
49-
lockedBlockTypes.forEach( ( lockedBlock ) => {
50-
if ( typeof lockedBlock === 'undefined' ) {
51-
return;
52-
}
53-
const existingBlock = innerBlocks.find(
54-
( block ) => block.name === lockedBlock.name
55-
);
56-
57-
if ( ! existingBlock ) {
58-
missingBlocks.push( lockedBlock );
59-
}
60-
} );
61-
return missingBlocks;
62-
};
63-
64-
/**
65-
* This hook is used to determine the position that a missing block should be inserted at.
66-
*
67-
* @return The index to insert the missing block at.
68-
*/
69-
const findBlockPosition = ( {
70-
defaultTemplatePosition,
71-
innerBlocks,
72-
currentDefaultTemplate,
73-
}: {
74-
defaultTemplatePosition: number;
75-
innerBlocks: BlockInstance[];
76-
currentDefaultTemplate: MutableRefObject< TemplateArray >;
77-
} ) => {
78-
switch ( defaultTemplatePosition ) {
79-
case -1:
80-
// The block is not part of the default template, so we append it to the current layout.
81-
return innerBlocks.length;
82-
// defaultTemplatePosition defaults to 0, so if this happens we can just return, this is because the block was
83-
// the first block in the default layout, so we can prepend it to the current layout.
84-
case 0:
85-
return 0;
86-
default:
87-
// The new layout may have extra blocks compared to the default template, so rather than insert
88-
// at the default position, we should append it after another default block.
89-
const adjacentBlock =
90-
currentDefaultTemplate.current[ defaultTemplatePosition - 1 ];
91-
const position = innerBlocks.findIndex(
92-
( { name: blockName } ) => blockName === adjacentBlock[ 0 ]
93-
);
94-
return position === -1 ? defaultTemplatePosition : position + 1;
95-
}
96-
};
17+
import { getMissingBlocks, findBlockPosition } from './utils';
9718

9819
/**
9920
* Hook to ensure FORCED blocks are rendered in the correct place.
@@ -112,11 +33,18 @@ export const useForcedLayout = ( {
11233
} ) => {
11334
const currentRegisteredBlocks = useRef( registeredBlocks );
11435
const currentDefaultTemplate = useRef( defaultTemplate );
115-
11636
const registry = useRegistry();
37+
const { isPreview } = useEditorContext();
38+
11739
useEffect( () => {
11840
let templateSynced = false;
41+
42+
if ( isPreview ) {
43+
return;
44+
}
45+
11946
const { replaceInnerBlocks } = dispatch( 'core/block-editor' );
47+
12048
return registry.subscribe( () => {
12149
const innerBlocks = registry
12250
.select( 'core/block-editor' )
@@ -181,5 +109,5 @@ export const useForcedLayout = ( {
181109
.insertBlocks( blockConfig, insertAtPosition, clientId );
182110
} );
183111
}, 'core/block-editor' );
184-
}, [ clientId, registry ] );
112+
}, [ clientId, isPreview, registry ] );
185113
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import type { Block } from '@wordpress/blocks';
5+
6+
export interface LockableBlock extends Block {
7+
attributes: {
8+
lock?: {
9+
type: 'object';
10+
remove?: boolean;
11+
move: boolean;
12+
default?: {
13+
remove?: boolean;
14+
move?: boolean;
15+
};
16+
};
17+
};
18+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import type { BlockInstance, TemplateArray } from '@wordpress/blocks';
5+
import type { MutableRefObject } from 'react';
6+
7+
/**
8+
* Internal dependencies
9+
*/
10+
import { LockableBlock } from './types';
11+
12+
export const isBlockLocked = ( {
13+
attributes,
14+
}: {
15+
attributes: LockableBlock[ 'attributes' ];
16+
} ) => Boolean( attributes.lock?.remove || attributes.lock?.default?.remove );
17+
18+
/**
19+
* This hook is used to determine which blocks are missing from a block. Given the list of inner blocks of a block, we
20+
* can check for any registered blocks that:
21+
* a) Are locked,
22+
* b) Have the parent set as the current block, and
23+
* c) Are not present in the list of inner blocks.
24+
*/
25+
export const getMissingBlocks = (
26+
innerBlocks: BlockInstance[],
27+
registeredBlockTypes: ( LockableBlock | undefined )[]
28+
) => {
29+
const lockedBlockTypes = registeredBlockTypes.filter(
30+
( block: LockableBlock | undefined ) => block && isBlockLocked( block )
31+
);
32+
const missingBlocks: LockableBlock[] = [];
33+
lockedBlockTypes.forEach( ( lockedBlock ) => {
34+
if ( typeof lockedBlock === 'undefined' ) {
35+
return;
36+
}
37+
const existingBlock = innerBlocks.find(
38+
( block ) => block.name === lockedBlock.name
39+
);
40+
41+
if ( ! existingBlock ) {
42+
missingBlocks.push( lockedBlock );
43+
}
44+
} );
45+
return missingBlocks;
46+
};
47+
48+
/**
49+
* This hook is used to determine the position that a missing block should be inserted at.
50+
*
51+
* @return The index to insert the missing block at.
52+
*/
53+
export const findBlockPosition = ( {
54+
defaultTemplatePosition,
55+
innerBlocks,
56+
currentDefaultTemplate,
57+
}: {
58+
defaultTemplatePosition: number;
59+
innerBlocks: BlockInstance[];
60+
currentDefaultTemplate: MutableRefObject< TemplateArray >;
61+
} ) => {
62+
switch ( defaultTemplatePosition ) {
63+
case -1:
64+
// The block is not part of the default template, so we append it to the current layout.
65+
return innerBlocks.length;
66+
// defaultTemplatePosition defaults to 0, so if this happens we can just return, this is because the block was
67+
// the first block in the default layout, so we can prepend it to the current layout.
68+
case 0:
69+
return 0;
70+
default:
71+
// The new layout may have extra blocks compared to the default template, so rather than insert
72+
// at the default position, we should append it after another default block.
73+
const adjacentBlock =
74+
currentDefaultTemplate.current[ defaultTemplatePosition - 1 ];
75+
const position = innerBlocks.findIndex(
76+
( { name: blockName } ) => blockName === adjacentBlock[ 0 ]
77+
);
78+
return position === -1 ? defaultTemplatePosition : position + 1;
79+
}
80+
};

assets/js/blocks/cart/edit.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import './editor.scss';
2222
import {
2323
addClassToBody,
2424
useBlockPropsWithLocking,
25-
useForcedLayout,
2625
BlockSettings,
2726
} from '../cart-checkout-shared';
2827
import '../cart-checkout-shared/sidebar-notices';
@@ -38,22 +37,17 @@ const ALLOWED_BLOCKS = [
3837
'woocommerce/empty-cart-block',
3938
];
4039

41-
export const Edit = ( { className, attributes, setAttributes, clientId } ) => {
42-
const { hasDarkControls, currentView } = attributes;
40+
export const Edit = ( { className, attributes, setAttributes } ) => {
41+
const { hasDarkControls, currentView, isPreview = false } = attributes;
4342
const defaultTemplate = [
4443
[ 'woocommerce/filled-cart-block', {}, [] ],
4544
[ 'woocommerce/empty-cart-block', {}, [] ],
4645
];
4746
const blockProps = useBlockPropsWithLocking( {
4847
className: classnames( className, 'wp-block-woocommerce-cart', {
49-
'is-editor-preview': attributes.isPreview,
48+
'is-editor-preview': isPreview,
5049
} ),
5150
} );
52-
useForcedLayout( {
53-
clientId,
54-
registeredBlocks: ALLOWED_BLOCKS,
55-
defaultTemplate,
56-
} );
5751

5852
return (
5953
<div { ...blockProps }>
@@ -81,6 +75,7 @@ export const Edit = ( { className, attributes, setAttributes, clientId } ) => {
8175
<EditorProvider
8276
previewData={ { previewCart } }
8377
currentView={ currentView }
78+
isPreview={ isPreview }
8479
>
8580
<CartBlockContext.Provider
8681
value={ {
@@ -92,7 +87,7 @@ export const Edit = ( { className, attributes, setAttributes, clientId } ) => {
9287
<InnerBlocks
9388
allowedBlocks={ ALLOWED_BLOCKS }
9489
template={ defaultTemplate }
95-
templateLock={ false }
90+
templateLock="insert"
9691
/>
9792
</CartProvider>
9893
</SlotFillProvider>

assets/js/blocks/cart/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ const settings = {
3636
html: false,
3737
multiple: false,
3838
},
39+
example: {
40+
attributes: {
41+
isPreview: true,
42+
},
43+
viewportWidth: 800,
44+
},
3945
attributes: blockAttributes,
4046
edit: Edit,
4147
save: Save,

assets/js/blocks/checkout/block.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
"html": false,
1111
"multiple": false
1212
},
13+
"example": {
14+
"attributes": {
15+
"isPreview": true
16+
},
17+
"viewportWidth": 800
18+
},
1319
"attributes": {
1420
"isPreview": {
1521
"type": "boolean",

assets/js/blocks/checkout/edit.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export const Edit = ( {
6464
showReturnToCart,
6565
showRateAfterTaxName,
6666
cartPageId,
67+
isPreview = false,
6768
} = attributes;
6869

6970
const defaultTemplate = [
@@ -146,6 +147,7 @@ export const Edit = ( {
146147
/>
147148
</InspectorControls>
148149
<EditorProvider
150+
isPreview={ isPreview }
149151
previewData={ { previewCart, previewSavedPaymentMethods } }
150152
>
151153
<SlotFillProvider>

assets/js/blocks/checkout/inner-blocks/checkout-fields-block/edit.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const Edit = ( {
2424
clientId: string;
2525
attributes: {
2626
className?: string;
27+
isPreview?: boolean;
2728
};
2829
} ): JSX.Element => {
2930
const blockProps = useBlockProps( {

0 commit comments

Comments
 (0)