Components: Improve ToolbarButton#18931
Conversation
| function ToolbarButton( { | ||
| containerClassName, | ||
| icon, | ||
| title, | ||
| shortcut, | ||
| subscript, | ||
| onClick, | ||
| className, | ||
| isActive, | ||
| isDisabled, | ||
| extraProps, | ||
| children, | ||
| ...props |
There was a problem hiding this comment.
Removed most of the props here so we can spread { ...props } directly into Button. This way, ToolbarButton (when used within <Toolbar __experimentalAccessibilityLabel="label">) and Button have identical API.
| <ToolbarButton title="control1" /> | ||
| <ToolbarButton title="control2" /> | ||
| <ToolbarButton label="control1" /> | ||
| <ToolbarButton label="control2" /> |
There was a problem hiding this comment.
When used within <Toolbar __experimentalAccessibilityLabel>, ToolbarButton passes all the props down to Button so they have the same API.
gziolo
left a comment
There was a problem hiding this comment.
I still need to do some testing with Storybook, but it is definitely looking very good. I like where it's all heading making it so much simpler to build toolbar elements.
ToolbarItem gives a lot of flexibility and should cover the majority of edge cases. We still should revisit the collapsed groups and offer some easier way to code the dropdown menu there. It's big enough to tackle it separately though after we refactor all the existing toolbars. Once it's done, it should be easier to come up with a good API.
| icon={ props.icon } | ||
| label={ props.title } | ||
| shortcut={ props.shortcut } | ||
| data-subscript={ props.subscript } |
There was a problem hiding this comment.
I will investigate in a follow-up whether we can get rid of subscript as I think we no longer use it in code and it probably was never meant to exist as public API.
There was a problem hiding this comment.
I kept it there so as to avoid breaking anything, but it's not being used in the new implementation (using ToolbarItem) anyway.
| <ToolbarButtonContainer className={ containerClassName }> | ||
| <Button | ||
| icon={ props.icon } | ||
| label={ props.title } |
There was a problem hiding this comment.
Does it mean that title should be deprecated in favor of label?
There was a problem hiding this comment.
I'd say that these props should be deprecated:
title(in favor oflabel)isActive(in favor ofisPressed)isDisabled(in favor ofdisabled)
Still not sure what to do with isDisabled though.
This PR only changes the behavior of ToolbarButton when it's used inside <Toolbar __experimentalAccessibilityLabel>, so if we decide to deprecate those props, I guess it should be in another PR.
There was a problem hiding this comment.
I like the idea, let's go this way in the follow-up PRs.
| } | ||
| } } | ||
| className={ classnames( 'components-toolbar__control', className ) } | ||
| isPressed={ props.isActive } |
There was a problem hiding this comment.
A similar question, should we align API and deprecated isActive in favor of isPressed?
There was a problem hiding this comment.
That's the current API. This PR only changes ToolbarButton when used within <Toolbar __experimentalAccessibilityLabel>.
There was a problem hiding this comment.
Right, we will need to align it at some point with the Button component as discussed.
| } } | ||
| className={ classnames( 'components-toolbar__control', className ) } | ||
| isPressed={ props.isActive } | ||
| disabled={ props.isDisabled } |
There was a problem hiding this comment.
I think this was discussed in other PRs, we should make a final call on whether we use isDisabled in all places instead of disabled to potentially break the direct association with the HTML attribute.
/cc @youknowriad @aduth
There was a problem hiding this comment.
I think it makes sense to adopt isDisabled. Specially if #19337 is merged as it'll not be the same as the HTML disabled prop.
| <ToolbarButton icon="editor-paragraph" title="Paragraph" /> | ||
| <ToolbarButton icon="editor-paragraph" label="Paragraph" /> | ||
| </ToolbarGroup> | ||
| <ToolbarGroup> |
There was a problem hiding this comment.
There are some cases in Gutenberg where we're using DropdownMenu directly instead <ToolbarGroup isCollapsed>. For example:
I'm not sure how easy is it to refactor those edge cases to use <ToolbarGroup isCollapsed>, so I just wanted to make sure ToolbarItem can be used.
There was a problem hiding this comment.
Cool, it all makes sense. I think I mentioned it already, I just wanted to ensure you are aware of the current state of the art :)
gziolo
left a comment
There was a problem hiding this comment.
It tests well. I guess, we can plan to merge it soon.
gziolo
left a comment
There was a problem hiding this comment.
We discussed the current state of this PR and future steps. Let's iterate quickly with smaller steps ![]()
|
Thanks for all the work here! |


Description
This PR is part of #18619. Please, refer to the issue for more context.
I confess that coming up with a good API here is really challenging, considering all the use cases in Gutenberg. So I'd really appreciate any feedback on that. The main use cases I identified and am trying to address with this PR are:
ToolbarButtonButtonsupports icons since Merge the Button and IconButton into a single component #19193.ToolbarButtonpasses all the props down toButton, so it also supports it.ToolbarItem(generic headless component for any other kind of toolbar item)Eventually, if this is common enough, we can create something like
ToolbarDropdownMenuto abstract the usage above. But for this first iteration I thought thatButtonandIconButtonwould be enough. The dropdown use case can also use<ToolbarGroup isCollapsed>, but some usages in Gutenberg (and in third party blocks, I suppose), can't be easily converted intoToolbarGroupdue to styling conflicts.There are other complicated cases like
BlockSwitcher, which usesDropdowndirectly with custom configuration.ToolbarItemcould be used for that as well.All the new features have been added as
__experimental.How has this been tested?
Check Storybook
Screenshots
Types of changes
New feature
Checklist: