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
3 changes: 2 additions & 1 deletion packages/dataviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ Array of operations that can be performed upon each record. Each action is an ob
- `isLoading`: whether the data is loading. `false` by default.
- `supportedLayouts`: array of layouts supported. By default, all are: `table`, `grid`, `list`.
- `deferredRendering`: whether the items should be rendered asynchronously. Useful when there's a field that takes a lot of time (e.g.: previews). `false` by default.
- `onSelectionChange`: callback that returns the selected items. So far, only the `list` view implements this.
- `onSelectionChange`: callback that signals the user selected one of more items, and takes them as parameter. So far, only the `list` view implements it.
- `onDetailsChange`: callback that signals the user triggered the details for one of more items, and takes them as paremeter. So far, only the `list` view implements it.
Copy link
Copy Markdown
Contributor

@youknowriad youknowriad Jan 9, 2024

Choose a reason for hiding this comment

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

I think there's a world where this is the same as onSelectionChange in other words, when a single item is selected in list view we navigate to "details" and vice versa

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's possible, indeed. The way it works now is optimized for being a listing: you navigate through the items, preview them, and can manage them. There's also the multi-selection use case for bulk editing that needs to be accommodated.


## Contributing to this package

Expand Down
5 changes: 4 additions & 1 deletion packages/dataviews/src/dataviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Search from './search';
import { VIEW_LAYOUTS } from './constants';

const defaultGetItemId = ( item ) => item.id;
const defaultOnSelectionChange = () => {};

export default function DataViews( {
view,
Expand All @@ -30,7 +31,8 @@ export default function DataViews( {
isLoading = false,
paginationInfo,
supportedLayouts,
onSelectionChange,
onSelectionChange = defaultOnSelectionChange,
onDetailsChange = null,
deferredRendering = false,
} ) {
const [ selection, setSelection ] = useState( [] );
Expand Down Expand Up @@ -89,6 +91,7 @@ export default function DataViews( {
getItemId={ getItemId }
isLoading={ isLoading }
onSelectionChange={ onSetSelection }
onDetailsChange={ onDetailsChange }
selection={ selection }
deferredRendering={ deferredRendering }
/>
Expand Down
97 changes: 75 additions & 22 deletions packages/dataviews/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -223,27 +223,69 @@

.dataviews-view-list {
margin: 0;
padding: $grid-unit-10;

li {
border-bottom: $border-width solid $gray-100;
margin: 0;
&:first-child {
border-top: $border-width solid $gray-100;

.dataviews-view-list__item-wrapper {
position: relative;
padding-right: $grid-unit-30;
border-radius: $grid-unit-05;

&::after {
position: absolute;
content: "";
top: 100%;
left: $grid-unit-30;
right: $grid-unit-30;
background: $gray-100;
height: 1px;
}
}
&:last-child {
border-bottom: 0;

&:not(.is-selected):hover {
color: var(--wp-admin-theme-color);

.dataviews-view-list__fields {
color: var(--wp-admin-theme-color);
}
}
}

.dataviews-view-list__item {
padding: $grid-unit-15 $grid-unit-40;
cursor: default;
&:focus,
&:hover {
background-color: lighten($gray-100, 3%);
li.is-selected,
li.is-selected:focus-within {
.dataviews-view-list__item-wrapper {
background-color: var(--wp-admin-theme-color);
color: $white;

.dataviews-view-list__fields,
.components-button {
color: $white;
}

&::after {
background: transparent;
}
}
}

.dataviews-view-list__item {
padding: $grid-unit-15 0 $grid-unit-15 $grid-unit-30;
width: 100%;
cursor: pointer;
&:focus {
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
&::before {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This pseudo-element serves to visualize the focus ring as it was part of the parent node (.dataviews-list-view__wrapper). See conversation.

position: absolute;
content: "";
top: -1px;
right: -1px;
bottom: -1px;
left: -1px;
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
z-index: -1;
border-radius: $grid-unit-05;
}
}
h3 {
overflow: hidden;
Expand All @@ -252,22 +294,12 @@
}
}

.dataviews-view-list__item-selected,
.dataviews-view-list__item-selected:hover {
background-color: $gray-100;

&:focus {
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
}
}

.dataviews-view-list__media-wrapper {
min-width: $grid-unit-40;
height: $grid-unit-40;
border-radius: $grid-unit-05;
overflow: hidden;
position: relative;
margin-top: $grid-unit-05;

&::after {
content: "";
Expand Down Expand Up @@ -301,6 +333,27 @@
}
}
}

.dataviews-view-list__details-button {
align-self: center;
opacity: 0;
}

li.is-selected,
li:hover,
li:focus-within {
.dataviews-view-list__details-button {
opacity: 1;
}
}

li.is-selected {
.dataviews-view-list__details-button {
&:focus {
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) currentColor;
}
}
}
}

.dataviews-action-modal {
Expand Down
62 changes: 38 additions & 24 deletions packages/dataviews/src/view-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ import { useAsyncList } from '@wordpress/compose';
import {
__experimentalHStack as HStack,
__experimentalVStack as VStack,
Button,
} from '@wordpress/components';
import { ENTER, SPACE } from '@wordpress/keycodes';
import { info } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';

export default function ViewList( {
view,
fields,
data,
getItemId,
onSelectionChange,
onDetailsChange,
selection,
deferredRendering,
} ) {
Expand Down Expand Up @@ -49,28 +53,27 @@ export default function ViewList( {
<ul className="dataviews-view-list">
{ usedData.map( ( item ) => {
return (
<li key={ getItemId( item ) }>
<div
role="button"
tabIndex={ 0 }
aria-pressed={ selection.includes( item.id ) }
onKeyDown={ onEnter( item ) }
className={ classNames(
'dataviews-view-list__item',
{
'dataviews-view-list__item-selected':
selection.includes( item.id ),
}
) }
onClick={ () => onSelectionChange( [ item ] ) }
>
<HStack spacing={ 3 } alignment="flex-start">
<div className="dataviews-view-list__media-wrapper">
{ mediaField?.render( { item } ) || (
<div className="dataviews-view-list__media-placeholder"></div>
) }
</div>
<HStack>
<li
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The changes here are to accommodate the two buttons as siblings. This is what we want:

<ul>
  <li>
    <div role="button">...</div> <!-- CONTENTS -->
    <button /> <!-- DETAILS BUTTON -->
  </li>
</ul>

Then, in CSS, we make it look like the first button (contents) wraps the second in situations such as focus. See accessibility conversation.

key={ getItemId( item ) }
className={ classNames( {
'is-selected': selection.includes( item.id ),
} ) }
>
<HStack className="dataviews-view-list__item-wrapper">
<div
role="button"
tabIndex={ 0 }
aria-pressed={ selection.includes( item.id ) }
onKeyDown={ onEnter( item ) }
className="dataviews-view-list__item"
onClick={ () => onSelectionChange( [ item ] ) }
>
<HStack spacing={ 3 } justify="start">
<div className="dataviews-view-list__media-wrapper">
{ mediaField?.render( { item } ) || (
<div className="dataviews-view-list__media-placeholder"></div>
) }
</div>
<VStack spacing={ 1 }>
{ primaryField?.render( { item } ) }
<div className="dataviews-view-list__fields">
Expand All @@ -89,8 +92,19 @@ export default function ViewList( {
</div>
</VStack>
</HStack>
</HStack>
</div>
</div>
{ onDetailsChange && (
<Button
className="dataviews-view-list__details-button"
onClick={ () =>
onDetailsChange( [ item ] )
}
icon={ info }
label={ __( 'View details' ) }
size="compact"
/>
) }
</HStack>
</li>
);
} ) }
Expand Down
2 changes: 1 addition & 1 deletion packages/edit-site/src/components/page-main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function PageMain() {
) : (
<PagePatterns />
);
} else if ( window?.__experimentalAdminViews && path === '/pages' ) {
} else if ( window?.__experimentalAdminViews && path === '/page' ) {
return <PagePages />;
}

Expand Down
31 changes: 18 additions & 13 deletions packages/edit-site/src/components/page-pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import { ENTER, SPACE } from '@wordpress/keycodes';
*/
import Page from '../page';
import Link from '../routes/link';
import { default as DEFAULT_VIEWS } from '../sidebar-dataviews/default-views';
import {
DEFAULT_VIEWS,
DEFAULT_CONFIG_PER_VIEW_TYPE,
} from '../sidebar-dataviews/default-views';
import {
ENUMERATION_TYPE,
LAYOUT_GRID,
Expand All @@ -44,17 +47,6 @@ import { unlock } from '../../lock-unlock';
const { useLocation, useHistory } = unlock( routerPrivateApis );

const EMPTY_ARRAY = [];
const defaultConfigPerViewType = {
[ LAYOUT_TABLE ]: {},
[ LAYOUT_GRID ]: {
mediaField: 'featured-image',
primaryField: 'title',
},
[ LAYOUT_LIST ]: {
primaryField: 'title',
mediaField: 'featured-image',
},
};

function useView( type ) {
const {
Expand Down Expand Up @@ -138,6 +130,18 @@ export default function PagePages() {
[ setPageId ]
);

const onDetailsChange = useCallback(
( items ) => {
if ( !! postType && items?.length === 1 ) {
history.push( {
postId: items[ 0 ].id,
postType,
} );
}
},
[ history, postType ]
);

const queryArgs = useMemo( () => {
const filters = {};
view.filters.forEach( ( filter ) => {
Expand Down Expand Up @@ -309,7 +313,7 @@ export default function PagePages() {
newView = {
...newView,
layout: {
...defaultConfigPerViewType[ newView.type ],
...DEFAULT_CONFIG_PER_VIEW_TYPE[ newView.type ],
},
};
}
Expand Down Expand Up @@ -339,6 +343,7 @@ export default function PagePages() {
view={ view }
onChangeView={ onChangeView }
onSelectionChange={ onSelectionChange }
onDetailsChange={ onDetailsChange }
/>
</Page>
{ view.type === LAYOUT_LIST && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
* Internal dependencies
*/
import SidebarNavigationItem from '../sidebar-navigation-item';
import DEFAULT_VIEWS from './default-views';
import { DEFAULT_VIEWS } from './default-views';
import { unlock } from '../../lock-unlock';

const { useHistory, useLocation } = unlock( routerPrivateApis );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,27 @@ import { trash } from '@wordpress/icons';
/**
* Internal dependencies
*/
import { LAYOUT_TABLE, OPERATOR_IN } from '../../utils/constants';
import {
LAYOUT_LIST,
LAYOUT_TABLE,
LAYOUT_GRID,
OPERATOR_IN,
} from '../../utils/constants';

export const DEFAULT_CONFIG_PER_VIEW_TYPE = {
Copy link
Copy Markdown
Member Author

@oandregal oandregal Jan 9, 2024

Choose a reason for hiding this comment

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

This was moved from page-pages/index.js to initialize the DEFAULT_VIEWS with the layout data, which was not being initialized. It wasn't an issue until now because the table doesn't have any layout data, but the list does.

[ LAYOUT_TABLE ]: {},
[ LAYOUT_GRID ]: {
mediaField: 'featured-image',
primaryField: 'title',
},
[ LAYOUT_LIST ]: {
primaryField: 'title',
mediaField: 'featured-image',
},
};

const DEFAULT_PAGE_BASE = {
type: LAYOUT_TABLE,
type: LAYOUT_LIST,
search: '',
filters: [],
page: 1,
Expand All @@ -22,10 +39,12 @@ const DEFAULT_PAGE_BASE = {
// All fields are visible by default, so it's
// better to keep track of the hidden ones.
hiddenFields: [ 'date', 'featured-image' ],
layout: {},
layout: {
...DEFAULT_CONFIG_PER_VIEW_TYPE[ LAYOUT_LIST ],
},
};

const DEFAULT_VIEWS = {
export const DEFAULT_VIEWS = {
page: [
{
title: __( 'All' ),
Expand Down Expand Up @@ -55,5 +74,3 @@ const DEFAULT_VIEWS = {
},
],
};

export default DEFAULT_VIEWS;
Loading