diff --git a/INSTRUCTIONS.md b/INSTRUCTIONS.md new file mode 100644 index 0000000..3b31011 --- /dev/null +++ b/INSTRUCTIONS.md @@ -0,0 +1,51 @@ +# Save Component + +This React [component](https://github.com/WordPress/gutenberg/blob/57da3c91a166d917a2a9de98177be9c3dfe07ee5/docs/reference-guides/block-api/block-edit-save.md#save) determines what's saved to the database. + +Its only job is to return markup. + +The returned markup is saved to the database as HTML, with attributes stored in a comment: + +```html + +
+``` + +And that saved markup is what displays on the front-end. + +Unlike the `Edit` component, this component isn't interactive. + +So you won't see `useState()` or REST API calls in `Save`. + +The wrapping element of `Save` [should have](https://github.com/WordPress/gutenberg/blob/57da3c91a166d917a2a9de98177be9c3dfe07ee5/docs/reference-guides/block-api/block-edit-save.md#block-wrapper-props-1) `useBlockProps.save()` spread into it: +```jsx +export default function Save( { attributes } ) { + const blockProps = useBlockProps.save(); + + return
+``` + +This adds classes, and sometimes attributes from the [Block Supports](https://github.com/WordPress/gutenberg/blob/57da3c91a166d917a2a9de98177be9c3dfe07ee5/docs/reference-guides/block-api/block-supports.md#supports) API: +```html +
+``` + +## Exercise +You'll see a lot of [block validation](https://github.com/WordPress/gutenberg/blob/57da3c91a166d917a2a9de98177be9c3dfe07ee5/docs/reference-guides/block-api/block-edit-save.md#validation) notices like: + +>This block contains unexpected or invalid content. + +This is normal when editing the `Save` component. + +Click 'Attempt Block Recovery' and continue developing: + +![unexpected-invalid-content](https://user-images.githubusercontent.com/4063887/152257716-0477a0dc-d666-4249-a5e4-65c96a1e7817.gif) + +Once you finish this `Save` component, this block will be done. + +It'll display on the front-end. + +### File +- [js/src/save.exercise.js](js/src/save.exercise.js) + +[Solution video](https://bit.ly/34tiHr2) diff --git a/js/src/save.exercise.js b/js/src/save.exercise.js new file mode 100644 index 0000000..b2d3818 --- /dev/null +++ b/js/src/save.exercise.js @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import * as React from 'react'; + +/** + * WordPress dependencies + */ +// @ts-ignore The declaration file is outdated. +// 🚧 Import useBlockProps from '@wordpress/block-editor' + +/** + * Internal dependencies + */ +// 🚧 Import ProgressIndicator + +/** + * The component to save the markup. + * + * @param {{attributes: import('./index').Attributes}} props + * @return {React.ReactElement} The component. + */ +export default function Save( { attributes } ) { + // 🚧 Declare a const here and give it the value of useBlockProps.save() + + return
+ { /* 🚧 Render ProgressIndicator, and pass it the prop it expects */ } +
; +} diff --git a/js/src/save.final.js b/js/src/save.final.js new file mode 100644 index 0000000..410cda4 --- /dev/null +++ b/js/src/save.final.js @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import * as React from 'react'; + +/** + * WordPress dependencies + */ +// @ts-ignore The declaration file is outdated. +import { useBlockProps } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import ProgressIndicator from './progress-indicator'; + +/** + * The component to save the markup. + * + * @param {{attributes: import('./index').Attributes}} props + * @return {React.ReactElement} The component. + */ +export default function Save( { attributes } ) { + const blockProps = useBlockProps.save(); + + return
+ +
; +} diff --git a/js/src/save.js b/js/src/save.js index 410cda4..0154ba3 100644 --- a/js/src/save.js +++ b/js/src/save.js @@ -1,29 +1,7 @@ -/** - * External dependencies - */ -import * as React from 'react'; - -/** - * WordPress dependencies - */ -// @ts-ignore The declaration file is outdated. -import { useBlockProps } from '@wordpress/block-editor'; - /** * Internal dependencies */ -import ProgressIndicator from './progress-indicator'; - -/** - * The component to save the markup. - * - * @param {{attributes: import('./index').Attributes}} props - * @return {React.ReactElement} The component. - */ -export default function Save( { attributes } ) { - const blockProps = useBlockProps.save(); +import Save from './save.exercise'; +// import Save from './save.final'; - return
- -
; -} +export default Save;