@@ -570,21 +599,14 @@ function DataviewsViewConfigDropdown( {
}
function _DataViewsViewConfig( {
- density,
- setDensity,
defaultLayouts = { list: {}, grid: {}, table: {} },
}: {
- density: number;
- setDensity: React.Dispatch< React.SetStateAction< number > >;
defaultLayouts?: SupportedLayouts;
} ) {
return (
<>
-
+
>
);
}
diff --git a/packages/dataviews/src/components/dataviews/index.tsx b/packages/dataviews/src/components/dataviews/index.tsx
index 3e8224e61bc5d..ee6073f40bf3d 100644
--- a/packages/dataviews/src/components/dataviews/index.tsx
+++ b/packages/dataviews/src/components/dataviews/index.tsx
@@ -75,7 +75,6 @@ export default function DataViews< Item >( {
header,
}: DataViewsProps< Item > ) {
const [ selectionState, setSelectionState ] = useState< string[] >( [] );
- const [ density, setDensity ] = useState< number >( 0 );
const isUncontrolled =
selectionProperty === undefined || onChangeSelection === undefined;
const selection = isUncontrolled ? selectionState : selectionProperty;
@@ -119,7 +118,6 @@ export default function DataViews< Item >( {
getItemId,
isItemClickable,
onClickItem,
- density,
} }
>
@@ -151,8 +149,6 @@ export default function DataViews< Item >( {
>
{ header }
diff --git a/packages/dataviews/src/dataviews-layouts/grid/density-picker.tsx b/packages/dataviews/src/dataviews-layouts/grid/density-picker.tsx
deleted file mode 100644
index 34ddf6c3fe52f..0000000000000
--- a/packages/dataviews/src/dataviews-layouts/grid/density-picker.tsx
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * WordPress dependencies
- */
-import { RangeControl } from '@wordpress/components';
-import { __ } from '@wordpress/i18n';
-import { useViewportMatch } from '@wordpress/compose';
-import { useEffect, useMemo } from '@wordpress/element';
-
-const viewportBreaks = {
- xhuge: { min: 3, max: 6, default: 5 },
- huge: { min: 2, max: 4, default: 4 },
- xlarge: { min: 2, max: 3, default: 3 },
- large: { min: 1, max: 2, default: 2 },
- mobile: { min: 1, max: 2, default: 2 },
-};
-
-function useViewPortBreakpoint() {
- const isXHuge = useViewportMatch( 'xhuge', '>=' );
- const isHuge = useViewportMatch( 'huge', '>=' );
- const isXlarge = useViewportMatch( 'xlarge', '>=' );
- const isLarge = useViewportMatch( 'large', '>=' );
- const isMobile = useViewportMatch( 'mobile', '>=' );
-
- if ( isXHuge ) {
- return 'xhuge';
- }
- if ( isHuge ) {
- return 'huge';
- }
- if ( isXlarge ) {
- return 'xlarge';
- }
- if ( isLarge ) {
- return 'large';
- }
- if ( isMobile ) {
- return 'mobile';
- }
- return null;
-}
-
-export default function DensityPicker( {
- density,
- setDensity,
-}: {
- density: number;
- setDensity: React.Dispatch< React.SetStateAction< number > >;
-} ) {
- const viewport = useViewPortBreakpoint();
- useEffect( () => {
- setDensity( ( _density ) => {
- if ( ! viewport || ! _density ) {
- return 0;
- }
- const breakValues = viewportBreaks[ viewport ];
- if ( _density < breakValues.min ) {
- return breakValues.min;
- }
- if ( _density > breakValues.max ) {
- return breakValues.max;
- }
- return _density;
- } );
- }, [ setDensity, viewport ] );
- const breakValues = viewportBreaks[ viewport || 'mobile' ];
- const densityToUse = density || breakValues.default;
-
- const marks = useMemo(
- () =>
- Array.from(
- { length: breakValues.max - breakValues.min + 1 },
- ( _, i ) => {
- return {
- value: breakValues.min + i,
- };
- }
- ),
- [ breakValues ]
- );
-
- if ( ! viewport ) {
- return null;
- }
-
- return (
- {
- setDensity( breakValues.max + breakValues.min - value );
- } }
- step={ 1 }
- />
- );
-}
diff --git a/packages/dataviews/src/dataviews-layouts/grid/index.tsx b/packages/dataviews/src/dataviews-layouts/grid/index.tsx
index e218172b7900a..b1a28694058c9 100644
--- a/packages/dataviews/src/dataviews-layouts/grid/index.tsx
+++ b/packages/dataviews/src/dataviews-layouts/grid/index.tsx
@@ -25,6 +25,7 @@ import { useHasAPossibleBulkAction } from '../../components/dataviews-bulk-actio
import type { Action, NormalizedField, ViewGridProps } from '../../types';
import type { SetSelection } from '../../private-types';
import getClickableItemProps from '../utils/get-clickable-item-props';
+import useGridStyle from './use-grid-style';
interface GridItemProps< Item > {
selection: string[];
@@ -192,7 +193,6 @@ export default function ViewGrid< Item >( {
isItemClickable,
selection,
view,
- density,
}: ViewGridProps< Item > ) {
const mediaField = fields.find(
( field ) => field.id === view.layout?.mediaField
@@ -223,9 +223,7 @@ export default function ViewGrid< Item >( {
{ visibleFields: [], badgeFields: [] }
);
const hasData = !! data?.length;
- const gridStyle = density
- ? { gridTemplateColumns: `repeat(${ density }, minmax(0, 1fr))` }
- : {};
+ const gridStyle = useGridStyle( view );
return (
<>
{ hasData && (
diff --git a/packages/dataviews/src/dataviews-layouts/grid/style.scss b/packages/dataviews/src/dataviews-layouts/grid/style.scss
index f209accc6de15..a428f342bef6e 100644
--- a/packages/dataviews/src/dataviews-layouts/grid/style.scss
+++ b/packages/dataviews/src/dataviews-layouts/grid/style.scss
@@ -40,7 +40,6 @@
.dataviews-view-grid__media {
width: 100%;
- min-height: 200px;
aspect-ratio: 1/1;
background-color: $gray-100;
border-radius: $grid-unit-05;
diff --git a/packages/dataviews/src/dataviews-layouts/grid/use-grid-style.ts b/packages/dataviews/src/dataviews-layouts/grid/use-grid-style.ts
new file mode 100644
index 0000000000000..ea2c0607543b7
--- /dev/null
+++ b/packages/dataviews/src/dataviews-layouts/grid/use-grid-style.ts
@@ -0,0 +1,40 @@
+/**
+ * WordPress dependencies
+ */
+import { useViewportMatch } from '@wordpress/compose';
+
+/**
+ * Internal dependencies
+ */
+import type { Density, ViewGrid } from '../../types';
+
+export default function useGridStyle( view: ViewGrid ) {
+ const isXHuge = useViewportMatch( 'xhuge' );
+ const isHuge = useViewportMatch( 'huge' );
+ const isXlarge = useViewportMatch( 'xlarge' );
+ const isMedium = useViewportMatch( 'small' );
+ // The `balanced` density (default) is handled with css. If another density is selected,
+ // we query the viewport to determine the number of columns to display per option.
+ if ( ! [ 'comfortable', 'compact' ].includes( view.density as Density ) ) {
+ return;
+ }
+
+ let gridColumns;
+ if ( isXHuge ) {
+ gridColumns = { min: 4, max: 6 };
+ } else if ( isHuge ) {
+ gridColumns = { min: 3, max: 5 };
+ } else if ( isXlarge ) {
+ gridColumns = { min: 2, max: 4 };
+ } else if ( isMedium ) {
+ gridColumns = { min: 1, max: 3 };
+ } else {
+ // Default to mobile.
+ gridColumns = { min: 1, max: 2 };
+ }
+ return {
+ gridTemplateColumns: `repeat(${
+ view.density === 'compact' ? gridColumns.max : gridColumns.min
+ }, minmax(0, 1fr))`,
+ };
+}
diff --git a/packages/dataviews/src/dataviews-layouts/index.ts b/packages/dataviews/src/dataviews-layouts/index.ts
index eece17d0f4f10..4a97baacf833c 100644
--- a/packages/dataviews/src/dataviews-layouts/index.ts
+++ b/packages/dataviews/src/dataviews-layouts/index.ts
@@ -30,6 +30,7 @@ export const VIEW_LAYOUTS = [
label: __( 'Grid' ),
component: ViewGrid,
icon: category,
+ supports: { density: true },
},
{
type: LAYOUT_LIST,
diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts
index 71990f72d4eec..efdcee9a530b1 100644
--- a/packages/dataviews/src/types.ts
+++ b/packages/dataviews/src/types.ts
@@ -247,6 +247,8 @@ export interface NormalizedFilter {
isPrimary: boolean;
}
+export type Density = 'compact' | 'balanced' | 'comfortable';
+
interface ViewBase {
/**
* The layout of the view.
@@ -292,6 +294,11 @@ interface ViewBase {
* The fields to render
*/
fields?: string[];
+
+ /**
+ * The density of the view.
+ */
+ density?: Density;
}
export interface CombinedField {
@@ -501,7 +508,6 @@ export interface ViewBaseProps< Item > {
onClickItem: ( item: Item ) => void;
isItemClickable: ( item: Item ) => boolean;
view: View;
- density: number;
}
export interface ViewTableProps< Item > extends ViewBaseProps< Item > {