diff --git a/INSTRUCTIONS.md b/INSTRUCTIONS.md new file mode 100644 index 0000000..800fd01 --- /dev/null +++ b/INSTRUCTIONS.md @@ -0,0 +1,37 @@ +# Block Registration + +All content in the WordPress block editor is a block. + +This is similar to other editors like [Medium](https://medium.com/), [Notion](https://www.notion.so/), and [MailChimp](https://mailchimp.com/). + +Blocks are usually interactive, so they have a React component to edit them. + +In this exercise, we're going to register a block so the editor is aware of it. + +The modern way to register a WordPress block is [with](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/) a `block.json` file. + +A `block.json` file [must be present](https://github.com/WordPress/wporg-plugin-guidelines/blob/28d945f414db3bb42e04805fb109e7178cbabc9a/blocks.md#4-block-plugins-must-include-a-blockjson-file) to be eligible for the [Block Directory](https://wordpress.org/plugins/browse/block/). + +Also, WordPress [recommends](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#benefits-using-the-metadata-file) registering a block with PHP and JS. + +Both registrations will be simple because of `block.json`. + +## Exercise + +You're going to register the block in JS and PHP. + +Look for 🚧 in the exercise files for where to edit. + +In [js/src/index.exercise.js](js/src/index.exercise.js), `registerBlockType()` will look like: + +```js +registerBlockType( block.name, { + // edit component here. +``` + +### Files +- [progress-indicator.php](progress-indicator.php) +- [js/src/index.exercise.js](js/src/index.exercise.js) + +### Solution +https://user-images.githubusercontent.com/4063887/159091534-12a41901-4100-4fc5-8222-fa25413977d7.mp4 diff --git a/js/src/edit.js b/js/src/edit.js index 2bbce03..efc53f0 100644 --- a/js/src/edit.js +++ b/js/src/edit.js @@ -6,63 +6,11 @@ import * as React from 'react'; /** * WordPress dependencies */ -import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; -import { ColorPalette, PanelBody, RangeControl } from '@wordpress/components'; -import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; -/** - * Internal dependencies - */ -import ProgressIndicator from './progress-indicator'; - -/** - * The component for the editor. - * - * @param {{ - * attributes: import('./index').Attributes, - * setAttributes: Function - * }} props - * @return {React.ReactElement} The component. - */ -export default function Edit( { attributes, setAttributes } ) { - const blockProps = useBlockProps(); - const { colors } = useSelect( - ( select ) => select( 'core/block-editor' ).getSettings() - ); - - return
- - - - - setAttributes( { color: newValue } ) - } - /> - - - - setAttributes( { currentStep: Number( newValue ) } ) - } - min={ 1 } - max={ attributes.numberOfSteps } - /> - - setAttributes( { numberOfSteps: Number( newValue ) } ) - } - min={ 1 } - max={ 10 } - /> - - -
; +/** The component for the editor. */ +export default function Edit() { + return + { __( 'This is a placeholder for the Progress Indicator block', 'progress-indicator' ) } + ; } diff --git a/js/src/index.exercise.js b/js/src/index.exercise.js new file mode 100644 index 0000000..107976b --- /dev/null +++ b/js/src/index.exercise.js @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import block from '../../block.json'; +// 🚧 Import the edit component. +// Import the save component. + +/** + * @typedef {{ + * color: typeof block.attributes.color.default, + * currentStep: typeof block.attributes.currentStep.default, + * numberOfSteps: typeof block.attributes.numberOfSteps.default + * }} Attributes + */ + +// @ts-ignore The declaration file is wrong. +registerBlockType( block.name, { + // 🚧 For property 'edit', pass the edit component imported above. + // For property 'save', pass the save component imported above. +} ); diff --git a/js/src/index.final.js b/js/src/index.final.js new file mode 100644 index 0000000..8b02e92 --- /dev/null +++ b/js/src/index.final.js @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import block from '../../block.json'; +import edit from './edit'; +import save from './save'; + +/** + * @typedef {{ + * color: typeof block.attributes.color.default, + * currentStep: typeof block.attributes.currentStep.default, + * numberOfSteps: typeof block.attributes.numberOfSteps.default + * }} Attributes + */ + +// @ts-ignore The declaration file is wrong. +registerBlockType( block.name, { + edit, + save, +} ); diff --git a/js/src/index.js b/js/src/index.js index 8b02e92..1271da2 100644 --- a/js/src/index.js +++ b/js/src/index.js @@ -1,25 +1,2 @@ -/** - * WordPress dependencies - */ -import { registerBlockType } from '@wordpress/blocks'; - -/** - * Internal dependencies - */ -import block from '../../block.json'; -import edit from './edit'; -import save from './save'; - -/** - * @typedef {{ - * color: typeof block.attributes.color.default, - * currentStep: typeof block.attributes.currentStep.default, - * numberOfSteps: typeof block.attributes.numberOfSteps.default - * }} Attributes - */ - -// @ts-ignore The declaration file is wrong. -registerBlockType( block.name, { - edit, - save, -} ); +// export * from './index.final'; +export * from './index.exercise'; diff --git a/js/src/progress-indicator.js b/js/src/progress-indicator.js index 2b373b4..9cdddc1 100644 --- a/js/src/progress-indicator.js +++ b/js/src/progress-indicator.js @@ -8,7 +8,6 @@ import tinycolor2 from 'tinycolor2'; * The progress indicator component. * * @param {{attributes: import('./').Attributes}} props - * @return {React.ReactElement} The component. */ export default function ProgressIndicator( { attributes } ) { const color = tinycolor2( attributes.color ); diff --git a/js/src/progress-indicator.test.js b/js/src/progress-indicator.test.js deleted file mode 100644 index b93d704..0000000 --- a/js/src/progress-indicator.test.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * External dependencies - */ -import '@testing-library/jest-dom/extend-expect'; -import { render, screen } from '@testing-library/react'; - -/** - * Internal dependencies - */ -import ProgressIndicator from './progress-indicator'; - -test( 'ProgressIndicator with current step of 2/5', () => { - render( - - ); - - it.each( [ 2, 3, 4, 5 ], ( number ) => { - expect( screen.getByText( number ) ).toBeInTheDocument(); - } ); - - expect( screen.getAllByRole( 'img' ).length ).toEqual( 1 ); -} ); - -test( 'ProgressIndicator with current step of 5/5', () => { - render( - - ); - - expect( screen.queryByText( 4 ) ).not.toBeInTheDocument(); - expect( screen.getByText( 5 ) ).toBeInTheDocument(); - expect( screen.getAllByRole( 'img' ).length ).toEqual( 4 ); -} ); diff --git a/js/src/save.js b/js/src/save.js index 83cb567..178ce7f 100644 --- a/js/src/save.js +++ b/js/src/save.js @@ -6,23 +6,15 @@ import * as React from 'react'; /** * WordPress dependencies */ -import { useBlockProps } from '@wordpress/block-editor'; - -/** - * Internal dependencies - */ -import ProgressIndicator from './progress-indicator'; +import { __ } from '@wordpress/i18n'; /** * The component to save the markup. * - * @param {{attributes: import('./').Attributes}} props * @return {React.ReactElement} The component. */ -export default function Save( { attributes } ) { - const blockProps = useBlockProps.save(); - - return
- -
; +export default function Save() { + return + { __( 'This is a placeholder for the Progress Indicator block', 'progress-indicator' ) } + ; } diff --git a/phpcs.xml b/phpcs.xml index 1250d37..21a3205 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,5 +1,5 @@ - + diff --git a/progress-indicator.php b/progress-indicator.php index a3c5fe9..83192a0 100644 --- a/progress-indicator.php +++ b/progress-indicator.php @@ -22,9 +22,9 @@ add_action( 'init', __NAMESPACE__ . '\register_block' ); -/** - * Registers the block with the block.json file. - */ -function register_block() { - register_block_type( __DIR__ ); -} +// 🚧 Define a function register_block(). +// That function should simply call the PHP function to register a block: https://developer.wordpress.org/reference/functions/register_block_type/ +// And that function's only argument should be the directory of this plugin. +// You can get that directory from a magic constant: https://www.php.net/manual/en/language.constants.magic.php +// That's where it'll look for the block.json file. +// Do npm run lint:php to see if there's anything else to add.