Skip to content

Commit

Permalink
DataViews: Refactor to prepare exposing the underlying UI pieces (#63694
Browse files Browse the repository at this point in the history
)

Co-authored-by: youknowriad <[email protected]>
Co-authored-by: jorgefilipecosta <[email protected]>
Co-authored-by: ntsekouras <[email protected]>
  • Loading branch information
4 people authored Jul 19, 2024
1 parent 43569d2 commit 6a2a1db
Show file tree
Hide file tree
Showing 33 changed files with 1,354 additions and 1,291 deletions.
3 changes: 2 additions & 1 deletion packages/base-styles/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ $z-layers: (
".block-editor-template-part__selection-modal": 1000001,
".block-editor-block-rename-modal": 1000001,
".edit-site-list__rename-modal": 1000001,
".dataviews-bulk-actions__modal": 1000001,
".dataviews-action-modal": 1000001,
".editor-action-modal": 1000001,
".editor-post-template__swap-template-modal": 1000001,
Expand Down Expand Up @@ -208,7 +209,7 @@ $z-layers: (
".dataviews-view-table thead": 1,

// Ensure quick actions toolbar appear above pagination
".dataviews-bulk-actions": 2,
".dataviews-bulk-actions-toolbar": 2,
);

@function z-index( $key ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { useCallback, useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import type { Form, Field, NormalizedField } from './types';
import { normalizeFields } from './normalize-fields';
import type { Form, Field, NormalizedField } from '../../types';
import { normalizeFields } from '../../normalize-fields';

type DataFormProps< Item > = {
data: Item;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
__unstableMotion as motion,
__unstableAnimatePresence as AnimatePresence,
} from '@wordpress/components';
import { useMemo, useState, useRef } from '@wordpress/element';
import { useMemo, useState, useRef, useContext } from '@wordpress/element';
import { _n, sprintf, __ } from '@wordpress/i18n';
import { closeSmall } from '@wordpress/icons';
import { useReducedMotion } from '@wordpress/compose';
Expand All @@ -17,10 +17,13 @@ import { useRegistry } from '@wordpress/data';
/**
* Internal dependencies
*/
import { ActionWithModal } from './item-actions';
import type { Action } from './types';
import type { ActionTriggerProps } from './item-actions';
import type { SetSelection } from './private-types';
import { useSomeItemHasAPossibleBulkAction } from '../dataviews-bulk-actions';
import DataViewsContext from '../dataviews-context';
import { ActionWithModal } from '../dataviews-item-actions';
import { LAYOUT_GRID, LAYOUT_TABLE } from '../../constants';
import type { Action } from '../../types';
import type { ActionTriggerProps } from '../dataviews-item-actions';
import type { SetSelection } from '../../private-types';

interface ActionButtonProps< Item > {
action: Action< Item >;
Expand All @@ -36,14 +39,6 @@ interface ToolbarContentProps< Item > {
onChangeSelection: SetSelection;
}

interface BulkActionsToolbarProps< Item > {
data: Item[];
selection: string[];
actions: Action< Item >[];
onChangeSelection: SetSelection;
getItemId: ( item: Item ) => string;
}

const SNACKBAR_VARIANTS = {
init: {
bottom: -48,
Expand Down Expand Up @@ -136,7 +131,7 @@ function renderToolbarContent< Item >(
return (
<>
<ToolbarGroup>
<div className="dataviews-bulk-actions__selection-count">
<div className="dataviews-bulk-actions-toolbar__selection-count">
{ selection.length === 1
? __( '1 item selected' )
: sprintf(
Expand Down Expand Up @@ -214,13 +209,14 @@ function ToolbarContent< Item >( {
return buttons.current;
}

export default function BulkActionsToolbar< Item >( {
data,
selection,
actions = EMPTY_ARRAY,
onChangeSelection,
getItemId,
}: BulkActionsToolbarProps< Item > ) {
function _BulkActionsToolbar() {
const {
data,
selection,
actions = EMPTY_ARRAY,
onChangeSelection,
getItemId,
} = useContext( DataViewsContext );
const isReducedMotion = useReducedMotion();
const selectedItems = useMemo( () => {
return data.filter( ( item ) =>
Expand Down Expand Up @@ -258,10 +254,10 @@ export default function BulkActionsToolbar< Item >( {
animate="open"
exit="exit"
variants={ isReducedMotion ? undefined : SNACKBAR_VARIANTS }
className="dataviews-bulk-actions"
className="dataviews-bulk-actions-toolbar"
>
<Toolbar label={ __( 'Bulk actions' ) }>
<div className="dataviews-bulk-actions-toolbar-wrapper">
<div className="dataviews-bulk-actions-toolbar__wrapper">
<ToolbarContent
selection={ selection }
actionsToShow={ actionsToShow }
Expand All @@ -274,3 +270,19 @@ export default function BulkActionsToolbar< Item >( {
</AnimatePresence>
);
}

export default function BulkActionsToolbar() {
const { data, actions = [], view } = useContext( DataViewsContext );
const hasPossibleBulkAction = useSomeItemHasAPossibleBulkAction(
actions,
data
);
if (
! [ LAYOUT_TABLE, LAYOUT_GRID ].includes( view.type ) ||
! hasPossibleBulkAction
) {
return null;
}

return <_BulkActionsToolbar />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.dataviews-bulk-actions-toolbar {
position: sticky;
display: flex;
flex-direction: column;
align-content: center;
flex-wrap: wrap;
width: fit-content;
margin-left: auto;
margin-right: auto;
bottom: $grid-unit-30;
z-index: z-index(".dataviews-bulk-actions-toolbar");

.components-accessible-toolbar {
border-color: $gray-300;
box-shadow: $shadow-popover;

.components-toolbar-group {
border-color: $gray-200;

&:last-child {
border: 0;
}
}
}

.dataviews-bulk-actions-toolbar__selection-count {
display: flex;
align-items: center;
margin: 0 $grid-unit-10 0 $grid-unit-10;
}
}

.dataviews-bulk-actions-toolbar__wrapper {
display: flex;
flex-grow: 1;
width: 100%;

.components-toolbar-group {
align-items: center;
}

.components-button.is-busy {
max-height: $button-size;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ import {
Modal,
} from '@wordpress/components';
import { __, sprintf, _n } from '@wordpress/i18n';
import { useMemo, useState, useCallback } from '@wordpress/element';
import { useMemo, useState, useCallback, useContext } from '@wordpress/element';
import { useRegistry } from '@wordpress/data';

/**
* Internal dependencies
*/
import { unlock } from './lock-unlock';
import type { Action, ActionModal } from './types';
import type { SetSelection } from './private-types';
import DataViewsContext from '../dataviews-context';
import { LAYOUT_TABLE, LAYOUT_GRID } from '../../constants';
import { unlock } from '../../lock-unlock';
import type { Action, ActionModal } from '../../types';

const {
DropdownMenuV2: DropdownMenu,
Expand Down Expand Up @@ -43,14 +44,6 @@ interface ActionsMenuGroupProps< Item > {
setActionWithModal: ( action?: ActionModal< Item > ) => void;
}

interface BulkActionsProps< Item > {
data: Item[];
actions: Action< Item >[];
selection: string[];
onChangeSelection: SetSelection;
getItemId: ( item: Item ) => string;
}

export function useHasAPossibleBulkAction< Item >(
actions: Action< Item >[],
item: Item
Expand Down Expand Up @@ -105,7 +98,7 @@ function ActionWithModal< Item >( {
title={ ! hideModalHeader ? label : undefined }
__experimentalHideHeader={ !! hideModalHeader }
onRequestClose={ onCloseModal }
overlayClassName="dataviews-action-modal"
overlayClassName="dataviews-bulk-actions__modal"
>
<RenderModal
items={ eligibleItems }
Expand Down Expand Up @@ -180,20 +173,21 @@ function ActionsMenuGroup< Item >( {
);
}

export default function BulkActions< Item >( {
data,
actions,
selection,
onChangeSelection,
getItemId,
}: BulkActionsProps< Item > ) {
function _BulkActions() {
const {
data,
actions = [],
selection,
onChangeSelection,
getItemId,
} = useContext( DataViewsContext );
const bulkActions = useMemo(
() => actions.filter( ( action ) => action.supportsBulk ),
[ actions ]
);
const [ isMenuOpen, onMenuOpenChange ] = useState( false );
const [ actionWithModal, setActionWithModal ] = useState<
ActionModal< Item > | undefined
ActionModal< any > | undefined
>();
const selectableItems = useMemo( () => {
return data.filter( ( item ) => {
Expand Down Expand Up @@ -227,7 +221,7 @@ export default function BulkActions< Item >( {
style={ { minWidth: '240px' } }
trigger={
<Button
className="dataviews-bulk-edit-button"
className="dataviews-bulk-actions__edit-button"
__next40pxDefaultSize
variant="tertiary"
size="compact"
Expand Down Expand Up @@ -288,3 +282,19 @@ export default function BulkActions< Item >( {
</>
);
}

export default function BulkActions() {
const { data, actions = [], view } = useContext( DataViewsContext );
const hasPossibleBulkAction = useSomeItemHasAPossibleBulkAction(
actions,
data
);
if (
! [ LAYOUT_TABLE, LAYOUT_GRID ].includes( view.type ) ||
! hasPossibleBulkAction
) {
return null;
}

return <_BulkActions />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.dataviews-bulk-actions__modal {
z-index: z-index(".dataviews-bulk-actions__modal");
}

.dataviews-bulk-actions__edit-button.components-button {
flex-shrink: 0;
}
47 changes: 47 additions & 0 deletions packages/dataviews/src/components/dataviews-context/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* WordPress dependencies
*/
import { createContext } from '@wordpress/element';

/**
* Internal dependencies
*/
import type { View, Action, NormalizedField } from '../../types';
import type { SetSelection } from '../../private-types';
import { LAYOUT_TABLE } from '../../constants';

type DataViewsContextType< Item > = {
view: View;
onChangeView: ( view: View ) => void;
fields: NormalizedField< Item >[];
actions?: Action< Item >[];
data: Item[];
isLoading?: boolean;
paginationInfo: {
totalItems: number;
totalPages: number;
};
selection: string[];
onChangeSelection: SetSelection;
openedFilter: string | null;
setOpenedFilter: ( openedFilter: string | null ) => void;
getItemId: ( item: Item ) => string;
};

const DataViewsContext = createContext< DataViewsContextType< any > >( {
view: { type: LAYOUT_TABLE },
onChangeView: () => {},
fields: [],
data: [],
paginationInfo: {
totalItems: 0,
totalPages: 0,
},
selection: [],
onChangeSelection: () => {},
setOpenedFilter: () => {},
openedFilter: null,
getItemId: ( item ) => item.id,
} );

export default DataViewsContext;
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import { forwardRef } from '@wordpress/element';
/**
* Internal dependencies
*/
import { unlock } from './lock-unlock';
import type { NormalizedFilter, View } from './types';
import { unlock } from '../../lock-unlock';
import type { NormalizedFilter, View } from '../../types';

const {
DropdownMenuV2: DropdownMenu,
Expand Down Expand Up @@ -46,7 +46,7 @@ function AddFilter(
<Button
accessibleWhenDisabled
size="compact"
className="dataviews-filters-button"
className="dataviews-filters__button"
variant="tertiary"
disabled={ ! inactiveFilters.length }
ref={ ref }
Expand Down
Loading

0 comments on commit 6a2a1db

Please sign in to comment.