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.
|
||||
*
|
||||
*/
|
||||
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';
|
||||
$style_path = '/build/style-index.css';
|
||||
|
||||
|
@ -53,7 +62,6 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
|||
wp_set_script_translations(
|
||||
'{{slug}}-blocks-integration',
|
||||
'{{slug}}',
|
||||
'{{slug}}',
|
||||
dirname( __FILE__ ) . '/languages'
|
||||
);
|
||||
}
|
||||
|
@ -64,7 +72,7 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
|||
* @return string[]
|
||||
*/
|
||||
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[]
|
||||
*/
|
||||
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() {
|
||||
$data = array(
|
||||
'{{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;
|
||||
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
|
@ -103,4 +175,4 @@ class {{slugPascalCase}}_Blocks_Integration implements IntegrationInterface {
|
|||
}
|
||||
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';
|
||||
|
||||
const exampleDataFromSettings = getSetting( '{{slug}}_data' );
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { registerFilters } from './filters';
|
||||
import { ExampleComponent } from './ExampleComponent';
|
||||
|
||||
const exampleDataFromSettings = getSetting( '{{slug}}_data' );
|
||||
|
||||
const render = () => {
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -10,6 +10,23 @@ const defaultRules = defaultConfig.module.rules.filter( ( rule ) => {
|
|||
|
||||
module.exports = {
|
||||
...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: {
|
||||
...defaultConfig.module,
|
||||
rules: [
|
||||
|
|
Loading…
Reference in New Issue