diff --git a/INSTRUCTIONS.md b/INSTRUCTIONS.md new file mode 100644 index 0000000..2f25ae9 --- /dev/null +++ b/INSTRUCTIONS.md @@ -0,0 +1,29 @@ +# Progress Indicator Component + +This is where the block comes together. + +You'll see the block render in the editor. + +And you'll almost be finished once you finish this exercise. + +## Exercise + +When this works, `npm run lint:js` and `npm run test:js` should pass. + +In `ProgressIndicator`, you'll conditionally render an `` or a number. + +When conditionally rendering in React, we'll usually use ternary conditionals: +```jsx +
+ { isOpen + ? __( 'This is open', 'progress-indicator' ) + : __( 'This is closed', 'progress-indicator' ) + } +
+``` + +### Files +- [js/src/progress-indicator.exercise.js](js/src/progress-indicator.exercise.js) +- [js/src/edit.js](js/src/edit.js) + +[Solution video](https://bit.ly/364b0Is) diff --git a/js/src/edit.js b/js/src/edit.js index 1ea3cf9..200b115 100644 --- a/js/src/edit.js +++ b/js/src/edit.js @@ -15,7 +15,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import ProgressIndicator from './progress-indicator'; +// 🚧 Import the ProgressIndicator /** * The component for the editor. @@ -33,7 +33,7 @@ export default function Edit( { attributes, setAttributes } ) { ); return
- + { /* 🚧 Render the ProgressIndicator here, with the prop it expects. */ } + { /* Step Lines */ } +
+ { [ ...Array( attributes.numberOfSteps - 1 ) ].map( ( value, index ) => { + const isLineComplete = attributes.currentStep > index + 1; + const style = { + backgroundColor: isLineComplete ? attributes.color : '#d1d5db', + }; + + // 🚧 Return a
with these props: + // key: some unique value + // style: the style object above + // className: "pib-progress-indicator__line" + } ) } +
+ { /* Step Circles */ } + { [ ...Array( attributes.numberOfSteps ) ].map( ( value, index ) => { + const stepNumber = index + 1; + let style = {}; + + if ( attributes.currentStep === stepNumber ) { + style = { + border: `2px solid ${ attributes.color }`, + boxShadow: `#ffffff 0 0 0 0, ${ color.lighten( 43 ).toString() } 0 0 0 4px, #000000 0 0 0 0`, + color: isColorDark ? attributes.color : '#6b7280', + }; + } else if ( attributes.currentStep > stepNumber ) { + style = { + backgroundColor: attributes.color, + border: `2px solid ${ attributes.color }`, + color: isColorDark ? '#ecfdf5' : '#6b7280', + }; + } + + return
+ { /* + 🚧 If the current step is more than stepNumber, render: + + + + Otherwise, simply render stepNumber + */ } +
; + } ) } +
; +} diff --git a/js/src/progress-indicator.final.js b/js/src/progress-indicator.final.js new file mode 100644 index 0000000..b5a320a --- /dev/null +++ b/js/src/progress-indicator.final.js @@ -0,0 +1,61 @@ +/** + * External dependencies + */ +import * as React from 'react'; +import tinycolor2 from 'tinycolor2'; + +/** + * The progress indicator component. + * + * @param {{attributes: import('./index').Attributes}} props + * @return {React.ReactElement} The component. + */ +export default function ProgressIndicator( { attributes } ) { + const color = tinycolor2( attributes.color ); + const isColorDark = color.getBrightness() < 130; + + return
+ { /* Step Lines */ } +
+ { [ ...Array( attributes.numberOfSteps - 1 ) ].map( ( value, index ) => { + const isLineComplete = attributes.currentStep > index + 1; + + return
; + } ) } +
+ { /* Step Circles */ } + { [ ...Array( attributes.numberOfSteps ) ].map( ( value, index ) => { + const stepNumber = index + 1; + let style = {}; + + if ( attributes.currentStep === stepNumber ) { + style = { + border: `2px solid ${ attributes.color }`, + boxShadow: `#ffffff 0 0 0 0, ${ color.lighten( 43 ).toString() } 0 0 0 4px, #000000 0 0 0 0`, + color: isColorDark ? attributes.color : '#6b7280', + }; + } else if ( attributes.currentStep > stepNumber ) { + style = { + backgroundColor: attributes.color, + border: `2px solid ${ attributes.color }`, + color: isColorDark ? '#ecfdf5' : '#6b7280', + }; + } + + return
+ { attributes.currentStep > stepNumber + ? + + + : stepNumber + } +
; + } ) } +
; +} diff --git a/js/src/progress-indicator.js b/js/src/progress-indicator.js index de4d0d1..b616f35 100644 --- a/js/src/progress-indicator.js +++ b/js/src/progress-indicator.js @@ -1,57 +1,7 @@ /** - * External dependencies + * Internal dependencies */ -import * as React from 'react'; -import tinycolor2 from 'tinycolor2'; +import ProgressIndicator from './progress-indicator.exercise'; +// import ProgressIndicator from './progress-indicator.final'; -/** - * The progress indicator component. - * - * @param {{attributes: import('./index').Attributes}} props - * @return {React.ReactElement} The component. - */ -export default function ProgressIndicator( { attributes } ) { - const color = tinycolor2( attributes.color ); - const isColorDark = color.getBrightness() < 130; - - return
- { /* Step Lines */ } -
- { [ ...Array( attributes.numberOfSteps - 1 ) ].map( ( value, index ) => { - const isLineComplete = attributes.currentStep > index + 1; - - return
; - } ) } -
- { /* Step Circles */ } - { [ ...Array( attributes.numberOfSteps ) ].map( ( value, index ) => { - const stepNumber = index + 1; - const style = {}; - - if ( attributes.currentStep === stepNumber ) { - style.border = `2px solid ${ attributes.color }`; - style.boxShadow = `#ffffff 0 0 0 0, ${ color.lighten( 43 ).toString() } 0 0 0 4px, #000000 0 0 0 0`; - style.color = isColorDark ? attributes.color : '#6b7280'; - } else if ( attributes.currentStep > stepNumber ) { - style.backgroundColor = attributes.color; - style.border = `2px solid ${ attributes.color }`; - style.color = isColorDark ? '#ecfdf5' : '#6b7280'; - } - - return
- { attributes.currentStep > stepNumber - ? - - - : stepNumber - } -
; - } ) } -
; -} +export default ProgressIndicator; diff --git a/js/src/save.js b/js/src/save.js index 410cda4..82c9887 100644 --- a/js/src/save.js +++ b/js/src/save.js @@ -7,23 +7,15 @@ 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'; +import { __ } from '@wordpress/i18n'; /** * 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
- -
; +export default function Save() { + return + { __( 'This is a placeholder for the Progress Indicator block', 'progress-indicator' ) } + ; }