-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Remove text align control for paragraph, heading, and button in contentOnly editing mode #57906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5c70648
f8fa12f
b522b8e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ import { | |
| useBlockProps, | ||
| store as blockEditorStore, | ||
| HeadingLevelDropdown, | ||
| useBlockEditingMode, | ||
| } from '@wordpress/block-editor'; | ||
|
|
||
| /** | ||
|
|
@@ -40,6 +41,7 @@ function HeadingEdit( { | |
| } ), | ||
| style, | ||
| } ); | ||
| const blockEditingMode = useBlockEditingMode(); | ||
|
|
||
| const { canGenerateAnchors } = useSelect( ( select ) => { | ||
| const { getGlobalBlockCount, getSettings } = select( blockEditorStore ); | ||
|
|
@@ -90,20 +92,22 @@ function HeadingEdit( { | |
|
|
||
| return ( | ||
| <> | ||
| <BlockControls group="block"> | ||
| <HeadingLevelDropdown | ||
| value={ level } | ||
| onChange={ ( newLevel ) => | ||
| setAttributes( { level: newLevel } ) | ||
| } | ||
| /> | ||
| <AlignmentControl | ||
| value={ textAlign } | ||
| onChange={ ( nextAlign ) => { | ||
| setAttributes( { textAlign: nextAlign } ); | ||
| } } | ||
| /> | ||
| </BlockControls> | ||
| { blockEditingMode === 'default' && ( | ||
| <BlockControls group="block"> | ||
| <HeadingLevelDropdown | ||
| value={ level } | ||
| onChange={ ( newLevel ) => | ||
| setAttributes( { level: newLevel } ) | ||
| } | ||
| /> | ||
|
Comment on lines
+97
to
+102
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I disagree with the removal of this. Heading level is not a visual setting but rater a semantic one. Depending on where a pattern is used adjusting the heading level is required to make sure content follows good semantics and is as accessible as possible.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, though we'd need to explore making it work as an attribute that supports block binding, as it wasn't working. I guess there is still a question of whether it should be retained as viewable in contentOnly mode outside of patterns. I'll add it to the tracking issue to explore.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would consider this a breaking change for how content only mode currently functions. I get there are implications for the new block connections and overrides. But this is making the existing content only locking mode less usable.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was really a bug, as that attribute isn't marked I understand the point that it limits important functionality though. I think it's one of those attributes that falls between the cracks in not being content, but being important for the structure of content. I think there's some suffering from 'contentOnly' mode not being properly thought out, and personally I don't think the |
||
| <AlignmentControl | ||
| value={ textAlign } | ||
| onChange={ ( nextAlign ) => { | ||
| setAttributes( { textAlign: nextAlign } ); | ||
| } } | ||
| /> | ||
| </BlockControls> | ||
| ) } | ||
| <RichText | ||
| identifier="content" | ||
| tagName={ tagName } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| /** | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, why was this duplicated?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Native code doesn't support |
||
| * External dependencies | ||
| */ | ||
| import classnames from 'classnames'; | ||
|
|
||
| /** | ||
| * WordPress dependencies | ||
| */ | ||
| import { __ } from '@wordpress/i18n'; | ||
| import { useEffect, Platform } from '@wordpress/element'; | ||
| import { useDispatch, useSelect } from '@wordpress/data'; | ||
| import { createBlock, getDefaultBlockName } from '@wordpress/blocks'; | ||
| import { | ||
| AlignmentControl, | ||
| BlockControls, | ||
| RichText, | ||
| useBlockProps, | ||
| store as blockEditorStore, | ||
| HeadingLevelDropdown, | ||
| } from '@wordpress/block-editor'; | ||
|
|
||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { generateAnchor, setAnchor } from './autogenerate-anchors'; | ||
|
|
||
| function HeadingEdit( { | ||
| attributes, | ||
| setAttributes, | ||
| mergeBlocks, | ||
| onReplace, | ||
| style, | ||
| clientId, | ||
| } ) { | ||
| const { textAlign, content, level, placeholder, anchor } = attributes; | ||
| const tagName = 'h' + level; | ||
| const blockProps = useBlockProps( { | ||
| className: classnames( { | ||
| [ `has-text-align-${ textAlign }` ]: textAlign, | ||
| } ), | ||
| style, | ||
| } ); | ||
|
|
||
| const { canGenerateAnchors } = useSelect( ( select ) => { | ||
| const { getGlobalBlockCount, getSettings } = select( blockEditorStore ); | ||
| const settings = getSettings(); | ||
|
|
||
| return { | ||
| canGenerateAnchors: | ||
| !! settings.generateAnchors || | ||
| getGlobalBlockCount( 'core/table-of-contents' ) > 0, | ||
| }; | ||
| }, [] ); | ||
|
|
||
| const { __unstableMarkNextChangeAsNotPersistent } = | ||
| useDispatch( blockEditorStore ); | ||
|
|
||
| // Initially set anchor for headings that have content but no anchor set. | ||
| // This is used when transforming a block to heading, or for legacy anchors. | ||
| useEffect( () => { | ||
| if ( ! canGenerateAnchors ) { | ||
| return; | ||
| } | ||
|
|
||
| if ( ! anchor && content ) { | ||
| // This side-effect should not create an undo level. | ||
| __unstableMarkNextChangeAsNotPersistent(); | ||
| setAttributes( { | ||
| anchor: generateAnchor( clientId, content ), | ||
| } ); | ||
| } | ||
| setAnchor( clientId, anchor ); | ||
|
|
||
| // Remove anchor map when block unmounts. | ||
| return () => setAnchor( clientId, null ); | ||
| }, [ anchor, content, clientId, canGenerateAnchors ] ); | ||
|
|
||
| const onContentChange = ( value ) => { | ||
| const newAttrs = { content: value }; | ||
| if ( | ||
| canGenerateAnchors && | ||
| ( ! anchor || | ||
| ! value || | ||
| generateAnchor( clientId, content ) === anchor ) | ||
| ) { | ||
| newAttrs.anchor = generateAnchor( clientId, value ); | ||
| } | ||
| setAttributes( newAttrs ); | ||
| }; | ||
|
|
||
| return ( | ||
| <> | ||
| <BlockControls group="block"> | ||
| <HeadingLevelDropdown | ||
| value={ level } | ||
| onChange={ ( newLevel ) => | ||
| setAttributes( { level: newLevel } ) | ||
| } | ||
| /> | ||
| <AlignmentControl | ||
| value={ textAlign } | ||
| onChange={ ( nextAlign ) => { | ||
| setAttributes( { textAlign: nextAlign } ); | ||
| } } | ||
| /> | ||
| </BlockControls> | ||
| <RichText | ||
| identifier="content" | ||
| tagName={ tagName } | ||
| value={ content } | ||
| onChange={ onContentChange } | ||
| onMerge={ mergeBlocks } | ||
| onSplit={ ( value, isOriginal ) => { | ||
| let block; | ||
|
|
||
| if ( isOriginal || value ) { | ||
| block = createBlock( 'core/heading', { | ||
| ...attributes, | ||
| content: value, | ||
| } ); | ||
| } else { | ||
| block = createBlock( | ||
| getDefaultBlockName() ?? 'core/heading' | ||
| ); | ||
| } | ||
|
|
||
| if ( isOriginal ) { | ||
| block.clientId = clientId; | ||
| } | ||
|
|
||
| return block; | ||
| } } | ||
| onReplace={ onReplace } | ||
| onRemove={ () => onReplace( [] ) } | ||
| placeholder={ placeholder || __( 'Heading' ) } | ||
| textAlign={ textAlign } | ||
| { ...( Platform.isNative && { deleteEnter: true } ) } // setup RichText on native mobile to delete the "Enter" key as it's handled by the JS/RN side | ||
| { ...blockProps } | ||
| /> | ||
| </> | ||
| ); | ||
| } | ||
|
|
||
| export default HeadingEdit; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ import { | |
| RichText, | ||
| useBlockProps, | ||
| useSettings, | ||
| useBlockEditingMode, | ||
| } from '@wordpress/block-editor'; | ||
| import { createBlock } from '@wordpress/blocks'; | ||
| import { formatLtr } from '@wordpress/icons'; | ||
|
|
@@ -108,28 +109,31 @@ function ParagraphBlock( { | |
| } ), | ||
| style: { direction }, | ||
| } ); | ||
| const blockEditingMode = useBlockEditingMode(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is adding a store subscription for every paragraph block and is thus causing a performance regression.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for catching it. There's a few blocks that use |
||
|
|
||
| return ( | ||
| <> | ||
| <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> | ||
| { blockEditingMode === 'default' && ( | ||
| <BlockControls group="block"> | ||
| <AlignmentControl | ||
| value={ align } | ||
| onChange={ ( newAlign ) => | ||
| setAttributes( { | ||
| align: newAlign, | ||
| dropCap: hasDropCapDisabled( newAlign ) | ||
| ? false | ||
| : dropCap, | ||
| } ) | ||
| } | ||
| /> | ||
| <ParagraphRTLControl | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this moved in the condition?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not? Not sure it's something that should appear for
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a language thing no? That's content? |
||
| direction={ direction } | ||
| setDirection={ ( newDirection ) => | ||
| setAttributes( { direction: newDirection } ) | ||
| } | ||
| /> | ||
| </BlockControls> | ||
| ) } | ||
| <InspectorControls group="typography"> | ||
| <DropCapControl | ||
| clientId={ clientId } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sounds to me like the
blockEditingModeshould be part of the alignment control component.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good option. There are a few controls that have this kind of implementation.
It's a little hard to avoid this issue - #57941 (comment).
I'll look into if there's an alternative. 👍