Edit Post: Refactor More (Ellipsis) Menu#5161
Conversation
There was a problem hiding this comment.
Maybe we should perform this call only when clicking on the button. Serializing blocks can harm performance.
There was a problem hiding this comment.
Would you like to call it directly using wp.data.select or expose it as a function here?
@mcsf what's your take on this?
There was a problem hiding this comment.
On a second thought, maybe it's not that severe because it's only shown when you open the dropdown menu, it's probably run only once because you don't edit content when this menu is open.
There was a problem hiding this comment.
Right, it doesn't render when you edit your post. It only renders once when you open the dropdown.
There was a problem hiding this comment.
Actually, ClipboardButton is flexible and accepts a function for text, so the following works:
diff --git a/edit-post/components/header/copy-content-menu-item/index.js b/edit-post/components/header/copy-content-menu-item/index.js
index 88561ae1..a55688ad 100644
--- a/edit-post/components/header/copy-content-menu-item/index.js
+++ b/edit-post/components/header/copy-content-menu-item/index.js
@@ -2,11 +2,13 @@
* WordPress dependencies
*/
import { ClipboardButton, withState } from '@wordpress/components';
-import { compose } from '@wordpress/element';
-import { query } from '@wordpress/data';
+import { select } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
-function CopyContentMenuItem( { editedPostContent, hasCopied, setState } ) {
+const editedPostContent = () =>
+ select( 'core/editor' ).getEditedPostAttribute( 'content' );
+
+function CopyContentMenuItem( { hasCopied, setState } ) {
return (
<ClipboardButton
text={ editedPostContent }
@@ -21,9 +23,6 @@ function CopyContentMenuItem( { editedPostContent, hasCopied, setState } ) {
);
}
-export default compose(
- query( ( select ) => ( {
- editedPostContent: select( 'core/editor' ).getEditedPostAttribute( 'content' ),
- } ) ),
- withState( { hasCopied: false } )
+export default withState(
+ { hasCopied: false }
)( CopyContentMenuItem );
There was a problem hiding this comment.
Not sure which is better. Probably can stay as it is.
e16d4e0 to
4a5fb14
Compare
|
Nice, this seems to work great! 👍 👍 |
There was a problem hiding this comment.
Actually, ClipboardButton is flexible and accepts a function for text, so the following works:
diff --git a/edit-post/components/header/copy-content-menu-item/index.js b/edit-post/components/header/copy-content-menu-item/index.js
index 88561ae1..a55688ad 100644
--- a/edit-post/components/header/copy-content-menu-item/index.js
+++ b/edit-post/components/header/copy-content-menu-item/index.js
@@ -2,11 +2,13 @@
* WordPress dependencies
*/
import { ClipboardButton, withState } from '@wordpress/components';
-import { compose } from '@wordpress/element';
-import { query } from '@wordpress/data';
+import { select } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
-function CopyContentMenuItem( { editedPostContent, hasCopied, setState } ) {
+const editedPostContent = () =>
+ select( 'core/editor' ).getEditedPostAttribute( 'content' );
+
+function CopyContentMenuItem( { hasCopied, setState } ) {
return (
<ClipboardButton
text={ editedPostContent }
@@ -21,9 +23,6 @@ function CopyContentMenuItem( { editedPostContent, hasCopied, setState } ) {
);
}
-export default compose(
- query( ( select ) => ( {
- editedPostContent: select( 'core/editor' ).getEditedPostAttribute( 'content' ),
- } ) ),
- withState( { hasCopied: false } )
+export default withState(
+ { hasCopied: false }
)( CopyContentMenuItem );
edit-post/hooks/more-menu/index.js
Outdated
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import CopyContentMenuItem from '../../components/header/copy-content-menu-item'; |
There was a problem hiding this comment.
You're hooking CopyContentMenuItem into Gutenberg but keeping its definition outside edit-post/hooks. That's interesting; could you explain why?
There was a problem hiding this comment.
I wasn't sure where to put it. I guess you are right that it should stay as a subfolder inside edit-post/hooks/ :)
5748678 to
28e3031
Compare
| @@ -1,9 +1,9 @@ | |||
| .components-choice-menu { | |||
| .components-menu-items-group { | |||
There was a problem hiding this comment.
This should be .components-menu-items__group
https://github.com/WordPress/gutenberg/blob/master/docs/coding-guidelines.md#css
| import EditorActions from '../editor-actions'; | ||
|
|
||
| const element = ( | ||
| const MoreMenu = () => ( |
There was a problem hiding this comment.
Did this need to be changed to a function?
See also an explanation of this type of optimization: https://babeljs.io/docs/plugins/transform-react-constant-elements/
There was a problem hiding this comment.
That's interesting. I haven't seen it before in the React docs.
This transform should be enabled only in production (e.g., just before minifying your code) because although it improves runtime performance, it makes warning messages more cryptic.
Can we enable the transform instead and leave all the low-level optimizations to Babel?
| <EditorActions /> | ||
| <MenuItemsGroup | ||
| label={ __( 'Tools' ) } | ||
| filterName="editPost.MoreMenu.tools" |
There was a problem hiding this comment.
Conceptually-speaking, why do we need two things - plugin slots and filterable menus - to express the same idea of "add to this menu" ? As of current master, we have both in this menu, and it's not clear why I would use one or the other, or why one can't be satisfied by the other.
There was a problem hiding this comment.
gutenberg/edit-post/components/header/more-menu/index.js
Lines 36 to 40 in f175813
There was a problem hiding this comment.
My guess is filterable menus were some of the earlier experiments, partly motivated by the emergence of @wordpress/hooks. They also felt cheaper (perhaps deceptively simple?). I'd say by now slots have established themselves as the standard extension method, though.
There was a problem hiding this comment.
cc @gziolo I think he was talking about removing those at some point?
There was a problem hiding this comment.
Yes, we should remove those filters and replace the only occurrence of hook based extension with slot and fill. As @mcsf already pointed out, this was an early exploration which turned out to be suboptimal from developer’s standpoint.
I had it planned to refactor on my todos list but it was never a priority. I will take care of it this week to avoid confusion.
Description
This PR adds a couple of refactorings to make More Menu extensible:
EllipsisMenutoMoreMenuto align with what was discussed on Slack some time ago.CopyContentButtonand hooks fromeditorfolder toeditPostfolder.editPost.MoreMenu.${ groupName ).MenuItemsChoicecomponent to be able to pass it down to the menu group.How to test?
Make sure all existing menu items display and work as before.
You can dynamically add new menu items by executing the following code:
You might need to reopen More Menu to see the changes applied. We can fix that in the follow-up PR if we decide to have it dynamically re-render when new filters gets added or removed. It can be achieved by extracting most of the logic or even updating
withFiltersHOC: https://github.com/WordPress/gutenberg/blob/master/components/higher-order/with-filters/index.js#L26.Screenshots (jpeg or gifs if applicable):
More Menu with filters applied:
In the screenshot I added plain text, that’s why it doesn’t look perfect. We would rather expose a few components to consume there to make sure it looks properly.
Checklist: