[components] Add panel toggle icon overrides#40711
Conversation
|
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @danieliser! In case you missed it, we'd love to have you join us in our Slack community, where we hold regularly weekly meetings open to anyone to coordinate with each other. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
amustaque97
left a comment
There was a problem hiding this comment.
Thank you for working on this. I tested it locally and it is working fine. 👍🏻
|
@amustaque97 - Not a problem. Scratched an itch. Looking forward to doing so more often 💯 |
|
I didn't add changelog note, wasn't sure if that was something I do as part of the PR or done when it was merged. Happy to add one now if I should have done so. |
Yeah, feel free to add changelog now. 🙂 |
There was a problem hiding this comment.
Hey @danieliser , thank you for working on this!
I left a few inline comments.
As @amustaque97 said, please do add an entry to the CHANGELOG in this PR
It would be also great if these component's stories were converted from using knobs to using controls — although this could be totally done in a follow-up PR . Would you be up for that?
| An icon to be shown as the toggle button within the `PanelBody` title when open. | ||
|
|
||
| - Type: `String` | ||
| - Required: No |
There was a problem hiding this comment.
These props are not Strings — let's update the description as follow:
| An icon to be shown as the toggle button within the `PanelBody` title when open. | |
| - Type: `String` | |
| - Required: No | |
| An icon to be shown as the toggle button within the `PanelBody` title, in its expanded state. See [the `@wordpress/icons` package](https://github.com/WordPress/gutenberg/blob/trunk/packages/icons/README.md) for a list of available icons. | |
| - Type: `React.ReactNode` | |
| - Required: No | |
| - Default: `chevronUp` icon from `@wordpress/icons` |
There was a problem hiding this comment.
@ciampo - Sorry, wasn't sure what type they should be, I copied from the lines above documenting the existing icon prop which also said string.
Should I update the original icon prop documentation to match?
There was a problem hiding this comment.
Should I update the original icon prop documentation to match?
Yes please. I believe the icon prop being a String is a leftover from earlier times when dashicons were the main way to provide icons.
| const iconOpen = boolean( 'Open Icon', true ) ? closeSmall : undefined; | ||
| const iconClosed = boolean( 'Closed Icon', true ) ? plus : undefined; |
There was a problem hiding this comment.
We should either:
- use a
selectcontrol to give users a few icons to choose from - use
booleancontrols, but call themcustomIconExpandedandcustomIconCollapsed
mirka
left a comment
There was a problem hiding this comment.
Thank you for another great contribution!
As for the naming and API:
-
I feel strongly that we should use the word "disclosure" in the prop name (e.g.
disclosureIcon). An unqualifiediconis a little too vague here since we already have aniconprop, and the term "disclosure" is in line with web standards. -
What do we think about just adding one prop (e.g.
disclosureIcon), and have the consumer switch their own icon states viaonToggle?// Not sure if this works, just writing off the top of my head const [ isOpen, setIsOpen ] = useState(); return <PanelBody onToggle={ setIsOpen } disclosureIcon= { isOpen ? Foo : Bar } />
I don't feel super strongly about this point, but I wanted to suggest it because this particular customization falls outside of established Gutenberg design patterns, so I'm hesitant to add two extra props just for this relatively niche use case.
|
@mirka I'm open to consensus, but don't have an experienced enough opinion within this project to weigh in. Will see what others say. My only 2 cents would be that I would personally have no clue as a developer using this component what |
Given that @danieliser is proposing to add two props, at the moment named
How would this approach work when the component is uncontrolled? Apart from that, for the newly added prop(s), should their name start or end with |
Fair point! That is something that we can mitigate via docs (readme and Storybook) though. In general we'll want to keep our terminology in line with the underlying web standards (e.g. ARIA disclosure widget,
Yeah that was unclear, sorry. Unqualified in the sense that expanded/collapsed are states of
From my skimming of the code, this component only works uncontrolled. Hence the need to hook into
My rule of thumb for naming things like this is "Can it be mistaken for a boolean?". So my vote goes to "ends with |
|
I'll also note that, if we were to design this component API from scratch today, I think we should be using the |
|
I think that @mirka 's points here are definitely relevant — I'm in favour of applying her suggestion and, therefore, switch to one prop called We will need to update docs, Storybook and CHANGELOG accordingly.
From a quick look, I thought |
Ah you're right, TIL |
|
I had considered handling it in a more programattic and single interface way where you could pass an icon, string or callback and the callback would get isExpanded as an argument. In that way you could theoretically also forward current toggle state to the icon prop callback function. Something like And for rendering something along the lines of One thing of note, we changed icon labeling from open/closed, to expanded/collapsed, but all the internal logic is labeled open/closed. Just something to consider. |
|
My preference would be to follow @mirka 's suggestion, and have I wouldn't add a callback, simply because the consumer of
There seems to be a lack of coherence in the way the docs and the code have been written: in some cases, it refer to the terms "expand" and "collapse" (example), but in others, it refers to "opened" and "closed" (like for the Anyway, if we introduce just a new |
|
May I ask for more examples of how this would be customized and for what reasons? Expandable panels have some assumed mechanics and the design might fluctuate assuming arrows (for example, relocating them on the left for ToolsPanels). |
|
@mtias - I can, though mine goes a little beyond what is proposed here. Our version has a dropdown in the header when open, but the idea was similar and had this component supported what I was trying to do before I wrote a custom version I'd have gone a different route. In our case showing a panel also enables features on the block immediately, it the panel being open is a setting in itself toggling on more advanced stuff. |


What?
This adds support for customizing the PanelBody toggle icons beyond just
chevronUp&chevronDown.Why?
This allows replacing the up & down icons with something else for better context.
Without this a developer is required to duplicate 4+ files to remake the needed components. This is primarily due to usage of internal functions that are not exposed
import { useControlledState, useUpdateEffect } from '../utils';How?
iconOpen&iconClosedprops with defaults set to currentchevron*icons. I had considerediconUp&iconDownbut decided these were more explicit. They could be even more specific by changing them totoggleIconUpor similar. Open to suggestion.Testing Instructions
Panel&PanelBody.iconOpenand/oriconClosedprops toPanelBody.Screenshots or screencast