-
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
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When used within <Toolbar __experimentalAccessibilityLabel>
, ToolbarButton
passes all the props down to Button
so they have the same API.
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.
Nice 👍
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it mean that title
should be deprecated in favor of label
?
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A similar question, should we align API and deprecated isActive
in favor of isPressed
?
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.
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 the current API. This PR only changes ToolbarButton
when used within <Toolbar __experimentalAccessibilityLabel>
.
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There are some cases in Gutenberg where we're using DropdownMenu
directly instead <ToolbarGroup isCollapsed>
. For example:
gutenberg/packages/block-editor/src/components/block-settings-menu/index.js
Lines 59 to 66 in 2c1e3be
<Toolbar> | |
<DropdownMenu | |
icon="ellipsis" | |
label={ __( 'More options' ) } | |
className="block-editor-block-settings-menu" | |
popoverProps={ POPOVER_PROPS } | |
> | |
{ ( { onClose } ) => ( |
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 :)
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 tests well. I guess, we can plan to merge it soon.
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.
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:
ToolbarButton
Button
supports icons since Merge the Button and IconButton into a single component #19193.ToolbarButton
passes 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
ToolbarDropdownMenu
to abstract the usage above. But for this first iteration I thought thatButton
andIconButton
would 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 intoToolbarGroup
due to styling conflicts.There are other complicated cases like
BlockSwitcher
, which usesDropdown
directly with custom configuration.ToolbarItem
could 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: