-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
ToolsPanel: Try splitting out ToolsPanelDropdownMenu #44284
Conversation
Size Change: +55 B (0%) Total Size: 1.26 MB
ℹ️ View Unchanged
|
@ciampo: Here's a rough attempt at implementing what was discussed in #44180. What do you think? I tried to go further and split out the I'm not 100% sure about the direction. It works and is composition-ey, but, idk... does it make Would a simple prop be better? <ToolsPanel
heading={ <>
<Button icon={ arrowLeft } label="Back" isSmall />
<Heading level={ 2 }>Typography</Heading>
</> }
resetAll={ resetAll }
>
<ToolsPanelItem>...</ToolsPanelItem>
<ToolsPanelItem>...</ToolsPanelItem>
</ToolsPanel> Or, maybe I could use absolute positioning to fake the effect that I'm after in #44180? 😅 |
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.
Thank you for trying this out! Code changes are nice and clean, and easy to follow thanks to the detailed PR description
I tried to go further and split out the
Grid
fromToolsPanel
so that we have bothToolsPanel
(provides a grid) andToolsPanelProvider
(no grid) but had difficulty separating some of theclassName
logic thatToolsPanel
has.I'm not 100% sure about the direction. It works and is composition-ey, but, idk... does it make
ToolsPanel
too unopinionated? AToolsPanel
should providePanel
bits, no?
I'm not fully convinced either. Let's keep the Grid
wrapper as part of ToolsPanel
for now, we can always come back to this at a later point.
Would a simple prop be better?
It's definitely a possibility, although I'd personally prefer using children
instead of render props, as it feels cleaner to me.
Seeing the route that we're taking here, I think that we should just stop using ToolsPanelHeader
internally, and always expect consumers of ToolsPanel
to define their own label explicitly (this would also mean removing the label
prop from ToolsPanel
).
In order to avoid too much disruption during the "transition", we could:
- on this PR:
- keep the newly created
ToolsPanelDropdownMenu
as-is on this PR - refactor
ToolsPanelHeader
to behave like currently ontrunk
, but refactoring it to useToolsPanelDropdownMenu
internally - refactor most Storybook examples and tests to avoid using the
label
prop - this way, current usages of
ToolsPanel
would keep working as expected
- keep the newly created
- Refactor usages of
ToolsPanel
across the codebase to stop using thelabel
prop, and define their own header as part ofchildren
instead (including usingToolsPanelDropdownMenu
) - Formally deprecate the
label
prop (outputting a console warning) and scheduling the prop for deletion in 2 WordPress versions time. - When removing the
label
prop, we'll be also able to remove theToolsPanelHeader
component altogether.
What do you think? Tagging @aaronrobertshaw and @mirka for thoughts too.
export function useToolsPanelDropdownMenu( | ||
props: WordPressComponentProps< ToolsPanelDropdownMenuProps, 'div', false > | ||
) { | ||
const { ...otherProps } = useContextSystem( |
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.
Nit: we don't need the rest operator here
}; | ||
|
||
export type ToolsPanelHeaderProps = ToolsPanelDropdownMenuProps; |
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.
Nit: we'd probably need to duplicate the type here, since we'd want the description for the label
prop to be different for the two components
Thanks for your thoughts! API design feels more like art than science so extra opinions are really helpful.
👍 sounds like a plan.
My worry with this is that we're making In other words this: <ToolsPanel resetAll={ resetAll }>
<HStack style={{ gridColumn: 'span 2' }}>
<Heading level={ 2 } style={{ fontSize: 'inherit', fontWeight: 500, lineHeight: 'normal' }}>
Typography
</Heading>
<ToolsPanelDropdownMenu label="Typography settings" />
</HStack>
<ToolsPanelItem>...</ToolsPanelItem>
<ToolsPanelItem>...</ToolsPanelItem>
</ToolsPanel> Becomes this: <ToolsPanel resetAll={ resetAll }>
<ToolsPanelRow>
<HStack>
<ToolsPanelHeading>Typography</ToolsPanelHeading>
<ToolsPanelDropdownMenu label="Typography settings" />
</HStack>
</ToolsPanelRow>
<ToolsPanelItem>...</ToolsPanelItem>
<ToolsPanelItem>...</ToolsPanelItem>
</ToolsPanel> |
After some more exploration I realised this won't work for #44180 because what I actually want is for the header to appear completely outside of the <HStack>
<NavigatorBackButton />
<Heading />
<ToolsPanelDropdownMenu />
</HStack>
<ToolsPanel>
<ToolsPanelItem />
<ToolsPanelItem />
</ToolsPanel> I think the only solution to combining the headers in #44180 is to have it so that a consumer can use the To be honest though this is becoming more work than I think it's worth so I'll put this on ice and explore some other options first 🙂 |
Yes, that would be a good idea. Basically,
Yeah, the only way there would be to completely destructure
Sure — feel free to ping again if/when you resume work on this, always happy to help |
No such thing as a failed experiment 😀 thanks for the thoughts @ciampo |
Nonetheless a very interesting API thinking exercise, it may be useful in the future — who knows! Thank you 🙏 |
What?
Splits
ToolsPanelDropdownMenu
out fromToolsPanel
.Why?
So that consumers can implement their own header design while using ToolsPanel. See #44180 for one such example of when we want to do this.
How?
ToolsPanelHeader
is split up intoToolsPanelHeader
andToolsPanelDropdownMenu
.resetAll
andtoggleItem
props are removed fromToolsPanelHeader
. These are now accessed viaToolsPanelContext
.label
prop onToolsPanel
as optional.Grid
fromToolsPanel
.ToolsPanel
wouldn't even really be a panel anymore?ToolsPanel
. In particular it usesmenuItems
in order to calculate theclassName
.Testing Instructions
Screenshots or screencast