diff --git a/packages/dataviews/src/components/dataviews/index.tsx b/packages/dataviews/src/components/dataviews/index.tsx index 8b862228c34fda..45044a3c8d4a2d 100644 --- a/packages/dataviews/src/components/dataviews/index.tsx +++ b/packages/dataviews/src/components/dataviews/index.tsx @@ -23,9 +23,16 @@ import DataViewsFooter from '../dataviews-footer'; import DataViewsSearch from '../dataviews-search'; import DataViewsViewConfig from '../dataviews-view-config'; import { normalizeFields } from '../../normalize-fields'; -import type { Action, Field, View, SupportedLayouts } from '../../types'; +import type { + Action, + Field, + View, + SupportedLayouts, + ActionContext, +} from '../../types'; import type { SelectionOrUpdater } from '../../private-types'; import { __ } from '@wordpress/i18n'; +import { pin } from '@wordpress/icons'; type ItemWithId = { id: string }; @@ -140,35 +147,40 @@ export default function DataViews< Item >( { ( callback: ( items: Item[], context: any ) => void ) => { return [ { - id: 'pin', - label: __( 'Pin' ), - callback: ( items: Item[], context: any ) => { - items.forEach( ( item ) => - onPinItem( getItemId( item ) ) - ); - callback( items, context ); + id: 'togglePin', + label: ( items: Item[] ) => { + const itemId = getItemId( items[ 0 ] ); + return combinedPinnedItems.includes( itemId ) + ? __( 'Unpin' ) + : __( 'Pin' ); }, - }, - { - id: 'unpin', - label: __( 'Unpin' ), - callback: ( items: Item[], context: any ) => { - items.forEach( ( item ) => - onUnpinItem( getItemId( item ) ) - ); + isPrimary: true, + icon: pin, + callback: ( + items: Item[], + context: ActionContext< Item > + ) => { + items.forEach( ( item ) => { + const itemId = getItemId( item ); + if ( combinedPinnedItems.includes( itemId ) ) { + onUnpinItem( itemId ); + } else { + onPinItem( itemId ); + } + } ); callback( items, context ); }, }, ]; }, - [ getItemId, onPinItem, onUnpinItem ] + [ getItemId, onPinItem, onUnpinItem, combinedPinnedItems ] ); const actionsWithDefaultActions = useMemo( () => { const defaultActions = createDefaultActions( ( items, context ) => context.onActionPerformed?.( items ) ); - return [ ...defaultActions, ...actions ]; + return [ ...defaultActions, ...actions ]; // Combine default and custom actions }, [ actions, createDefaultActions ] ); return ( diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts index 0887bea0681d34..5231032bb93390 100644 --- a/packages/dataviews/src/types.ts +++ b/packages/dataviews/src/types.ts @@ -472,17 +472,16 @@ export interface ActionModal< Item > extends ActionBase< Item > { modalHeader?: string; } +export interface ActionContext< Item > { + registry: any; + onActionPerformed?: ( items: Item[] ) => void; +} + export interface ActionButton< Item > extends ActionBase< Item > { /** * The callback to execute when the action is triggered. */ - callback: ( - items: Item[], - context: { - registry: any; - onActionPerformed?: ( items: Item[] ) => void; - } - ) => void; + callback: ( items: Item[], context: ActionContext< Item > ) => void; } export type Action< Item > = ActionModal< Item > | ActionButton< Item >;