diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 5a070a5bb6e52..b688265625368 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -391,6 +391,14 @@ Opens the global block inserter. Opens the publish panel. +# **openSidebarPanel** + +Opens a sidebar panel with the provided title. + +_Parameters_ + +- _panelTitle_ `string`: The name of sidebar panel. + # **pressKeyTimes** Presses the given keyboard key a number of times in sequence. diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index d1345d0e9163b..fae789fc950cd 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -44,6 +44,7 @@ export { } from './observe-focus-loss'; export { openDocumentSettingsSidebar } from './open-document-settings-sidebar'; export { openPublishPanel } from './open-publish-panel'; +export { openSidebarPanel } from './open-sidebar-panel'; export { trashAllPosts } from './posts'; export { pressKeyTimes } from './press-key-times'; export { pressKeyWithModifier } from './press-key-with-modifier'; diff --git a/packages/e2e-test-utils/src/open-sidebar-panel.js b/packages/e2e-test-utils/src/open-sidebar-panel.js new file mode 100644 index 0000000000000..541b108d504d1 --- /dev/null +++ b/packages/e2e-test-utils/src/open-sidebar-panel.js @@ -0,0 +1,21 @@ +/** + * Internal dependencies + */ +import { findSidebarPanelToggleButtonWithTitle } from './find-sidebar-panel-toggle-button-with-title'; + +/** + * Opens a sidebar panel with the provided title. + * + * @param {string} panelTitle The name of sidebar panel. + */ +export async function openSidebarPanel( panelTitle ) { + const panelToggle = await findSidebarPanelToggleButtonWithTitle( + panelTitle + ); + const panelIsCollapsed = await panelToggle.evaluate( + ( node ) => node.getAttribute( 'aria-expanded' ) === 'false' + ); + if ( panelIsCollapsed ) { + await panelToggle.click(); + } +} diff --git a/packages/e2e-tests/specs/editor/various/datepicker.test.js b/packages/e2e-tests/specs/editor/various/datepicker.test.js index 6118f05368ae7..129eeb9891274 100644 --- a/packages/e2e-tests/specs/editor/various/datepicker.test.js +++ b/packages/e2e-tests/specs/editor/various/datepicker.test.js @@ -1,7 +1,10 @@ /** * WordPress dependencies */ -import { createNewPost } from '@wordpress/e2e-test-utils'; +import { + createNewPost, + findSidebarPanelToggleButtonWithTitle, +} from '@wordpress/e2e-test-utils'; describe( 'Datepicker', () => { beforeEach( async () => { @@ -9,80 +12,92 @@ describe( 'Datepicker', () => { } ); it( 'should show the publishing date as "Immediately" if the date is not altered', async () => { - const publishingDate = await page.$eval( - '.edit-post-post-schedule__toggle', - ( dateLabel ) => dateLabel.textContent + const panelToggle = await findSidebarPanelToggleButtonWithTitle( + 'Publish:' + ); + const publishDate = await panelToggle.$eval( + '.editor-post-publish-panel__link', + ( publishDateSpan ) => publishDateSpan.textContent ); - expect( publishingDate ).toEqual( 'Immediately' ); + expect( publishDate ).toEqual( 'Immediately' ); } ); it( 'should show the publishing date if the date is in the past', async () => { // Open the datepicker. - await page.click( '.edit-post-post-schedule__toggle' ); + const panelToggle = await findSidebarPanelToggleButtonWithTitle( + 'Publish:' + ); + await panelToggle.click(); // Change the publishing date to a year in the past. await page.click( '.components-datetime__time-field-year' ); await page.keyboard.press( 'ArrowDown' ); // Close the datepicker. - await page.click( '.edit-post-post-schedule__toggle' ); + await panelToggle.click(); - const publishingDate = await page.$eval( - '.edit-post-post-schedule__toggle', - ( dateLabel ) => dateLabel.textContent + const publishDate = await panelToggle.$eval( + '.editor-post-publish-panel__link', + ( publishDateSpan ) => publishDateSpan.textContent ); - expect( publishingDate ).toMatch( + expect( publishDate ).toMatch( /[A-Za-z]{3} \d{1,2}, \d{4} \d{1,2}:\d{2} [ap]m/ ); } ); it( 'should show the publishing date if the date is in the future', async () => { // Open the datepicker. - await page.click( '.edit-post-post-schedule__toggle' ); + const panelToggle = await findSidebarPanelToggleButtonWithTitle( + 'Publish:' + ); + await panelToggle.click(); // Change the publishing date to a year in the future. await page.click( '.components-datetime__time-field-year' ); await page.keyboard.press( 'ArrowUp' ); // Close the datepicker. - await page.click( '.edit-post-post-schedule__toggle' ); + await panelToggle.click(); - const publishingDate = await page.$eval( - '.edit-post-post-schedule__toggle', - ( dateLabel ) => dateLabel.textContent + const publishDate = await panelToggle.$eval( + '.editor-post-publish-panel__link', + ( publishDateSpan ) => publishDateSpan.textContent ); - expect( publishingDate ).not.toEqual( 'Immediately' ); + expect( publishDate ).not.toEqual( 'Immediately' ); // The expected date format will be "Sep 26, 2018 11:52 pm". - expect( publishingDate ).toMatch( + expect( publishDate ).toMatch( /[A-Za-z]{3} \d{1,2}, \d{4} \d{1,2}:\d{2} [ap]m/ ); } ); it( 'should show the publishing date as "Immediately" if the date is cleared', async () => { // Open the datepicker. - await page.click( '.edit-post-post-schedule__toggle' ); + const panelToggle = await findSidebarPanelToggleButtonWithTitle( + 'Publish:' + ); + await panelToggle.click(); // Change the publishing date to a year in the future. await page.click( '.components-datetime__time-field-year' ); await page.keyboard.press( 'ArrowUp' ); // Close the datepicker. - await page.click( '.edit-post-post-schedule__toggle' ); + await panelToggle.click(); // Open the datepicker. - await page.click( '.edit-post-post-schedule__toggle' ); + await panelToggle.click(); - // Clear the date + // Clear the date. await page.click( '.components-datetime__date-reset-button' ); - const publishingDate = await page.$eval( - '.edit-post-post-schedule__toggle', - ( dateLabel ) => dateLabel.textContent + const publishDate = await panelToggle.$eval( + '.editor-post-publish-panel__link', + ( publishDateSpan ) => publishDateSpan.textContent ); - expect( publishingDate ).toEqual( 'Immediately' ); + expect( publishDate ).toEqual( 'Immediately' ); } ); } ); diff --git a/packages/e2e-tests/specs/editor/various/new-post.test.js b/packages/e2e-tests/specs/editor/various/new-post.test.js index 41db6ce7148b2..5c11971f6b51d 100644 --- a/packages/e2e-tests/specs/editor/various/new-post.test.js +++ b/packages/e2e-tests/specs/editor/various/new-post.test.js @@ -5,6 +5,7 @@ import { activatePlugin, createNewPost, deactivatePlugin, + openSidebarPanel, } from '@wordpress/e2e-test-utils'; describe( 'new editor state', () => { @@ -34,6 +35,8 @@ describe( 'new editor state', () => { ); expect( postPreviewButton ).not.toBeNull(); // Should display the Post Formats UI. + await openSidebarPanel( 'Post Format' ); + await page.waitForSelector( '.editor-post-format' ); const postFormatsUi = await page.$( '.editor-post-format' ); expect( postFormatsUi ).not.toBeNull(); } ); diff --git a/packages/e2e-tests/specs/editor/various/post-visibility.test.js b/packages/e2e-tests/specs/editor/various/post-visibility.test.js index 6844b9bd97345..2675629ce1d83 100644 --- a/packages/e2e-tests/specs/editor/various/post-visibility.test.js +++ b/packages/e2e-tests/specs/editor/various/post-visibility.test.js @@ -5,6 +5,7 @@ import { setBrowserViewport, createNewPost, openDocumentSettingsSidebar, + openSidebarPanel, } from '@wordpress/e2e-test-utils'; describe( 'Post visibility', () => { @@ -19,7 +20,7 @@ describe( 'Post visibility', () => { await openDocumentSettingsSidebar(); - await page.click( '.edit-post-post-visibility__toggle' ); + await openSidebarPanel( 'Visibility:' ); const [ privateLabel ] = await page.$x( '//label[text()="Private"]' @@ -45,7 +46,7 @@ describe( 'Post visibility', () => { await openDocumentSettingsSidebar(); // Set a publish date for the next month. - await page.click( '.edit-post-post-schedule__toggle' ); + await openSidebarPanel( 'Publish' ); await page.click( 'div[aria-label="Move forward to switch to the next month."]' ); @@ -55,7 +56,7 @@ describe( 'Post visibility', () => { ) )[ 0 ].click(); - await page.click( '.edit-post-post-visibility__toggle' ); + await openSidebarPanel( 'Visibility:' ); const [ privateLabel ] = await page.$x( '//label[text()="Private"]' ); await privateLabel.click(); diff --git a/packages/e2e-tests/specs/editor/various/scheduling.test.js b/packages/e2e-tests/specs/editor/various/scheduling.test.js index 7732f8d8a0e7c..36165ced76779 100644 --- a/packages/e2e-tests/specs/editor/various/scheduling.test.js +++ b/packages/e2e-tests/specs/editor/various/scheduling.test.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { createNewPost } from '@wordpress/e2e-test-utils'; +import { createNewPost, openSidebarPanel } from '@wordpress/e2e-test-utils'; describe( 'Scheduling', () => { beforeEach( createNewPost ); @@ -19,7 +19,7 @@ describe( 'Scheduling', () => { }; it( 'Should keep date time UI focused when the previous and next month buttons are clicked', async () => { - await page.click( '.edit-post-post-schedule__toggle' ); + await openSidebarPanel( 'Publish:' ); await page.click( 'div[aria-label="Move backward to switch to the previous month."]' ); diff --git a/packages/e2e-tests/specs/editor/various/sidebar.test.js b/packages/e2e-tests/specs/editor/various/sidebar.test.js index bc37aa3ec43a9..f8038023714af 100644 --- a/packages/e2e-tests/specs/editor/various/sidebar.test.js +++ b/packages/e2e-tests/specs/editor/various/sidebar.test.js @@ -2,8 +2,10 @@ * WordPress dependencies */ import { + activatePlugin, clearLocalStorage, createNewPost, + deactivatePlugin, findSidebarPanelWithTitle, enableFocusLossObservation, disableFocusLossObservation, @@ -120,11 +122,21 @@ describe( 'Sidebar', () => { } ); it( 'should be possible to programmatically remove Document Settings panels', async () => { + await activatePlugin( 'gutenberg-test-plugin-post-formats-support' ); + await createNewPost(); await enableFocusLossObservation(); await openDocumentSettingsSidebar(); + expect( await findSidebarPanelWithTitle( 'General' ) ).toBeDefined(); + expect( + await findSidebarPanelWithTitle( 'Visibility:' ) + ).toBeDefined(); + expect( await findSidebarPanelWithTitle( 'Publish:' ) ).toBeDefined(); + expect( + await findSidebarPanelWithTitle( 'Post Format' ) + ).toBeDefined(); expect( await findSidebarPanelWithTitle( 'Categories' ) ).toBeDefined(); expect( await findSidebarPanelWithTitle( 'Tags' ) ).toBeDefined(); expect( @@ -132,21 +144,29 @@ describe( 'Sidebar', () => { ).toBeDefined(); expect( await findSidebarPanelWithTitle( 'Excerpt' ) ).toBeDefined(); expect( await findSidebarPanelWithTitle( 'Discussion' ) ).toBeDefined(); - expect( - await findSidebarPanelWithTitle( 'Status & visibility' ) - ).toBeDefined(); await page.evaluate( () => { const { removeEditorPanel } = wp.data.dispatch( 'core/edit-post' ); + removeEditorPanel( 'post-status' ); + removeEditorPanel( 'visibility' ); + removeEditorPanel( 'schedule' ); + removeEditorPanel( 'post-format' ); removeEditorPanel( 'taxonomy-panel-category' ); removeEditorPanel( 'taxonomy-panel-post_tag' ); removeEditorPanel( 'featured-image' ); removeEditorPanel( 'post-excerpt' ); removeEditorPanel( 'discussion-panel' ); - removeEditorPanel( 'post-status' ); } ); + expect( await findSidebarPanelWithTitle( 'General' ) ).toBeUndefined(); + expect( + await findSidebarPanelWithTitle( 'Visibility:' ) + ).toBeUndefined(); + expect( await findSidebarPanelWithTitle( 'Publish:' ) ).toBeUndefined(); + expect( + await findSidebarPanelWithTitle( 'Post Format' ) + ).toBeUndefined(); expect( await findSidebarPanelWithTitle( 'Categories' ) ).toBeUndefined(); @@ -158,8 +178,7 @@ describe( 'Sidebar', () => { expect( await findSidebarPanelWithTitle( 'Discussion' ) ).toBeUndefined(); - expect( - await findSidebarPanelWithTitle( 'Status & visibility' ) - ).toBeUndefined(); + + await deactivatePlugin( 'gutenberg-test-plugin-post-formats-support' ); } ); } ); diff --git a/packages/edit-post/src/components/sidebar/post-format/index.js b/packages/edit-post/src/components/sidebar/post-format/index.js index 67f8f690f7403..36ad9db250779 100644 --- a/packages/edit-post/src/components/sidebar/post-format/index.js +++ b/packages/edit-post/src/components/sidebar/post-format/index.js @@ -1,20 +1,49 @@ /** * WordPress dependencies */ -import { PanelRow } from '@wordpress/components'; +import { PanelBody } from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; import { PostFormat as PostFormatForm, PostFormatCheck, } from '@wordpress/editor'; +import { __ } from '@wordpress/i18n'; + +const PANEL_NAME = 'post-format'; + +export default function PostFormat() { + const { isOpened, isRemoved } = useSelect( ( select ) => { + // We use isEditorPanelRemoved to hide the panel if it was + // programatically removed. We don't use isEditorPanelEnabled since + // this panel should not be disabled through the UI. + const { isEditorPanelRemoved, isEditorPanelOpened } = select( + 'core/edit-post' + ); + + return { + isOpened: isEditorPanelOpened( PANEL_NAME ), + isRemoved: isEditorPanelRemoved( PANEL_NAME ), + }; + }, [] ); + + const { toggleEditorPanelOpened } = useDispatch( 'core/edit-post' ); + + if ( isRemoved ) { + return null; + } -export function PostFormat() { return ( - + { + toggleEditorPanelOpened( PANEL_NAME ); + } } + title={ __( 'Post Format' ) } + > - + ); } - -export default PostFormat; diff --git a/packages/edit-post/src/components/sidebar/post-schedule/index.js b/packages/edit-post/src/components/sidebar/post-schedule/index.js index cf644bc9a6ae1..72e7ffd866100 100644 --- a/packages/edit-post/src/components/sidebar/post-schedule/index.js +++ b/packages/edit-post/src/components/sidebar/post-schedule/index.js @@ -1,39 +1,57 @@ /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; -import { PanelRow, Dropdown, Button } from '@wordpress/components'; +import { PanelBody } from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; import { PostSchedule as PostScheduleForm, - PostScheduleLabel, PostScheduleCheck, + PostScheduleLabel, } from '@wordpress/editor'; +import { __ } from '@wordpress/i18n'; + +const PANEL_NAME = 'schedule'; + +export default function PostSchedule() { + const { isOpened, isRemoved } = useSelect( ( select ) => { + // We use isEditorPanelRemoved to hide the panel if it was + // programatically removed. We don't use isEditorPanelEnabled since + // this panel should not be disabled through the UI. + const { isEditorPanelRemoved, isEditorPanelOpened } = select( + 'core/edit-post' + ); + + return { + isOpened: isEditorPanelOpened( PANEL_NAME ), + isRemoved: isEditorPanelRemoved( PANEL_NAME ), + }; + }, [] ); + + const { toggleEditorPanelOpened } = useDispatch( 'core/edit-post' ); + + if ( isRemoved ) { + return null; + } -export function PostSchedule() { return ( - - { __( 'Publish' ) } - ( - <> - - - ) } - renderContent={ () => } - /> - + { + toggleEditorPanelOpened( PANEL_NAME ); + } } + title={ + <> + { __( 'Publish:' ) } + + + + + } + > + + ); } - -export default PostSchedule; diff --git a/packages/edit-post/src/components/sidebar/post-schedule/style.scss b/packages/edit-post/src/components/sidebar/post-schedule/style.scss deleted file mode 100644 index c19896af20ab6..0000000000000 --- a/packages/edit-post/src/components/sidebar/post-schedule/style.scss +++ /dev/null @@ -1,14 +0,0 @@ -.edit-post-post-schedule { - width: 100%; - position: relative; - justify-content: left; - - span { - display: block; - width: 45%; - } -} - -.components-button.edit-post-post-schedule__toggle { - text-align: right; -} diff --git a/packages/edit-post/src/components/sidebar/post-status/index.js b/packages/edit-post/src/components/sidebar/post-status/index.js index 11311e91849c2..9401d7b7463a3 100644 --- a/packages/edit-post/src/components/sidebar/post-status/index.js +++ b/packages/edit-post/src/components/sidebar/post-status/index.js @@ -9,13 +9,10 @@ import { compose, ifCondition } from '@wordpress/compose'; /** * Internal dependencies */ -import PostVisibility from '../post-visibility'; import PostTrash from '../post-trash'; -import PostSchedule from '../post-schedule'; import PostSticky from '../post-sticky'; import PostAuthor from '../post-author'; import PostSlug from '../post-slug'; -import PostFormat from '../post-format'; import PostPendingStatus from '../post-pending-status'; import PluginPostStatusInfo from '../plugin-post-status-info'; @@ -28,16 +25,13 @@ function PostStatus( { isOpened, onTogglePanel } ) { return ( { ( fills ) => ( <> - - - diff --git a/packages/edit-post/src/components/sidebar/post-visibility/index.js b/packages/edit-post/src/components/sidebar/post-visibility/index.js index 2eacd4d3042aa..69fa3b262f48f 100644 --- a/packages/edit-post/src/components/sidebar/post-visibility/index.js +++ b/packages/edit-post/src/components/sidebar/post-visibility/index.js @@ -1,43 +1,65 @@ /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; -import { PanelRow, Dropdown, Button } from '@wordpress/components'; +import { PanelBody } from '@wordpress/components'; +import { useDispatch, useSelect } from '@wordpress/data'; import { PostVisibility as PostVisibilityForm, - PostVisibilityLabel, PostVisibilityCheck, + PostVisibilityLabel, } from '@wordpress/editor'; +import { __ } from '@wordpress/i18n'; + +const PANEL_NAME = 'visibility'; export function PostVisibility() { + const { isOpened, isRemoved } = useSelect( ( select ) => { + // We use isEditorPanelRemoved to hide the panel if it was + // programatically removed. We don't use isEditorPanelEnabled since + // this panel should not be disabled through the UI. + const { isEditorPanelRemoved, isEditorPanelOpened } = select( + 'core/edit-post' + ); + + return { + isOpened: isEditorPanelOpened( PANEL_NAME ), + isRemoved: isEditorPanelRemoved( PANEL_NAME ), + }; + }, [] ); + + const { toggleEditorPanelOpened } = useDispatch( 'core/edit-post' ); + + if ( isRemoved ) { + return null; + } + return ( ( - - { __( 'Visibility' ) } + { + toggleEditorPanelOpened( PANEL_NAME ); + } } + title={ + <> + { __( 'Visibility:' ) } + + + + + } + > { ! canEdit && ( - - - ) } - { canEdit && ( - ( - + { __( + 'You do not have permission to change the visibility.' ) } - renderContent={ () => } - /> + ) } - + { canEdit && } + ) } /> ); diff --git a/packages/edit-post/src/components/sidebar/post-visibility/style.scss b/packages/edit-post/src/components/sidebar/post-visibility/style.scss deleted file mode 100644 index 7b6be78514663..0000000000000 --- a/packages/edit-post/src/components/sidebar/post-visibility/style.scss +++ /dev/null @@ -1,42 +0,0 @@ -.edit-post-post-visibility { - width: 100%; - justify-content: left; - - span { - display: block; - width: 45%; - } -} - -.edit-post-post-visibility__dialog .components-popover__content { - @include break-medium { - // 279px (sidebar width) - 20px (padding) - 2px (horizontal borders) - width: 257px; - } -} - -.edit-post-post-visibility__dialog-legend { - font-weight: 600; -} - -.edit-post-post-visibility__choice { - margin: 10px 0; -} - -.edit-post-post-visibility__dialog-radio, -.edit-post-post-visibility__dialog-label { - vertical-align: top; -} - -.edit-post-post-visibility__dialog-password-input { - width: calc(100% - 20px); - margin-left: 20px; -} - -.edit-post-post-visibility__dialog-info { - color: $dark-gray-200; - padding-left: 20px; - font-style: italic; - margin: 4px 0 0; - line-height: 1.4; -} diff --git a/packages/edit-post/src/components/sidebar/settings-sidebar/index.js b/packages/edit-post/src/components/sidebar/settings-sidebar/index.js index 39a4a759662cd..6182f262f1d85 100644 --- a/packages/edit-post/src/components/sidebar/settings-sidebar/index.js +++ b/packages/edit-post/src/components/sidebar/settings-sidebar/index.js @@ -10,6 +10,9 @@ import { Platform } from '@wordpress/element'; */ import SettingsHeader from '../settings-header'; import PostStatus from '../post-status'; +import PostVisibility from '../post-visibility'; +import PostSchedule from '../post-schedule'; +import PostFormat from '../post-format'; import LastRevision from '../last-revision'; import PostTaxonomies from '../post-taxonomies'; import FeaturedImage from '../featured-image'; @@ -68,6 +71,9 @@ const SettingsSidebar = () => { { sidebarName === 'edit-post/document' && ( <> + + + diff --git a/packages/edit-post/src/style.scss b/packages/edit-post/src/style.scss index 13b9ae6ae7ec7..1f6b3a299c4fa 100644 --- a/packages/edit-post/src/style.scss +++ b/packages/edit-post/src/style.scss @@ -14,10 +14,8 @@ $footer-height: $button-size-small; @import "./components/sidebar/last-revision/style.scss"; @import "./components/sidebar/post-author/style.scss"; @import "./components/sidebar/post-link/style.scss"; -@import "./components/sidebar/post-schedule/style.scss"; @import "./components/sidebar/post-slug/style.scss"; @import "./components/sidebar/post-status/style.scss"; -@import "./components/sidebar/post-visibility/style.scss"; @import "./components/sidebar/settings-header/style.scss"; @import "./components/text-editor/style.scss"; @import "./components/visual-editor/style.scss"; diff --git a/packages/editor/src/components/post-format/index.js b/packages/editor/src/components/post-format/index.js index f126fb2aa7d09..1c58dad8c0495 100644 --- a/packages/editor/src/components/post-format/index.js +++ b/packages/editor/src/components/post-format/index.js @@ -29,7 +29,7 @@ export const POST_FORMAT_TITLES = { video: __( 'Video' ), }; -export default function PostFormat() { +export default function PostFormat( { showDescription = false } ) { const instanceId = useInstanceId( PostFormat ); const postFormatSelectorId = `post-format-selector-${ instanceId }`; @@ -86,9 +86,24 @@ export default function PostFormat() { label: POST_FORMAT_TITLES[ format ], value: format, } ) ) } + aria-describedby={ + showDescription + ? `editor-post-format__description-${ postFormatSelectorId }` + : undefined + } /> + { showDescription && ( +

+ { __( + 'Your theme uses post formats to highlight different kinds of content, like images or videos. Apply a post format to see this special styling.' + ) } +

+ ) } + { suggestedFormat && (
{ __( 'Suggestion:' ) }{ ' ' }