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

Components: Improve ToolbarButton #18931

Merged
merged 12 commits into from
Jan 7, 2020

Conversation

diegohaz
Copy link
Member

@diegohaz diegohaz commented Dec 5, 2019

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

    import { Toolbar, ToolbarButton } from "@wordpress/components";
    
    <Toolbar __experimentalAccessibilityLabel="label">
      <ToolbarButton>Button 1</ToolbarButton>
      <ToolbarButton icon="icon">Button 2</ToolbarButton>
    </Toolbar>

    Button supports icons since Merge the Button and IconButton into a single component #19193. ToolbarButton passes all the props down to Button, so it also supports it.

  • ToolbarItem (generic headless component for any other kind of toolbar item)

    import { Toolbar, __experimentalToolbarItem as ToolbarItem } from "@wordpress/components";
    
    <Toolbar __experimentalAccessibilityLabel="label">
      <ToolbarItem>
        {toggleProps => (
          <DropdownMenu
            icon="icon"
            label="label"
            controls={ ... }
            toggleProps={ toggleProps }
          />
        )}
      </ToolbarItem>
    </Toolbar>

Eventually, if this is common enough, we can create something like ToolbarDropdownMenu to abstract the usage above. But for this first iteration I thought that Button and IconButton 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 into ToolbarGroup due to styling conflicts.

There are other complicated cases like BlockSwitcher, which uses Dropdown 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

image

Types of changes

New feature

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR. .

@gziolo gziolo added [Package] Components /packages/components [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Type] Enhancement A suggestion for improvement. labels Dec 5, 2019
@diegohaz diegohaz mentioned this pull request Dec 24, 2019
6 tasks
Comment on lines 19 to +24
function ToolbarButton( {
containerClassName,
icon,
title,
shortcut,
subscript,
onClick,
className,
isActive,
isDisabled,
extraProps,
children,
...props
Copy link
Member Author

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" />
Copy link
Member Author

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.

Copy link
Member

Choose a reason for hiding this comment

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

Nice 👍

Copy link
Member

@gziolo gziolo left a 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 }
Copy link
Member

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.

Copy link
Member Author

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 }
Copy link
Member

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?

Copy link
Member Author

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 of label)
  • isActive (in favor of isPressed)
  • isDisabled (in favor of disabled)

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.

Copy link
Member

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 }
Copy link
Member

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?

Copy link
Member

Choose a reason for hiding this comment

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

In stories, I still can see isActive:
Screen Shot 2020-01-03 at 12 03 10

Copy link
Member Author

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>.

Copy link
Member

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 }
Copy link
Member

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

Copy link
Member Author

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>
Copy link
Member

Choose a reason for hiding this comment

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

Is there any difference between this and:

Screen Shot 2020-01-03 at 12 09 57

It looks like we have the collapsed group case covered :)

Copy link
Member Author

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:

<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.

Copy link
Member

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 :)

Copy link
Member

@gziolo gziolo left a 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.

Copy link
Member

@gziolo gziolo left a 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 :shipit:

@diegohaz diegohaz merged commit b3048b1 into WordPress:master Jan 7, 2020
@diegohaz diegohaz deleted the update/toolbar-button branch January 7, 2020 16:22
@mtias
Copy link
Member

mtias commented Jan 7, 2020

Thanks for all the work here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Package] Components /packages/components [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants