Skip to content

Commit

Permalink
Block API: try separate controls registration
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Apr 16, 2024
1 parent cca1f55 commit 3f5af61
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 146 deletions.
25 changes: 24 additions & 1 deletion packages/block-editor/src/components/block-edit/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import {
getBlockType,
} from '@wordpress/blocks';
import { useContext, useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import { InspectorControls, BlockControls } from '../../components';

/**
* Internal dependencies
Expand All @@ -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(
<Wrapper group={ control.group } key={ control.key }>
<control.Control { ...props } />
</Wrapper>
);
}
}

// `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 <Component { ...props } />;
return [
<Component { ...props } key="content">
{ controls }
</Component>,
];
};

const EditWithFilters = withFilters( 'editor.BlockEdit' )( Edit );
Expand Down
183 changes: 40 additions & 143 deletions packages/block-library/src/paragraph/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -31,67 +17,10 @@ import { useOnEnter } from './use-enter';

const name = 'core/paragraph';

function ParagraphRTLControl( { direction, setDirection } ) {
return (
isRTL() && (
<ToolbarButton
icon={ formatLtr }
title={ _x( 'Left to right', 'editor button' ) }
isActive={ direction === 'ltr' }
onClick={ () => {
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 (
<ToolsPanelItem
hasValue={ () => !! dropCap }
label={ __( 'Drop cap' ) }
onDeselect={ () => setAttributes( { dropCap: undefined } ) }
resetAllFilter={ () => ( { dropCap: undefined } ) }
panelId={ clientId }
>
<ToggleControl
__nextHasNoMarginBottom
label={ __( 'Drop cap' ) }
checked={ !! dropCap }
onChange={ () => setAttributes( { dropCap: ! dropCap } ) }
help={ helpText }
disabled={ hasDropCapDisabled( align ) ? true : false }
/>
</ToolsPanelItem>
);
}

function ParagraphBlock( {
attributes,
mergeBlocks,
Expand All @@ -109,81 +38,49 @@ function ParagraphBlock( {
} ),
style: { direction },
} );
const blockEditingMode = useBlockEditingMode();

return (
<>
{ blockEditingMode === 'default' && (
<BlockControls group="block">
<AlignmentControl
value={ align }
onChange={ ( newAlign ) =>
setAttributes( {
align: newAlign,
dropCap: hasDropCapDisabled( newAlign )
? false
: dropCap,
} )
}
/>
<ParagraphRTLControl
direction={ direction }
setDirection={ ( newDirection ) =>
setAttributes( { direction: newDirection } )
}
/>
</BlockControls>
) }
<InspectorControls group="typography">
<DropCapControl
clientId={ clientId }
attributes={ attributes }
setAttributes={ setAttributes }
/>
</InspectorControls>
<RichText
identifier="content"
tagName="p"
{ ...blockProps }
value={ content }
onChange={ ( newContent ) =>
setAttributes( { content: newContent } )
<RichText
identifier="content"
tagName="p"
{ ...blockProps }
value={ content }
onChange={ ( 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
/>
);
}

Expand Down
109 changes: 107 additions & 2 deletions packages/block-library/src/paragraph/index.js
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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: {
Expand Down Expand Up @@ -54,6 +64,101 @@ export const settings = {
},
edit,
save,
attributeControls: [
{
key: 'align',
type: 'toolbar',
group: 'block',
Control( { attributes, setAttributes } ) {
const { align, dropCap } = attributes;
return (
<AlignmentControl
value={ align }
onChange={ ( newAlign ) =>
setAttributes( {
align: newAlign,
dropCap: hasDropCapDisabled( newAlign )
? false
: dropCap,
} )
}
/>
);
},
},
{
key: 'direction',
type: 'toolbar',
group: 'block',
Control( { attributes, setAttributes } ) {
const { direction } = attributes;
return (
isRTL() && (
<ToolbarButton
icon={ formatLtr }
title={ _x( 'Left to right', 'editor button' ) }
isActive={ direction === 'ltr' }
onClick={ () => {
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 (
<ToolsPanelItem
hasValue={ () => !! dropCap }
label={ __( 'Drop cap' ) }
onDeselect={ () =>
setAttributes( { dropCap: undefined } )
}
resetAllFilter={ () => ( { dropCap: undefined } ) }
panelId={ clientId }
>
<ToggleControl
__nextHasNoMarginBottom
label={ __( 'Drop cap' ) }
checked={ !! dropCap }
onChange={ () =>
setAttributes( { dropCap: ! dropCap } )
}
help={ helpText }
disabled={
hasDropCapDisabled( align ) ? true : false
}
/>
</ToolsPanelItem>
);
},
},
],
};

export const init = () => initBlock( { name, metadata, settings } );

0 comments on commit 3f5af61

Please sign in to comment.