Skip to content

Commit

Permalink
DataViews: API for layout density support
Browse files Browse the repository at this point in the history
  • Loading branch information
ntsekouras committed Nov 7, 2024
1 parent ab6e729 commit af17dba
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function UnconnectedToggleGroupControl(
const [ controlElement, setControlElement ] = useState< HTMLElement >();
const refs = useMergeRefs( [ setControlElement, forwardedRef ] );
const selectedRect = useTrackElementOffsetRect(
value ? selectedElement : undefined
value || value === 0 ? selectedElement : undefined
);
useAnimatedOffsetRect( controlElement, selectedRect, {
prefix: 'selected',
Expand Down
2 changes: 0 additions & 2 deletions packages/dataviews/src/components/dataviews-context/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ type DataViewsContextType< Item > = {
openedFilter: string | null;
setOpenedFilter: ( openedFilter: string | null ) => void;
getItemId: ( item: Item ) => string;
density: number;
};

const DataViewsContext = createContext< DataViewsContextType< any > >( {
Expand All @@ -43,7 +42,6 @@ const DataViewsContext = createContext< DataViewsContextType< any > >( {
setOpenedFilter: () => {},
openedFilter: null,
getItemId: ( item ) => item.id,
density: 0,
} );

export default DataViewsContext;
2 changes: 0 additions & 2 deletions packages/dataviews/src/components/dataviews-layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export default function DataViewsLayout() {
selection,
onChangeSelection,
setOpenedFilter,
density,
} = useContext( DataViewsContext );

const ViewComponent = VIEW_LAYOUTS.find( ( v ) => v.type === view.type )
Expand All @@ -45,7 +44,6 @@ export default function DataViewsLayout() {
selection={ selection }
setOpenedFilter={ setOpenedFilter }
view={ view }
density={ density }
/>
);
}
72 changes: 48 additions & 24 deletions packages/dataviews/src/components/dataviews-view-config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import { useInstanceId } from '@wordpress/compose';
*/
import {
SORTING_DIRECTIONS,
LAYOUT_GRID,
LAYOUT_TABLE,
sortIcons,
sortLabels,
Expand All @@ -46,10 +45,10 @@ import {
getVisibleFieldIds,
getHiddenFieldIds,
} from '../../dataviews-layouts';
import { DensityOptions } from '../../types';
import type { SupportedLayouts, View, Field } from '../../types';
import DataViewsContext from '../dataviews-context';
import { unlock } from '../../lock-unlock';
import DensityPicker from '../../dataviews-layouts/grid/density-picker';

const { Menu } = unlock( componentsPrivateApis );

Expand Down Expand Up @@ -239,6 +238,50 @@ function ItemsPerPageControl() {
);
}

function DensityPicker() {
const { view, onChangeView } = useContext( DataViewsContext );
if (
! VIEW_LAYOUTS.find( ( layout ) => layout.type === view.type )
?.supportsDensity
) {
return null;
}
return (
<ToggleGroupControl
__nextHasNoMarginBottom
size="__unstable-large"
label={ __( 'Density' ) }
value={ view.density || DensityOptions.medium }
onChange={ ( value ) => {
onChangeView( {
...view,
density: value as DensityOptions,
} );
} }
isBlock
>
<ToggleGroupControlOption
key="comfortable"
value={ DensityOptions.comfortable }
label={ _x(
'Comfortable',
'Density option for DataView layout'
) }
/>
<ToggleGroupControlOption
key="medium"
value={ DensityOptions.medium }
label={ _x( 'Medium', 'Density option for DataView layout' ) }
/>
<ToggleGroupControlOption
key="compact"
value={ DensityOptions.compact }
label={ _x( 'Compact', 'Density option for DataView layout' ) }
/>
</ToggleGroupControl>
);
}

interface FieldItemProps {
id: any;
label: string;
Expand Down Expand Up @@ -512,14 +555,7 @@ function SettingsSection( {
);
}

function DataviewsViewConfigDropdown( {
density,
setDensity,
}: {
density: number;
setDensity: React.Dispatch< React.SetStateAction< number > >;
} ) {
const { view } = useContext( DataViewsContext );
function DataviewsViewConfigDropdown() {
const popoverId = useInstanceId(
_DataViewsViewConfig,
'dataviews-view-config-dropdown'
Expand Down Expand Up @@ -551,12 +587,7 @@ function DataviewsViewConfigDropdown( {
<SortFieldControl />
<SortDirectionControl />
</HStack>
{ view.type === LAYOUT_GRID && (
<DensityPicker
density={ density }
setDensity={ setDensity }
/>
) }
<DensityPicker />
<ItemsPerPageControl />
</SettingsSection>
<SettingsSection title={ __( 'Properties' ) }>
Expand All @@ -570,21 +601,14 @@ function DataviewsViewConfigDropdown( {
}

function _DataViewsViewConfig( {
density,
setDensity,
defaultLayouts = { list: {}, grid: {}, table: {} },
}: {
density: number;
setDensity: React.Dispatch< React.SetStateAction< number > >;
defaultLayouts?: SupportedLayouts;
} ) {
return (
<>
<ViewTypeMenu defaultLayouts={ defaultLayouts } />
<DataviewsViewConfigDropdown
density={ density }
setDensity={ setDensity }
/>
<DataviewsViewConfigDropdown />
</>
);
}
Expand Down
4 changes: 0 additions & 4 deletions packages/dataviews/src/components/dataviews/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,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;
Expand Down Expand Up @@ -110,7 +109,6 @@ export default function DataViews< Item >( {
openedFilter,
setOpenedFilter,
getItemId,
density,
} }
>
<div className="dataviews-wrapper">
Expand Down Expand Up @@ -142,8 +140,6 @@ export default function DataViews< Item >( {
>
<DataViewsViewConfig
defaultLayouts={ defaultLayouts }
density={ density }
setDensity={ setDensity }
/>
{ header }
</HStack>
Expand Down
102 changes: 0 additions & 102 deletions packages/dataviews/src/dataviews-layouts/grid/density-picker.tsx

This file was deleted.

22 changes: 18 additions & 4 deletions packages/dataviews/src/dataviews-layouts/grid/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import { __ } from '@wordpress/i18n';
import ItemActions from '../../components/dataviews-item-actions';
import SingleSelectionCheckbox from '../../components/dataviews-selection-checkbox';
import { useHasAPossibleBulkAction } from '../../components/dataviews-bulk-actions';
import { DensityOptions } from '../../types';
import type { Action, NormalizedField, ViewGridProps } from '../../types';
import type { SetSelection } from '../../private-types';
import useDensityOptions from './use-density-options';

interface GridItemProps< Item > {
selection: string[];
Expand Down Expand Up @@ -172,7 +174,6 @@ export default function ViewGrid< Item >( {
onChangeSelection,
selection,
view,
density,
}: ViewGridProps< Item > ) {
const mediaField = fields.find(
( field ) => field.id === view.layout?.mediaField
Expand Down Expand Up @@ -203,9 +204,22 @@ export default function ViewGrid< Item >( {
{ visibleFields: [], badgeFields: [] }
);
const hasData = !! data?.length;
const gridStyle = density
? { gridTemplateColumns: `repeat(${ density }, minmax(0, 1fr))` }
: {};
// The `DensityOptions.medium` (default) is handled with css. If another density is selected,
// we query the viewport to determine the number of columns to display per option.
const densityOptions = useDensityOptions();
const gridStyle =
!! view.density &&
[ DensityOptions.comfortable, DensityOptions.compact ].includes(
view.density as DensityOptions
)
? {
gridTemplateColumns: `repeat(${
view.density === DensityOptions.compact
? densityOptions.max
: densityOptions.min
}, minmax(0, 1fr))`,
}
: {};
return (
<>
{ hasData && (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* WordPress dependencies
*/
import { useViewportMatch } from '@wordpress/compose';

export default function useDensityOptions() {
const isXHuge = useViewportMatch( 'xhuge' );
const isHuge = useViewportMatch( 'huge' );
const isXlarge = useViewportMatch( 'xlarge' );
const isLarge = useViewportMatch( 'large' );
if ( isXHuge ) {
return { min: 3, max: 6 };
}
if ( isHuge ) {
return { min: 2, max: 4 };
}
if ( isXlarge ) {
return { min: 2, max: 3 };
}
if ( isLarge ) {
return { min: 1, max: 2 };
}
// Default to mobile.
return { min: 1, max: 2 };
}
1 change: 1 addition & 0 deletions packages/dataviews/src/dataviews-layouts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const VIEW_LAYOUTS = [
label: __( 'Grid' ),
component: ViewGrid,
icon: category,
supportsDensity: true,
},
{
type: LAYOUT_LIST,
Expand Down
Loading

0 comments on commit af17dba

Please sign in to comment.