diff --git a/packages/editor/src/components/post-comments/index.js b/packages/editor/src/components/post-comments/index.js
index 85d9948575d05..694655092237c 100644
--- a/packages/editor/src/components/post-comments/index.js
+++ b/packages/editor/src/components/post-comments/index.js
@@ -2,7 +2,11 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
-import { CheckboxControl } from '@wordpress/components';
+import {
+ RadioControl,
+ __experimentalText as Text,
+ __experimentalVStack as VStack,
+} from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
/**
@@ -10,6 +14,34 @@ import { useDispatch, useSelect } from '@wordpress/data';
*/
import { store as editorStore } from '../../store';
+const COMMENT_OPTIONS = [
+ {
+ label: (
+ <>
+ { __( 'Open' ) }
+
+ { __( 'Visitors can add new comments and replies.' ) }
+
+ >
+ ),
+ value: 'open',
+ },
+ {
+ label: (
+ <>
+ { __( 'Closed' ) }
+
+ { __( 'Visitors cannot add new comments or replies.' ) }
+
+
+ { __( 'Existing comments remain visible.' ) }
+
+ >
+ ),
+ value: 'closed',
+ },
+];
+
function PostComments() {
const commentStatus = useSelect(
( select ) =>
@@ -18,18 +50,24 @@ function PostComments() {
[]
);
const { editPost } = useDispatch( editorStore );
- const onToggleComments = () =>
+ const handleStatus = ( newCommentStatus ) =>
editPost( {
- comment_status: commentStatus === 'open' ? 'closed' : 'open',
+ comment_status: newCommentStatus,
} );
return (
-
+
);
}
diff --git a/packages/editor/src/components/post-discussion/panel.js b/packages/editor/src/components/post-discussion/panel.js
index 6ff022a2b8b52..f829ed01eebb9 100644
--- a/packages/editor/src/components/post-discussion/panel.js
+++ b/packages/editor/src/components/post-discussion/panel.js
@@ -2,8 +2,16 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
-import { PanelBody, PanelRow } from '@wordpress/components';
-import { useDispatch, useSelect } from '@wordpress/data';
+import {
+ Dropdown,
+ Button,
+ __experimentalVStack as VStack,
+ __experimentalText as Text,
+} from '@wordpress/components';
+import { useSelect } from '@wordpress/data';
+import { useState, useMemo } from '@wordpress/element';
+import { __experimentalInspectorPopoverHeader as InspectorPopoverHeader } from '@wordpress/block-editor';
+import { store as coreStore } from '@wordpress/core-data';
/**
* Internal dependencies
@@ -12,50 +20,119 @@ import { store as editorStore } from '../../store';
import PostTypeSupportCheck from '../post-type-support-check';
import PostComments from '../post-comments';
import PostPingbacks from '../post-pingbacks';
+import PostPanelRow from '../post-panel-row';
const PANEL_NAME = 'discussion-panel';
-function DiscussionPanel() {
- const { isEnabled, isOpened } = useSelect( ( select ) => {
- const { isEditorPanelEnabled, isEditorPanelOpened } =
- select( editorStore );
+function ModalContents( { onClose } ) {
+ return (
+
+ );
+}
+
+function PostDiscussionToggle( { isOpen, onClick } ) {
+ const {
+ commentStatus,
+ pingStatus,
+ commentsSupported,
+ trackbacksSupported,
+ } = useSelect( ( select ) => {
+ const { getEditedPostAttribute } = select( editorStore );
+ const { getPostType } = select( coreStore );
+ const postType = getPostType( getEditedPostAttribute( 'type' ) );
return {
- isEnabled: isEditorPanelEnabled( PANEL_NAME ),
- isOpened: isEditorPanelOpened( PANEL_NAME ),
+ commentStatus: getEditedPostAttribute( 'comment_status' ) ?? 'open',
+ pingStatus: getEditedPostAttribute( 'ping_status' ) ?? 'open',
+ commentsSupported: !! postType.supports.comments,
+ trackbacksSupported: !! postType.supports.trackbacks,
};
}, [] );
-
- const { toggleEditorPanelOpened } = useDispatch( editorStore );
-
- if ( ! isEnabled ) {
- return null;
+ let label;
+ if ( commentStatus === 'open' ) {
+ if ( pingStatus === 'open' ) {
+ label = __( 'Open' );
+ } else {
+ label = trackbacksSupported ? __( 'Comments only' ) : __( 'Open' );
+ }
+ } else if ( pingStatus === 'open' ) {
+ label = commentsSupported ? __( 'Pings only' ) : __( 'Pings enabled' );
+ } else {
+ label = __( 'Closed' );
}
-
return (
- toggleEditorPanelOpened( PANEL_NAME ) }
+
+ { label }
+
);
}
export default function PostDiscussionPanel() {
+ const { isEnabled } = useSelect( ( select ) => {
+ const { isEditorPanelEnabled } = select( editorStore );
+ return {
+ isEnabled: isEditorPanelEnabled( PANEL_NAME ),
+ };
+ }, [] );
+
+ // Use internal state instead of a ref to make sure that the component
+ // re-renders when the popover's anchor updates.
+ const [ popoverAnchor, setPopoverAnchor ] = useState( null );
+ // Memoize popoverProps to avoid returning a new object every time.
+ const popoverProps = useMemo(
+ () => ( {
+ // Anchor the popover to the middle of the entire row so that it doesn't
+ // move around when the label changes.
+ anchor: popoverAnchor,
+ placement: 'left-start',
+ offset: 36,
+ shift: true,
+ } ),
+ [ popoverAnchor ]
+ );
+
+ if ( ! isEnabled ) {
+ return null;
+ }
+
return (
-
+
+ (
+
+ ) }
+ renderContent={ ( { onClose } ) => (
+
+ ) }
+ />
+
);
}
diff --git a/packages/editor/src/components/post-discussion/style.scss b/packages/editor/src/components/post-discussion/style.scss
new file mode 100644
index 0000000000000..b1eae85140285
--- /dev/null
+++ b/packages/editor/src/components/post-discussion/style.scss
@@ -0,0 +1,26 @@
+.editor-post-discussion__panel-dialog .editor-post-discussion {
+ // sidebar width - popover padding - form margin
+ min-width: $sidebar-width - $grid-unit-20 - $grid-unit-20;
+ margin: $grid-unit-10;
+
+ .components-radio-control__option {
+ align-items: flex-start;
+ }
+
+ .components-radio-control__label .components-text {
+ display: block;
+ margin-top: $grid-unit-05;
+ }
+}
+.editor-post-discussion__panel-toggle {
+ &.components-button {
+ height: auto;
+ }
+ .components-text {
+ color: inherit;
+ }
+}
+
+.editor-post-discussion__panel-dialog .components-popover__content {
+ min-width: 320px;
+}
diff --git a/packages/editor/src/components/post-pingbacks/index.js b/packages/editor/src/components/post-pingbacks/index.js
index d6e1c419ee6f9..832088b86364a 100644
--- a/packages/editor/src/components/post-pingbacks/index.js
+++ b/packages/editor/src/components/post-pingbacks/index.js
@@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
-import { CheckboxControl } from '@wordpress/components';
+import { CheckboxControl, ExternalLink } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
/**
@@ -26,9 +26,18 @@ function PostPingbacks() {
return (
+ { __( 'Learn more about pingbacks & trackbacks' ) }
+
+ }
/>
);
}
diff --git a/packages/editor/src/components/sidebar/index.js b/packages/editor/src/components/sidebar/index.js
index be516d5b51ee6..30d27a8c5db30 100644
--- a/packages/editor/src/components/sidebar/index.js
+++ b/packages/editor/src/components/sidebar/index.js
@@ -26,7 +26,6 @@ import PageAttributesPanel from '../page-attributes/panel';
import PatternOverridesPanel from '../pattern-overrides-panel';
import PluginDocumentSettingPanel from '../plugin-document-setting-panel';
import PluginSidebar from '../plugin-sidebar';
-import PostDiscussionPanel from '../post-discussion/panel';
import PostLastRevisionPanel from '../post-last-revision/panel';
import PostSummary from './post-summary';
import PostTaxonomiesPanel from '../post-taxonomies/panel';
@@ -120,7 +119,6 @@ const SidebarContent = ( {
-
{ extraPanels }
diff --git a/packages/editor/src/components/sidebar/post-summary.js b/packages/editor/src/components/sidebar/post-summary.js
index a2d5a7cba18cb..807ff25c2d9ff 100644
--- a/packages/editor/src/components/sidebar/post-summary.js
+++ b/packages/editor/src/components/sidebar/post-summary.js
@@ -12,6 +12,7 @@ import PostActions from '../post-actions';
import PostAuthorPanel from '../post-author/panel';
import PostCardPanel from '../post-card-panel';
import PostContentInformation from '../post-content-information';
+import PostDiscussionPanel from '../post-discussion/panel';
import { PrivatePostExcerptPanel as PostExcerptPanel } from '../post-excerpt/panel';
import PostFeaturedImagePanel from '../post-featured-image/panel';
import PostFormatPanel from '../post-format/panel';
@@ -80,6 +81,7 @@ export default function PostSummary( { onActionPerformed } ) {
+
diff --git a/packages/editor/src/style.scss b/packages/editor/src/style.scss
index 42597de342efa..c7d4aae8d8f43 100644
--- a/packages/editor/src/style.scss
+++ b/packages/editor/src/style.scss
@@ -18,6 +18,7 @@
@import "./components/post-actions/style.scss";
@import "./components/post-card-panel/style.scss";
@import "./components/post-content-information/style.scss";
+@import "./components/post-discussion/style.scss";
@import "./components/post-excerpt/style.scss";
@import "./components/post-featured-image/style.scss";
@import "./components/post-format/style.scss";
diff --git a/test/e2e/specs/editor/various/sidebar.spec.js b/test/e2e/specs/editor/various/sidebar.spec.js
index 02004f0c458f4..ddd4bc01a8196 100644
--- a/test/e2e/specs/editor/various/sidebar.spec.js
+++ b/test/e2e/specs/editor/various/sidebar.spec.js
@@ -114,7 +114,6 @@ test.describe( 'Sidebar', () => {
'No Title',
'Categories',
'Tags',
- 'Discussion',
] );
// Also check 'panels' that are not rendered as TabPanels.
const postExcerptPanel = page.getByRole( 'button', {
@@ -123,6 +122,9 @@ test.describe( 'Sidebar', () => {
const postFeaturedImagePanel = page.getByRole( 'button', {
name: 'Set featured image',
} );
+ const postDiscussionPanel = page.getByRole( 'button', {
+ name: 'Change discussion options',
+ } );
const postSummarySection = page.getByRole( 'checkbox', {
name: 'Stick to the top of the blog',
} );
@@ -130,6 +132,7 @@ test.describe( 'Sidebar', () => {
await expect( postExcerptPanel ).toBeVisible();
await expect( postFeaturedImagePanel ).toBeVisible();
await expect( postSummarySection ).toBeVisible();
+ await expect( postDiscussionPanel ).toHaveCount( 1 );
await page.evaluate( () => {
const { removeEditorPanel } =
@@ -147,5 +150,6 @@ test.describe( 'Sidebar', () => {
await expect( postExcerptPanel ).toBeHidden();
await expect( postFeaturedImagePanel ).toBeHidden();
await expect( postSummarySection ).toBeHidden();
+ await expect( postDiscussionPanel ).toHaveCount( 0 );
} );
} );