-
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
Replace the renderBlockMenu prop with a Slot #7199
Replace the renderBlockMenu prop with a Slot #7199
Conversation
count === 1 && <SharedBlockSettings key="shared-block" uid={ firstBlockUID } onToggle={ onClose } itemsRole="menuitem" />, | ||
<BlockTransformations key="transformations" uids={ uids } onClick={ onClose } itemsRole="menuitem" />, | ||
] } ) } | ||
<PluginsBlockSettingsMenuSlot fillProps={ { onClose } } /> |
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.
Questions:
- This adds the menu items to the top of the list, should we add another slot after the menu items?
- We don't use any prop (aside onClose) in our current usage, but I guess if we want to expose this to plugins, we'd probably need
uids
?
Thoughts?
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.
This adds the menu items to the top of the list, should we add another slot after the menu items?
I don't know what is the exact use case in here, but I don't feel very good about having two slots only to have a way to pick whether we should prepend or append menu items. I'm wondering if we shouldn't rethink the way all slot operate. There are a few things we can explore. First of all, we could convert all menu items into fills to have better controls over them and:
- Introduce priority prop for fills.
- Add a filter for a slot which would allow reordering or modifications of fills.
...or maybe use a filter instead of Slot/Fill in the first place.
In general, there is an expectation from plugin developers to have a way to remove some of the fills that are rendered. We can provide an API for that, or find a way to guard fills with the check which allows preventing their rendering if the given condition is met.
We don't use any prop (aside
onClose
) in our current usage, but I guess if we want to expose this to plugins, we'd probably needuids
?
count
might make sense, too.
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.
Yes, I agree it's not perfect, Slots are limited to specific positions. A priority/order
support makes sense. That said, I think it's a bigger problem than what this PR is trying to solve and it concerns all the other slots.
Like you said, I think we should move on like this, for now, it's way better than the renderBlockMenu
prop and address the slots flexibility in a dedicated issue/PR.
@@ -86,8 +86,7 @@ export class BlockListBlock extends Component { | |||
} | |||
|
|||
createInnerBlockList( uid ) { | |||
const { renderBlockMenu } = this.props; | |||
return createInnerBlockList( uid, renderBlockMenu ); | |||
return createInnerBlockList( uid ); |
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 didn't want to refactor further here because it's taken care of in #7192
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 didn't want to refactor further here because it's taken care of in #7192
By refactoring, do you include removal of the unused-as-of-these-changes renderBlockMenu
argument of createInnerBlockList
?
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.
In general, I like the flexibility Slot & Fill gives, but there are a few limitations I described in my detailed comment. It helps to remove renderBlockMenu
from the BlockEditContext
which is great. If it works exactly as before, I would proceed. @aduth should have a much better idea if it fits.
@@ -23,6 +23,11 @@ import BlockTransformations from './block-transformations'; | |||
import SharedBlockSettings from './shared-block-settings'; | |||
import UnknownConverter from './unknown-converter'; | |||
|
|||
const { Fill: PluginsBlockSettingsMenu, Slot: PluginsBlockSettingsMenuSlot } = |
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: it should land in its own file.
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.
This is how files with Slot/Fill look like: https://github.com/WordPress/gutenberg/blob/master/edit-post/components/sidebar/plugin-post-publish-panel/index.js.
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 personally don't like the pattern of assigning the .Slot
into the Fill because we don't want to expose the Slots but I'm following the pattern now, we can change that later.
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 is what it is, I followed what was in code before ...
count === 1 && <SharedBlockSettings key="shared-block" uid={ firstBlockUID } onToggle={ onClose } itemsRole="menuitem" />, | ||
<BlockTransformations key="transformations" uids={ uids } onClick={ onClose } itemsRole="menuitem" />, | ||
] } ) } | ||
<PluginsBlockSettingsMenuSlot fillProps={ { onClose } } /> |
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.
This adds the menu items to the top of the list, should we add another slot after the menu items?
I don't know what is the exact use case in here, but I don't feel very good about having two slots only to have a way to pick whether we should prepend or append menu items. I'm wondering if we shouldn't rethink the way all slot operate. There are a few things we can explore. First of all, we could convert all menu items into fills to have better controls over them and:
- Introduce priority prop for fills.
- Add a filter for a slot which would allow reordering or modifications of fills.
...or maybe use a filter instead of Slot/Fill in the first place.
In general, there is an expectation from plugin developers to have a way to remove some of the fills that are rendered. We can provide an API for that, or find a way to guard fills with the check which allows preventing their rendering if the given condition is met.
We don't use any prop (aside
onClose
) in our current usage, but I guess if we want to expose this to plugins, we'd probably needuids
?
count
might make sense, too.
76038ad
to
e0f28fd
Compare
{ count === 1 && <UnknownConverter uid={ firstBlockUID } role="menuitem" /> } | ||
<BlockDuplicateButton uids={ uids } rootUID={ rootUID } role="menuitem" /> | ||
{ count === 1 && <SharedBlockSettings uid={ firstBlockUID } onToggle={ onClose } itemsRole="menuitem" /> } | ||
<BlockTransformations uids={ uids } onClick={ onClose } itemsRole="menuitem" />, |
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.
Found this ,
:D
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.
:)
|
||
const { Fill: PluginBlockSettingsMenu, Slot } = createSlotFill( 'PluginsBlockSettingsMenu' ); | ||
|
||
PluginBlockSettingsMenu.Slot = Slot; |
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 should document it somewhere. In general, we should document all Slot/Fill pairs from editor
. Let's open a follow-up task.
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.
yes, I was not sure if we wanted to document it now or wait until we figure out #7199 (comment)
e0f28fd
to
d9ec524
Compare
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 tested it locally and it works as expected. The comma needs to be removed and it's a very good improvement.
While it's tempting to give developers full control over these items so far as the flexibility it provides, to me it seems like this isn't something a developer should want to be concerned with, and in its impact on opening the potential for inconsistent user experience (or even abuse), not something that has a net benefit for anyone involved. Ultimately, what is a developer trying to do, and in what ways does order matter? For plugin developers, it seems like the mere presence in the list of options should be sufficient (though I'm open to hearing use-cases to the contrary). The complication for us here is that "Show Block Settings" is part of a core (post editor) behavior, and we do agree its sensible to be shown in a specific order (i.e. first in the list). So how do we distinguish between:
Among plugin extensions proper, I personally don't think it's in the interest of anyone to introduce a concept of ordering. A single slot should be sufficient. To the user, its order in the list should be consistent (deterministic), but aside from that, I'd not care what metric is used for ordering. For core behaviors, maybe it should be a separate slot from that of plugins, which prompts other questions:
|
Good thoughts @aduth we're often tricked by the fact developers want to extend everything for better and for worse. And often for worse in terms of UX for the user. What's the way forward here, should we just rename the slot something like |
@youknowriad There's precedent here with core PHP function naming (e.g.
I'd prefer if it was not available at all, though I cannot think of a solution for this currently. Seems reasonable to have as a naming convention for now, and since it's intended to be private, can be open for future backwards-incompatible refactoring. |
But there's still a question: Even for core behaviors, would the expected behavior of the slot be to append or prepend? Do we need to reflect this in the name of the slot? Something like |
I think |
I guess I don't like thinking of these as prepend and append behaviors, but rather within slots, each fill should be agnostic to its ordering. This is a strong "IMO" and is partly influenced by the complications which result by trying to introduce ordering / prioritization (though elsewhere we've relented, e.g. core block registration and transforms). Where the menu is effectively a set of slots / default items:
|
My reasoning is that if we use it twice to another UI button, it won't act as "First Item" |
At that point (and only if it's considered reasonable) we ought to consider whether a formal ordering system should be implemented. |
9e38b71
to
d45ac48
Compare
We could try to implement it by leveraging filters from |
Related #7192
This PR replaces the
renderBlockMenu
Prop with Slot/Fill.Testing instructions