Update `@woocommerce/extend-checkout-block` to include an example of a forced inner block (#33833)
* Update main integration file to register newsletter block scripts/styles * Add files for example newsletter block * Use only one internal dependencies comment * Include newsletter block in index * Move entry to correct position in webpack * Rename functions to register scripts and styles * Add changelog * Remove block registration code * Register slug as a block category to prevent warnings in console * Add comment explaining the purpose of the function * Bring templates up to date with latest changes to WC Blocks The way the validation store selectors work was updated, so this template will use the new selectors. * Ensure error message shows when box is not checked * Ensure checkbox is targeted with CSS in editor
This commit is contained in:
parent
bfe0e958b8
commit
c539e5614f
|
@ -19,9 +19,18 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When called invokes any initialization/setup for the integration.
|
* When called invokes any initialization/setup for the integration.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function initialize() {
|
public function initialize() {
|
||||||
|
$this->register_newsletter_block_frontend_scripts();
|
||||||
|
$this->register_newsletter_block_editor_scripts();
|
||||||
|
$this->register_newsletter_block_editor_styles();
|
||||||
|
$this->register_main_integration();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the main JS file required to add filters and Slot/Fills.
|
||||||
|
*/
|
||||||
|
public function register_main_integration() {
|
||||||
$script_path = '/build/index.js';
|
$script_path = '/build/index.js';
|
||||||
$style_path = '/build/style-index.css';
|
$style_path = '/build/style-index.css';
|
||||||
|
|
||||||
|
@ -53,7 +62,6 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
||||||
wp_set_script_translations(
|
wp_set_script_translations(
|
||||||
'{{slug}}-blocks-integration',
|
'{{slug}}-blocks-integration',
|
||||||
'{{slug}}',
|
'{{slug}}',
|
||||||
'{{slug}}',
|
|
||||||
dirname( __FILE__ ) . '/languages'
|
dirname( __FILE__ ) . '/languages'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +72,7 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function get_script_handles() {
|
public function get_script_handles() {
|
||||||
return array( '{{slug}}-blocks-integration' );
|
return array( '{{slug}}-blocks-integration', '{{slug}}-checkout-newsletter-subscription-block-frontend' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +81,7 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function get_editor_script_handles() {
|
public function get_editor_script_handles() {
|
||||||
return array( '{{slug}}-blocks-integration' );
|
return array( '{{slug}}-blocks-integration', '{{slug}}-checkout-newsletter-subscription-block-editor' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,13 +92,77 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
||||||
public function get_script_data() {
|
public function get_script_data() {
|
||||||
$data = array(
|
$data = array(
|
||||||
'{{slug}}-active' => true,
|
'{{slug}}-active' => true,
|
||||||
'example-data' => 'This is some example data from the server',
|
'example-data' => __( 'This is some example data from the server', '{{slug}}' ),
|
||||||
|
'optInDefaultText' => __( 'I want to receive updates about products and promotions.', '{{ slug }}' ),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function register_newsletter_block_editor_styles() {
|
||||||
|
$style_path = '/build/style-{{slug}}-checkout-newsletter-subscription-block.css';
|
||||||
|
|
||||||
|
$style_url = plugins_url( $style_path, __FILE__ );
|
||||||
|
wp_enqueue_style(
|
||||||
|
'{{slug}}-blocks-integration',
|
||||||
|
$style_url,
|
||||||
|
[],
|
||||||
|
$this->get_file_version( $style_path )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function register_newsletter_block_editor_scripts() {
|
||||||
|
$script_path = '/build/{{slug}}-checkout-newsletter-subscription-block.js';
|
||||||
|
$script_url = plugins_url( $script_path, __FILE__ );
|
||||||
|
$script_asset_path = dirname( __FILE__ ) . '/build/{{slug}}-checkout-newsletter-subscription-block.asset.php';
|
||||||
|
$script_asset = file_exists( $script_asset_path )
|
||||||
|
? require $script_asset_path
|
||||||
|
: array(
|
||||||
|
'dependencies' => array(),
|
||||||
|
'version' => $this->get_file_version( $script_asset_path ),
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_register_script(
|
||||||
|
'{{slug}}-checkout-newsletter-subscription-block-editor',
|
||||||
|
$script_url,
|
||||||
|
$script_asset['dependencies'],
|
||||||
|
$script_asset['version'],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_set_script_translations(
|
||||||
|
'{{slug}}-newsletter-block-editor', // script handle
|
||||||
|
'{{slug}}', // text domain
|
||||||
|
dirname( __FILE__ ) . '/languages'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function register_newsletter_block_frontend_scripts() {
|
||||||
|
$script_path = '/build/{{slug}}-checkout-newsletter-subscription-block-frontend.js';
|
||||||
|
$script_url = plugins_url( $script_path, __FILE__ );
|
||||||
|
$script_asset_path = dirname( __FILE__ ) . '/build/newsletter-block-frontend.asset.php';
|
||||||
|
$script_asset = file_exists( $script_asset_path )
|
||||||
|
? require $script_asset_path
|
||||||
|
: array(
|
||||||
|
'dependencies' => array(),
|
||||||
|
'version' => $this->get_file_version( $script_asset_path ),
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_register_script(
|
||||||
|
'{{slug}}-checkout-newsletter-subscription-block-frontend',
|
||||||
|
$script_url,
|
||||||
|
$script_asset['dependencies'],
|
||||||
|
$script_asset['version'],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
wp_set_script_translations(
|
||||||
|
'{{slug}}-checkout-newsletter-subscription-block-frontend', // script handle
|
||||||
|
'{{slug}}', // text domain
|
||||||
|
dirname( __FILE__ ) . '/languages'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the file modified time as a cache buster if we're in dev mode.
|
* Get the file modified time as a cache buster if we're in dev mode.
|
||||||
*
|
*
|
||||||
|
@ -103,4 +175,4 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
||||||
}
|
}
|
||||||
return {{slugPascalCase}}_VERSION;
|
return {{slugPascalCase}}_VERSION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,3 +33,19 @@ add_action('woocommerce_blocks_loaded', function() {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the slug as a block category with WordPress.
|
||||||
|
*/
|
||||||
|
function register_{{slugPascalCase}}_block_category( $categories ) {
|
||||||
|
return array_merge(
|
||||||
|
$categories,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'slug' => '{{slug}}',
|
||||||
|
'title' => __( '{{slugPascalCase}} Blocks', '{{slug}}' ),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
add_action( 'block_categories_all', 'register_{{slugPascalCase}}_block_category', 10, 2 );
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Include an example of adding an inner block to the WooCommerce Blocks Checkout Block
|
|
@ -1 +1,2 @@
|
||||||
import './js/index';
|
import './js/index';
|
||||||
|
import './js/checkout-newsletter-subscription-block';
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { useEffect, useState } from '@wordpress/element';
|
||||||
|
import { CheckboxControl } from '@woocommerce/blocks-checkout';
|
||||||
|
import { getSetting } from '@woocommerce/settings';
|
||||||
|
import { useSelect, useDispatch } from '@wordpress/data';
|
||||||
|
|
||||||
|
const { optInDefaultText } = getSetting( '{{slug}}_data', '' );
|
||||||
|
|
||||||
|
const Block = ( { children, checkoutExtensionData } ) => {
|
||||||
|
const [ checked, setChecked ] = useState( false );
|
||||||
|
const { setExtensionData } = checkoutExtensionData;
|
||||||
|
|
||||||
|
const { setValidationErrors, clearValidationError } = useDispatch(
|
||||||
|
'wc/store/validation'
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
setExtensionData( '{{slug}}', 'optin', checked );
|
||||||
|
if ( ! checked ) {
|
||||||
|
setValidationErrors( {
|
||||||
|
'{{slug}}': {
|
||||||
|
message: 'Please tick the box',
|
||||||
|
hidden: false,
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearValidationError( '{{slug}}' );
|
||||||
|
}, [
|
||||||
|
clearValidationError,
|
||||||
|
setValidationErrors,
|
||||||
|
checked,
|
||||||
|
setExtensionData,
|
||||||
|
] );
|
||||||
|
|
||||||
|
const { validationError } = useSelect( ( select ) => {
|
||||||
|
const store = select( 'wc/store/validation' );
|
||||||
|
return {
|
||||||
|
validationError: store.getValidationError( '{{slug}}' ),
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<CheckboxControl
|
||||||
|
id="subscribe-to-newsletter"
|
||||||
|
checked={ checked }
|
||||||
|
onChange={ setChecked }
|
||||||
|
>
|
||||||
|
{ children || optInDefaultText }
|
||||||
|
</CheckboxControl>
|
||||||
|
|
||||||
|
{ validationError?.hidden === false && (
|
||||||
|
<div>
|
||||||
|
<span role="img" aria-label="Warning emoji">
|
||||||
|
⚠️
|
||||||
|
</span>
|
||||||
|
{ validationError?.message }
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Block;
|
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"apiVersion": 2,
|
||||||
|
"name": "{{slug}}/checkout-newsletter-subscription",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"title": "Newsletter Subscription!",
|
||||||
|
"category": "{{slug}}",
|
||||||
|
"description": "Adds a newsletter subscription checkbox to the checkout.",
|
||||||
|
"supports": {
|
||||||
|
"html": false,
|
||||||
|
"align": false,
|
||||||
|
"multiple": false,
|
||||||
|
"reusable": false
|
||||||
|
},
|
||||||
|
"parent": [
|
||||||
|
"woocommerce/checkout-contact-information-block"
|
||||||
|
],
|
||||||
|
"attributes": {
|
||||||
|
"lock": {
|
||||||
|
"type": "object",
|
||||||
|
"default": {
|
||||||
|
"remove": true,
|
||||||
|
"move": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "string",
|
||||||
|
"source": "html",
|
||||||
|
"selector": ".wp-block-{{slug}}-checkout-newsletter-subscription",
|
||||||
|
"default": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"textdomain": "{{slug}}",
|
||||||
|
"editorStyle": "file:../../../build/style-{{slug}}-checkout-newsletter-subscription-block.css"
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import {
|
||||||
|
useBlockProps,
|
||||||
|
RichText,
|
||||||
|
InspectorControls,
|
||||||
|
} from '@wordpress/block-editor';
|
||||||
|
import { PanelBody } from '@wordpress/components';
|
||||||
|
import { CheckboxControl } from '@woocommerce/blocks-checkout';
|
||||||
|
import { getSetting } from '@woocommerce/settings';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import './style.scss';
|
||||||
|
const { optInDefaultText } = getSetting( '{{slug}}_data', '' );
|
||||||
|
|
||||||
|
export const Edit = ( { attributes, setAttributes } ) => {
|
||||||
|
const { text } = attributes;
|
||||||
|
const blockProps = useBlockProps();
|
||||||
|
return (
|
||||||
|
<div { ...blockProps }>
|
||||||
|
<InspectorControls>
|
||||||
|
<PanelBody title={ __( 'Block options', '{{slug}}' ) }>
|
||||||
|
Options for the block go here.
|
||||||
|
</PanelBody>
|
||||||
|
</InspectorControls>
|
||||||
|
<CheckboxControl
|
||||||
|
id="newsletter-text"
|
||||||
|
checked={ false }
|
||||||
|
disabled={ true }
|
||||||
|
/>
|
||||||
|
<RichText
|
||||||
|
value={ text || optInDefaultText }
|
||||||
|
onChange={ ( value ) => setAttributes( { text: value } ) }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Save = ( { attributes } ) => {
|
||||||
|
const { text } = attributes;
|
||||||
|
return (
|
||||||
|
<div { ...useBlockProps.save() }>
|
||||||
|
<RichText.Content value={ text } />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { registerCheckoutBlock } from '@woocommerce/blocks-checkout';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import Block from './block';
|
||||||
|
import metadata from './block.json';
|
||||||
|
|
||||||
|
registerCheckoutBlock( {
|
||||||
|
metadata,
|
||||||
|
component: Block,
|
||||||
|
} );
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { SVG } from '@wordpress/components';
|
||||||
|
import { registerBlockType } from '@wordpress/blocks';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { Edit, Save } from './edit';
|
||||||
|
import metadata from './block.json';
|
||||||
|
registerBlockType( metadata, {
|
||||||
|
icon: {
|
||||||
|
src: (
|
||||||
|
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 16">
|
||||||
|
<g fill="none" fillRule="evenodd">
|
||||||
|
<path
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
d="M2 .75h16c.69 0 1.25.56 1.25 1.25v12c0 .69-.56 1.25-1.25 1.25H2c-.69 0-1.25-.56-1.25-1.25V2C.75 1.31 1.31.75 2 .75z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M7.667 7.667A2.34 2.34 0 0010 5.333 2.34 2.34 0 007.667 3a2.34 2.34 0 00-2.334 2.333 2.34 2.34 0 002.334 2.334zM11.556 3H17v3.889h-5.444V3zm2.722 2.916l1.944-1.36v-.779L14.278 5.14l-1.945-1.362v.778l1.945 1.361zm-5.834-.583a.78.78 0 00-.777-.777.78.78 0 00-.778.777c0 .428.35.778.778.778a.78.78 0 00.777-.778zm3.89 5.904c0-1.945-3.088-2.785-4.667-2.785-1.58 0-4.667.84-4.667 2.785v1.097h9.333v-1.097zM7.666 10c-1.012 0-2.163.389-2.738.778h5.475C9.821 10.38 8.678 10 7.667 10z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</SVG>
|
||||||
|
),
|
||||||
|
foreground: '#874FB9',
|
||||||
|
},
|
||||||
|
edit: Edit,
|
||||||
|
save: Save,
|
||||||
|
} );
|
|
@ -0,0 +1,27 @@
|
||||||
|
.wp-block-{{slug}}-checkout-newsletter-subscription {
|
||||||
|
margin: 20px 0;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.block-editor-rich-text__editable {
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-components-checkbox {
|
||||||
|
margin-right: 16px;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-styles-wrapper {
|
||||||
|
|
||||||
|
.wp-block-{{slug}}-checkout-newsletter-subscription {
|
||||||
|
.wc-block-components-checkbox {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,14 +9,11 @@ import { getSetting } from '@woocommerce/settings';
|
||||||
*/
|
*/
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
const exampleDataFromSettings = getSetting( '{{slug}}_data' );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { registerFilters } from './filters';
|
import { registerFilters } from './filters';
|
||||||
import { ExampleComponent } from './ExampleComponent';
|
import { ExampleComponent } from './ExampleComponent';
|
||||||
|
|
||||||
|
const exampleDataFromSettings = getSetting( '{{slug}}_data' );
|
||||||
|
|
||||||
const render = () => {
|
const render = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -10,6 +10,23 @@ const defaultRules = defaultConfig.module.rules.filter( ( rule ) => {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...defaultConfig,
|
...defaultConfig,
|
||||||
|
entry: {
|
||||||
|
index: path.resolve(process.cwd(), 'src', 'js', 'index.js'),
|
||||||
|
'{{slug}}-checkout-newsletter-subscription-block': path.resolve(
|
||||||
|
process.cwd(),
|
||||||
|
'src',
|
||||||
|
'js',
|
||||||
|
'checkout-newsletter-subscription-block',
|
||||||
|
'index.js'
|
||||||
|
),
|
||||||
|
'{{slug}}-checkout-newsletter-subscription-block-frontend': path.resolve(
|
||||||
|
process.cwd(),
|
||||||
|
'src',
|
||||||
|
'js',
|
||||||
|
'checkout-newsletter-subscription-block',
|
||||||
|
'frontend.js'
|
||||||
|
),
|
||||||
|
},
|
||||||
module: {
|
module: {
|
||||||
...defaultConfig.module,
|
...defaultConfig.module,
|
||||||
rules: [
|
rules: [
|
||||||
|
|
Loading…
Reference in New Issue