Skip to content

Commit 36f91c4

Browse files
committed
Add ellipsis menu to Summary panel
- Makes the Summary panel non-collapsible. - Adds an ellipsis toolbar button that opens a menu. - Moves 'Stick to the top', 'Mark as pending', 'Revision history' and 'Trash post' buttons into the ellipsis menu.
1 parent db626c5 commit 36f91c4

File tree

25 files changed

+456
-252
lines changed

25 files changed

+456
-252
lines changed

packages/block-editor/src/components/inspector-popover-header/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,14 @@ export default function InspectorPopoverHeader( {
4141
{ title }
4242
</Heading>
4343
<Spacer />
44-
{ actions.map( ( { label, icon, onClick } ) => (
44+
{ actions.map( ( { label, icon, isPressed, onClick } ) => (
4545
<Button
4646
key={ label }
4747
className="block-editor-inspector-popover-header__action"
4848
label={ label }
4949
icon={ icon }
5050
variant={ ! icon && 'tertiary' }
51+
isPressed={ isPressed }
5152
onClick={ onClick }
5253
>
5354
{ ! icon && label }

packages/e2e-tests/specs/editor/various/change-detection.test.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,12 @@ describe( 'Change detection', () => {
9999
// Toggle post as needing review (not persisted for autosave).
100100
await ensureSidebarOpened();
101101

102-
const postPendingReviewButton = (
103-
await page.$x( "//label[contains(text(), 'Pending review')]" )
104-
)[ 0 ];
105-
await postPendingReviewButton.click( 'button' );
102+
await page.click( '*[aria-label="Post options"]' );
103+
await page.waitForXPath( "//*[text()='Mark as pending']" );
104+
const [ postMarkAsPendingButton ] = await page.$x(
105+
"//*[text()='Mark as pending']"
106+
);
107+
await postMarkAsPendingButton.click();
106108

107109
// Force autosave to occur immediately.
108110
await Promise.all( [
@@ -347,7 +349,12 @@ describe( 'Change detection', () => {
347349

348350
// Trash post.
349351
await openDocumentSettingsSidebar();
350-
await page.click( '.editor-post-trash.components-button' );
352+
await page.click( '*[aria-label="Post options"]' );
353+
await page.waitForXPath( "//*[text()='Move to trash']" );
354+
const [ postMoveToTrashButton ] = await page.$x(
355+
"//*[text()='Move to trash']"
356+
);
357+
await postMoveToTrashButton.click();
351358

352359
await Promise.all( [
353360
// Wait for "Saved" to confirm save complete.

packages/e2e-tests/specs/editor/various/sidebar.test.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ describe( 'Sidebar', () => {
127127
expect( await findSidebarPanelWithTitle( 'Categories' ) ).toBeDefined();
128128
expect( await findSidebarPanelWithTitle( 'Tags' ) ).toBeDefined();
129129
expect( await findSidebarPanelWithTitle( 'Discussion' ) ).toBeDefined();
130-
expect( await findSidebarPanelWithTitle( 'Summary' ) ).toBeDefined();
130+
expect(
131+
await page.$x(
132+
"//*[contains(@class, 'edit-post-sidebar')]//h2[text()='Summary']"
133+
)
134+
).toHaveLength( 1 );
131135

132136
await page.evaluate( () => {
133137
const { removeEditorPanel } = wp.data.dispatch( 'core/edit-post' );
@@ -151,8 +155,10 @@ describe( 'Sidebar', () => {
151155
expect(
152156
await page.$x( getPanelToggleSelector( 'Discussion' ) )
153157
).toEqual( [] );
154-
expect( await page.$x( getPanelToggleSelector( 'Summary' ) ) ).toEqual(
155-
[]
156-
);
158+
expect(
159+
await page.$x(
160+
"//*[contains(@class, 'edit-post-sidebar')]//h2[text()='Summary']"
161+
)
162+
).toHaveLength( 0 );
157163
} );
158164
} );

packages/edit-post/src/components/sidebar/last-revision/index.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

packages/edit-post/src/components/sidebar/last-revision/style.scss

Lines changed: 0 additions & 9 deletions
This file was deleted.

packages/edit-post/src/components/sidebar/post-pending-status/index.js

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import {
5+
__experimentalHStack as HStack,
6+
__experimentalHeading as Heading,
7+
DropdownMenu,
8+
MenuGroup,
9+
} from '@wordpress/components';
10+
import { __, sprintf } from '@wordpress/i18n';
11+
import { moreVertical } from '@wordpress/icons';
12+
import {
13+
store as editorStore,
14+
usePostPendingStatusCheck,
15+
usePostLastRevisionCheck,
16+
usePostTrashCheck,
17+
} from '@wordpress/editor';
18+
import { useSelect } from '@wordpress/data';
19+
import { store as coreStore } from '@wordpress/core-data';
20+
21+
/**
22+
* Internal dependencies
23+
*/
24+
import PostPendingStatus from './post-pending-status';
25+
import PostLastRevision from './post-last-revision';
26+
import PostTrash from './post-trash';
27+
28+
export default function PostStatusHeader() {
29+
const hasPostPendingStatus = usePostPendingStatusCheck();
30+
const hasPostLastRevision = usePostLastRevisionCheck();
31+
const hasPostTrash = usePostTrashCheck();
32+
33+
const postTypeName = useSelect( ( select ) => {
34+
const postTypeSlug = select( editorStore ).getCurrentPostType();
35+
const postType = select( coreStore ).getPostType( postTypeSlug );
36+
return postType?.labels?.singular_name;
37+
}, [] );
38+
39+
return (
40+
<HStack className="edit-post-post-status__header">
41+
<Heading className="edit-post-post-status__heading" level={ 2 }>
42+
{ __( 'Summary' ) }
43+
</Heading>
44+
{ ( hasPostPendingStatus ||
45+
hasPostLastRevision ||
46+
hasPostTrash ) && (
47+
<DropdownMenu
48+
icon={ moreVertical }
49+
label={
50+
postTypeName
51+
? // translators: %s: Post type, e.g. "Post" or "Page".
52+
sprintf( __( '%s options' ), postTypeName )
53+
: __( 'Post options' )
54+
}
55+
toggleProps={ { isSmall: true } }
56+
>
57+
{ () => (
58+
<>
59+
{ ( hasPostPendingStatus ||
60+
hasPostLastRevision ) && (
61+
<MenuGroup>
62+
{ hasPostPendingStatus && (
63+
<PostPendingStatus />
64+
) }
65+
{ hasPostLastRevision && (
66+
<PostLastRevision />
67+
) }
68+
</MenuGroup>
69+
) }
70+
{ hasPostTrash && (
71+
<MenuGroup>
72+
<PostTrash />
73+
</MenuGroup>
74+
) }
75+
</>
76+
) }
77+
</DropdownMenu>
78+
) }
79+
</HStack>
80+
);
81+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import classnames from 'classnames';
5+
6+
/**
7+
* WordPress dependencies
8+
*/
9+
import { useSelect } from '@wordpress/data';
10+
import { store as editorStore } from '@wordpress/editor';
11+
import { MenuItem } from '@wordpress/components';
12+
import { addQueryArgs } from '@wordpress/url';
13+
import { __ } from '@wordpress/i18n';
14+
15+
export default function PostLastRevision() {
16+
const { revisionsCount, lastRevisionId } = useSelect(
17+
( select ) => ( {
18+
revisionsCount:
19+
select( editorStore ).getCurrentPostRevisionsCount(),
20+
lastRevisionId:
21+
select( editorStore ).getCurrentPostLastRevisionId(),
22+
} ),
23+
[]
24+
);
25+
26+
return (
27+
<MenuItem
28+
icon={
29+
<RevisionsCountBadge>{ revisionsCount }</RevisionsCountBadge>
30+
}
31+
href={ addQueryArgs( 'revision.php', {
32+
revision: lastRevisionId,
33+
gutenberg: true,
34+
} ) }
35+
>
36+
{ __( 'Revision history' ) }
37+
</MenuItem>
38+
);
39+
}
40+
41+
function RevisionsCountBadge( { className, children } ) {
42+
return (
43+
<span
44+
className={ classnames(
45+
className,
46+
'edit-post-post-status__revisions-count-badge'
47+
) }
48+
>
49+
{ children }
50+
</span>
51+
);
52+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { useSelect, useDispatch } from '@wordpress/data';
5+
import { store as editorStore } from '@wordpress/editor';
6+
import { MenuItem } from '@wordpress/components';
7+
import { check } from '@wordpress/icons';
8+
import { __ } from '@wordpress/i18n';
9+
10+
export default function PostPendingStatus() {
11+
const status = useSelect(
12+
( select ) => select( editorStore ).getEditedPostAttribute( 'status' ),
13+
[]
14+
);
15+
16+
const { editPost } = useDispatch( editorStore );
17+
18+
return (
19+
<MenuItem
20+
icon={ status === 'pending' ? check : null }
21+
isSelected={ status === 'pending' }
22+
role="menuitemcheckbox"
23+
onClick={ () => {
24+
editPost( {
25+
status: status === 'pending' ? 'draft' : 'pending',
26+
} );
27+
} }
28+
>
29+
{ __( 'Mark as pending' ) }
30+
</MenuItem>
31+
);
32+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { useDispatch } from '@wordpress/data';
5+
import { store as editorStore } from '@wordpress/editor';
6+
import { MenuItem } from '@wordpress/components';
7+
import { trash } from '@wordpress/icons';
8+
import { __ } from '@wordpress/i18n';
9+
10+
export default function PostTrash() {
11+
const { trashPost } = useDispatch( editorStore );
12+
return (
13+
<MenuItem
14+
className="edit-post-post-status__post-trash"
15+
icon={ trash }
16+
isDestructive
17+
onClick={ () => trashPost() }
18+
>
19+
{ __( 'Move to trash' ) }
20+
</MenuItem>
21+
);
22+
}

0 commit comments

Comments
 (0)