Skip to content

Commit

Permalink
DataViews: Add grid keyboard navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
ntsekouras committed Dec 22, 2024
1 parent 52a8062 commit 4453d8e
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export function useHasAPossibleBulkAction< Item >(
item: Item
) {
return useMemo( () => {
return actions.some( ( action ) => {
return actions?.some( ( action ) => {
return (
action.supportsBulk &&
( ! action.isEligible || action.isEligible( item ) )
Expand Down
105 changes: 73 additions & 32 deletions packages/dataviews/src/dataviews-layouts/grid/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Spinner,
Flex,
FlexItem,
Composite,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
Expand Down Expand Up @@ -56,6 +57,14 @@ interface GridItemProps< Item > {
hasBulkActions: boolean;
}

function chunk( array: any, size: any ) {
const chunks = [];
for ( let i = 0, j = array.length; i < j; i += size ) {
chunks.push( array.slice( i, i + size ) );
}
return chunks;
}

function GridItem< Item >( {
view,
selection,
Expand Down Expand Up @@ -120,6 +129,7 @@ function GridItem< Item >( {
<VStack
spacing={ 0 }
key={ id }
role="gridcell"
className={ clsx( 'dataviews-view-grid__card', {
'is-selected': hasBulkAction && isSelected,
} ) }
Expand Down Expand Up @@ -270,44 +280,75 @@ export default function ViewGrid< Item >( {
const updatedPreviewSize = useUpdatedPreviewSizeOnViewportChange();
const hasBulkActions = useSomeItemHasAPossibleBulkAction( actions, data );
const usedPreviewSize = updatedPreviewSize || view.layout?.previewSize;
const gridStyle = usedPreviewSize
? {
gridTemplateColumns: `repeat(${ usedPreviewSize }, minmax(0, 1fr))`,
}
: {};
return (
<>
{ hasData && (
<Grid
gap={ 8 }
columns={ 2 }
alignment="top"
<Composite
role="grid"
className="dataviews-view-grid"
style={ gridStyle }
focusLoop
focusWrap
aria-busy={ isLoading }
>
{ data.map( ( item ) => {
return (
<GridItem
key={ getItemId( item ) }
view={ view }
selection={ selection }
onChangeSelection={ onChangeSelection }
onClickItem={ onClickItem }
isItemClickable={ isItemClickable }
getItemId={ getItemId }
item={ item }
actions={ actions }
mediaField={ mediaField }
titleField={ titleField }
descriptionField={ descriptionField }
regularFields={ regularFields }
badgeFields={ badgeFields }
hasBulkActions={ hasBulkActions }
/>
);
} ) }
</Grid>
<VStack spacing={ 8 }>
{ chunk( data, usedPreviewSize ).map( ( row, i ) => (
<Composite.Row
key={ i }
role="row"
className="dataviews-view-grid__row"
>
<Grid columns={ usedPreviewSize } gap={ 8 }>
{ row.map( ( item: any ) => (
<Composite.Item
key={ getItemId( item ) }
render={
<div
id={ getItemId( item ) }
className="dataviews-view-grid__row__gridcell"
>
<GridItem
view={ view }
selection={ selection }
onChangeSelection={
onChangeSelection
}
onClickItem={
onClickItem
}
isItemClickable={
isItemClickable
}
getItemId={ getItemId }
item={ item }
actions={ actions }
mediaField={
mediaField
}
titleField={
titleField
}
descriptionField={
descriptionField
}
regularFields={
regularFields
}
badgeFields={
badgeFields
}
hasBulkActions={
hasBulkActions
}
/>
</div>
}
/>
) ) }
</Grid>
</Composite.Row>
) ) }
</VStack>
</Composite>
) }
{ ! hasData && (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ export function useUpdatedPreviewSizeOnViewportChange() {
const viewport = useViewPortBreakpoint();
return useMemo( () => {
const previewSize = view.layout?.previewSize;
let newPreviewSize;
if ( ! previewSize ) {
return;
// For mobile, we want the `min` value as the default.
const breakValueProp = viewport === 'mobile' ? 'min' : 'default';
return viewportBreaks[ viewport ][ breakValueProp ];
}
let newPreviewSize;
const breakValues = viewportBreaks[ viewport ];
if ( previewSize < breakValues.min ) {
newPreviewSize = breakValues.min;
Expand Down
41 changes: 23 additions & 18 deletions packages/dataviews/src/dataviews-layouts/grid/style.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.dataviews-view-grid {
display: flex;
align-items: flex-start;
justify-content: center;
margin-bottom: auto;
grid-template-rows: max-content;
padding: 0 $grid-unit-60 $grid-unit-30;
transition: padding ease-out 0.1s;
container-type: inline-size;
Expand Down Expand Up @@ -116,27 +118,10 @@
}

.dataviews-view-grid.dataviews-view-grid {
/**
* Breakpoints were adjusted from media queries breakpoints to account for
* the sidebar width. This was done to match the existing styles we had.
*/
@container (max-width: 480px) {
grid-template-columns: repeat(1, minmax(0, 1fr));
padding-left: $grid-unit-30;
padding-right: $grid-unit-30;
}
@container (min-width: 480px) {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@container (min-width: 780px) {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
@container (min-width: 1140px) {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
@container (min-width: 1520px) {
grid-template-columns: repeat(5, minmax(0, 1fr));
}
}

.dataviews-view-grid__field-value:empty,
Expand All @@ -160,3 +145,23 @@
.dataviews-view-grid__media--clickable {
cursor: pointer;
}


.dataviews-view-grid__row {
.dataviews-view-grid__row__gridcell {
outline: 0;
outline-style: solid;
// outline-offset: calc(-1 * var(--wp-admin-border-width-focus));
border-radius: $grid-unit-10;

&[data-focus-visible] {
outline-color: var(--wp-admin-theme-color);
outline-width: var(--wp-admin-border-width-focus);
}

&:hover {
outline-color: rgba($black, 0.3);
outline-width: var(--wp-admin-border-width-focus);
}
}
}

0 comments on commit 4453d8e

Please sign in to comment.