From 4e26178be1ea43d058d8dde338af85694a6888a5 Mon Sep 17 00:00:00 2001
From: Ella <4710635+ellatrix@users.noreply.github.com>
Date: Mon, 13 Nov 2023 06:36:48 +0200
Subject: [PATCH] Block styles: remove __unstableElementContext in favour of
useStyleOverride (#54493)
---
.../src/components/block-list/index.js | 22 ++------
packages/block-editor/src/hooks/duotone.js | 56 ++++++++-----------
packages/block-editor/src/hooks/layout.js | 30 ++--------
packages/block-editor/src/hooks/position.js | 23 ++------
packages/block-editor/src/hooks/style.js | 42 +++++---------
packages/block-editor/src/hooks/utils.js | 34 ++++++++++-
packages/block-editor/src/private-apis.js | 3 +-
.../block-library/src/gallery/gap-styles.js | 19 ++++---
8 files changed, 95 insertions(+), 134 deletions(-)
diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js
index a9d5f15f12f81..ab57605563e1d 100644
--- a/packages/block-editor/src/components/block-list/index.js
+++ b/packages/block-editor/src/components/block-list/index.js
@@ -17,12 +17,7 @@ import {
useMergeRefs,
useDebounce,
} from '@wordpress/compose';
-import {
- createContext,
- useState,
- useMemo,
- useCallback,
-} from '@wordpress/element';
+import { createContext, useMemo, useCallback } from '@wordpress/element';
/**
* Internal dependencies
@@ -40,13 +35,10 @@ import {
} from '../block-edit/context';
import { useTypingObserver } from '../observe-typing';
-const elementContext = createContext();
-
export const IntersectionObserver = createContext();
const pendingBlockVisibilityUpdatesPerRegistry = new WeakMap();
function Root( { className, ...settings } ) {
- const [ element, setElement ] = useState();
const isLargeViewport = useViewportMatch( 'medium' );
const { isOutlineMode, isFocusMode, editorMode } = useSelect(
( select ) => {
@@ -115,13 +107,9 @@ function Root( { className, ...settings } ) {
settings
);
return (
-
-
-
- { /* Ensure element and layout styles are always at the end of the document */ }
-
-
-
+
+
+
);
}
@@ -133,8 +121,6 @@ export default function BlockList( settings ) {
);
}
-BlockList.__unstableElementContext = elementContext;
-
function Items( {
placeholder,
rootClientId,
diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js
index 5470ea5789f3a..5442e394e68c7 100644
--- a/packages/block-editor/src/hooks/duotone.js
+++ b/packages/block-editor/src/hooks/duotone.js
@@ -16,7 +16,6 @@ import {
import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import { useMemo, useEffect } from '@wordpress/element';
-import { useDispatch } from '@wordpress/data';
/**
* Internal dependencies
@@ -34,12 +33,10 @@ import {
} from '../components/duotone/utils';
import { getBlockCSSSelector } from '../components/global-styles/get-block-css-selector';
import { scopeSelector } from '../components/global-styles/utils';
-import { useBlockSettings } from './utils';
+import { useBlockSettings, useStyleOverride } from './utils';
import { default as StylesFiltersPanel } from '../components/global-styles/filters-panel';
import { useBlockEditingMode } from '../components/block-editing-mode';
import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
-import { store as blockEditorStore } from '../store';
-import { unlock } from '../lock-unlock';
const EMPTY_ARRAY = [];
@@ -291,8 +288,27 @@ function DuotoneStyles( {
const isValidFilter = Array.isArray( colors ) || colors === 'unset';
- const { setStyleOverride, deleteStyleOverride } = unlock(
- useDispatch( blockEditorStore )
+ useStyleOverride(
+ isValidFilter
+ ? {
+ css:
+ colors !== 'unset'
+ ? getDuotoneStylesheet( selector, filterId )
+ : getDuotoneUnsetStylesheet( selector ),
+ __unstableType: 'presets',
+ }
+ : undefined
+ );
+ useStyleOverride(
+ isValidFilter
+ ? {
+ assets:
+ colors !== 'unset'
+ ? getDuotoneFilter( filterId, colors )
+ : '',
+ __unstableType: 'svgs',
+ }
+ : undefined
);
const blockElement = useBlockElement( clientId );
@@ -300,19 +316,6 @@ function DuotoneStyles( {
useEffect( () => {
if ( ! isValidFilter ) return;
- setStyleOverride( filterId, {
- css:
- colors !== 'unset'
- ? getDuotoneStylesheet( selector, filterId )
- : getDuotoneUnsetStylesheet( selector ),
- __unstableType: 'presets',
- } );
- setStyleOverride( `duotone-${ filterId }`, {
- assets:
- colors !== 'unset' ? getDuotoneFilter( filterId, colors ) : '',
- __unstableType: 'svgs',
- } );
-
// Safari does not always update the duotone filter when the duotone colors
// are changed. When using Safari, force the block element to be repainted by
// the browser to ensure any changes are reflected visually. This logic matches
@@ -329,20 +332,7 @@ function DuotoneStyles( {
blockElement.offsetHeight;
blockElement.style.display = display;
}
-
- return () => {
- deleteStyleOverride( filterId );
- deleteStyleOverride( `duotone-${ filterId }` );
- };
- }, [
- isValidFilter,
- blockElement,
- colors,
- selector,
- filterId,
- setStyleOverride,
- deleteStyleOverride,
- ] );
+ }, [ isValidFilter, blockElement ] );
return null;
}
diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js
index e6113484f8a2c..f4730702e9adb 100644
--- a/packages/block-editor/src/hooks/layout.js
+++ b/packages/block-editor/src/hooks/layout.js
@@ -9,7 +9,7 @@ import classnames from 'classnames';
import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks';
-import { useSelect, useDispatch } from '@wordpress/data';
+import { useSelect } from '@wordpress/data';
import {
Button,
ButtonGroup,
@@ -17,7 +17,6 @@ import {
PanelBody,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
-import { useEffect } from '@wordpress/element';
/**
* Internal dependencies
@@ -29,8 +28,7 @@ import { getLayoutType, getLayoutTypes } from '../layouts';
import { useBlockEditingMode } from '../components/block-editing-mode';
import { LAYOUT_DEFINITIONS } from '../layouts/definitions';
import { kebabCase } from '../utils/object';
-import { useBlockSettings } from './utils';
-import { unlock } from '../lock-unlock';
+import { useBlockSettings, useStyleOverride } from './utils';
const layoutBlockSupportKey = 'layout';
@@ -381,17 +379,7 @@ function BlockWithLayoutStyles( { block: BlockListBlock, props } ) {
layoutClasses
);
- const { setStyleOverride, deleteStyleOverride } = unlock(
- useDispatch( blockEditorStore )
- );
-
- useEffect( () => {
- if ( ! css ) return;
- setStyleOverride( selector, { css } );
- return () => {
- deleteStyleOverride( selector );
- };
- }, [ selector, css, setStyleOverride, deleteStyleOverride ] );
+ useStyleOverride( { css } );
return (
{
- if ( ! css ) return;
- setStyleOverride( selector, { css } );
- return () => {
- deleteStyleOverride( selector );
- };
- }, [ selector, css, setStyleOverride, deleteStyleOverride ] );
+ useStyleOverride( { css } );
return ;
}
diff --git a/packages/block-editor/src/hooks/position.js b/packages/block-editor/src/hooks/position.js
index bdd8095e9b250..710dbfaf5ace0 100644
--- a/packages/block-editor/src/hooks/position.js
+++ b/packages/block-editor/src/hooks/position.js
@@ -14,22 +14,16 @@ import {
} from '@wordpress/components';
import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
-import {
- useContext,
- useMemo,
- createPortal,
- Platform,
-} from '@wordpress/element';
+import { useMemo, Platform } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
/**
* Internal dependencies
*/
-import BlockList from '../components/block-list';
import { useSettings } from '../components/use-settings';
import InspectorControls from '../components/inspector-controls';
import useBlockDisplayInformation from '../components/use-block-display-information';
-import { cleanEmptyObject } from './utils';
+import { cleanEmptyObject, useStyleOverride } from './utils';
import { unlock } from '../lock-unlock';
import { store as blockEditorStore } from '../store';
@@ -368,7 +362,6 @@ export const withPositionStyles = createHigherOrderComponent(
hasPositionBlockSupport && ! isPositionDisabled;
const id = useInstanceId( BlockListBlock );
- const element = useContext( BlockList.__unstableElementContext );
// Higher specificity to override defaults in editor UI.
const positionSelector = `.wp-container-${ id }.wp-container-${ id }`;
@@ -392,15 +385,9 @@ export const withPositionStyles = createHigherOrderComponent(
!! attributes?.style?.position?.type,
} );
- return (
- <>
- { allowPositionStyles &&
- element &&
- !! css &&
- createPortal( , element ) }
-
- >
- );
+ useStyleOverride( { css } );
+
+ return ;
},
'withPositionStyles'
);
diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js
index 356042e3017ca..d74e10b0208f1 100644
--- a/packages/block-editor/src/hooks/style.js
+++ b/packages/block-editor/src/hooks/style.js
@@ -6,7 +6,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
-import { useContext, useMemo, createPortal } from '@wordpress/element';
+import { useMemo } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
import {
getBlockSupport,
@@ -19,7 +19,6 @@ import { getCSSRules, compileCSS } from '@wordpress/style-engine';
/**
* Internal dependencies
*/
-import BlockList from '../components/block-list';
import { BACKGROUND_SUPPORT_KEY, BackgroundImagePanel } from './background';
import { BORDER_SUPPORT_KEY, BorderPanel } from './border';
import { COLOR_SUPPORT_KEY, ColorEdit } from './color';
@@ -34,7 +33,7 @@ import {
DimensionsPanel,
} from './dimensions';
import useDisplayBlockControls from '../components/use-display-block-controls';
-import { shouldSkipSerialization } from './utils';
+import { shouldSkipSerialization, useStyleOverride } from './utils';
import { scopeSelector } from '../components/global-styles/utils';
import { useBlockEditingMode } from '../components/block-editing-mode';
@@ -484,33 +483,20 @@ const withElementsStyles = createHigherOrderComponent(
: undefined;
}, [ baseElementSelector, blockElementStyles, props.name ] );
- const element = useContext( BlockList.__unstableElementContext );
+ useStyleOverride( { css: styles } );
return (
- <>
- { styles &&
- element &&
- createPortal(
- ,
- element
- ) }
-
-
- >
+
);
},
'withElementsStyles'
diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js
index e7c71ea5551f8..5985b821d00a8 100644
--- a/packages/block-editor/src/hooks/utils.js
+++ b/packages/block-editor/src/hooks/utils.js
@@ -2,7 +2,8 @@
* WordPress dependencies
*/
import { getBlockSupport } from '@wordpress/blocks';
-import { useMemo } from '@wordpress/element';
+import { useMemo, useEffect, useId } from '@wordpress/element';
+import { useDispatch } from '@wordpress/data';
/**
* Internal dependencies
@@ -10,6 +11,8 @@ import { useMemo } from '@wordpress/element';
import { useSettings } from '../components';
import { useSettingsForBlockElement } from '../components/global-styles/hooks';
import { getValueFromObjectPath, setImmutably } from '../utils/object';
+import { store as blockEditorStore } from '../store';
+import { unlock } from '../lock-unlock';
/**
* Removed falsy values from nested object.
@@ -115,6 +118,35 @@ export function shouldSkipSerialization( blockType, featureSet, feature ) {
return skipSerialization;
}
+export function useStyleOverride( { id, css, assets, __unstableType } = {} ) {
+ const { setStyleOverride, deleteStyleOverride } = unlock(
+ useDispatch( blockEditorStore )
+ );
+ const fallbackId = useId();
+ useEffect( () => {
+ // Unmount if there is CSS and assets are empty.
+ if ( ! css && ! assets ) return;
+ const _id = id || fallbackId;
+ setStyleOverride( _id, {
+ id,
+ css,
+ assets,
+ __unstableType,
+ } );
+ return () => {
+ deleteStyleOverride( _id );
+ };
+ }, [
+ id,
+ css,
+ assets,
+ __unstableType,
+ fallbackId,
+ setStyleOverride,
+ deleteStyleOverride,
+ ] );
+}
+
/**
* Based on the block and its context, returns an object of all the block settings.
* This object can be passed as a prop to all the Styles UI components
diff --git a/packages/block-editor/src/private-apis.js b/packages/block-editor/src/private-apis.js
index cf4e251874282..b1d499ae09946 100644
--- a/packages/block-editor/src/private-apis.js
+++ b/packages/block-editor/src/private-apis.js
@@ -12,7 +12,7 @@ import { PrivateListView } from './components/list-view';
import BlockInfo from './components/block-info-slot-fill';
import BlockContextualToolbar from './components/block-tools/block-contextual-toolbar';
import { useShouldContextualToolbarShow } from './utils/use-should-contextual-toolbar-show';
-import { cleanEmptyObject } from './hooks/utils';
+import { cleanEmptyObject, useStyleOverride } from './hooks/utils';
import BlockQuickNavigation from './components/block-quick-navigation';
import { LayoutStyle } from './components/block-list/layout';
import { BlockRemovalWarningModal } from './components/block-removal-warning-modal';
@@ -45,6 +45,7 @@ lock( privateApis, {
BlockContextualToolbar,
useShouldContextualToolbarShow,
cleanEmptyObject,
+ useStyleOverride,
BlockQuickNavigation,
LayoutStyle,
BlockRemovalWarningModal,
diff --git a/packages/block-library/src/gallery/gap-styles.js b/packages/block-library/src/gallery/gap-styles.js
index 7bd0932d62f5b..4c2002d4b7ddc 100644
--- a/packages/block-library/src/gallery/gap-styles.js
+++ b/packages/block-library/src/gallery/gap-styles.js
@@ -2,13 +2,18 @@
* WordPress dependencies
*/
import {
- BlockList,
__experimentalGetGapCSSValue as getGapCSSValue,
+ privateApis as blockEditorPrivateApis,
} from '@wordpress/block-editor';
-import { useContext, createPortal } from '@wordpress/element';
+
+/**
+ * Internal dependencies
+ */
+import { unlock } from '../lock-unlock';
+
+const { useStyleOverride } = unlock( blockEditorPrivateApis );
export default function GapStyles( { blockGap, clientId } ) {
- const styleElement = useContext( BlockList.__unstableElementContext );
// --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default
// gap on the gallery.
const fallbackValue = `var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )`;
@@ -35,11 +40,7 @@ export default function GapStyles( { blockGap, clientId } ) {
gap: ${ gapValue }
}`;
- const GapStyle = () => {
- return ;
- };
+ useStyleOverride( { css: gap } );
- return gap && styleElement
- ? createPortal( , styleElement )
- : null;
+ return null;
}