@wordpress/editor
Version:
Enhanced block editor for WordPress posts.
173 lines (163 loc) • 4.51 kB
JavaScript
/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { useState, useMemo } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import {
privateApis as componentsPrivateApis,
Button,
Modal,
} from '@wordpress/components';
import { moreVertical } from '@wordpress/icons';
import { store as coreStore } from '@wordpress/core-data';
/**
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';
import { usePostActions } from './actions';
const { DropdownMenuV2, kebabCase } = unlock( componentsPrivateApis );
export default function PostActions( { postType, postId, onActionPerformed } ) {
const [ isActionsMenuOpen, setIsActionsMenuOpen ] = useState( false );
const { item, permissions } = useSelect(
( select ) => {
const { getEditedEntityRecord, getEntityRecordPermissions } =
unlock( select( coreStore ) );
return {
item: getEditedEntityRecord( 'postType', postType, postId ),
permissions: getEntityRecordPermissions(
'postType',
postType,
postId
),
};
},
[ postId, postType ]
);
const itemWithPermissions = useMemo( () => {
return {
...item,
permissions,
};
}, [ item, permissions ] );
const allActions = usePostActions( { postType, onActionPerformed } );
const actions = useMemo( () => {
return allActions.filter( ( action ) => {
return (
! action.isEligible || action.isEligible( itemWithPermissions )
);
} );
}, [ allActions, itemWithPermissions ] );
return (
<DropdownMenuV2
open={ isActionsMenuOpen }
trigger={
<Button
size="small"
icon={ moreVertical }
label={ __( 'Actions' ) }
disabled={ ! actions.length }
accessibleWhenDisabled
className="editor-all-actions-button"
onClick={ () =>
setIsActionsMenuOpen( ! isActionsMenuOpen )
}
/>
}
onOpenChange={ setIsActionsMenuOpen }
placement="bottom-end"
>
<ActionsDropdownMenuGroup
actions={ actions }
item={ itemWithPermissions }
onClose={ () => {
setIsActionsMenuOpen( false );
} }
/>
</DropdownMenuV2>
);
}
// From now on all the functions on this file are copied as from the dataviews packages,
// The editor packages should not be using the dataviews packages directly,
// and the dataviews package should not be using the editor packages directly,
// so duplicating the code here seems like the least bad option.
// Copied as is from packages/dataviews/src/item-actions.js
function DropdownMenuItemTrigger( { action, onClick, items } ) {
const label =
typeof action.label === 'string' ? action.label : action.label( items );
return (
<DropdownMenuV2.Item
onClick={ onClick }
hideOnClick={ ! action.RenderModal }
>
<DropdownMenuV2.ItemLabel>{ label }</DropdownMenuV2.ItemLabel>
</DropdownMenuV2.Item>
);
}
// Copied as is from packages/dataviews/src/item-actions.js
// With an added onClose prop.
function ActionWithModal( { action, item, ActionTrigger, onClose } ) {
const [ isModalOpen, setIsModalOpen ] = useState( false );
const actionTriggerProps = {
action,
onClick: () => setIsModalOpen( true ),
items: [ item ],
};
const { RenderModal, hideModalHeader } = action;
return (
<>
<ActionTrigger { ...actionTriggerProps } />
{ isModalOpen && (
<Modal
title={ action.modalHeader || action.label }
__experimentalHideHeader={ !! hideModalHeader }
onRequestClose={ () => {
setIsModalOpen( false );
} }
overlayClassName={ `editor-action-modal editor-action-modal__${ kebabCase(
action.id
) }` }
focusOnMount="firstContentElement"
size="small"
>
<RenderModal
items={ [ item ] }
closeModal={ () => {
setIsModalOpen( false );
onClose();
} }
/>
</Modal>
) }
</>
);
}
// Copied as is from packages/dataviews/src/item-actions.js
// With an added onClose prop.
function ActionsDropdownMenuGroup( { actions, item, onClose } ) {
return (
<DropdownMenuV2.Group>
{ actions.map( ( action ) => {
if ( action.RenderModal ) {
return (
<ActionWithModal
key={ action.id }
action={ action }
item={ item }
ActionTrigger={ DropdownMenuItemTrigger }
onClose={ onClose }
/>
);
}
return (
<DropdownMenuItemTrigger
key={ action.id }
action={ action }
onClick={ () => action.callback( [ item ] ) }
items={ [ item ] }
/>
);
} ) }
</DropdownMenuV2.Group>
);
}