-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Extending AlignmentToolbar Options #27629
Comments
@augustuswm What are the additional alignment options you're looking to add? |
It depends on the frontend that we are implementing, but for a current project we are working on we would be looking to add additional left / right floating alignments for images and multiple "Wide" alignments. For images we have a standard left floated treatment that aligns with the left hand edge of the text as well as a left floated treatment that extends out past the left hand edge. (With the same options for right floating images). The wide alignment case is simpler, essentially adding (for lack of better names) a slight wide and extra wide option. Alignment widths that are narrower and wider than the Wide alignment. |
@augustuswm: were you able to add any more alignment options? If so, would you care to share how you achieved this? |
@landwire - We have not. That work was put off as getting something implemented looked like it would be too much effort for what we were going to use it for. We may revisit in the next few months depending on what priorities look like. Taking a quick 2 minute look at the master branch, I think the same core issue exists as it doesn't look like there is an api to modify |
This is similar to something we would like to achieve. Most of the time we have a layout with a base content width, which is used nearly throughout all pages. But there are elements that need to be narrower. So what we would need instead of "no alignment (default), wide, full" is something like "narrow, no alignment (default), wide (maybe), full". I know this could be done by using the default width on every element that needs to be narrow and wide on every other element. But that is not very intuitiv when setting up a page. Have you any thoughts on this? |
This would be beneficial on so many projects. Right now we just use custom classes to alter alignment, but that's not the smoothest use of Gutenberg. And since users can't select multiple block styles, we're lacking any sort of UI based design features for alignment outside of the box. A filter for |
I'm trying to achieve the same as well. Most websites are using wide container on desktop, usually 1200px and higher. A Narrow option or even Custom Width is vital to limit certain sections on desktop. It can be useful for almost all block types such as single paragraph, images or even columns block. In my opinion, asking customers to add a "align-narrow" CSS class through Additional CSS Classes field is "asking too much" :) |
I would really like this too. I'd love to be able to use a filter to add to the alignment options. Right now I make a filter that adds an option for "extra wide" in the sidebar, but it's hard to explain to clients why they choose an alignment option on the block toolbar, but for "extra wide" they need to use the sidebar. |
This is not at all PR ready, but internally at my company we are using the following if it is helpful to sketch out the idea. It is by no means extensively tested, and is really targeted to work for our use case. Replace direct use of
Replace default use of
Filter alignments returned from
Filter default controls used by
Filter direct use of
There is likely more to do to make this really generic and work everywhere, but we use these filters in to extend the list of alignments to |
I would like to add the option of |
I'm a bit new to block development and not familiar with react. But I was playing around with native javascript here. Unfortunately, there is no way to extend the core block alignment toolbar. But it is possible to create our own. Here's my solution with a cool advantage: you can extend your custom alignments like Another advantage is that you can use " Apart from the fact that the control element does not appear as active, it already works very well. I think I need to use other components here and work with React UseState. Anyone interested is welcome to help. var {
__,
} = wp.i18n;
var {
BlockControls,
useBlockProps,
} = wp.blockEditor;
var {
ToolbarDropdownMenu,
ToolbarGroup,
DropdownMenu,
MenuGroup,
MenuItem,
} = wp.components;
var {
createHigherOrderComponent,
} = wp.compose;
var {
getBlockSupport,
} = wp.blocks;
var {
Fragment,
createElement,
} = wp.element;
var el = createElement;
/*
* Disable default "align" to hide the core block alignment toolbar.
* Clone the block specific "align" supports values and store these in "alignCustom" instead.
*/
function modifyBlockAlignmentSupport( settings, name ) {
if ( ! name.includes('acf/') ) {
// Only modify our acf blocks
return settings;
}
const hasAlignSupport = getBlockSupport( name, 'align', false );
if( ! hasAlignSupport ) {
return settings;
}
// Get the original align values from the block supports settings
let originalAlignSupport = settings.supports.align;
// Modify the default block supports settings
newSettings = {
...settings,
supports: {
...settings.supports,
align: false, // <-- This will disable the default align to hide the core block alignment toolbar
alignCustom: originalAlignSupport, // <-- We clone the default align and store it here instead
}
};
return newSettings;
}
wp.hooks.addFilter( 'blocks.registerBlockType', 'plugin-name/modify-block-align-support', modifyBlockAlignmentSupport );
/*
* Function to handle the block alignment icons
*/
function blockAlignIcon( name ) {
var icons = {
'none': 'M5 15h14V9H5v6zm0 4.8h14v-1.5H5v1.5zM5 4.2v1.5h14V4.2H5z',
'full': 'M5 4v11h14V4H5zm3 15.8h8v-1.5H8v1.5z',
'wide': 'M5 9v6h14V9H5zm11-4.8H8v1.5h8V4.2zM8 19.8h8v-1.5H8v1.5z',
'narrow': 'M5 9v6h14V9H5zm11-4.8H8v1.5h8V4.2zM8 19.8h8v-1.5H8v1.5z',
'left': 'M4 9v6h14V9H4zm8-4.8H4v1.5h8V4.2zM4 19.8h8v-1.5H4v1.5z',
'center': 'M7 9v6h10V9H7zM5 19.8h14v-1.5H5v1.5zM5 4.3v1.5h14V4.3H5z',
'right': 'M6 15h14V9H6v6zm6-10.8v1.5h8V4.2h-8zm0 15.6h8v-1.5h-8v1.5z',
}
//var path = icons.name ? icons.name : icons.none;
var path = icons[name];
return el('svg', { width: 24, height: 24 },
el('path', { d: path } )
);
}
/*
* Filter to add custom block alignment toolbar controls
*/
var customBlockAlignmentControls = createHigherOrderComponent( function( BlockEdit ) {
return function( props ) {
const blockName = props.name;
const currentAlign = props.attributes.align;
const originalEdit = el( BlockEdit, props );
// Check for block align support
const blockAlignSupport = getBlockSupport( blockName, 'alignCustom', false );
// We add this custom controls to our acf blocks only
if( ! blockName.includes('acf/') ) {
// Return unmodified block edit
return originalEdit;
}
// Do not add this custom controls if the block type has no align support
if( ! blockAlignSupport ) {
// Return unmodified block edit
return originalEdit;
}
// Get the current ToolbarDropdownMenu icon, depending on the selected align
let currentIcon = currentAlign ? currentAlign : 'none';
currentIcon = blockAlignIcon( currentIcon );
/*
* Define a function to set the "align" attribute, after selecting a specific block alignment
*/
function onChangeAlignment( newAlignment ) {
let iconName = newAlignment;
if( newAlignment === 'none' ) {
// Because we don't want a "alignnone" classname in our block
newAlignment = false;
}
// Change the block align attribute
props.setAttributes( {
align: newAlignment === undefined ? 'none' : newAlignment,
} );
// Change the current ToolbarDropdownMenu icon if the block align has been changed
const alignToolbarButton = document.querySelector('[aria-label="Align"]');
if( alignToolbarButton ) {
let iconPath = blockAlignIcon( iconName );
iconPath = iconPath.props.children.props.d;
alignToolbarButton.innerHTML = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="' + iconPath + '"/></svg>';
}
}
/*
* List all possible block alignments
*/
const alignControls = {
none: __('None', 'textdomain'),
full: __('Full width', 'textdomain'),
wide: __('Wide width', 'textdomain'),
narrow: __('Narrow width', 'textdomain'),
left: __('Align left', 'textdomain'),
center: __('Align center', 'textdomain'),
right: __('Align right', 'textdomain'),
}
/*
* Build the toolbar block alignment controls depening on the align support of the block type
*/
const allowedAlignControls = [];
for( let key in alignControls ) {
if( ! blockAlignSupport.includes( key ) && key !== 'none' ) {
// [None] should be there all the time to reset other selected alignments
// Only add the current align control if it's supported
continue;
}
let controlTitle = alignControls[key];
let newControl = {
title: controlTitle,
icon: blockAlignIcon( key ),
onClick: () => onChangeAlignment( key ),
};
allowedAlignControls.push(newControl);
}
/*
* Re-Build the block toolbar and edit
*/
return el(
Fragment,
{},
el( BlockControls, {
key: 'controls',
group: 'default',
},
el( ToolbarGroup, null,
el( ToolbarDropdownMenu, {
label: 'Align',
icon: currentIcon,
controls: allowedAlignControls,
} ),
),
), el( BlockEdit, props )
);
};
}, 'withInspectorControls' );
wp.hooks.addFilter( 'editor.BlockEdit', 'plugin-name/with-inspector-controls', customBlockAlignmentControls ); |
Would be great if this could be done just by adding some layout settings in theme.json. That would be so helpful! |
I've been looking for something like this since using gutenberg, pretty much all the designs I have to implement have more than wide and full alignement (it's often normal/wide/wider/fullscreen) but a flexible way to achieve this would be great. There's currently two ways of enabling wide and full alignment:
"layout": {
"contentSize": "886px",
"wideSize": "1114px"
},
A more generalized system with add_theme_support('alignments', true) and a configuration in theme.json like this: "layout": {
"default": "700px",
"wide": "880px"
"wider": "1000px"
"even-wider": "1200px"
"full": "100vw"
} or something like this: {
"layout": {
"default": {
"name": "Default",
"size": "700px",
"icon": "<svg></svg>"
},
"wide": {
"name": "Wide",
"size": "800px",
"icon": "<svg></svg>"
},
"wider": {
"name": "Wider",
"size": "1000px",
"icon": "<svg></svg>"
},
"even-wider": {
"name": "Even wider",
"size": "1200px",
"icon": "<svg></svg>"
},
"full": {
"name": "Full",
"size": "100vw",
"icon": "<svg></svg>"
}
}
} @markhowellsmead @talldan @skorasaurus what do you think ? |
I've been waiting for this for five years. It looks as though no-one cares about this. |
Let's disable these for now. Users shouldn't be customizing this and only using theme-defined sizes. The hope is that a solution for additional wide sizes will be available in Core/Gutenberg. See: WordPress/gutenberg#27629
This has been a constant source of friction for us when using Gutenberg, and is something I've mentioned in other threads (and I know many others have as well). I do not understand why max-width options are not handled in As it works now, we are assigning our two most common widths to |
@eric-michel |
@landwire Agreed. I'm not sure how to bring more visibility to this issue given how long it's been waiting in the wings. One workaround that does work is altering the content max-widths via the Layout setting in Group blocks: But this solution is just as cumbersome as using utility classes - maybe moreso. If I want to regularly use a "narrow" alignment of 500px max width, I don't want to have to create a Group block where I manually enter |
Pinging @WordPress/outreach to get some more visibility and feedback on this, please. 🙏 |
Is your feature request related to a problem? Please describe.
Short: We would like to be able to extend
BLOCK_ALIGNMENTS_CONTROLS
at runtime.My apologies in advance if this is already configurable somewhere (or if this is not in the scope of Gutenberg) as I am still getting a handle on the Gutenberg source.
Longer: We currently develop our in house CMS on top of WordPress, and we were looking to extend the default alignment options. From what I can tell we can currently define custom alignment keys in our block registrations (
supports.align
) or filter existing block registrations to add additional alignment keys. While they are technically functional, these alignments do not have icons or titles in the AlignmentToolbar as they are not present in theBLOCK_ALIGNMENTS_CONTROLS
object that is defined in https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/block-alignment-toolbar/index.jsDescribe the solution you'd like
A filter we could hook with a function that would return the extended
BLOCK_ALIGNMENTS_CONTROLS
. This filter would then be invoked by the AlignmentToolbar instead of the referencing theBLOCK_ALIGNMENTS_CONTROLS
object.Describe alternatives you've considered
I think this functionality could also be handled by a registration model with a store, but that seems like a lot of extra work. I'm sure there are other options, but I'm not familiar enough with Gutenberg internals to suggest them.
Alternatively we can certainly solve this with a self-built version of Gutenberg, but we prefer to stay with the version distributed with WordPress releases if possible.
The text was updated successfully, but these errors were encountered: