diff --git a/docs/reference/deprecated.md b/docs/reference/deprecated.md index e1a54e3498c1d..13efe9f8940bd 100644 --- a/docs/reference/deprecated.md +++ b/docs/reference/deprecated.md @@ -2,6 +2,7 @@ Gutenberg's deprecation policy is intended to support backwards-compatibility fo ## 4.5.0 - `Dropdown.refresh()` has been deprecated as the contained `Popover` is now automatically refreshed. +- `wp.editor.PostPublishPanelToggle` has been deprecated in favor of `wp.editor.PostPublishButton`. ## 4.4.0 diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index 554ae583210c0..c63a7058eeb7c 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -39,34 +39,39 @@ function Header( { tabIndex="-1" > - { ! isPublishSidebarOpened && ( -
+
+ { ! isPublishSidebarOpened && ( + // This button isn't completely hidden by the publish sidebar. + // We can't hide the whole toolbar when the publish sidebar is open because + // we want to prevent mounting/unmounting the PostPublishButtonOrToggle DOM node. + // We track that DOM node to return focus to the PostPublishButtonOrToggle + // when the publish sidebar has been closed. - - + +
+ -
- - - { __( 'You’ll find more settings for your page and blocks in the sidebar. Click “Settings” to open it.' ) } - -
- - + + { __( 'You’ll find more settings for your page and blocks in the sidebar. Click “Settings” to open it.' ) } +
- ) } + + +
); } diff --git a/packages/edit-post/src/components/header/post-publish-button-or-toggle.js b/packages/edit-post/src/components/header/post-publish-button-or-toggle.js index efa0621f72a99..edf6699fc9eaf 100644 --- a/packages/edit-post/src/components/header/post-publish-button-or-toggle.js +++ b/packages/edit-post/src/components/header/post-publish-button-or-toggle.js @@ -6,9 +6,9 @@ import { get } from 'lodash'; /** * WordPress dependencies. */ -import { PostPublishPanelToggle, PostPublishButton } from '@wordpress/editor'; import { compose } from '@wordpress/compose'; import { withDispatch, withSelect } from '@wordpress/data'; +import { PostPublishButton } from '@wordpress/editor'; import { withViewportMatch } from '@wordpress/viewport'; export function PostPublishButtonOrToggle( { @@ -24,54 +24,55 @@ export function PostPublishButtonOrToggle( { isScheduled, togglePublishSidebar, } ) { - const button = ( - - ); - const toggle = ( - - ); + const IS_TOGGLE = 'toggle'; + const IS_BUTTON = 'button'; + let component; /** - * We want to show a BUTTON when the post status is at the _final stage_ + * Conditions to show a BUTTON (publish directly) or a TOGGLE (open publish sidebar): + * + * 1) We want to show a BUTTON when the post status is at the _final stage_ * for a particular role (see https://codex.wordpress.org/Post_Status): * * - is published * - is scheduled to be published - * - is pending and can't be published (but only for viewports >= medium) + * - is pending and can't be published (but only for viewports >= medium). + * Originally, we considered showing a button for pending posts that couldn't be published + * (for example, for an author with the contributor role). Some languages can have + * long translations for "Submit for review", so given the lack of UI real estate available + * we decided to take into account the viewport in that case. + * See: https://github.com/WordPress/gutenberg/issues/10475 + * + * 2) Then, in small viewports, we'll show a TOGGLE. * - * Originally we considered showing a button for pending posts - * that couldn't be published (for ex, for a contributor role). - * Some languages can have really long translations for "Submit for review", - * so given the lack of UI real state we decided to take into account the viewport - * in that particular case. + * 3) Finally, we'll use the publish sidebar status to decide: + * + * - if it is enabled, we show a TOGGLE + * - if it is disabled, we show a BUTTON */ if ( isPublished || ( isScheduled && isBeingScheduled ) || ( isPending && ! hasPublishAction && ! isLessThanMediumViewport ) ) { - return button; + component = IS_BUTTON; + } else if ( isLessThanMediumViewport ) { + component = IS_TOGGLE; + } else if ( isPublishSidebarEnabled ) { + component = IS_TOGGLE; + } else { + component = IS_BUTTON; } - /** - * Then, we take other things into account: - * - * - Show TOGGLE if it is small viewport. - * - Otherwise, use publish sidebar status to decide - TOGGLE if enabled, BUTTON if not. - */ - if ( isLessThanMediumViewport ) { - return toggle; - } - - return isPublishSidebarEnabled ? toggle : button; + return ( + + ); } export default compose( diff --git a/packages/edit-post/src/components/header/test/__snapshots__/index.js.snap b/packages/edit-post/src/components/header/test/__snapshots__/index.js.snap index 59d931e6ef389..95ed8d68d7ded 100644 --- a/packages/edit-post/src/components/header/test/__snapshots__/index.js.snap +++ b/packages/edit-post/src/components/header/test/__snapshots__/index.js.snap @@ -1,13 +1,37 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PostPublishButtonOrToggle should render a button when post is not (1), (2), (3), the viewport is >= medium, and the publish sidebar is disabled 1`] = ``; +exports[`PostPublishButtonOrToggle should render a button when post is not (1), (2), (3), the viewport is >= medium, and the publish sidebar is disabled 1`] = ` + +`; -exports[`PostPublishButtonOrToggle should render a button when the post is pending and cannot be published but the viewport is >= medium (3) 1`] = ``; +exports[`PostPublishButtonOrToggle should render a button when the post is pending and cannot be published but the viewport is >= medium (3) 1`] = ` + +`; -exports[`PostPublishButtonOrToggle should render a button when the post is published (1) 1`] = ``; +exports[`PostPublishButtonOrToggle should render a button when the post is published (1) 1`] = ` + +`; -exports[`PostPublishButtonOrToggle should render a button when the post is scheduled (2) 1`] = ``; +exports[`PostPublishButtonOrToggle should render a button when the post is scheduled (2) 1`] = ` + +`; -exports[`PostPublishButtonOrToggle should render a toggle when post is not (1), (2), (3), the viewport is >= medium, and the publish sidebar is enabled 1`] = ``; +exports[`PostPublishButtonOrToggle should render a toggle when post is not (1), (2), (3), the viewport is >= medium, and the publish sidebar is enabled 1`] = ` + +`; -exports[`PostPublishButtonOrToggle should render a toggle when post is not published or scheduled and the viewport is < medium 1`] = ``; +exports[`PostPublishButtonOrToggle should render a toggle when post is not published or scheduled and the viewport is < medium 1`] = ` + +`; diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index 9379ec67de996..bd2900c13df71 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -1,5 +1,9 @@ ## 6.2.1 (Unreleased) +### Deprecations + +- `wp.editor.PostPublishPanelToggle` has been deprecated in favor of `wp.editor.PostPublishButton`. + ### Polish - Reactive block styles. diff --git a/packages/editor/src/components/post-publish-button/index.js b/packages/editor/src/components/post-publish-button/index.js index 69233c86931d8..cfed6dbd112f5 100644 --- a/packages/editor/src/components/post-publish-button/index.js +++ b/packages/editor/src/components/post-publish-button/index.js @@ -10,6 +10,8 @@ import { Button } from '@wordpress/components'; import { Component, createRef } from '@wordpress/element'; import { withSelect, withDispatch } from '@wordpress/data'; import { compose } from '@wordpress/compose'; +import { __ } from '@wordpress/i18n'; +import { DotTip } from '@wordpress/nux'; /** * Internal dependencies @@ -28,19 +30,22 @@ export class PostPublishButton extends Component { render() { const { - isSaving, - onStatusChange, - onSave, + forceIsDirty, + forceIsSaving, + hasPublishAction, isBeingScheduled, - visibility, - isPublishable, - isSaveable, + isOpen, isPostSavingLocked, + isPublishable, isPublished, - hasPublishAction, + isSaveable, + isSaving, + isToggle, + onSave, + onStatusChange, onSubmit = noop, - forceIsDirty, - forceIsSaving, + onToggle, + visibility, } = this.props; const isButtonDisabled = isSaving || @@ -49,6 +54,13 @@ export class PostPublishButton extends Component { isPostSavingLocked || ( ! isPublishable && ! forceIsDirty ); + const isToggleDisabled = + isPublished || + isSaving || + forceIsSaving || + ! isSaveable || + ( ! isPublishable && ! forceIsDirty ); + let publishStatus; if ( ! hasPublishAction ) { publishStatus = 'pending'; @@ -66,17 +78,38 @@ export class PostPublishButton extends Component { onSave(); }; + const buttonProps = { + 'aria-disabled': isButtonDisabled, + className: 'editor-post-publish-button', + isBusy: isSaving && isPublished, + isLarge: true, + isPrimary: true, + onClick, + }; + + const toggleProps = { + 'aria-disabled': isToggleDisabled, + 'aria-expanded': isOpen, + className: 'editor-post-publish-panel__toggle', + isBusy: isSaving && isPublished, + isPrimary: true, + onClick: onToggle, + }; + + const toggleChildren = isBeingScheduled ? __( 'Schedule…' ) : __( 'Publish…' ); + const buttonChildren = ; + + const componentProps = isToggle ? toggleProps : buttonProps; + const componentChildren = isToggle ? toggleChildren : buttonChildren; return ( ); } diff --git a/packages/editor/src/components/post-publish-button/test/index.js b/packages/editor/src/components/post-publish-button/test/index.js index b48d60f836671..8fbef6007144a 100644 --- a/packages/editor/src/components/post-publish-button/test/index.js +++ b/packages/editor/src/components/post-publish-button/test/index.js @@ -11,8 +11,8 @@ import { PostPublishButton } from '../'; jest.mock( '../../../../../components/src/button' ); describe( 'PostPublishButton', () => { - describe( 'disabled', () => { - it( 'should be disabled if post is currently saving', () => { + describe( 'aria-disabled', () => { + it( 'should be true if post is currently saving', () => { const wrapper = shallow( { /> ); - expect( wrapper.prop( 'disabled' ) ).toBe( true ); + expect( wrapper.prop( 'aria-disabled' ) ).toBe( true ); } ); - it( 'should be disabled if forceIsSaving is true', () => { + it( 'should be true if forceIsSaving is true', () => { const wrapper = shallow( { /> ); - expect( wrapper.prop( 'disabled' ) ).toBe( true ); + expect( wrapper.prop( 'aria-disabled' ) ).toBe( true ); } ); - it( 'should be disabled if post is not publishable and not forceIsDirty', () => { + it( 'should be true if post is not publishable and not forceIsDirty', () => { const wrapper = shallow( { /> ); - expect( wrapper.prop( 'disabled' ) ).toBe( true ); + expect( wrapper.prop( 'aria-disabled' ) ).toBe( true ); } ); - it( 'should be disabled if post is not saveable', () => { + it( 'should be true if post is not saveable', () => { const wrapper = shallow( { /> ); - expect( wrapper.prop( 'disabled' ) ).toBe( true ); + expect( wrapper.prop( 'aria-disabled' ) ).toBe( true ); } ); - it( 'should be disabled if post saving is locked', () => { + it( 'should be true if post saving is locked', () => { const wrapper = shallow( { /> ); - expect( wrapper.prop( 'disabled' ) ).toBe( true ); + expect( wrapper.prop( 'aria-disabled' ) ).toBe( true ); } ); - it( 'should be enabled if post is saveable but not publishable and forceIsDirty is true', () => { + it( 'should be false if post is saveable but not publishable and forceIsDirty is true', () => { const wrapper = shallow( { /> ); - expect( wrapper.prop( 'disabled' ) ).toBe( false ); + expect( wrapper.prop( 'aria-disabled' ) ).toBe( false ); } ); - it( 'should be enabled if post is publishave and saveable', () => { + it( 'should be false if post is publishave and saveable', () => { const wrapper = shallow( { /> ); - expect( wrapper.prop( 'disabled' ) ).toBe( false ); + expect( wrapper.prop( 'aria-disabled' ) ).toBe( false ); } ); } ); diff --git a/packages/editor/src/components/post-publish-panel/index.js b/packages/editor/src/components/post-publish-panel/index.js index e6d324624fab0..0b38b0dd78400 100644 --- a/packages/editor/src/components/post-publish-panel/index.js +++ b/packages/editor/src/components/post-publish-panel/index.js @@ -12,6 +12,7 @@ import { IconButton, Spinner, CheckboxControl, + withFocusReturn, withConstrainedTabbing, } from '@wordpress/components'; import { withSelect, withDispatch } from '@wordpress/data'; @@ -142,5 +143,6 @@ export default compose( [ }, }; } ), + withFocusReturn, withConstrainedTabbing, ] )( PostPublishPanel ); diff --git a/packages/editor/src/components/post-publish-panel/test/toggle.js b/packages/editor/src/components/post-publish-panel/test/toggle.js index 81126aa76a14d..1f1a4971dbd35 100644 --- a/packages/editor/src/components/post-publish-panel/test/toggle.js +++ b/packages/editor/src/components/post-publish-panel/test/toggle.js @@ -20,6 +20,9 @@ describe( 'PostPublishPanelToggle', () => { ); expect( wrapper.prop( 'disabled' ) ).toBe( true ); + expect( console ).toHaveWarnedWith( + 'PostPublishPanelToggle is deprecated and will be removed from Gutenberg in 4.5. Please use PostPublishButton instead.' + ); } ); it( 'should be disabled if post is currently force saving', () => { diff --git a/packages/editor/src/components/post-publish-panel/toggle.js b/packages/editor/src/components/post-publish-panel/toggle.js index a617354392031..0cf8b56019cb4 100644 --- a/packages/editor/src/components/post-publish-panel/toggle.js +++ b/packages/editor/src/components/post-publish-panel/toggle.js @@ -3,6 +3,7 @@ */ import { Button } from '@wordpress/components'; import { compose } from '@wordpress/compose'; +import deprecated from '@wordpress/deprecated'; import { __ } from '@wordpress/i18n'; import { withSelect } from '@wordpress/data'; import { DotTip } from '@wordpress/nux'; @@ -25,6 +26,12 @@ export function PostPublishPanelToggle( { ! isSaveable || ( ! isPublishable && ! forceIsDirty ); + deprecated( 'PostPublishPanelToggle', { + version: '4.5', + alternative: 'PostPublishButton', + plugin: 'Gutenberg', + } ); + return (