Skip to content
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

Try: Add new textAlign block support #59531

Merged
merged 34 commits into from Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4091d64
Try: Add new `textAlign` block support
t-hamano Mar 3, 2024
909a3e7
Merge branch 'trunk' into add/text-align-block-support
t-hamano Mar 5, 2024
a6818b5
Remove `justify` option
t-hamano Mar 5, 2024
7303bd1
Add unit test
t-hamano Mar 5, 2024
ff07c27
Move definition from `textAlign` to `typography.textAlign`
t-hamano Mar 5, 2024
f68e1f0
Update documentation
t-hamano Mar 5, 2024
3e67645
Update block.json schema
t-hamano Mar 5, 2024
59dc958
Try to fix block.json schema unit test
t-hamano Mar 5, 2024
a4a43b0
Merge branch 'trunk' into add/text-align-block-support
t-hamano Mar 19, 2024
ff9a5ea
Add support for dynamic blocks
t-hamano Mar 19, 2024
7a2604c
Add skipSerialization support
t-hamano Mar 19, 2024
3c63337
Fix prop order in lib/theme.json
t-hamano Mar 20, 2024
f968646
Update useTypographyProps hook
t-hamano Mar 20, 2024
11fba78
Merge branch 'trunk' into add/text-align-block-support
t-hamano Mar 20, 2024
28b655d
Fix PHPCS errors
t-hamano Mar 20, 2024
7594e2b
Update fixtures
t-hamano Mar 20, 2024
7293e8a
Fix JS hok namespace and attribute definition
t-hamano Mar 21, 2024
f083864
Dont't use HTML_TAG_Processor to apply text-align class
t-hamano Mar 22, 2024
856f23a
Merge branch 'trunk' into add/text-align-block-support
t-hamano Mar 27, 2024
697b670
Apply support as inline style instead of class name
t-hamano Mar 27, 2024
d07af76
Remove unnecessary code
t-hamano Mar 28, 2024
3094465
Merge branch 'trunk' into add/text-align-block-support
t-hamano Apr 3, 2024
36575d5
Output as class name instead of inline style
t-hamano Apr 3, 2024
125639e
Update fixtures
t-hamano Apr 3, 2024
bb24696
Merge branch 'trunk' into add/text-align-block-support
t-hamano Apr 5, 2024
e1edff4
Add `TEXT_ALIGN_SUPPORT_KEY` to `TYPOGRAPHY_SUPPORT_KEYS` and remove …
t-hamano Apr 5, 2024
c38bcc9
Include `text-align` when pasting styles
t-hamano Apr 5, 2024
c1b5a43
Update theme.json schema
t-hamano Apr 5, 2024
6a8ecaa
Update Global Settings & Styles documentation
t-hamano Apr 5, 2024
6c31e6d
Update fixtures
t-hamano Apr 5, 2024
787658b
Add `textAlign` to `useBlockSettings`
t-hamano Apr 5, 2024
13acc91
Merge branch 'trunk' into add/text-align-block-support
t-hamano Apr 13, 2024
611a0b2
Make styles work in the Site Editor
t-hamano Apr 13, 2024
2dbaeb1
Merge branch 'trunk' into add/text-align-block-support
t-hamano Apr 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/block-editor/src/hooks/index.js
Expand Up @@ -8,6 +8,7 @@ import {
} from './utils';
import './compat';
import align from './align';
import textAlign from './text-align';
import './lock';
import anchor from './anchor';
import ariaLabel from './aria-label';
Expand All @@ -33,6 +34,7 @@ import './use-bindings-attributes';
createBlockEditFilter(
[
align,
textAlign,
anchor,
customClassName,
style,
Expand All @@ -47,6 +49,7 @@ createBlockEditFilter(
);
createBlockListBlockFilter( [
align,
textAlign,
style,
color,
dimensions,
Expand All @@ -59,6 +62,7 @@ createBlockListBlockFilter( [
] );
createBlockSaveFilter( [
align,
textAlign,
anchor,
ariaLabel,
customClassName,
Expand Down
198 changes: 198 additions & 0 deletions packages/block-editor/src/hooks/text-align.js
@@ -0,0 +1,198 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { addFilter } from '@wordpress/hooks';
import {
getBlockSupport,
getBlockType,
hasBlockSupport,
} from '@wordpress/blocks';
import {
alignLeft,
alignRight,
alignCenter,
alignJustify,
} from '@wordpress/icons';

/**
* Internal dependencies
*/
import { AlignmentControl, BlockControls } from '../components';
import { useBlockEditingMode } from '../components/block-editing-mode';

const TEXT_ALIGNMENT_OPTIONS = [
{
icon: alignLeft,
title: __( 'Align text left' ),
align: 'left',
},
{
icon: alignCenter,
title: __( 'Align text center' ),
align: 'center',
},
{
icon: alignRight,
title: __( 'Align text right' ),
align: 'right',
},
{
icon: alignJustify,
title: __( 'Justify text' ),
align: 'justify',
},
];

const VALID_TEXT_ALIGNMENTS = [ 'left', 'center', 'right', 'justify' ];

/**
* Returns the valid text alignments.
* Takes into consideration the text aligns supported by a block.
* Exported just for testing purposes, not exported outside the module.
*
* @param {?boolean|string[]} blockTextAlign Text aligns supported by the block.
*
* @return {string[]} Valid text alignments.
*/
export function getValidTextAlignments( blockTextAlign ) {
let validTextAlignments;
if ( Array.isArray( blockTextAlign ) ) {
validTextAlignments = VALID_TEXT_ALIGNMENTS.filter( ( textAlign ) =>
blockTextAlign.includes( textAlign )
);
} else if ( blockTextAlign === true ) {
// `true` includes all alignments...
validTextAlignments = [ ...VALID_TEXT_ALIGNMENTS ];
} else {
validTextAlignments = [];
}

return validTextAlignments;
}

/**
* Filters registered block settings, extending attributes to include `textAlign`.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
export function addAttribute( settings ) {
// Allow blocks to specify their own attribute definition with default values if needed.
if ( 'type' in ( settings.attributes?.textAlign ?? {} ) ) {
return settings;
}
if ( hasBlockSupport( settings, 'textAlign' ) ) {
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
textAlign: {
type: 'string',
// Allow for '' since it is used by the `updateTextAlignment` function
// in toolbar controls for special cases with defined default values.
enum: [ ...VALID_TEXT_ALIGNMENTS, '' ],
},
};
}

return settings;
}

function BlockEditTextAlignmentToolbarControlsPure( {
name: blockName,
textAlign,
setAttributes,
} ) {
const validTextAlignments = getValidTextAlignments(
getBlockSupport( blockName, 'textAlign' )
);
const blockEditingMode = useBlockEditingMode();
if ( ! validTextAlignments.length || blockEditingMode !== 'default' ) {
return null;
}

const textAlignmentControls = TEXT_ALIGNMENT_OPTIONS.filter( ( control ) =>
validTextAlignments.includes( control.align )
);

const updateTextAlignment = ( nextTextAlign ) => {
if ( ! nextTextAlign ) {
const blockType = getBlockType( blockName );
const blockDefaultTextAlign =
blockType?.attributes?.textAlign?.default;
if ( blockDefaultTextAlign ) {
nextTextAlign = '';
}
}
setAttributes( { textAlign: nextTextAlign } );
};

return (
<BlockControls group="block">
<AlignmentControl
value={ textAlign }
onChange={ updateTextAlignment }
alignmentControls={ textAlignmentControls }
/>
</BlockControls>
);
}

export default {
edit: BlockEditTextAlignmentToolbarControlsPure,
useBlockProps,
addSaveProps: addAssignedTextAlign,
attributeKeys: [ 'textAlign' ],
hasSupport( name ) {
return hasBlockSupport( name, 'textAlign', false );
},
};

function useBlockProps( { name, textAlign } ) {
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
const validTextAlignments = getValidTextAlignments(
getBlockSupport( name, 'textAlign' )
);
if ( ! validTextAlignments.length ) {
return null;
}
const className = classnames( {
[ `has-text-align-${ textAlign }` ]: textAlign,
} );
return { className };
}

/**
* Override props assigned to save component to inject text alignment class
* name if block supports it.
*
* @param {Object} props Additional props applied to save element.
* @param {Object} blockType Block type.
* @param {Object} attributes Block attributes.
*
* @return {Object} Filtered props applied to save element.
*/
export function addAssignedTextAlign( props, blockType, attributes ) {
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
const { textAlign } = attributes;
const blockTextAlign = getBlockSupport( blockType, 'textAlign' );
const isTextAlignValid =
getValidTextAlignments( blockTextAlign ).includes( textAlign );
if ( isTextAlignValid ) {
props.className = classnames(
`has-text-align-${ textAlign }`,
props.className
);
}
return props;
}

addFilter(
'blocks.registerBlockType',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be cool to abstract this hook into the default export (an addAttribute property or something) but I guess that's separate from this PR.

'core/editor/align/addAttribute',
addAttribute
);
4 changes: 4 additions & 0 deletions packages/block-library/src/common.scss
Expand Up @@ -46,6 +46,10 @@
text-align: right;
}

.has-text-align-justify {
text-align: justify;
}

// This tag marks the end of the styles that apply to editing canvas contents and need to be manipulated when we resize the editor.
#end-resizable-editor-section {
display: none;
Expand Down