Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 27 additions & 100 deletions packages/editor/src/components/post-visibility/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import {
VisuallyHidden,
__experimentalConfirmDialog as ConfirmDialog,
TextControl,
RadioControl,
__experimentalVStack as VStack,
} from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { useSelect, useDispatch } from '@wordpress/data';
Expand All @@ -15,7 +15,7 @@ import { __experimentalInspectorPopoverHeader as InspectorPopoverHeader } from '
/**
* Internal dependencies
*/
import { visibilityOptions } from './utils';
import { VISIBILITY_OPTIONS } from './utils';
import { store as editorStore } from '../../store';

/**
Expand All @@ -34,42 +34,26 @@ export default function PostVisibility( { onClose } ) {
password: select( editorStore ).getEditedPostAttribute( 'password' ),
} ) );

const { editPost, savePost } = useDispatch( editorStore );
const { editPost } = useDispatch( editorStore );

const [ hasPassword, setHasPassword ] = useState( !! password );
const [ showPrivateConfirmDialog, setShowPrivateConfirmDialog ] =
useState( false );

const setPublic = () => {
editPost( {
status: visibility === 'private' ? 'draft' : status,
password: '',
} );
setHasPassword( false );
};

const setPrivate = () => {
setShowPrivateConfirmDialog( true );
};

const confirmPrivate = () => {
editPost( { status: 'private', password: '' } );
setHasPassword( false );
setShowPrivateConfirmDialog( false );
savePost();
};

const handleDialogCancel = () => {
setShowPrivateConfirmDialog( false );
};
function updateVisibility( value ) {
const nextValues = {
public: {
status: visibility === 'private' ? 'draft' : status,
password: '',
},
private: { status: 'private', password: '' },
password: {
status: visibility === 'private' ? 'draft' : status,
password: password || '',
},
};

const setPasswordProtected = () => {
editPost( {
status: visibility === 'private' ? 'draft' : status,
password: password || '',
} );
setHasPassword( true );
};
editPost( nextValues[ value ] );
setHasPassword( value === 'password' );
}

const updatePassword = ( value ) => {
editPost( { password: value } );
Expand All @@ -82,33 +66,13 @@ export default function PostVisibility( { onClose } ) {
help={ __( 'Control how this post is viewed.' ) }
onClose={ onClose }
/>
<fieldset className="editor-post-visibility__fieldset">
<VisuallyHidden as="legend">
{ __( 'Visibility' ) }
</VisuallyHidden>
<PostVisibilityChoice
instanceId={ instanceId }
value="public"
label={ visibilityOptions.public.label }
info={ visibilityOptions.public.info }
checked={ visibility === 'public' && ! hasPassword }
onChange={ setPublic }
/>
<PostVisibilityChoice
instanceId={ instanceId }
value="private"
label={ visibilityOptions.private.label }
info={ visibilityOptions.private.info }
checked={ visibility === 'private' }
onChange={ setPrivate }
/>
<PostVisibilityChoice
instanceId={ instanceId }
value="password"
label={ visibilityOptions.password.label }
info={ visibilityOptions.password.info }
checked={ hasPassword }
onChange={ setPasswordProtected }
<VStack spacing={ 4 }>
<RadioControl
label={ __( 'Visibility' ) }
hideLabelFromVision
options={ VISIBILITY_OPTIONS }
selected={ hasPassword ? 'password' : visibility }
onChange={ updateVisibility }
/>
{ hasPassword && (
<TextControl
Expand All @@ -123,44 +87,7 @@ export default function PostVisibility( { onClose } ) {
maxLength={ 255 }
/>
) }
</fieldset>
<ConfirmDialog
isOpen={ showPrivateConfirmDialog }
onConfirm={ confirmPrivate }
onCancel={ handleDialogCancel }
confirmButtonText={ __( 'Publish' ) }
size="medium"
>
{ __( 'Would you like to privately publish this post now?' ) }
</ConfirmDialog>
</div>
);
}

function PostVisibilityChoice( { instanceId, value, label, info, ...props } ) {
return (
<div className="editor-post-visibility__choice">
<input
type="radio"
name={ `editor-post-visibility__setting-${ instanceId }` }
value={ value }
id={ `editor-post-${ value }-${ instanceId }` }
aria-describedby={ `editor-post-${ value }-${ instanceId }-description` }
className="editor-post-visibility__radio"
{ ...props }
/>
<label
htmlFor={ `editor-post-${ value }-${ instanceId }` }
className="editor-post-visibility__label"
>
{ label }
</label>
<p
id={ `editor-post-${ value }-${ instanceId }-description` }
className="editor-post-visibility__info"
>
{ info }
</p>
</VStack>
</div>
);
}
11 changes: 7 additions & 4 deletions packages/editor/src/components/post-visibility/label.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
import { visibilityOptions } from './utils';
import { VISIBILITY_OPTIONS } from './utils';
import { store as editorStore } from '../../store';

/**
Expand All @@ -24,8 +24,11 @@ export default function PostVisibilityLabel() {
* @return {string} Post visibility label.
*/
export function usePostVisibilityLabel() {
const visibility = useSelect( ( select ) =>
select( editorStore ).getEditedPostVisibility()
const visibility = useSelect(
( select ) => select( editorStore ).getEditedPostVisibility(),
[]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question: why adding the dependencies empty array?

Copy link
Member Author

@Mamaduka Mamaduka Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a best practice. useSelect is similar to useEffect, dependencies need to be provided and empty array means same thing. In this case, only re-select values when component mounts or store updates.

);
return visibilityOptions[ visibility ]?.label;

return VISIBILITY_OPTIONS.find( ( option ) => option.value === visibility )
?.label;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question: is find() more expensive than the previous implementation that was simpler because the options object had keys?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to change visibilityOptions from an object into an array for RadioControl. There should be no noticeable difference here.

}
21 changes: 0 additions & 21 deletions packages/editor/src/components/post-visibility/style.scss

This file was deleted.

19 changes: 11 additions & 8 deletions packages/editor/src/components/post-visibility/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
*/
import { __ } from '@wordpress/i18n';

export const visibilityOptions = {
public: {
export const VISIBILITY_OPTIONS = [
{
label: __( 'Public' ),
info: __( 'Visible to everyone.' ),
value: 'public',
description: __( 'Visible to everyone.' ),
},
private: {
{
label: __( 'Private' ),
info: __( 'Only visible to site admins and editors.' ),
value: 'private',
description: __( 'Only visible to site admins and editors.' ),
},
password: {
{
label: __( 'Password protected' ),
info: __( 'Only visible to those who know the password.' ),
value: 'password',
description: __( 'Only visible to those who know the password.' ),
},
};
];
1 change: 0 additions & 1 deletion packages/editor/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
@import "./components/post-text-editor/style.scss";
@import "./components/post-title/style.scss";
@import "./components/post-url/style.scss";
@import "./components/post-visibility/style.scss";
@import "./components/posts-per-page/style.scss";
@import "./components/post-trash/style.scss";
@import "./components/preview-dropdown/style.scss";
Expand Down
Loading