Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataViews: API for layout density support #66837

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 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
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 @@ -28,7 +28,6 @@ type DataViewsContextType< Item > = {
getItemId: ( item: Item ) => string;
onClickItem: ( item: Item ) => void;
isItemClickable: ( item: Item ) => boolean;
density: number;
};

const DataViewsContext = createContext< DataViewsContextType< any > >( {
Expand All @@ -47,7 +46,6 @@ const DataViewsContext = createContext< DataViewsContextType< any > >( {
getItemId: ( item ) => item.id,
onClickItem: () => {},
isItemClickable: () => false,
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,
onClickItem,
isItemClickable,
} = useContext( DataViewsContext );
Expand All @@ -49,7 +48,6 @@ export default function DataViewsLayout() {
onClickItem={ onClickItem }
isItemClickable={ isItemClickable }
view={ view }
density={ density }
/>
);
}
74 changes: 48 additions & 26 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,9 @@ import {
getVisibleFieldIds,
getHiddenFieldIds,
} from '../../dataviews-layouts';
import type { SupportedLayouts, View, Field } from '../../types';
import type { Density, 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 +237,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 || 'medium' }
onChange={ ( value ) => {
onChangeView( {
...view,
density: value as Density,
} );
} }
isBlock
>
<ToggleGroupControlOption
key="comfortable"
value="comfortable"
label={ _x(
'Comfortable',
'Density option for DataView layout'
) }
/>
<ToggleGroupControlOption
key="medium"
value="medium"
label={ _x( 'Medium', 'Density option for DataView layout' ) }
/>
<ToggleGroupControlOption
key="compact"
value="compact"
label={ _x( 'Compact', 'Density option for DataView layout' ) }
/>
</ToggleGroupControl>
);
}

interface FieldItemProps {
id: any;
label: string;
Expand Down Expand Up @@ -512,19 +554,11 @@ 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'
);

return (
<Dropdown
popoverProps={ {
Expand All @@ -551,12 +585,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 +599,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 @@ -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;
Expand Down Expand Up @@ -119,7 +118,6 @@ export default function DataViews< Item >( {
getItemId,
isItemClickable,
onClickItem,
density,
} }
>
<div className="dataviews-wrapper">
Expand Down Expand Up @@ -151,8 +149,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.

6 changes: 2 additions & 4 deletions packages/dataviews/src/dataviews-layouts/grid/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 && (
Expand Down
1 change: 0 additions & 1 deletion packages/dataviews/src/dataviews-layouts/grid/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
40 changes: 40 additions & 0 deletions packages/dataviews/src/dataviews-layouts/grid/use-grid-style.ts
Original file line number Diff line number Diff line change
@@ -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,
ntsekouras marked this conversation as resolved.
Show resolved Hide resolved
// 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))`,
};
}
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,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This could also be an array of supported presets.

Copy link
Member

Choose a reason for hiding this comment

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

We already have some hardcode logic in the view config that is layout specific. Note how the arrows to "move fields right/left" only show up in the table layout is active but not in any other layout:

Screenshot 2024-11-13 at 10 52 14

This is hardcoded logic we should aim to remove. The view config components should be layout agnostic, otherwise, we cannot open it to 3rd party layouts.

Connecting that thought with what you're doing here, it may be a good time to design this API to "declare features supported by the layout" instead of making it specific to density. For example, using supports: [ 'layout' ] or supports: { layout: true } instead of supportsDensity: true.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree and was something I had in mind to do (your suggestion) if we had another case in the future. Since we have, I'll do it now. Thanks!

},
{
type: LAYOUT_LIST,
Expand Down
Loading
Loading