diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js
index 3980dd7b2aead..01ba9102db24a 100644
--- a/packages/block-editor/src/components/block-list/block.js
+++ b/packages/block-editor/src/components/block-list/block.js
@@ -11,6 +11,7 @@ import {
useMemo,
useCallback,
RawHTML,
+ useRef,
} from '@wordpress/element';
import {
getBlockType,
@@ -28,8 +29,9 @@ import {
withSelect,
useDispatch,
useSelect,
+ useRegistry,
} from '@wordpress/data';
-import { compose, pure, ifCondition } from '@wordpress/compose';
+import { compose, pure } from '@wordpress/compose';
import { safeHTML } from '@wordpress/dom';
/**
@@ -78,7 +80,7 @@ function Block( { children, isHtml, ...props } ) {
}
function BlockListBlock( {
- block: { __unstableBlockSource },
+ __unstableBlockSource,
mode,
isLocked,
canRemove,
@@ -283,7 +285,7 @@ const applyWithSelect = withSelect( ( select, { clientId, rootClientId } ) => {
// This function should never be called when a block is not present in
// the state. It happens now because the order in withSelect rendering
// is not correct.
- const { name, attributes, isValid } = block || {};
+ const { name, isValid, __unstableBlockSource } = block || {};
// Do not add new properties here, use `useSelect` instead to avoid
// leaking new props to the public API (editor.BlockListBlock filter).
@@ -297,10 +299,11 @@ const applyWithSelect = withSelect( ( select, { clientId, rootClientId } ) => {
// access the block prop.
// Ideally these blocks would rely on the clientId prop only.
// This is kept for backward compatibility reasons.
- block,
+ // block,
name,
- attributes,
+ // attributes,
isValid,
+ __unstableBlockSource,
isSelected,
};
} );
@@ -540,9 +543,38 @@ export default compose(
pure,
applyWithSelect,
applyWithDispatch,
+ ( WrappedComponent ) => ( props ) => {
+ const subscriptions = useRef( new Set() );
+ const registry = useRegistry();
+ const attributes = useSelect(
+ ( select ) =>
+ Object.fromEntries(
+ Object.entries(
+ select( blockEditorStore ).getBlockAttributes(
+ props.clientId
+ )
+ ).filter( ( [ key ] ) => subscriptions.current.has( key ) )
+ ),
+ [ props.clientId ]
+ );
+
+ const proxy = new Proxy( attributes, {
+ get( target, name ) {
+ if ( target.hasOwnProperty( name ) ) {
+ return target[ name ];
+ }
+
+ subscriptions.current.add( name );
+ return registry
+ .select( blockEditorStore )
+ .getBlockAttributes( props.clientId )[ name ];
+ },
+ } );
+ return ;
+ },
// Block is sometimes not mounted at the right time, causing it be undefined
// see issue for more info
// https://github.com/WordPress/gutenberg/issues/17013
- ifCondition( ( { block } ) => !! block ),
+ // ifCondition( ( { block } ) => !! block ),
withFilters( 'editor.BlockListBlock' )
)( BlockListBlock );
diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js
index 836a9cd5a57c6..00c7dba948779 100644
--- a/packages/block-editor/src/hooks/layout.js
+++ b/packages/block-editor/src/hooks/layout.js
@@ -350,7 +350,7 @@ export const withInspectorControls = createHigherOrderComponent(
*/
export const withLayoutStyles = createHigherOrderComponent(
( BlockListBlock ) => ( props ) => {
- const { name, attributes, block } = props;
+ const { name, attributes } = props;
const hasLayoutBlockSupport = hasBlockSupport(
name,
layoutBlockSupportKey
@@ -372,7 +372,7 @@ export const withLayoutStyles = createHigherOrderComponent(
? { ...layout, type: 'constrained' }
: layout || defaultBlockLayout || {};
const layoutClasses = hasLayoutBlockSupport
- ? useLayoutClasses( block )
+ ? useLayoutClasses( { name, attributes } )
: null;
// Higher specificity to override defaults from theme.json.
const selector = `.wp-container-${ id }.wp-container-${ id }`;
diff --git a/packages/block-library/src/paragraph/edit.js b/packages/block-library/src/paragraph/edit.js
index 5cb465dc6da66..50e39d42c1d3b 100644
--- a/packages/block-library/src/paragraph/edit.js
+++ b/packages/block-library/src/paragraph/edit.js
@@ -19,6 +19,7 @@ import {
RichText,
useBlockProps,
useSetting,
+ store as blockEditorStore,
} from '@wordpress/block-editor';
import { createBlock } from '@wordpress/blocks';
import { formatLtr } from '@wordpress/icons';
@@ -27,6 +28,7 @@ import { formatLtr } from '@wordpress/icons';
* Internal dependencies
*/
import { useOnEnter } from './use-enter';
+import { useSelect } from '@wordpress/data';
const name = 'core/paragraph';
@@ -49,6 +51,74 @@ function hasDropCapDisabled( align ) {
return align === ( isRTL() ? 'left' : 'right' ) || align === 'center';
}
+// function useAttributes( name ) {
+// return useSelect(
+// ( select ) => select( blockEditorStore ).getAttribute( name ),
+// [ name ]
+// );
+// }
+
+function BlockContent( {
+ attributes,
+ mergeBlocks,
+ onReplace,
+ onRemove,
+ setAttributes,
+ clientId,
+ blockProps,
+} ) {
+ const content = useSelect(
+ ( select ) =>
+ select( blockEditorStore ).getBlockAttributes( clientId ).content,
+ [ clientId ]
+ );
+ const { placeholder } = attributes;
+ return (
+
+ setAttributes( { content: newContent } )
+ }
+ onSplit={ ( value, isOriginal ) => {
+ let newAttributes;
+
+ if ( isOriginal || value ) {
+ newAttributes = {
+ ...attributes,
+ content: value,
+ };
+ }
+
+ const block = createBlock( name, newAttributes );
+
+ if ( isOriginal ) {
+ block.clientId = clientId;
+ }
+
+ return block;
+ } }
+ onMerge={ mergeBlocks }
+ onReplace={ onReplace }
+ onRemove={ onRemove }
+ aria-label={
+ content
+ ? __( 'Paragraph block' )
+ : __(
+ 'Empty block; start writing or type forward slash to choose a block'
+ )
+ }
+ data-empty={ content ? false : true }
+ placeholder={ placeholder || __( 'Type / to choose a block' ) }
+ data-custom-placeholder={ placeholder ? true : undefined }
+ __unstableEmbedURLOnPaste
+ __unstableAllowPrefixTransformations
+ />
+ );
+}
+
function ParagraphBlock( {
attributes,
mergeBlocks,
@@ -57,16 +127,8 @@ function ParagraphBlock( {
setAttributes,
clientId,
} ) {
- const { align, content, direction, dropCap, placeholder } = attributes;
+ const { align, direction, dropCap } = attributes;
const isDropCapFeatureEnabled = useSetting( 'typography.dropCap' );
- const blockProps = useBlockProps( {
- ref: useOnEnter( { clientId, content } ),
- className: classnames( {
- 'has-drop-cap': hasDropCapDisabled( align ) ? false : dropCap,
- [ `has-text-align-${ align }` ]: align,
- } ),
- style: { direction },
- } );
let helpText;
if ( hasDropCapDisabled( align ) ) {
@@ -77,6 +139,15 @@ function ParagraphBlock( {
helpText = __( 'Toggle to show a large initial letter.' );
}
+ const blockProps = useBlockProps( {
+ ref: useOnEnter( { clientId } ),
+ className: classnames( {
+ 'has-drop-cap': hasDropCapDisabled( align ) ? false : dropCap,
+ [ `has-text-align-${ align }` ]: align,
+ } ),
+ style: { direction },
+ } );
+
return (
<>
@@ -123,47 +194,14 @@ function ParagraphBlock( {
) }
-
- setAttributes( { content: newContent } )
- }
- onSplit={ ( value, isOriginal ) => {
- let newAttributes;
-
- if ( isOriginal || value ) {
- newAttributes = {
- ...attributes,
- content: value,
- };
- }
-
- const block = createBlock( name, newAttributes );
-
- if ( isOriginal ) {
- block.clientId = clientId;
- }
-
- return block;
- } }
- onMerge={ mergeBlocks }
+
>
);
diff --git a/packages/block-library/src/paragraph/use-enter.js b/packages/block-library/src/paragraph/use-enter.js
index 22bef120ef17c..fb7619df5e957 100644
--- a/packages/block-library/src/paragraph/use-enter.js
+++ b/packages/block-library/src/paragraph/use-enter.js
@@ -23,6 +23,7 @@ export function useOnEnter( props ) {
getBlockName,
getBlock,
getNextBlockClientId,
+ getBlockAttributes,
} = useSelect( blockEditorStore );
const propsRef = useRef( props );
propsRef.current = props;
@@ -36,7 +37,8 @@ export function useOnEnter( props ) {
return;
}
- const { content, clientId } = propsRef.current;
+ const { clientId } = propsRef.current;
+ const { content } = getBlockAttributes( clientId );
// The paragraph should be empty.
if ( content.length ) {