From 8bc50d440c374609a2f7836101e5929779978a71 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Fri, 4 Jun 2021 21:41:11 +0530 Subject: [PATCH 01/21] Add Reusable block save button, snackbar on save and Welcome Guide --- packages/block-library/src/block/edit.js | 205 +++++++++--------- packages/block-library/src/block/editor.scss | 28 +++ .../src/block/reusable-block-welcome-guide.js | 48 ++++ 3 files changed, 183 insertions(+), 98 deletions(-) create mode 100644 packages/block-library/src/block/reusable-block-welcome-guide.js diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index bf4f933773d6bf..1f9b78f63e7bb0 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -2,19 +2,9 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; -import { - useEntityBlockEditor, - useEntityProp, - store as coreStore, -} from '@wordpress/core-data'; -import { - Placeholder, - Spinner, - ToolbarGroup, - ToolbarButton, - TextControl, - PanelBody, -} from '@wordpress/components'; +import { useEntityBlockEditor, useEntityProp, store as coreStore } from '@wordpress/core-data'; +import { Placeholder, Spinner, ToolbarGroup, ToolbarButton, TextControl, PanelBody } from '@wordpress/components'; +import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { __experimentalUseInnerBlocksProps as useInnerBlocksProps, @@ -28,120 +18,139 @@ import { } from '@wordpress/block-editor'; import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; import { ungroup } from '@wordpress/icons'; +import { store as noticesStore } from '@wordpress/notices'; -export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { - const [ hasAlreadyRendered, RecursionProvider ] = useNoRecursiveRenders( - ref - ); - const { isMissing, hasResolved } = useSelect( - ( select ) => { - const persistedBlock = select( coreStore ).getEntityRecord( - 'postType', - 'wp_block', - ref - ); - const hasResolvedBlock = select( - coreStore - ).hasFinishedResolution( 'getEntityRecord', [ +/** + * Internal dependencies + */ +import ReusableBlockWelcomeGuide from './reusable-block-welcome-guide'; + +export default function ReusableBlockEdit({ attributes: { ref }, clientId }) { + const [hasAlreadyRendered, RecursionProvider] = useNoRecursiveRenders(ref); + const { isMissing, hasResolved, hasEdits } = useSelect( + (select) => { + const persistedBlock = select(coreStore).getEntityRecord('postType', 'wp_block', ref); + const hasResolvedBlock = select(coreStore).hasFinishedResolution('getEntityRecord', [ 'postType', 'wp_block', ref, - ] ); + ]); + const blockHasEdits = select(coreStore).hasEditsForEntityRecord('postType', 'wp_block', ref); return { hasResolved: hasResolvedBlock, - isMissing: hasResolvedBlock && ! persistedBlock, + isMissing: hasResolvedBlock && !persistedBlock, + hasEdits: blockHasEdits, }; }, - [ ref, clientId ] - ); - - const { - __experimentalConvertBlockToStatic: convertBlockToStatic, - } = useDispatch( reusableBlocksStore ); - - const [ blocks, onInput, onChange ] = useEntityBlockEditor( - 'postType', - 'wp_block', - { id: ref } - ); - const [ title, setTitle ] = useEntityProp( - 'postType', - 'wp_block', - 'title', - ref - ); - - const blockProps = useBlockProps(); - - const innerBlocksProps = useInnerBlocksProps( - {}, - { - value: blocks, - onInput, - onChange, - renderAppender: blocks?.length - ? undefined - : InnerBlocks.ButtonBlockAppender, - } - ); - - if ( hasAlreadyRendered ) { - return ( -
- - { __( 'Block cannot be rendered inside itself.' ) } - + [ref, clientId] + ); + + const { __experimentalConvertBlockToStatic: convertBlockToStatic } = useDispatch(reusableBlocksStore); + + const [blocks, onInput, onChange] = useEntityBlockEditor('postType', 'wp_block', { id: ref }); + const [title, setTitle] = useEntityProp('postType', 'wp_block', 'title', ref); + + const blockProps = useBlockProps(); + + const innerBlocksProps = useInnerBlocksProps( + {}, + { + value: blocks, + onInput, + onChange, + renderAppender: blocks?.length ? undefined : InnerBlocks.ButtonBlockAppender, + } + ); + + // local states for gudie modal + const [isGudieOpen, setIsGudieOpen] = useState(false); + + const { saveEditedEntityRecord } = useDispatch(coreStore); + const { createNotice } = useDispatch(noticesStore); + + // save the unsaved records + const saveEditedRecords = () => { + saveEditedEntityRecord('postType', 'wp_block', ref); + showSnackbar(); + }; + + const showSnackbar = () => { + createNotice('success', __('Reusable block saved.'), { + type: 'snackbar', + isDismissible: true, + actions: [ + { + label: __('Learn more'), + onClick: () => setIsGudieOpen(true), + }, + ], + }); + }; + + if (hasAlreadyRendered) { + return ( +
+ {__('Block cannot be rendered inside itself.')}
); - } - - if ( isMissing ) { - return ( -
- - { __( 'Block has been deleted or is unavailable.' ) } - + } + + if (isMissing) { + return ( +
+ {__('Block has been deleted or is unavailable.')}
); - } - - if ( ! hasResolved ) { - return ( -
+ } + + if (!hasResolved) { + return ( +
); - } - - return ( + } + + return ( -
+
convertBlockToStatic( clientId ) } - label={ __( 'Convert to regular blocks' ) } - icon={ ungroup } + onClick={() => convertBlockToStatic(clientId)} + label={__('Convert to regular blocks')} + icon={ungroup} showTooltip - /> + /> + + + + {__('Save')} + - + + clientId={clientId} + wrapperProps={innerBlocksProps} + className='block-library-block__reusable-block-container' + /> + {isGudieOpen && }
); diff --git a/packages/block-library/src/block/editor.scss b/packages/block-library/src/block/editor.scss index b3eb1a67e99459..93af75d8216943 100644 --- a/packages/block-library/src/block/editor.scss +++ b/packages/block-library/src/block/editor.scss @@ -14,3 +14,31 @@ display: none; } } + +// Styles for Reusable Block Welcome Guide +.edit-reusable-block-welcome-guide { + $image-height: 240px; + $image-width: 312px; + width: 312px; + + &__heading { + font-family: $default-font; + font-size: 24px; + line-height: 1.4; + margin: $grid-unit-20 0 $grid-unit-20 0; + padding: 0 $grid-unit-40; + } + + &__text { + font-size: $default-font-size; + line-height: 1.4; + margin: 0 0 $grid-unit-30 0; + padding: 0 $grid-unit-40; + } + + &__image { + background: #00a0d2; + height: 240px; + margin: 0 0 $grid-unit-20; + } +} diff --git a/packages/block-library/src/block/reusable-block-welcome-guide.js b/packages/block-library/src/block/reusable-block-welcome-guide.js new file mode 100644 index 00000000000000..4ee030453587e1 --- /dev/null +++ b/packages/block-library/src/block/reusable-block-welcome-guide.js @@ -0,0 +1,48 @@ +/** + * WordPress dependencies + */ +import { Guide, ExternalLink } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { + if ( ! isGudieOpen ) { + return null; + } + + return ( + setIsGudieOpen( false ) } + pages={ [ + { + image: ( +
+ ), + content: ( + <> +

+ { __( 'Get familiar with Reusable blocks' ) } +

+

+ { __( + 'You just saved a Reusable block. Any other documents that include this block have been updated to reflect this change. ' + ) } + + { __( 'Learn More.' ) } + +

+ + ), + }, + ] } + /> + ); +} + +export default ReusableBlockWelcomeGuide; From fd391bd5436c248b27398c7ec59ca2d57e9ba17d Mon Sep 17 00:00:00 2001 From: thisissandip Date: Fri, 11 Jun 2021 19:16:34 +0530 Subject: [PATCH 02/21] Update the way to check dirty records and Fix l10n --- packages/block-library/src/block/edit.js | 134 +++++++++++------------ 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 1f9b78f63e7bb0..ac1d3bac56c0b3 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -43,77 +43,77 @@ export default function ReusableBlockEdit({ attributes: { ref }, clientId }) { }; }, [ref, clientId] - ); - - const { __experimentalConvertBlockToStatic: convertBlockToStatic } = useDispatch(reusableBlocksStore); - - const [blocks, onInput, onChange] = useEntityBlockEditor('postType', 'wp_block', { id: ref }); - const [title, setTitle] = useEntityProp('postType', 'wp_block', 'title', ref); - - const blockProps = useBlockProps(); - - const innerBlocksProps = useInnerBlocksProps( - {}, - { - value: blocks, - onInput, - onChange, - renderAppender: blocks?.length ? undefined : InnerBlocks.ButtonBlockAppender, - } - ); - - // local states for gudie modal - const [isGudieOpen, setIsGudieOpen] = useState(false); - - const { saveEditedEntityRecord } = useDispatch(coreStore); - const { createNotice } = useDispatch(noticesStore); - - // save the unsaved records - const saveEditedRecords = () => { - saveEditedEntityRecord('postType', 'wp_block', ref); - showSnackbar(); - }; - - const showSnackbar = () => { - createNotice('success', __('Reusable block saved.'), { - type: 'snackbar', - isDismissible: true, - actions: [ - { - label: __('Learn more'), - onClick: () => setIsGudieOpen(true), - }, - ], - }); - }; - - if (hasAlreadyRendered) { - return ( -
+ ); + + const { __experimentalConvertBlockToStatic: convertBlockToStatic } = useDispatch(reusableBlocksStore); + + const [blocks, onInput, onChange] = useEntityBlockEditor('postType', 'wp_block', { id: ref }); + const [title, setTitle] = useEntityProp('postType', 'wp_block', 'title', ref); + + const blockProps = useBlockProps(); + + const innerBlocksProps = useInnerBlocksProps( + {}, + { + value: blocks, + onInput, + onChange, + renderAppender: blocks?.length ? undefined : InnerBlocks.ButtonBlockAppender, + } + ); + + // local states for gudie modal + const [isGudieOpen, setIsGudieOpen] = useState(false); + + const { saveEditedEntityRecord } = useDispatch(coreStore); + const { createNotice } = useDispatch(noticesStore); + + // save the unsaved records + const saveEditedRecords = () => { + saveEditedEntityRecord('postType', 'wp_block', ref); + showSnackbar(); + }; + + const showSnackbar = () => { + createNotice('success', __('Reusable block saved.'), { + type: 'snackbar', + isDismissible: true, + actions: [ + { + label: __('Learn more'), + onClick: () => setIsGudieOpen(true), + }, + ], + }); + }; + + if (hasAlreadyRendered) { + return ( +
{__('Block cannot be rendered inside itself.')}
); - } - - if (isMissing) { - return ( -
+ } + + if (isMissing) { + return ( +
{__('Block has been deleted or is unavailable.')}
); - } - - if (!hasResolved) { - return ( -
+ } + + if (!hasResolved) { + return ( +
); - } - - return ( + } + + return (
@@ -123,7 +123,7 @@ export default function ReusableBlockEdit({ attributes: { ref }, clientId }) { label={__('Convert to regular blocks')} icon={ungroup} showTooltip - /> + /> + }} + onClick={saveEditedRecords} + label={__('Save Globally')} + showTooltip + isDisabled={!hasEdits}> {__('Save')} @@ -149,7 +149,7 @@ export default function ReusableBlockEdit({ attributes: { ref }, clientId }) { clientId={clientId} wrapperProps={innerBlocksProps} className='block-library-block__reusable-block-container' - /> + /> {isGudieOpen && }
From afe992244e941cf26d297f5c7605a34363982461 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Fri, 11 Jun 2021 19:20:39 +0530 Subject: [PATCH 03/21] Remove External Link and Update Finish Button Text in Welcome Gudie --- .../src/block/reusable-block-welcome-guide.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/block/reusable-block-welcome-guide.js b/packages/block-library/src/block/reusable-block-welcome-guide.js index 4ee030453587e1..0092c30271f313 100644 --- a/packages/block-library/src/block/reusable-block-welcome-guide.js +++ b/packages/block-library/src/block/reusable-block-welcome-guide.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { Guide, ExternalLink } from '@wordpress/components'; +import { Guide } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { @@ -13,7 +13,7 @@ function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { setIsGudieOpen( false ) } pages={ [ { @@ -29,13 +29,6 @@ function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { { __( 'You just saved a Reusable block. Any other documents that include this block have been updated to reflect this change. ' ) } - - { __( 'Learn More.' ) } -

), From 424fbc967e11db14bcda85e04ae5863a7220034b Mon Sep 17 00:00:00 2001 From: thisissandip Date: Tue, 15 Jun 2021 20:43:53 +0530 Subject: [PATCH 04/21] Move Save Button to it's own group --- packages/block-library/src/block/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index ac1d3bac56c0b3..06e41c7fcde4d9 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -17,7 +17,7 @@ import { Warning, } from '@wordpress/block-editor'; import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; -import { ungroup } from '@wordpress/icons'; +import { ungroup, lock } from '@wordpress/icons'; import { store as noticesStore } from '@wordpress/notices'; /** From a4f9b21ee5090556d19c9e321fd0538e2453f008 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Tue, 15 Jun 2021 20:48:46 +0530 Subject: [PATCH 05/21] move hasEdits to top useSelect --- packages/block-library/src/block/edit.js | 144 +++++++++++++++-------- 1 file changed, 97 insertions(+), 47 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 06e41c7fcde4d9..1bc90a23f093f4 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -2,8 +2,19 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; -import { useEntityBlockEditor, useEntityProp, store as coreStore } from '@wordpress/core-data'; -import { Placeholder, Spinner, ToolbarGroup, ToolbarButton, TextControl, PanelBody } from '@wordpress/components'; +import { + useEntityBlockEditor, + useEntityProp, + store as coreStore, +} from '@wordpress/core-data'; +import { + Placeholder, + Spinner, + ToolbarGroup, + ToolbarButton, + TextControl, + PanelBody, +} from '@wordpress/components'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { @@ -25,30 +36,53 @@ import { store as noticesStore } from '@wordpress/notices'; */ import ReusableBlockWelcomeGuide from './reusable-block-welcome-guide'; -export default function ReusableBlockEdit({ attributes: { ref }, clientId }) { - const [hasAlreadyRendered, RecursionProvider] = useNoRecursiveRenders(ref); +export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { + const [ hasAlreadyRendered, RecursionProvider ] = useNoRecursiveRenders( + ref + ); const { isMissing, hasResolved, hasEdits } = useSelect( - (select) => { - const persistedBlock = select(coreStore).getEntityRecord('postType', 'wp_block', ref); - const hasResolvedBlock = select(coreStore).hasFinishedResolution('getEntityRecord', [ + ( select ) => { + const persistedBlock = select( coreStore ).getEntityRecord( + 'postType', + 'wp_block', + ref + ); + const hasResolvedBlock = select( + coreStore + ).hasFinishedResolution( 'getEntityRecord', [ 'postType', 'wp_block', ref, - ]); - const blockHasEdits = select(coreStore).hasEditsForEntityRecord('postType', 'wp_block', ref); + ] ); + const blockHasEdits = select( coreStore ).hasEditsForEntityRecord( + 'postType', + 'wp_block', + ref + ); return { hasResolved: hasResolvedBlock, - isMissing: hasResolvedBlock && !persistedBlock, + isMissing: hasResolvedBlock && ! persistedBlock, hasEdits: blockHasEdits, }; }, - [ref, clientId] + [ ref, clientId ] ); - const { __experimentalConvertBlockToStatic: convertBlockToStatic } = useDispatch(reusableBlocksStore); + const { + __experimentalConvertBlockToStatic: convertBlockToStatic, + } = useDispatch( reusableBlocksStore ); - const [blocks, onInput, onChange] = useEntityBlockEditor('postType', 'wp_block', { id: ref }); - const [title, setTitle] = useEntityProp('postType', 'wp_block', 'title', ref); + const [ blocks, onInput, onChange ] = useEntityBlockEditor( + 'postType', + 'wp_block', + { id: ref } + ); + const [ title, setTitle ] = useEntityProp( + 'postType', + 'wp_block', + 'title', + ref + ); const blockProps = useBlockProps(); @@ -58,54 +92,60 @@ export default function ReusableBlockEdit({ attributes: { ref }, clientId }) { value: blocks, onInput, onChange, - renderAppender: blocks?.length ? undefined : InnerBlocks.ButtonBlockAppender, + renderAppender: blocks?.length + ? undefined + : InnerBlocks.ButtonBlockAppender, } ); - + n; // local states for gudie modal - const [isGudieOpen, setIsGudieOpen] = useState(false); + const [ isGudieOpen, setIsGudieOpen ] = useState( false ); - const { saveEditedEntityRecord } = useDispatch(coreStore); - const { createNotice } = useDispatch(noticesStore); + const { saveEditedEntityRecord } = useDispatch( coreStore ); + const { createNotice } = useDispatch( noticesStore ); // save the unsaved records const saveEditedRecords = () => { - saveEditedEntityRecord('postType', 'wp_block', ref); + saveEditedEntityRecord( 'postType', 'wp_block', ref ); showSnackbar(); }; const showSnackbar = () => { - createNotice('success', __('Reusable block saved.'), { + createNotice( 'success', __( 'Reusable block saved.' ), { type: 'snackbar', isDismissible: true, actions: [ { - label: __('Learn more'), - onClick: () => setIsGudieOpen(true), + label: __( 'Learn more' ), + onClick: () => setIsGudieOpen( true ), }, ], - }); + } ); }; - if (hasAlreadyRendered) { + if ( hasAlreadyRendered ) { return ( -
- {__('Block cannot be rendered inside itself.')} +
+ + { __( 'Block cannot be rendered inside itself.' ) } +
); } - if (isMissing) { + if ( isMissing ) { return ( -
- {__('Block has been deleted or is unavailable.')} +
+ + { __( 'Block has been deleted or is unavailable.' ) } +
); } - if (!hasResolved) { + if ( ! hasResolved ) { return ( -
+
@@ -115,42 +155,52 @@ export default function ReusableBlockEdit({ attributes: { ref }, clientId }) { return ( -
+
convertBlockToStatic(clientId)} - label={__('Convert to regular blocks')} - icon={ungroup} + onClick={ () => convertBlockToStatic( clientId ) } + label={ __( 'Convert to regular blocks' ) } + icon={ ungroup } showTooltip /> - {__('Save')} + isDisabled={ ! hasEdits } + > + { __( 'Save' ) } - + - {isGudieOpen && } + { isGudieOpen && ( + + ) }
); From 297e62ea3397a85768d65bca4b6af093bdac9fe6 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Wed, 16 Jun 2021 02:11:39 +0530 Subject: [PATCH 06/21] Fix ESLint Errors --- packages/block-library/src/block/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 1bc90a23f093f4..9dccf32dd4d4d1 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -28,7 +28,7 @@ import { Warning, } from '@wordpress/block-editor'; import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; -import { ungroup, lock } from '@wordpress/icons'; +import { ungroup } from '@wordpress/icons'; import { store as noticesStore } from '@wordpress/notices'; /** From ea6ef3ae504e47ca0210a660534a91fcf928258d Mon Sep 17 00:00:00 2001 From: thisissandip Date: Wed, 30 Jun 2021 00:59:22 +0530 Subject: [PATCH 07/21] rebase --- packages/block-library/src/block/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 9dccf32dd4d4d1..02deeb0cfd31cd 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -97,7 +97,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { : InnerBlocks.ButtonBlockAppender, } ); - n; + // local states for gudie modal const [ isGudieOpen, setIsGudieOpen ] = useState( false ); From 38fbea78818bce24d68d70e0b12bcb10f73607f8 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Thu, 8 Jul 2021 03:00:17 +0530 Subject: [PATCH 08/21] Add welcome guide image --- .../src/block/reusable-block-welcome-guide.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/block/reusable-block-welcome-guide.js b/packages/block-library/src/block/reusable-block-welcome-guide.js index 0092c30271f313..13328f648dc8c4 100644 --- a/packages/block-library/src/block/reusable-block-welcome-guide.js +++ b/packages/block-library/src/block/reusable-block-welcome-guide.js @@ -4,6 +4,18 @@ import { Guide } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +function WelcomeGuideImage( { nonAnimatedSrc, animatedSrc } ) { + return ( + + + + + ); +} + function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { if ( ! isGudieOpen ) { return null; @@ -18,7 +30,10 @@ function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { pages={ [ { image: ( -
+ ), content: ( <> From 355595ad83217fdd16cbb054874563ba8c092cfa Mon Sep 17 00:00:00 2001 From: thisissandip Date: Mon, 12 Jul 2021 12:43:58 +0530 Subject: [PATCH 09/21] welcome guide updates and make save button to 32px in height --- packages/block-library/src/block/edit.js | 4 ++-- .../block-library/src/block/reusable-block-welcome-guide.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 02deeb0cfd31cd..cb5402ae1bdd7f 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -170,10 +170,10 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { isPrimary style={ { margin: '7px', - height: '34px', + height: '32px', } } onClick={ saveEditedRecords } - label={ __( 'Save Globally' ) } + label={ __( 'Save globally' ) } showTooltip isDisabled={ ! hasEdits } > diff --git a/packages/block-library/src/block/reusable-block-welcome-guide.js b/packages/block-library/src/block/reusable-block-welcome-guide.js index 13328f648dc8c4..117ec858b2f8b5 100644 --- a/packages/block-library/src/block/reusable-block-welcome-guide.js +++ b/packages/block-library/src/block/reusable-block-welcome-guide.js @@ -31,8 +31,8 @@ function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { { image: ( ), content: ( @@ -42,7 +42,7 @@ function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) {

{ __( - 'You just saved a Reusable block. Any other documents that include this block have been updated to reflect this change. ' + 'You just saved a Reusable block. Any other documents that include this block have been updated to reflect this change. To make local changes, try converting to regular blocks first.' ) }

From 1046bc4521f4f7ed7487c77d430240e0cf1982a4 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Thu, 15 Jul 2021 01:35:50 +0530 Subject: [PATCH 10/21] Save button box inset --- packages/block-library/src/block/edit.js | 5 +---- packages/block-library/src/block/editor.scss | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index cb5402ae1bdd7f..2a80cf38802df2 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -168,10 +168,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { Date: Sat, 17 Jul 2021 13:15:33 +0530 Subject: [PATCH 11/21] fix typos and add css comments --- packages/block-library/src/block/edit.js | 12 ++++++------ packages/block-library/src/block/editor.scss | 6 ++++-- .../src/block/reusable-block-welcome-guide.js | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 2a80cf38802df2..bb556b4731a83c 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -99,7 +99,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { ); // local states for gudie modal - const [ isGudieOpen, setIsGudieOpen ] = useState( false ); + const [ isGuideOpen, setIsGuideOpen ] = useState( false ); const { saveEditedEntityRecord } = useDispatch( coreStore ); const { createNotice } = useDispatch( noticesStore ); @@ -117,7 +117,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { actions: [ { label: __( 'Learn more' ), - onClick: () => setIsGudieOpen( true ), + onClick: () => setIsGuideOpen( true ), }, ], } ); @@ -170,7 +170,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { isPrimary className="block-library-block__reusable-block-save-button" onClick={ saveEditedRecords } - label={ __( 'Save globally' ) } + label={ __( 'Save reusable block' ) } showTooltip isDisabled={ ! hasEdits } > @@ -192,10 +192,10 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { wrapperProps={ innerBlocksProps } className="block-library-block__reusable-block-container" /> - { isGudieOpen && ( + { isGuideOpen && ( ) }
diff --git a/packages/block-library/src/block/editor.scss b/packages/block-library/src/block/editor.scss index 4c9d0581a9b460..11d9888189dbfb 100644 --- a/packages/block-library/src/block/editor.scss +++ b/packages/block-library/src/block/editor.scss @@ -19,11 +19,13 @@ .components-toolbar-group { .block-library-block__reusable-block-save-button { margin: 7px; - height: 32px; + height: $grid-unit-40; + + // override the default box inset properties to match height and width of the save button &::before { left: 0 !important; right: 0 !important; - height: 32px !important; + height: $grid-unit-40 !important; } } } diff --git a/packages/block-library/src/block/reusable-block-welcome-guide.js b/packages/block-library/src/block/reusable-block-welcome-guide.js index 117ec858b2f8b5..421c52bc3909aa 100644 --- a/packages/block-library/src/block/reusable-block-welcome-guide.js +++ b/packages/block-library/src/block/reusable-block-welcome-guide.js @@ -16,8 +16,8 @@ function WelcomeGuideImage( { nonAnimatedSrc, animatedSrc } ) { ); } -function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { - if ( ! isGudieOpen ) { +function ReusableBlockWelcomeGuide( { isGuideOpen, setIsGuideOpen } ) { + if ( ! isGuideOpen ) { return null; } @@ -26,7 +26,7 @@ function ReusableBlockWelcomeGuide( { isGudieOpen, setIsGudieOpen } ) { className="edit-reusable-block-welcome-guide" contentLabel={ __( 'Get familiar with Reusable blocks' ) } finishButtonText={ __( 'Got it' ) } - onFinish={ () => setIsGudieOpen( false ) } + onFinish={ () => setIsGuideOpen( false ) } pages={ [ { image: ( From a0ab53885a0104eaf73c53ca3a90451106be820f Mon Sep 17 00:00:00 2001 From: thisissandip Date: Wed, 28 Jul 2021 13:40:20 +0530 Subject: [PATCH 12/21] add dot to parent selector for reusable block --- packages/block-editor/package.json | 1 + .../components/block-parent-selector/index.js | 80 ++++++++++++------- .../block-parent-selector/style.scss | 27 +++++++ .../src/components/block-toolbar/style.scss | 8 ++ .../block-tools/block-contextual-toolbar.js | 70 +++++++++------- 5 files changed, 130 insertions(+), 56 deletions(-) diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 09ccc735d40ccf..ad4d9fe249eed4 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -38,6 +38,7 @@ "@wordpress/blocks": "file:../blocks", "@wordpress/components": "file:../components", "@wordpress/compose": "file:../compose", + "@wordpress/core-data": "file:../core-data", "@wordpress/data": "file:../data", "@wordpress/data-controls": "file:../data-controls", "@wordpress/deprecated": "file:../deprecated", diff --git a/packages/block-editor/src/components/block-parent-selector/index.js b/packages/block-editor/src/components/block-parent-selector/index.js index bd75159b0869e1..356edc3a8d8593 100644 --- a/packages/block-editor/src/components/block-parent-selector/index.js +++ b/packages/block-editor/src/components/block-parent-selector/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -6,6 +11,7 @@ import { ToolbarButton } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; import { useRef } from '@wordpress/element'; +import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies @@ -25,33 +31,46 @@ export default function BlockParentSelector() { const { selectBlock, toggleBlockHighlight } = useDispatch( blockEditorStore ); - const { firstParentClientId, shouldHide, hasReducedUI } = useSelect( - ( select ) => { - const { - getBlockName, - getBlockParents, - getSelectedBlockClientId, - getSettings, - } = select( blockEditorStore ); - const { hasBlockSupport } = select( blocksStore ); - const selectedBlockClientId = getSelectedBlockClientId(); - const parents = getBlockParents( selectedBlockClientId ); - const _firstParentClientId = parents[ parents.length - 1 ]; - const parentBlockName = getBlockName( _firstParentClientId ); - const _parentBlockType = getBlockType( parentBlockName ); - const settings = getSettings(); - return { - firstParentClientId: _firstParentClientId, - shouldHide: ! hasBlockSupport( - _parentBlockType, - '__experimentalParentSelector', - true - ), - hasReducedUI: settings.hasReducedUI, - }; - }, - [] - ); + const { + firstParentClientId, + shouldHide, + hasReducedUI, + reusableBlockHasEdits, + } = useSelect( ( select ) => { + const { + getBlockName, + getBlockParents, + getSelectedBlockClientId, + getSettings, + getBlockAttributes, + } = select( blockEditorStore ); + const { hasBlockSupport } = select( blocksStore ); + const selectedBlockClientId = getSelectedBlockClientId(); + const parents = getBlockParents( selectedBlockClientId ); + const _firstParentClientId = parents[ parents.length - 1 ]; + const parentBlockName = getBlockName( _firstParentClientId ); + const _parentBlockType = getBlockType( parentBlockName ); + const settings = getSettings(); + const parentBlockRef = getBlockAttributes( _firstParentClientId )?.ref; + const blockHasEdits = select( coreStore ).hasEditsForEntityRecord( + 'postType', + 'wp_block', + parentBlockRef + ); + const _reusableBlockHasEdits = + blockHasEdits && parentBlockName === 'core/block'; + + return { + firstParentClientId: _firstParentClientId, + shouldHide: ! hasBlockSupport( + _parentBlockType, + '__experimentalParentSelector', + true + ), + hasReducedUI: settings.hasReducedUI, + reusableBlockHasEdits: _reusableBlockHasEdits, + }; + }, [] ); const blockInformation = useBlockDisplayInformation( firstParentClientId ); // Allows highlighting the parent block outline when focusing or hovering @@ -71,13 +90,18 @@ export default function BlockParentSelector() { return null; } + const classes = classnames( 'block-editor-block-parent-selector', { + 'block-has-changes': reusableBlockHasEdits, + } ); + return (
+ { reusableBlockHasEdits &&
} selectBlock( firstParentClientId ) } diff --git a/packages/block-editor/src/components/block-parent-selector/style.scss b/packages/block-editor/src/components/block-parent-selector/style.scss index c5a1869835188c..d4503184e09efa 100644 --- a/packages/block-editor/src/components/block-parent-selector/style.scss +++ b/packages/block-editor/src/components/block-parent-selector/style.scss @@ -9,3 +9,30 @@ border-radius: $radius-block-ui; } } + +// styles for parent block selector when reusable block has changes +.block-editor-block-parent-selector.block-has-changes { + left: calc(-#{$grid-unit-60} - #{$grid-unit-30} - #{$border-width}); + + // increase the width of parent selector to make room for the dot + .block-editor-block-parent-selector__button { + width: $grid-unit-60 + $grid-unit-20; + } + + // move the parent selector icon to right side to make room for the dot + .block-editor-block-icon { + margin-right: -15px; + } + + // add the dot before the parent selector icon + .has-changes-dot { + position: absolute; + top: 50%; + transform: translateY(-50%); + background: var(--wp-admin-theme-color); + border-radius: 4px; + height: 8px; + width: 8px; + margin-left: 12px; + } +} diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index 6a747fa59cd8af..e9c9568d4615e7 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -54,6 +54,14 @@ } } +.block-editor-block-contextual-toolbar.block-has-changes:not(.is-fixed) { + margin-left: calc(#{$grid-unit-60} + #{$grid-unit-30}); + + .show-icon-labels & { + margin-left: 0; + } +} + .block-editor-block-parent-selector { position: absolute; top: -$border-width; diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js index a8e55abe6f408b..95558ab0ce6774 100644 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -9,6 +9,7 @@ import classnames from 'classnames'; import { __ } from '@wordpress/i18n'; import { hasBlockSupport, store as blocksStore } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; /** * Internal dependencies @@ -18,35 +19,47 @@ import BlockToolbar from '../block-toolbar'; import { store as blockEditorStore } from '../../store'; function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { - const { blockType, hasParents, showParentSelector } = useSelect( - ( select ) => { - const { - getBlockName, - getBlockParents, - getSelectedBlockClientIds, - } = select( blockEditorStore ); - const { getBlockType } = select( blocksStore ); - const selectedBlockClientIds = getSelectedBlockClientIds(); - const selectedBlockClientId = selectedBlockClientIds[ 0 ]; - const parents = getBlockParents( selectedBlockClientId ); - const firstParentClientId = parents[ parents.length - 1 ]; - const parentBlockName = getBlockName( firstParentClientId ); - const parentBlockType = getBlockType( parentBlockName ); + const { + blockType, + hasParents, + showParentSelector, + reusableBlockHasEdits, + } = useSelect( ( select ) => { + const { + getBlockName, + getBlockParents, + getSelectedBlockClientIds, + getBlockAttributes, + } = select( blockEditorStore ); + const { getBlockType } = select( blocksStore ); + const selectedBlockClientIds = getSelectedBlockClientIds(); + const selectedBlockClientId = selectedBlockClientIds[ 0 ]; + const parents = getBlockParents( selectedBlockClientId ); + const firstParentClientId = parents[ parents.length - 1 ]; + const parentBlockName = getBlockName( firstParentClientId ); + const parentBlockType = getBlockType( parentBlockName ); + const parentBlockRef = getBlockAttributes( firstParentClientId )?.ref; + const blockHasEdits = select( coreStore ).hasEditsForEntityRecord( + 'postType', + 'wp_block', + parentBlockRef + ); + const _reusableBlockHasEdits = + blockHasEdits && parentBlockName === 'core/block'; - return { - blockType: - selectedBlockClientId && - getBlockType( getBlockName( selectedBlockClientId ) ), - hasParents: parents.length, - showParentSelector: hasBlockSupport( - parentBlockType, - '__experimentalParentSelector', - true - ), - }; - }, - [] - ); + return { + blockType: + selectedBlockClientId && + getBlockType( getBlockName( selectedBlockClientId ) ), + hasParents: parents.length, + showParentSelector: hasBlockSupport( + parentBlockType, + '__experimentalParentSelector', + true + ), + reusableBlockHasEdits: _reusableBlockHasEdits, + }; + }, [] ); if ( blockType ) { if ( ! hasBlockSupport( blockType, '__experimentalToolbar', true ) ) { return null; @@ -57,6 +70,7 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { const classes = classnames( 'block-editor-block-contextual-toolbar', { 'has-parent': hasParents && showParentSelector, 'is-fixed': isFixed, + 'block-has-changes': reusableBlockHasEdits, } ); return ( From da40570ac3c236d245dc3eb1367bdbb8bd1cd33c Mon Sep 17 00:00:00 2001 From: thisissandip Date: Wed, 4 Aug 2021 12:20:25 +0530 Subject: [PATCH 13/21] Add dot to block parent seletor and reusable block toolbar --- packages/block-editor/README.md | 4 + packages/block-editor/package.json | 1 - .../src/components/block-has-dot/index.js | 40 ++++++++ .../components/block-parent-selector/index.js | 91 ++++++++++--------- .../block-parent-selector/style.scss | 4 +- .../src/components/block-switcher/index.js | 18 ++++ .../src/components/block-switcher/style.scss | 10 ++ .../src/components/block-toolbar/style.scss | 3 +- .../block-tools/block-contextual-toolbar.js | 84 ++++++++--------- packages/block-editor/src/components/index.js | 1 + packages/block-library/src/block/edit.js | 40 ++++++++ 11 files changed, 206 insertions(+), 90 deletions(-) create mode 100644 packages/block-editor/src/components/block-has-dot/index.js diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index fc1f1cb6fddd79..69895810d30bbd 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -149,6 +149,10 @@ Undocumented declaration. Undocumented declaration. +# **BlockHasDot** + +Undocumented declaration. + # **BlockIcon** Undocumented declaration. diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index ad4d9fe249eed4..09ccc735d40ccf 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -38,7 +38,6 @@ "@wordpress/blocks": "file:../blocks", "@wordpress/components": "file:../components", "@wordpress/compose": "file:../compose", - "@wordpress/core-data": "file:../core-data", "@wordpress/data": "file:../data", "@wordpress/data-controls": "file:../data-controls", "@wordpress/deprecated": "file:../deprecated", diff --git a/packages/block-editor/src/components/block-has-dot/index.js b/packages/block-editor/src/components/block-has-dot/index.js new file mode 100644 index 00000000000000..b081c5dccbbf3a --- /dev/null +++ b/packages/block-editor/src/components/block-has-dot/index.js @@ -0,0 +1,40 @@ +/** + * WordPress dependencies + */ +import { Fill } from '@wordpress/components'; + +function BlockHasDot( { + parentReusableBlockHasEdits, + selectedReusableBlockHasEdits, +} ) { + return ( + <> + { /* Add dot to the BlockParentSelector, if the parent block is reusable block and if the parent reusable block has edits */ } + + { ( { setReusableBlockHasEdits } ) => + parentReusableBlockHasEdits + ? setReusableBlockHasEdits( true ) + : setReusableBlockHasEdits( false ) + } + + { /* Move BlockContextualToolbar to right, if the parent block is reusable block and if the parent reusable block has edits */ } + + { ( { setMoveContextualToolbar } ) => + parentReusableBlockHasEdits + ? setMoveContextualToolbar( true ) + : setMoveContextualToolbar( false ) + } + + { /* Add dot before the switcher of Reusable block toolbar, if reusable block has edits */ } + + { ( { setReusableBlockHasDot } ) => + selectedReusableBlockHasEdits + ? setReusableBlockHasDot( true ) + : setReusableBlockHasDot( false ) + } + + + ); +} + +export default BlockHasDot; diff --git a/packages/block-editor/src/components/block-parent-selector/index.js b/packages/block-editor/src/components/block-parent-selector/index.js index 356edc3a8d8593..e592ce0a3b4777 100644 --- a/packages/block-editor/src/components/block-parent-selector/index.js +++ b/packages/block-editor/src/components/block-parent-selector/index.js @@ -7,11 +7,10 @@ import classnames from 'classnames'; * WordPress dependencies */ import { getBlockType, store as blocksStore } from '@wordpress/blocks'; -import { ToolbarButton } from '@wordpress/components'; +import { ToolbarButton, Slot } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; -import { useRef } from '@wordpress/element'; -import { store as coreStore } from '@wordpress/core-data'; +import { useRef, useState } from '@wordpress/element'; /** * Internal dependencies @@ -31,46 +30,34 @@ export default function BlockParentSelector() { const { selectBlock, toggleBlockHighlight } = useDispatch( blockEditorStore ); - const { - firstParentClientId, - shouldHide, - hasReducedUI, - reusableBlockHasEdits, - } = useSelect( ( select ) => { - const { - getBlockName, - getBlockParents, - getSelectedBlockClientId, - getSettings, - getBlockAttributes, - } = select( blockEditorStore ); - const { hasBlockSupport } = select( blocksStore ); - const selectedBlockClientId = getSelectedBlockClientId(); - const parents = getBlockParents( selectedBlockClientId ); - const _firstParentClientId = parents[ parents.length - 1 ]; - const parentBlockName = getBlockName( _firstParentClientId ); - const _parentBlockType = getBlockType( parentBlockName ); - const settings = getSettings(); - const parentBlockRef = getBlockAttributes( _firstParentClientId )?.ref; - const blockHasEdits = select( coreStore ).hasEditsForEntityRecord( - 'postType', - 'wp_block', - parentBlockRef - ); - const _reusableBlockHasEdits = - blockHasEdits && parentBlockName === 'core/block'; + const { firstParentClientId, shouldHide, hasReducedUI } = useSelect( + ( select ) => { + const { + getBlockName, + getBlockParents, + getSelectedBlockClientId, + getSettings, + } = select( blockEditorStore ); + const { hasBlockSupport } = select( blocksStore ); + const selectedBlockClientId = getSelectedBlockClientId(); + const parents = getBlockParents( selectedBlockClientId ); + const _firstParentClientId = parents[ parents.length - 1 ]; + const parentBlockName = getBlockName( _firstParentClientId ); + const _parentBlockType = getBlockType( parentBlockName ); + const settings = getSettings(); - return { - firstParentClientId: _firstParentClientId, - shouldHide: ! hasBlockSupport( - _parentBlockType, - '__experimentalParentSelector', - true - ), - hasReducedUI: settings.hasReducedUI, - reusableBlockHasEdits: _reusableBlockHasEdits, - }; - }, [] ); + return { + firstParentClientId: _firstParentClientId, + shouldHide: ! hasBlockSupport( + _parentBlockType, + '__experimentalParentSelector', + true + ), + hasReducedUI: settings.hasReducedUI, + }; + }, + [] + ); const blockInformation = useBlockDisplayInformation( firstParentClientId ); // Allows highlighting the parent block outline when focusing or hovering @@ -86,12 +73,17 @@ export default function BlockParentSelector() { }, } ); + // states to check reusable block edits + const [ reusableBlockHasEdits, setReusableBlockHasEdits ] = useState( + false + ); + if ( shouldHide || firstParentClientId === undefined ) { return null; } const classes = classnames( 'block-editor-block-parent-selector', { - 'block-has-changes': reusableBlockHasEdits, + 'parent-block-has-changes': reusableBlockHasEdits, } ); return ( @@ -101,7 +93,18 @@ export default function BlockParentSelector() { ref={ nodeRef } { ...showMoversGestures } > - { reusableBlockHasEdits &&
} + { /* Update the reusableBlockHasEdits state in BlockHasDot using Slot/Fill to update the parent-selector classes and to add dot to parent selector. */ } + + { /* Add dot to the parent selector if it is a reusable block and if the reusable block has edits. */ } + { reusableBlockHasEdits && ( +
+ ) } + selectBlock( firstParentClientId ) } diff --git a/packages/block-editor/src/components/block-parent-selector/style.scss b/packages/block-editor/src/components/block-parent-selector/style.scss index d4503184e09efa..8ab04f716b4aca 100644 --- a/packages/block-editor/src/components/block-parent-selector/style.scss +++ b/packages/block-editor/src/components/block-parent-selector/style.scss @@ -11,7 +11,7 @@ } // styles for parent block selector when reusable block has changes -.block-editor-block-parent-selector.block-has-changes { +.block-editor-block-parent-selector.parent-block-has-changes { left: calc(-#{$grid-unit-60} - #{$grid-unit-30} - #{$border-width}); // increase the width of parent selector to make room for the dot @@ -25,7 +25,7 @@ } // add the dot before the parent selector icon - .has-changes-dot { + .block-parent-selector-has-dot { position: absolute; top: 50%; transform: translateY(-50%); diff --git a/packages/block-editor/src/components/block-switcher/index.js b/packages/block-editor/src/components/block-switcher/index.js index 7c580817f8370f..47bc4b90d0a14c 100644 --- a/packages/block-editor/src/components/block-switcher/index.js +++ b/packages/block-editor/src/components/block-switcher/index.js @@ -12,6 +12,7 @@ import { ToolbarButton, ToolbarGroup, ToolbarItem, + Slot, } from '@wordpress/components'; import { switchToBlockType, @@ -21,6 +22,7 @@ import { } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; import { stack } from '@wordpress/icons'; +import { useState } from '@wordpress/element'; /** * Internal dependencies @@ -89,6 +91,9 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { const isReusable = blocks.length === 1 && isReusableBlock( blocks[ 0 ] ); const isTemplate = blocks.length === 1 && isTemplatePart( blocks[ 0 ] ); + // states to add dot to the reusable block toolbar, if the reusable block has changes + const [ reusableBlockHasDot, setReusableBlockHasDot ] = useState( false ); + // Simple block tranformation based on the `Block Transforms` API. const onBlockTransform = ( name ) => replaceBlocks( clientIds, switchToBlockType( blocks, name ) ); @@ -133,6 +138,7 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { hasBlockStyles || hasPossibleBlockTransformations || hasPatternTransformation; + return ( @@ -147,6 +153,18 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { } } icon={ <> + { /* Update the reusableBlockHasDot state in BlockHasDot using Slot/Fill to update to add dot to reusable block toolbar if it has edit. */ } + + { /* Add dot to the reusable block toolbar if resuable block has edits. */ } + { isReusable && reusableBlockHasDot && ( +
+ ) } + { - const { - getBlockName, - getBlockParents, - getSelectedBlockClientIds, - getBlockAttributes, - } = select( blockEditorStore ); - const { getBlockType } = select( blocksStore ); - const selectedBlockClientIds = getSelectedBlockClientIds(); - const selectedBlockClientId = selectedBlockClientIds[ 0 ]; - const parents = getBlockParents( selectedBlockClientId ); - const firstParentClientId = parents[ parents.length - 1 ]; - const parentBlockName = getBlockName( firstParentClientId ); - const parentBlockType = getBlockType( parentBlockName ); - const parentBlockRef = getBlockAttributes( firstParentClientId )?.ref; - const blockHasEdits = select( coreStore ).hasEditsForEntityRecord( - 'postType', - 'wp_block', - parentBlockRef - ); - const _reusableBlockHasEdits = - blockHasEdits && parentBlockName === 'core/block'; + const { blockType, hasParents, showParentSelector } = useSelect( + ( select ) => { + const { + getBlockName, + getBlockParents, + getSelectedBlockClientIds, + } = select( blockEditorStore ); + const { getBlockType } = select( blocksStore ); + const selectedBlockClientIds = getSelectedBlockClientIds(); + const selectedBlockClientId = selectedBlockClientIds[ 0 ]; + const parents = getBlockParents( selectedBlockClientId ); + const firstParentClientId = parents[ parents.length - 1 ]; + const parentBlockName = getBlockName( firstParentClientId ); + const parentBlockType = getBlockType( parentBlockName ); + + return { + blockType: + selectedBlockClientId && + getBlockType( getBlockName( selectedBlockClientId ) ), + hasParents: parents.length, + showParentSelector: hasBlockSupport( + parentBlockType, + '__experimentalParentSelector', + true + ), + }; + }, + [] + ); + + // states to move the contextual toolbar to right when block parent selector has dot + const [ moveContextualToolbar, setMoveContextualToolbar ] = useState( + false + ); - return { - blockType: - selectedBlockClientId && - getBlockType( getBlockName( selectedBlockClientId ) ), - hasParents: parents.length, - showParentSelector: hasBlockSupport( - parentBlockType, - '__experimentalParentSelector', - true - ), - reusableBlockHasEdits: _reusableBlockHasEdits, - }; - }, [] ); if ( blockType ) { if ( ! hasBlockSupport( blockType, '__experimentalToolbar', true ) ) { return null; @@ -70,7 +65,7 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { const classes = classnames( 'block-editor-block-contextual-toolbar', { 'has-parent': hasParents && showParentSelector, 'is-fixed': isFixed, - 'block-has-changes': reusableBlockHasEdits, + 'parent-block-has-changes': moveContextualToolbar, } ); return ( @@ -81,6 +76,11 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { aria-label={ __( 'Block tools' ) } { ...props } > + { /* Update the state for moveContextualToolbar in BlockHasDot using Slot/Fill. */ } + ); diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 3cfa70c4b9f408..44bb8791b6aa99 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -110,6 +110,7 @@ export { default as BlockSettingsMenuControls } from './block-settings-menu-cont export { default as BlockTitle } from './block-title'; export { default as BlockToolbar } from './block-toolbar'; export { default as BlockTools } from './block-tools'; +export { default as BlockHasDot } from './block-has-dot'; export { default as CopyHandler, useClipboardHandler as __unstableUseClipboardHandler, diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index bb556b4731a83c..aae9fa129ae864 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -21,11 +21,13 @@ import { __experimentalUseInnerBlocksProps as useInnerBlocksProps, __experimentalUseNoRecursiveRenders as useNoRecursiveRenders, __experimentalBlockContentOverlay as BlockContentOverlay, + BlockHasDot, InnerBlocks, BlockControls, InspectorControls, useBlockProps, Warning, + store as blockEditorStore, } from '@wordpress/block-editor'; import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; import { ungroup } from '@wordpress/icons'; @@ -68,6 +70,37 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { [ ref, clientId ] ); + const { + parentReusableBlockHasEdits, + selectedReusableBlockHasEdits, + } = useSelect( ( select ) => { + const { + getBlockParents, + getSelectedBlockClientId, + getBlockAttributes, + } = select( blockEditorStore ); + const selectedBlockClientId = getSelectedBlockClientId(); + const _selectedBlockRef = getBlockAttributes( selectedBlockClientId ) + ?.ref; + // check if the selected reusable block has edits + const _selectedblockHasEdits = select( + coreStore + ).hasEditsForEntityRecord( 'postType', 'wp_block', _selectedBlockRef ); + + const parents = getBlockParents( selectedBlockClientId ); + const _firstParentClientId = parents[ parents.length - 1 ]; + const _parentBlockRef = getBlockAttributes( _firstParentClientId )?.ref; + // check if the parent reusable block has edits + const _parentblockHasEdits = select( + coreStore + ).hasEditsForEntityRecord( 'postType', 'wp_block', _parentBlockRef ); + + return { + parentReusableBlockHasEdits: _parentblockHasEdits, + selectedReusableBlockHasEdits: _selectedblockHasEdits, + }; + }, [] ); + const { __experimentalConvertBlockToStatic: convertBlockToStatic, } = useDispatch( reusableBlocksStore ); @@ -156,6 +189,13 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { return (
+ { /* Adds a dot to the parent selector and the reusable block toolbar when Reusable block has edits. */ } + Date: Thu, 12 Aug 2021 12:41:13 +0530 Subject: [PATCH 14/21] add two separate components for unsaved changes indicator --- packages/block-editor/README.md | 4 -- .../src/components/block-has-dot/index.js | 40 ----------- .../components/block-parent-selector/index.js | 32 +-------- .../block-parent-selector/style.scss | 7 +- .../src/components/block-switcher/index.js | 72 ++++--------------- .../src/components/block-switcher/style.scss | 4 +- .../src/components/block-toolbar/style.scss | 2 +- .../block-tools/block-contextual-toolbar.js | 14 ---- ...lock-selector-unsaved-changes-indicator.js | 46 ++++++++++++ ...elected-block-unsaved-changes-indicator.js | 20 ++++++ packages/block-editor/src/components/index.js | 3 +- packages/block-library/src/block/edit.js | 50 +++++-------- 12 files changed, 110 insertions(+), 184 deletions(-) delete mode 100644 packages/block-editor/src/components/block-has-dot/index.js create mode 100644 packages/block-editor/src/components/block-unsaved-changes-indicator/parent-block-selector-unsaved-changes-indicator.js create mode 100644 packages/block-editor/src/components/block-unsaved-changes-indicator/selected-block-unsaved-changes-indicator.js diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 69895810d30bbd..fc1f1cb6fddd79 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -149,10 +149,6 @@ Undocumented declaration. Undocumented declaration. -# **BlockHasDot** - -Undocumented declaration. - # **BlockIcon** Undocumented declaration. diff --git a/packages/block-editor/src/components/block-has-dot/index.js b/packages/block-editor/src/components/block-has-dot/index.js deleted file mode 100644 index b081c5dccbbf3a..00000000000000 --- a/packages/block-editor/src/components/block-has-dot/index.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * WordPress dependencies - */ -import { Fill } from '@wordpress/components'; - -function BlockHasDot( { - parentReusableBlockHasEdits, - selectedReusableBlockHasEdits, -} ) { - return ( - <> - { /* Add dot to the BlockParentSelector, if the parent block is reusable block and if the parent reusable block has edits */ } - - { ( { setReusableBlockHasEdits } ) => - parentReusableBlockHasEdits - ? setReusableBlockHasEdits( true ) - : setReusableBlockHasEdits( false ) - } - - { /* Move BlockContextualToolbar to right, if the parent block is reusable block and if the parent reusable block has edits */ } - - { ( { setMoveContextualToolbar } ) => - parentReusableBlockHasEdits - ? setMoveContextualToolbar( true ) - : setMoveContextualToolbar( false ) - } - - { /* Add dot before the switcher of Reusable block toolbar, if reusable block has edits */ } - - { ( { setReusableBlockHasDot } ) => - selectedReusableBlockHasEdits - ? setReusableBlockHasDot( true ) - : setReusableBlockHasDot( false ) - } - - - ); -} - -export default BlockHasDot; diff --git a/packages/block-editor/src/components/block-parent-selector/index.js b/packages/block-editor/src/components/block-parent-selector/index.js index e592ce0a3b4777..ead1b6c1941edc 100644 --- a/packages/block-editor/src/components/block-parent-selector/index.js +++ b/packages/block-editor/src/components/block-parent-selector/index.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ @@ -10,7 +5,7 @@ import { getBlockType, store as blocksStore } from '@wordpress/blocks'; import { ToolbarButton, Slot } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; -import { useRef, useState } from '@wordpress/element'; +import { useRef } from '@wordpress/element'; /** * Internal dependencies @@ -45,7 +40,6 @@ export default function BlockParentSelector() { const parentBlockName = getBlockName( _firstParentClientId ); const _parentBlockType = getBlockType( parentBlockName ); const settings = getSettings(); - return { firstParentClientId: _firstParentClientId, shouldHide: ! hasBlockSupport( @@ -73,38 +67,18 @@ export default function BlockParentSelector() { }, } ); - // states to check reusable block edits - const [ reusableBlockHasEdits, setReusableBlockHasEdits ] = useState( - false - ); - if ( shouldHide || firstParentClientId === undefined ) { return null; } - const classes = classnames( 'block-editor-block-parent-selector', { - 'parent-block-has-changes': reusableBlockHasEdits, - } ); - return (
- { /* Update the reusableBlockHasEdits state in BlockHasDot using Slot/Fill to update the parent-selector classes and to add dot to parent selector. */ } - - { /* Add dot to the parent selector if it is a reusable block and if the reusable block has edits. */ } - { reusableBlockHasEdits && ( -
- ) } - + selectBlock( firstParentClientId ) } diff --git a/packages/block-editor/src/components/block-parent-selector/style.scss b/packages/block-editor/src/components/block-parent-selector/style.scss index 8ab04f716b4aca..9757cefcc726f7 100644 --- a/packages/block-editor/src/components/block-parent-selector/style.scss +++ b/packages/block-editor/src/components/block-parent-selector/style.scss @@ -10,7 +10,7 @@ } } -// styles for parent block selector when reusable block has changes +// styles for parent block selector when parent block has changes .block-editor-block-parent-selector.parent-block-has-changes { left: calc(-#{$grid-unit-60} - #{$grid-unit-30} - #{$border-width}); @@ -25,7 +25,7 @@ } // add the dot before the parent selector icon - .block-parent-selector-has-dot { + .parent-block-selector-unsaved-changes-indicator { position: absolute; top: 50%; transform: translateY(-50%); @@ -33,6 +33,7 @@ border-radius: 4px; height: 8px; width: 8px; - margin-left: 12px; + margin: 0 12px; } } + diff --git a/packages/block-editor/src/components/block-switcher/index.js b/packages/block-editor/src/components/block-switcher/index.js index 47bc4b90d0a14c..b70d2bde70b833 100644 --- a/packages/block-editor/src/components/block-switcher/index.js +++ b/packages/block-editor/src/components/block-switcher/index.js @@ -22,7 +22,6 @@ import { } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; import { stack } from '@wordpress/icons'; -import { useState } from '@wordpress/element'; /** * Internal dependencies @@ -33,7 +32,6 @@ import BlockIcon from '../block-icon'; import BlockTitle from '../block-title'; import BlockTransformationsMenu from './block-transformations-menu'; import BlockStylesMenu from './block-styles-menu'; -import PatternTransformationsMenu from './pattern-transformations-menu'; export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { const { replaceBlocks } = useDispatch( blockEditorStore ); @@ -43,14 +41,12 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { hasBlockStyles, icon, blockTitle, - patterns, } = useSelect( ( select ) => { - const { - getBlockRootClientId, - getBlockTransformItems, - __experimentalGetPatternTransformItems, - } = select( blockEditorStore ); + const { getBlockRootClientId, getBlockTransformItems } = select( + blockEditorStore + ); + const { getBlockStyles, getBlockType } = select( blocksStore ); const rootClientId = getBlockRootClientId( castArray( clientIds )[ 0 ] @@ -71,6 +67,7 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { ? getBlockType( firstBlockName )?.icon : stack; } + return { possibleBlockTransformations: getBlockTransformItems( blocks, @@ -79,10 +76,6 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { hasBlockStyles: !! styles?.length, icon: _icon, blockTitle: getBlockType( firstBlockName ).title, - patterns: __experimentalGetPatternTransformItems( - blocks, - rootClientId - ), }; }, [ clientIds, blocks, blockInformation?.icon ] @@ -91,17 +84,9 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { const isReusable = blocks.length === 1 && isReusableBlock( blocks[ 0 ] ); const isTemplate = blocks.length === 1 && isTemplatePart( blocks[ 0 ] ); - // states to add dot to the reusable block toolbar, if the reusable block has changes - const [ reusableBlockHasDot, setReusableBlockHasDot ] = useState( false ); - - // Simple block tranformation based on the `Block Transforms` API. - const onBlockTransform = ( name ) => + const onTransform = ( name ) => replaceBlocks( clientIds, switchToBlockType( blocks, name ) ); - // Pattern transformation through the `Patterns` API. - const onPatternTransform = ( transformedBlocks ) => - replaceBlocks( clientIds, transformedBlocks ); const hasPossibleBlockTransformations = !! possibleBlockTransformations.length; - const hasPatternTransformation = !! patterns?.length; if ( ! hasBlockStyles && ! hasPossibleBlockTransformations ) { return ( @@ -119,13 +104,9 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { const blockSwitcherDescription = 1 === blocks.length - ? sprintf( - /* translators: %s: block title. */ - __( '%s: Change block type or style' ), - blockTitle - ) + ? __( 'Change block type or style' ) : sprintf( - /* translators: %d: number of blocks. */ + /* translators: %s: number of blocks. */ _n( 'Change type of %d block', 'Change type of %d blocks', @@ -134,11 +115,6 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { blocks.length ); - const showDropDown = - hasBlockStyles || - hasPossibleBlockTransformations || - hasPatternTransformation; - return ( @@ -153,18 +129,9 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { } } icon={ <> - { /* Update the reusableBlockHasDot state in BlockHasDot using Slot/Fill to update to add dot to reusable block toolbar if it has edit. */ } - - { /* Add dot to the reusable block toolbar if resuable block has edits. */ } - { isReusable && reusableBlockHasDot && ( -
+ { isReusable && ( + ) } - { menuProps={ { orientation: 'both' } } > { ( { onClose } ) => - showDropDown && ( + ( hasBlockStyles || + hasPossibleBlockTransformations ) && (
- { hasPatternTransformation && ( - { - onPatternTransform( - transformedBlocks - ); - onClose(); - } } - /> - ) } { hasPossibleBlockTransformations && ( { } blocks={ blocks } onSelect={ ( name ) => { - onBlockTransform( name ); + onTransform( name ); onClose(); } } /> diff --git a/packages/block-editor/src/components/block-switcher/style.scss b/packages/block-editor/src/components/block-switcher/style.scss index 0ce3547ad91258..af8b602e0c7e5e 100644 --- a/packages/block-editor/src/components/block-switcher/style.scss +++ b/packages/block-editor/src/components/block-switcher/style.scss @@ -1,8 +1,8 @@ .block-editor-block-switcher { position: relative; - // Show dot before the block switcher in reusable block toolbar if reusable block has edits - .reusable-block-toolbar-has-dot { + // Show dot before the block switcher in block toolbar if block has edits + .block-unsaved-changes-indicator { position: relative; background: var(--wp-admin-theme-color); border-radius: 4px; diff --git a/packages/block-editor/src/components/block-toolbar/style.scss b/packages/block-editor/src/components/block-toolbar/style.scss index bfc878066b8f4f..1695034cfc745c 100644 --- a/packages/block-editor/src/components/block-toolbar/style.scss +++ b/packages/block-editor/src/components/block-toolbar/style.scss @@ -54,7 +54,7 @@ } } -// move contextual toolbar to right +// move contextual toolbar to right when parent block has changes .block-editor-block-contextual-toolbar.parent-block-has-changes:not(.is-fixed) { margin-left: calc(#{$grid-unit-60} + #{$grid-unit-30}); diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js index 85512fcae3a30b..a8e55abe6f408b 100644 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -9,8 +9,6 @@ import classnames from 'classnames'; import { __ } from '@wordpress/i18n'; import { hasBlockSupport, store as blocksStore } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; -import { useState } from '@wordpress/element'; -import { Slot } from '@wordpress/components'; /** * Internal dependencies @@ -49,12 +47,6 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { }, [] ); - - // states to move the contextual toolbar to right when block parent selector has dot - const [ moveContextualToolbar, setMoveContextualToolbar ] = useState( - false - ); - if ( blockType ) { if ( ! hasBlockSupport( blockType, '__experimentalToolbar', true ) ) { return null; @@ -65,7 +57,6 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { const classes = classnames( 'block-editor-block-contextual-toolbar', { 'has-parent': hasParents && showParentSelector, 'is-fixed': isFixed, - 'parent-block-has-changes': moveContextualToolbar, } ); return ( @@ -76,11 +67,6 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { aria-label={ __( 'Block tools' ) } { ...props } > - { /* Update the state for moveContextualToolbar in BlockHasDot using Slot/Fill. */ } - ); diff --git a/packages/block-editor/src/components/block-unsaved-changes-indicator/parent-block-selector-unsaved-changes-indicator.js b/packages/block-editor/src/components/block-unsaved-changes-indicator/parent-block-selector-unsaved-changes-indicator.js new file mode 100644 index 00000000000000..af19bd3ca1766f --- /dev/null +++ b/packages/block-editor/src/components/block-unsaved-changes-indicator/parent-block-selector-unsaved-changes-indicator.js @@ -0,0 +1,46 @@ +/** + * WordPress dependencies + */ +import { Fill } from '@wordpress/components'; +import { useEffect } from '@wordpress/element'; + +function UnsavedChangesIndicator() { + useEffect( () => { + // add class to the parent selector to increase it's width + const parentSelectorBtn = document.querySelector( + '.block-editor-block-parent-selector' + ); + parentSelectorBtn.classList.add( 'parent-block-has-changes' ); + // add class to the contextual toolbar to move it to the right side + const contextualToolBar = document.querySelector( + '.block-editor-block-contextual-toolbar' + ); + contextualToolBar.classList.add( 'parent-block-has-changes' ); + + return () => { + // remove classes from the parent selector and contextual toolbar when component unmounts + document + .querySelector( '.block-editor-block-parent-selector' ) + .classList.remove( 'parent-block-has-changes' ); + document + .querySelector( '.block-editor-block-contextual-toolbar' ) + .classList.remove( 'parent-block-has-changes' ); + }; + }, [] ); + + return ( +
+ ); +} + +function ParentBlockSelectorUnsavedChangesIndicator() { + return ( + <> + + + + + ); +} + +export default ParentBlockSelectorUnsavedChangesIndicator; diff --git a/packages/block-editor/src/components/block-unsaved-changes-indicator/selected-block-unsaved-changes-indicator.js b/packages/block-editor/src/components/block-unsaved-changes-indicator/selected-block-unsaved-changes-indicator.js new file mode 100644 index 00000000000000..4c0d5168ee3d14 --- /dev/null +++ b/packages/block-editor/src/components/block-unsaved-changes-indicator/selected-block-unsaved-changes-indicator.js @@ -0,0 +1,20 @@ +/** + * WordPress dependencies + */ +import { Fill } from '@wordpress/components'; + +function UnsavedChangesIndicator() { + return
; +} + +function SelectedBlockUnsavedChangesIndicator() { + return ( + <> + + + + + ); +} + +export default SelectedBlockUnsavedChangesIndicator; diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 44bb8791b6aa99..54d8787b4bc5d1 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -110,7 +110,8 @@ export { default as BlockSettingsMenuControls } from './block-settings-menu-cont export { default as BlockTitle } from './block-title'; export { default as BlockToolbar } from './block-toolbar'; export { default as BlockTools } from './block-tools'; -export { default as BlockHasDot } from './block-has-dot'; +export { default as __experimentalParentBlockSelectorUnsavedChangesIndicator } from './block-unsaved-changes-indicator/parent-block-selector-unsaved-changes-indicator'; +export { default as __experimentalSelectedBlockUnsavedChangesIndicator } from './block-unsaved-changes-indicator/selected-block-unsaved-changes-indicator'; export { default as CopyHandler, useClipboardHandler as __unstableUseClipboardHandler, diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index aae9fa129ae864..a13dd6f4efa5e0 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -21,7 +21,8 @@ import { __experimentalUseInnerBlocksProps as useInnerBlocksProps, __experimentalUseNoRecursiveRenders as useNoRecursiveRenders, __experimentalBlockContentOverlay as BlockContentOverlay, - BlockHasDot, + __experimentalParentBlockSelectorUnsavedChangesIndicator as ParentBlockSelectorUnsavedChangesIndicator, + __experimentalSelectedBlockUnsavedChangesIndicator as SelectedBlockUnsavedChangesIndicator, InnerBlocks, BlockControls, InspectorControls, @@ -70,34 +71,20 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { [ ref, clientId ] ); - const { - parentReusableBlockHasEdits, - selectedReusableBlockHasEdits, - } = useSelect( ( select ) => { - const { - getBlockParents, - getSelectedBlockClientId, - getBlockAttributes, - } = select( blockEditorStore ); + const { isChildSelected, isSelected } = useSelect( ( select ) => { + const { getBlockParents, getSelectedBlockClientId } = select( + blockEditorStore + ); const selectedBlockClientId = getSelectedBlockClientId(); - const _selectedBlockRef = getBlockAttributes( selectedBlockClientId ) - ?.ref; - // check if the selected reusable block has edits - const _selectedblockHasEdits = select( - coreStore - ).hasEditsForEntityRecord( 'postType', 'wp_block', _selectedBlockRef ); + const _isSelected = selectedBlockClientId === clientId; const parents = getBlockParents( selectedBlockClientId ); - const _firstParentClientId = parents[ parents.length - 1 ]; - const _parentBlockRef = getBlockAttributes( _firstParentClientId )?.ref; - // check if the parent reusable block has edits - const _parentblockHasEdits = select( - coreStore - ).hasEditsForEntityRecord( 'postType', 'wp_block', _parentBlockRef ); + const firstParentClientId = parents[ parents.length - 1 ]; + const _isChildSelected = firstParentClientId === clientId; return { - parentReusableBlockHasEdits: _parentblockHasEdits, - selectedReusableBlockHasEdits: _selectedblockHasEdits, + isChildSelected: _isChildSelected, + isSelected: _isSelected, }; }, [] ); @@ -189,13 +176,14 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { return (
- { /* Adds a dot to the parent selector and the reusable block toolbar when Reusable block has edits. */ } - + { isSelected && hasEdits && ( + + ) } + + { isChildSelected && hasEdits && ( + + ) } + Date: Thu, 12 Aug 2021 12:51:43 +0530 Subject: [PATCH 15/21] undo block switcher changes --- .../src/components/block-switcher/index.js | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/packages/block-editor/src/components/block-switcher/index.js b/packages/block-editor/src/components/block-switcher/index.js index b70d2bde70b833..5bdb300227c036 100644 --- a/packages/block-editor/src/components/block-switcher/index.js +++ b/packages/block-editor/src/components/block-switcher/index.js @@ -32,6 +32,7 @@ import BlockIcon from '../block-icon'; import BlockTitle from '../block-title'; import BlockTransformationsMenu from './block-transformations-menu'; import BlockStylesMenu from './block-styles-menu'; +import PatternTransformationsMenu from './pattern-transformations-menu'; export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { const { replaceBlocks } = useDispatch( blockEditorStore ); @@ -41,12 +42,14 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { hasBlockStyles, icon, blockTitle, + patterns, } = useSelect( ( select ) => { - const { getBlockRootClientId, getBlockTransformItems } = select( - blockEditorStore - ); - + const { + getBlockRootClientId, + getBlockTransformItems, + __experimentalGetPatternTransformItems, + } = select( blockEditorStore ); const { getBlockStyles, getBlockType } = select( blocksStore ); const rootClientId = getBlockRootClientId( castArray( clientIds )[ 0 ] @@ -67,7 +70,6 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { ? getBlockType( firstBlockName )?.icon : stack; } - return { possibleBlockTransformations: getBlockTransformItems( blocks, @@ -76,6 +78,10 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { hasBlockStyles: !! styles?.length, icon: _icon, blockTitle: getBlockType( firstBlockName ).title, + patterns: __experimentalGetPatternTransformItems( + blocks, + rootClientId + ), }; }, [ clientIds, blocks, blockInformation?.icon ] @@ -84,9 +90,14 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { const isReusable = blocks.length === 1 && isReusableBlock( blocks[ 0 ] ); const isTemplate = blocks.length === 1 && isTemplatePart( blocks[ 0 ] ); - const onTransform = ( name ) => + // Simple block tranformation based on the `Block Transforms` API. + const onBlockTransform = ( name ) => replaceBlocks( clientIds, switchToBlockType( blocks, name ) ); + // Pattern transformation through the `Patterns` API. + const onPatternTransform = ( transformedBlocks ) => + replaceBlocks( clientIds, transformedBlocks ); const hasPossibleBlockTransformations = !! possibleBlockTransformations.length; + const hasPatternTransformation = !! patterns?.length; if ( ! hasBlockStyles && ! hasPossibleBlockTransformations ) { return ( @@ -104,9 +115,13 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { const blockSwitcherDescription = 1 === blocks.length - ? __( 'Change block type or style' ) + ? sprintf( + /* translators: %s: block title. */ + __( '%s: Change block type or style' ), + blockTitle + ) : sprintf( - /* translators: %s: number of blocks. */ + /* translators: %d: number of blocks. */ _n( 'Change type of %d block', 'Change type of %d blocks', @@ -115,6 +130,10 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { blocks.length ); + const showDropDown = + hasBlockStyles || + hasPossibleBlockTransformations || + hasPatternTransformation; return ( @@ -151,9 +170,22 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { menuProps={ { orientation: 'both' } } > { ( { onClose } ) => - ( hasBlockStyles || - hasPossibleBlockTransformations ) && ( + showDropDown && (
+ { hasPatternTransformation && ( + { + onPatternTransform( + transformedBlocks + ); + onClose(); + } } + /> + ) } { hasPossibleBlockTransformations && ( { } blocks={ blocks } onSelect={ ( name ) => { - onTransform( name ); + onBlockTransform( name ); onClose(); } } /> From 0df63a43f40cc2dd360eaaf3dd0baccb86c67488 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Mon, 30 Aug 2021 20:35:47 +0530 Subject: [PATCH 16/21] hide save btn when there are no changes --- .../src/components/block-switcher/index.js | 4 +-- ...lock-selector-unsaved-changes-indicator.js | 8 ++---- packages/block-library/src/block/edit.js | 25 ++++++++++--------- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/packages/block-editor/src/components/block-switcher/index.js b/packages/block-editor/src/components/block-switcher/index.js index 5bdb300227c036..5210ed0ba82876 100644 --- a/packages/block-editor/src/components/block-switcher/index.js +++ b/packages/block-editor/src/components/block-switcher/index.js @@ -148,9 +148,7 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => { } } icon={ <> - { isReusable && ( - - ) } + { // remove classes from the parent selector and contextual toolbar when component unmounts - document - .querySelector( '.block-editor-block-parent-selector' ) - .classList.remove( 'parent-block-has-changes' ); - document - .querySelector( '.block-editor-block-contextual-toolbar' ) - .classList.remove( 'parent-block-has-changes' ); + parentSelectorBtn.classList.remove( 'parent-block-has-changes' ); + contextualToolBar.classList.remove( 'parent-block-has-changes' ); }; }, [] ); diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index a13dd6f4efa5e0..994bdf86992971 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -193,18 +193,19 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { showTooltip /> - - - { __( 'Save' ) } - - + { hasEdits && ( + + + { __( 'Save' ) } + + + ) } From 74fcdd667123274e216097917a81e11ddc7e6f52 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Wed, 8 Sep 2021 18:52:29 +0530 Subject: [PATCH 17/21] update label and adjust margin --- packages/block-library/src/block/edit.js | 2 +- packages/block-library/src/block/editor.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 994bdf86992971..d700568a7d9bfb 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -199,7 +199,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { isPrimary className="block-library-block__reusable-block-save-button" onClick={ saveEditedRecords } - label={ __( 'Save reusable block' ) } + label={ __( 'Save globally' ) } showTooltip > { __( 'Save' ) } diff --git a/packages/block-library/src/block/editor.scss b/packages/block-library/src/block/editor.scss index 11d9888189dbfb..6add0f02c290fd 100644 --- a/packages/block-library/src/block/editor.scss +++ b/packages/block-library/src/block/editor.scss @@ -18,7 +18,7 @@ // Styles for save button .components-toolbar-group { .block-library-block__reusable-block-save-button { - margin: 7px; + margin: 8px; height: $grid-unit-40; // override the default box inset properties to match height and width of the save button From f038b11d2a38667747d689f4761efa5a18b35ddd Mon Sep 17 00:00:00 2001 From: thisissandip Date: Wed, 8 Sep 2021 19:23:28 +0530 Subject: [PATCH 18/21] use grid-unit-10 --- packages/block-library/src/block/editor.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/block/editor.scss b/packages/block-library/src/block/editor.scss index 6add0f02c290fd..df8aee8ec52b85 100644 --- a/packages/block-library/src/block/editor.scss +++ b/packages/block-library/src/block/editor.scss @@ -18,7 +18,7 @@ // Styles for save button .components-toolbar-group { .block-library-block__reusable-block-save-button { - margin: 8px; + margin: $grid-unit-10; height: $grid-unit-40; // override the default box inset properties to match height and width of the save button From 6e5b5453deccd4a66788090f09b0412b3af9c3c3 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Thu, 9 Sep 2021 19:58:12 +0530 Subject: [PATCH 19/21] adjust unsaved changes indicator margin --- .../src/components/block-parent-selector/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-parent-selector/style.scss b/packages/block-editor/src/components/block-parent-selector/style.scss index 9757cefcc726f7..ca6d770a21228e 100644 --- a/packages/block-editor/src/components/block-parent-selector/style.scss +++ b/packages/block-editor/src/components/block-parent-selector/style.scss @@ -33,7 +33,7 @@ border-radius: 4px; height: 8px; width: 8px; - margin: 0 12px; + margin: 0 14px; } } From bf3eaf906912658db59e95eb542a70f85454e3c3 Mon Sep 17 00:00:00 2001 From: thisissandip Date: Tue, 14 Sep 2021 20:51:00 +0530 Subject: [PATCH 20/21] increase parent selector focus indicator width --- .../src/components/block-parent-selector/style.scss | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/block-parent-selector/style.scss b/packages/block-editor/src/components/block-parent-selector/style.scss index ca6d770a21228e..a9edb8e7ec0623 100644 --- a/packages/block-editor/src/components/block-parent-selector/style.scss +++ b/packages/block-editor/src/components/block-parent-selector/style.scss @@ -33,7 +33,12 @@ border-radius: 4px; height: 8px; width: 8px; - margin: 0 14px; + margin: 0 12px; } -} + // increase the focus indicator width + .block-editor-block-parent-selector__button::before { + left: 7px; + right: 7px; + } +} From 740a109caf0bdbb4bc912b5d800f191f46d9a99c Mon Sep 17 00:00:00 2001 From: Kelly Hoffman Date: Mon, 1 Nov 2021 11:13:26 -0700 Subject: [PATCH 21/21] gets rid of visual jump Props @critterverse Ref: https://github.com/WordPress/gutenberg/pull/32464#pullrequestreview-770494293 --- .../src/components/block-parent-selector/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-parent-selector/style.scss b/packages/block-editor/src/components/block-parent-selector/style.scss index a9edb8e7ec0623..cdda3c9f498279 100644 --- a/packages/block-editor/src/components/block-parent-selector/style.scss +++ b/packages/block-editor/src/components/block-parent-selector/style.scss @@ -21,7 +21,7 @@ // move the parent selector icon to right side to make room for the dot .block-editor-block-icon { - margin-right: -15px; + margin-right: -16px; } // add the dot before the parent selector icon