From cae48d71e62ba00cdbe2801ed3ad599d33170ac9 Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Fri, 17 Mar 2023 10:02:43 +1100
Subject: [PATCH] Sticky Position: Add a "Make sticky" action to the Template
Part block (#49085)
* Sticky Position: Try adding a make sticky action to the Template Part block
* Hide button if the block or theme do not support sticky position
* Set to 0px for consistency
---
packages/block-editor/src/private-apis.js | 8 ++
.../convert-to-sticky-group.js | 97 +++++++++++++++++++
.../template-part-converter/index.js | 15 ++-
3 files changed, 116 insertions(+), 4 deletions(-)
create mode 100644 packages/edit-site/src/components/template-part-converter/convert-to-sticky-group.js
diff --git a/packages/block-editor/src/private-apis.js b/packages/block-editor/src/private-apis.js
index b34f35adc5c911..75a92c4ee4f11b 100644
--- a/packages/block-editor/src/private-apis.js
+++ b/packages/block-editor/src/private-apis.js
@@ -7,6 +7,11 @@ import { lock } from './lock-unlock';
import OffCanvasEditor from './components/off-canvas-editor';
import LeafMoreMenu from './components/off-canvas-editor/leaf-more-menu';
import { ComposedPrivateInserter as PrivateInserter } from './components/inserter';
+import { default as useConvertToGroupButtonProps } from './components/convert-to-group-buttons/use-convert-to-group-button-props';
+import {
+ hasStickyPositionSupport,
+ useIsPositionDisabled,
+} from './hooks/position';
/**
* Private @wordpress/block-editor APIs.
@@ -18,4 +23,7 @@ lock( privateApis, {
LeafMoreMenu,
OffCanvasEditor,
PrivateInserter,
+ useConvertToGroupButtonProps,
+ hasStickyPositionSupport,
+ useIsPositionDisabled,
} );
diff --git a/packages/edit-site/src/components/template-part-converter/convert-to-sticky-group.js b/packages/edit-site/src/components/template-part-converter/convert-to-sticky-group.js
new file mode 100644
index 00000000000000..ffdea304ba2968
--- /dev/null
+++ b/packages/edit-site/src/components/template-part-converter/convert-to-sticky-group.js
@@ -0,0 +1,97 @@
+/**
+ * WordPress dependencies
+ */
+import { switchToBlockType } from '@wordpress/blocks';
+import { MenuItem } from '@wordpress/components';
+import { useSelect, useDispatch } from '@wordpress/data';
+import {
+ store as blockEditorStore,
+ privateApis as blockEditorPrivateApis,
+} from '@wordpress/block-editor';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies
+ */
+import { unlock } from '../../private-apis';
+
+const {
+ hasStickyPositionSupport,
+ useConvertToGroupButtonProps,
+ useIsPositionDisabled,
+} = unlock( blockEditorPrivateApis );
+
+export default function ConvertToStickyGroup( { selectedClientIds, onClose } ) {
+ const { replaceBlocks } = useDispatch( blockEditorStore );
+ const { clientIds, isGroupable, blocksSelection, groupingBlockName } =
+ useConvertToGroupButtonProps( selectedClientIds );
+
+ const { canRemove, hasParents } = useSelect(
+ ( select ) => {
+ const { getBlockParents, canRemoveBlocks } =
+ select( blockEditorStore );
+ return {
+ canRemove: canRemoveBlocks( clientIds ),
+ hasParents: !! getBlockParents( clientIds[ 0 ] ).length,
+ };
+ },
+ [ clientIds ]
+ );
+
+ const isPositionDisabled = useIsPositionDisabled( {
+ name: groupingBlockName,
+ } );
+ const isStickySupported = hasStickyPositionSupport( groupingBlockName );
+
+ const onConvertToGroup = () => {
+ const newBlocks = switchToBlockType(
+ blocksSelection,
+ groupingBlockName
+ );
+
+ if ( newBlocks && newBlocks.length > 0 ) {
+ // Because the block is not in the store yet we can't use
+ // updateBlockAttributes so need to manually update attributes.
+ newBlocks[ 0 ].attributes.layout = {
+ type: 'default',
+ };
+ newBlocks[ 0 ].attributes.style = {
+ ...( newBlocks[ 0 ].attributes.style || {} ),
+ position: {
+ type: 'sticky',
+ top: '0px',
+ },
+ };
+ replaceBlocks( clientIds, newBlocks );
+ }
+ };
+
+ // For the button to be visible, the following conditions must be met:
+ // - The block is groupable.
+ // - The block can be removed.
+ // - A grouping block is available.
+ // - The block and theme both support sticky position.
+ // - The block has no parents, so is at the root of the template.
+ if (
+ ! isGroupable ||
+ ! canRemove ||
+ ! groupingBlockName ||
+ ! isStickySupported ||
+ hasParents ||
+ isPositionDisabled
+ ) {
+ return null;
+ }
+
+ // Allow converting a single template part block to a group.
+ return (
+
+ );
+}
diff --git a/packages/edit-site/src/components/template-part-converter/index.js b/packages/edit-site/src/components/template-part-converter/index.js
index 7694735cbb3025..02fb5e91703308 100644
--- a/packages/edit-site/src/components/template-part-converter/index.js
+++ b/packages/edit-site/src/components/template-part-converter/index.js
@@ -12,6 +12,7 @@ import {
*/
import ConvertToRegularBlocks from './convert-to-regular';
import ConvertToTemplatePart from './convert-to-template-part';
+import { default as ConvertToStickyGroup } from './convert-to-sticky-group';
export default function TemplatePartConverter() {
return (
@@ -36,10 +37,16 @@ function TemplatePartConverterMenuItem( { clientIds, onClose } ) {
// Allow converting a single template part to standard blocks.
if ( blocks.length === 1 && blocks[ 0 ]?.name === 'core/template-part' ) {
return (
-
+ <>
+
+
+ >
);
}
return ;