Skip to content

Commit

Permalink
PostPublishPanel: return focus to element that opened the panel (#11543)
Browse files Browse the repository at this point in the history
* Toggle disabled if post is published

* Return focus to Publish... button

- Do not unmount Header settings components.
- Hide the "Save draft" button because it's not hidden by the
  PostPublishPanel slide-in sidebar.

* Sort dependencies

* Extract props

* Toggle should be disabled if post is published

* Add toggleProps to button

* Inline text for toggle within the button component

* Always render the button component

* Use aria-disabled instead of disabled to avoid focus loss

* Improve comments

* Update snapshots

* Add deprecation notice in editor CHANGELOG

* Add deprecation notice in plugin

* Add deprecation in component

* Add DotTip to PostPublishButton

* Fix deprecation warning in tests

* Update PostPublishButton e2e tests to use aria-disabled instead of disabled att

* Update e2e test

This was relying on the preview button not being mounted
while the publish panel was opened. A better logic is to
check whether the actual publish panel is shown.

* Tweak comment

* Update version

* Update packages/editor/src/components/post-publish-panel/toggle.js

* Place component in a separate line

Co-Authored-By: nosolosw <[email protected]>

* Update version number

* Add comment

* Update comment

* Tweak comment

* chore: Move deps to 4.5
  • Loading branch information
nosolosw authored and youknowriad committed Nov 9, 2018
1 parent a2fee33 commit fc03492
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 102 deletions.
1 change: 1 addition & 0 deletions docs/reference/deprecated.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
49 changes: 27 additions & 22 deletions packages/edit-post/src/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,34 +39,39 @@ function Header( {
tabIndex="-1"
>
<HeaderToolbar />
{ ! isPublishSidebarOpened && (
<div className="edit-post-header__settings">
<div className="edit-post-header__settings">
{ ! 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.
<PostSavedState
forceIsDirty={ hasActiveMetaboxes }
forceIsSaving={ isSaving }
/>
<PostPreviewButton />
<PostPublishButtonOrToggle
forceIsDirty={ hasActiveMetaboxes }
forceIsSaving={ isSaving }
) }
<PostPreviewButton />
<PostPublishButtonOrToggle
forceIsDirty={ hasActiveMetaboxes }
forceIsSaving={ isSaving }
/>
<div>
<IconButton
icon="admin-generic"
label={ __( 'Settings' ) }
onClick={ toggleGeneralSidebar }
isToggled={ isEditorSidebarOpened }
aria-expanded={ isEditorSidebarOpened }
shortcut={ shortcuts.toggleSidebar }
/>
<div>
<IconButton
icon="admin-generic"
label={ __( 'Settings' ) }
onClick={ toggleGeneralSidebar }
isToggled={ isEditorSidebarOpened }
aria-expanded={ isEditorSidebarOpened }
shortcut={ shortcuts.toggleSidebar }
/>
<DotTip tipId="core/editor.settings">
{ __( 'You’ll find more settings for your page and blocks in the sidebar. Click “Settings” to open it.' ) }
</DotTip>
</div>
<PinnedPlugins.Slot />
<MoreMenu />
<DotTip tipId="core/editor.settings">
{ __( 'You’ll find more settings for your page and blocks in the sidebar. Click “Settings” to open it.' ) }
</DotTip>
</div>
) }
<PinnedPlugins.Slot />
<MoreMenu />
</div>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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( {
Expand All @@ -24,54 +24,55 @@ export function PostPublishButtonOrToggle( {
isScheduled,
togglePublishSidebar,
} ) {
const button = (
<PostPublishButton
forceIsDirty={ forceIsDirty }
forceIsSaving={ forceIsSaving }
/>
);
const toggle = (
<PostPublishPanelToggle
isOpen={ isPublishSidebarOpened }
onToggle={ togglePublishSidebar }
forceIsSaving={ forceIsSaving }
forceIsDirty={ forceIsDirty }
/>
);
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 (
<PostPublishButton
forceIsDirty={ forceIsDirty }
forceIsSaving={ forceIsSaving }
isOpen={ isPublishSidebarOpened }
isToggle={ component === IS_TOGGLE }
onToggle={ togglePublishSidebar }
/>
);
}

export default compose(
Expand Down
Original file line number Diff line number Diff line change
@@ -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`] = `<WithSelect(WithDispatch(PostPublishButton)) />`;
exports[`PostPublishButtonOrToggle should render a button when post is not (1), (2), (3), the viewport is >= medium, and the publish sidebar is disabled 1`] = `
<WithSelect(WithDispatch(PostPublishButton))
isToggle={false}
/>
`;

exports[`PostPublishButtonOrToggle should render a button when the post is pending and cannot be published but the viewport is >= medium (3) 1`] = `<WithSelect(WithDispatch(PostPublishButton)) />`;
exports[`PostPublishButtonOrToggle should render a button when the post is pending and cannot be published but the viewport is >= medium (3) 1`] = `
<WithSelect(WithDispatch(PostPublishButton))
isToggle={false}
/>
`;

exports[`PostPublishButtonOrToggle should render a button when the post is published (1) 1`] = `<WithSelect(WithDispatch(PostPublishButton)) />`;
exports[`PostPublishButtonOrToggle should render a button when the post is published (1) 1`] = `
<WithSelect(WithDispatch(PostPublishButton))
isToggle={false}
/>
`;

exports[`PostPublishButtonOrToggle should render a button when the post is scheduled (2) 1`] = `<WithSelect(WithDispatch(PostPublishButton)) />`;
exports[`PostPublishButtonOrToggle should render a button when the post is scheduled (2) 1`] = `
<WithSelect(WithDispatch(PostPublishButton))
isToggle={false}
/>
`;

exports[`PostPublishButtonOrToggle should render a toggle when post is not (1), (2), (3), the viewport is >= medium, and the publish sidebar is enabled 1`] = `<WithSelect(PostPublishPanelToggle) />`;
exports[`PostPublishButtonOrToggle should render a toggle when post is not (1), (2), (3), the viewport is >= medium, and the publish sidebar is enabled 1`] = `
<WithSelect(WithDispatch(PostPublishButton))
isToggle={true}
/>
`;

exports[`PostPublishButtonOrToggle should render a toggle when post is not published or scheduled and the viewport is < medium 1`] = `<WithSelect(PostPublishPanelToggle) />`;
exports[`PostPublishButtonOrToggle should render a toggle when post is not published or scheduled and the viewport is < medium 1`] = `
<WithSelect(WithDispatch(PostPublishButton))
isToggle={true}
/>
`;
4 changes: 4 additions & 0 deletions packages/editor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

- In `NavigableToolbar`, a property focusOnMount was added, if true, the toolbar will get focus as soon as it mounted. Defaults to false.

### Deprecations

- `wp.editor.PostPublishPanelToggle` has been deprecated in favor of `wp.editor.PostPublishButton`.

### Polish

- Reactive block styles.
Expand Down
65 changes: 49 additions & 16 deletions packages/editor/src/components/post-publish-button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 ||
Expand All @@ -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';
Expand All @@ -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 = <PublishButtonLabel forceIsSaving={ forceIsSaving } />;

const componentProps = isToggle ? toggleProps : buttonProps;
const componentChildren = isToggle ? toggleChildren : buttonChildren;
return (
<Button
ref={ this.buttonNode }
className="editor-post-publish-button"
isPrimary
isLarge
onClick={ onClick }
disabled={ isButtonDisabled }
isBusy={ isSaving && isPublished }
{ ...componentProps }
>
<PublishButtonLabel forceIsSaving={ forceIsSaving } />
{ componentChildren }
<DotTip tipId="core/editor.publish">
{ __( 'Finished writing? That’s great, let’s get this published right now. Just click “Publish” and you’re good to go.' ) }
</DotTip>
</Button>
);
}
Expand Down
Loading

0 comments on commit fc03492

Please sign in to comment.