From 3f5af611829b63176be26bd7d624aa0809933847 Mon Sep 17 00:00:00 2001 From: Ella Date: Tue, 16 Apr 2024 16:24:09 +0300 Subject: [PATCH] Block API: try separate controls registration --- .../src/components/block-edit/edit.js | 25 ++- packages/block-library/src/paragraph/edit.js | 183 ++++-------------- packages/block-library/src/paragraph/index.js | 109 ++++++++++- 3 files changed, 171 insertions(+), 146 deletions(-) diff --git a/packages/block-editor/src/components/block-edit/edit.js b/packages/block-editor/src/components/block-edit/edit.js index 31344b54337935..89d156c7f4f49b 100644 --- a/packages/block-editor/src/components/block-edit/edit.js +++ b/packages/block-editor/src/components/block-edit/edit.js @@ -13,6 +13,10 @@ import { getBlockType, } from '@wordpress/blocks'; import { useContext, useMemo } from '@wordpress/element'; +/** + * Internal dependencies + */ +import { InspectorControls, BlockControls } from '../../components'; /** * Internal dependencies @@ -37,12 +41,31 @@ const Edit = ( props ) => { return null; } + const controls = []; + + if ( blockType.attributeControls?.length > 0 ) { + for ( const control of blockType.attributeControls ) { + const Wrapper = + control.type === 'toolbar' ? BlockControls : InspectorControls; + + controls.push( + + + + ); + } + } + // `edit` and `save` are functions or components describing the markup // with which a block is displayed. If `blockType` is valid, assign // them preferentially as the render value for the block. const Component = blockType.edit || blockType.save; - return ; + return [ + + { controls } + , + ]; }; const EditWithFilters = withFilters( 'editor.BlockEdit' )( Edit ); diff --git a/packages/block-library/src/paragraph/edit.js b/packages/block-library/src/paragraph/edit.js index c3e434e93b714c..32d6cded3ce5b3 100644 --- a/packages/block-library/src/paragraph/edit.js +++ b/packages/block-library/src/paragraph/edit.js @@ -6,23 +6,9 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { __, _x, isRTL } from '@wordpress/i18n'; -import { - ToolbarButton, - ToggleControl, - __experimentalToolsPanelItem as ToolsPanelItem, -} from '@wordpress/components'; -import { - AlignmentControl, - BlockControls, - InspectorControls, - RichText, - useBlockProps, - useSettings, - useBlockEditingMode, -} from '@wordpress/block-editor'; +import { __, isRTL } from '@wordpress/i18n'; +import { RichText, useBlockProps } from '@wordpress/block-editor'; import { createBlock } from '@wordpress/blocks'; -import { formatLtr } from '@wordpress/icons'; /** * Internal dependencies @@ -31,67 +17,10 @@ import { useOnEnter } from './use-enter'; const name = 'core/paragraph'; -function ParagraphRTLControl( { direction, setDirection } ) { - return ( - isRTL() && ( - { - setDirection( direction === 'ltr' ? undefined : 'ltr' ); - } } - /> - ) - ); -} - function hasDropCapDisabled( align ) { return align === ( isRTL() ? 'left' : 'right' ) || align === 'center'; } -function DropCapControl( { clientId, attributes, setAttributes } ) { - // Please do not add a useSelect call to the paragraph block unconditionally. - // Every useSelect added to a (frequently used) block will degrade load - // and type performance. By moving it within InspectorControls, the subscription is - // now only added for the selected block(s). - const [ isDropCapFeatureEnabled ] = useSettings( 'typography.dropCap' ); - - if ( ! isDropCapFeatureEnabled ) { - return null; - } - - const { align, dropCap } = attributes; - - let helpText; - if ( hasDropCapDisabled( align ) ) { - helpText = __( 'Not available for aligned text.' ); - } else if ( dropCap ) { - helpText = __( 'Showing large initial letter.' ); - } else { - helpText = __( 'Toggle to show a large initial letter.' ); - } - - return ( - !! dropCap } - label={ __( 'Drop cap' ) } - onDeselect={ () => setAttributes( { dropCap: undefined } ) } - resetAllFilter={ () => ( { dropCap: undefined } ) } - panelId={ clientId } - > - setAttributes( { dropCap: ! dropCap } ) } - help={ helpText } - disabled={ hasDropCapDisabled( align ) ? true : false } - /> - - ); -} - function ParagraphBlock( { attributes, mergeBlocks, @@ -109,81 +38,49 @@ function ParagraphBlock( { } ), style: { direction }, } ); - const blockEditingMode = useBlockEditingMode(); - return ( - <> - { blockEditingMode === 'default' && ( - - - setAttributes( { - align: newAlign, - dropCap: hasDropCapDisabled( newAlign ) - ? false - : dropCap, - } ) - } - /> - - setAttributes( { direction: newDirection } ) - } - /> - - ) } - - - - - setAttributes( { content: newContent } ) + + setAttributes( { content: newContent } ) + } + onSplit={ ( value, isOriginal ) => { + let newAttributes; + + if ( isOriginal || value ) { + newAttributes = { + ...attributes, + content: value, + }; } - onSplit={ ( value, isOriginal ) => { - let newAttributes; - - if ( isOriginal || value ) { - newAttributes = { - ...attributes, - content: value, - }; - } - const block = createBlock( name, newAttributes ); + const block = createBlock( name, newAttributes ); - if ( isOriginal ) { - block.clientId = clientId; - } - - return block; - } } - onMerge={ mergeBlocks } - onReplace={ onReplace } - onRemove={ onRemove } - aria-label={ - RichText.isEmpty( content ) - ? __( - 'Empty block; start writing or type forward slash to choose a block' - ) - : __( 'Block: Paragraph' ) + if ( isOriginal ) { + block.clientId = clientId; } - data-empty={ RichText.isEmpty( content ) } - placeholder={ placeholder || __( 'Type / to choose a block' ) } - data-custom-placeholder={ placeholder ? true : undefined } - __unstableEmbedURLOnPaste - __unstableAllowPrefixTransformations - /> - + + return block; + } } + onMerge={ mergeBlocks } + onReplace={ onReplace } + onRemove={ onRemove } + aria-label={ + RichText.isEmpty( content ) + ? __( + 'Empty block; start writing or type forward slash to choose a block' + ) + : __( 'Block: Paragraph' ) + } + data-empty={ RichText.isEmpty( content ) } + placeholder={ placeholder || __( 'Type / to choose a block' ) } + data-custom-placeholder={ placeholder ? true : undefined } + __unstableEmbedURLOnPaste + __unstableAllowPrefixTransformations + /> ); } diff --git a/packages/block-library/src/paragraph/index.js b/packages/block-library/src/paragraph/index.js index 715fb35ec05ab1..82c5257d58bde6 100644 --- a/packages/block-library/src/paragraph/index.js +++ b/packages/block-library/src/paragraph/index.js @@ -1,8 +1,14 @@ /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; -import { paragraph as icon } from '@wordpress/icons'; +import { __, _x, isRTL } from '@wordpress/i18n'; +import { paragraph as icon, formatLtr } from '@wordpress/icons'; +import { AlignmentControl, useSettings } from '@wordpress/block-editor'; +import { + ToolbarButton, + ToggleControl, + __experimentalToolsPanelItem as ToolsPanelItem, +} from '@wordpress/components'; /** * Internal dependencies @@ -18,6 +24,10 @@ const { name } = metadata; export { metadata, name }; +function hasDropCapDisabled( align ) { + return align === ( isRTL() ? 'left' : 'right' ) || align === 'center'; +} + export const settings = { icon, example: { @@ -54,6 +64,101 @@ export const settings = { }, edit, save, + attributeControls: [ + { + key: 'align', + type: 'toolbar', + group: 'block', + Control( { attributes, setAttributes } ) { + const { align, dropCap } = attributes; + return ( + + setAttributes( { + align: newAlign, + dropCap: hasDropCapDisabled( newAlign ) + ? false + : dropCap, + } ) + } + /> + ); + }, + }, + { + key: 'direction', + type: 'toolbar', + group: 'block', + Control( { attributes, setAttributes } ) { + const { direction } = attributes; + return ( + isRTL() && ( + { + setAttributes( { + direction: + direction === 'ltr' ? undefined : 'ltr', + } ); + } } + /> + ) + ); + }, + }, + { + key: 'dropCap', + type: 'inspector', + group: 'typography', + Control( { attributes, setAttributes, clientId } ) { + const [ isDropCapFeatureEnabled ] = + useSettings( 'typography.dropCap' ); + + if ( ! isDropCapFeatureEnabled ) { + return null; + } + + const { align, dropCap } = attributes; + + let helpText; + if ( hasDropCapDisabled( align ) ) { + helpText = __( 'Not available for aligned text.' ); + } else if ( dropCap ) { + helpText = __( 'Showing large initial letter.' ); + } else { + helpText = __( 'Toggle to show a large initial letter.' ); + } + + return ( + !! dropCap } + label={ __( 'Drop cap' ) } + onDeselect={ () => + setAttributes( { dropCap: undefined } ) + } + resetAllFilter={ () => ( { dropCap: undefined } ) } + panelId={ clientId } + > + + setAttributes( { dropCap: ! dropCap } ) + } + help={ helpText } + disabled={ + hasDropCapDisabled( align ) ? true : false + } + /> + + ); + }, + }, + ], }; export const init = () => initBlock( { name, metadata, settings } );