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: Add density option to table layout #67170

Merged
merged 7 commits into from
Nov 25, 2024
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
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 }
/>
);
}
30 changes: 7 additions & 23 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,
Copy link
Member

Choose a reason for hiding this comment

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

This is an improvement: we have only the LAYOUT_TABLE dependency here. 🎉

LAYOUT_TABLE,
sortIcons,
sortLabels,
Expand All @@ -49,7 +48,6 @@ import {
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 @@ -512,19 +510,15 @@ function SettingsSection( {
);
}

function DataviewsViewConfigDropdown( {
density,
setDensity,
}: {
density: number;
setDensity: React.Dispatch< React.SetStateAction< number > >;
} ) {
function DataviewsViewConfigDropdown() {
const { view } = useContext( DataViewsContext );
const popoverId = useInstanceId(
_DataViewsViewConfig,
'dataviews-view-config-dropdown'
);

const activeLayout = VIEW_LAYOUTS.find(
( layout ) => layout.type === view.type
);
return (
<Dropdown
popoverProps={ {
Expand All @@ -551,11 +545,8 @@ function DataviewsViewConfigDropdown( {
<SortFieldControl />
<SortDirectionControl />
</HStack>
{ view.type === LAYOUT_GRID && (
<DensityPicker
density={ density }
setDensity={ setDensity }
/>
{ !! activeLayout?.viewConfigOptions && (
<activeLayout.viewConfigOptions />
) }
<ItemsPerPageControl />
</SettingsSection>
Expand All @@ -570,21 +561,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 }
ntsekouras marked this conversation as resolved.
Show resolved Hide resolved
/>
{ header }
</HStack>
Expand Down
10 changes: 7 additions & 3 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 { useUpdatedPreviewSizeOnViewportChange } from './preview-size-picker';

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,8 +223,12 @@ export default function ViewGrid< Item >( {
{ visibleFields: [], badgeFields: [] }
);
const hasData = !! data?.length;
const gridStyle = density
? { gridTemplateColumns: `repeat(${ density }, minmax(0, 1fr))` }
const updatedPreviewSize = useUpdatedPreviewSizeOnViewportChange();
const usedPreviewSize = updatedPreviewSize || view.layout?.previewSize;
const gridStyle = usedPreviewSize
? {
gridTemplateColumns: `repeat(${ usedPreviewSize }, minmax(0, 1fr))`,
}
: {};
return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
import { RangeControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useViewportMatch } from '@wordpress/compose';
import { useEffect, useMemo } from '@wordpress/element';
import { useMemo, useContext } from '@wordpress/element';

/**
* Internal dependencies
*/
import DataViewsContext from '../../components/dataviews-context';
import type { ViewGrid } from '../../types';

const viewportBreaks = {
xhuge: { min: 3, max: 6, default: 5 },
Expand Down Expand Up @@ -39,31 +45,32 @@ function useViewPortBreakpoint() {
return null;
}

export default function DensityPicker( {
density,
setDensity,
}: {
density: number;
setDensity: React.Dispatch< React.SetStateAction< number > >;
} ) {
export function useUpdatedPreviewSizeOnViewportChange() {
const viewport = useViewPortBreakpoint();
const view = useContext( DataViewsContext ).view as ViewGrid;
return useMemo( () => {
const previewSize = view.layout?.previewSize;
let newPreviewSize;
if ( ! viewport || ! previewSize ) {
return;
}
const breakValues = viewportBreaks[ viewport ];
if ( previewSize < breakValues.min ) {
newPreviewSize = breakValues.min;
}
if ( previewSize > breakValues.max ) {
newPreviewSize = breakValues.max;
}
ntsekouras marked this conversation as resolved.
Show resolved Hide resolved
return newPreviewSize;
}, [ viewport, view ] );
}

export default function PreviewSizePicker() {
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 context = useContext( DataViewsContext );
const view = context.view as ViewGrid;
const breakValues = viewportBreaks[ viewport || 'mobile' ];
const densityToUse = density || breakValues.default;
const previewSizeToUse = view.layout?.previewSize || breakValues.default;

const marks = useMemo(
() =>
Expand All @@ -88,13 +95,19 @@ export default function DensityPicker( {
__next40pxDefaultSize
showTooltip={ false }
label={ __( 'Preview size' ) }
value={ breakValues.max + breakValues.min - densityToUse }
value={ breakValues.max + breakValues.min - previewSizeToUse }
marks={ marks }
min={ breakValues.min }
max={ breakValues.max }
withInputField={ false }
onChange={ ( value = 0 ) => {
setDensity( breakValues.max + breakValues.min - value );
context.onChangeView( {
...view,
layout: {
...view.layout,
previewSize: breakValues.max + breakValues.min - value,
},
} );
} }
step={ 1 }
/>
Expand Down
4 changes: 4 additions & 0 deletions packages/dataviews/src/dataviews-layouts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,23 @@ import ViewGrid from './grid';
import ViewList from './list';
import { LAYOUT_GRID, LAYOUT_LIST, LAYOUT_TABLE } from '../constants';
import type { View, Field } from '../types';
import PreviewSizePicker from './grid/preview-size-picker';
import DensityPicker from './table/density-picker';

export const VIEW_LAYOUTS = [
{
type: LAYOUT_TABLE,
label: __( 'Table' ),
component: ViewTable,
icon: blockTable,
viewConfigOptions: DensityPicker,
},
{
type: LAYOUT_GRID,
label: __( 'Grid' ),
component: ViewGrid,
icon: category,
viewConfigOptions: PreviewSizePicker,
},
{
type: LAYOUT_LIST,
Expand Down
57 changes: 57 additions & 0 deletions packages/dataviews/src/dataviews-layouts/table/density-picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* WordPress dependencies
*/
import {
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';
import { useContext } from '@wordpress/element';

/**
* Internal dependencies
*/
import DataViewsContext from '../../components/dataviews-context';
import type { ViewTable, Density } from '../../types';

export default function DensityPicker() {
const context = useContext( DataViewsContext );
const view = context.view as ViewTable;
return (
<ToggleGroupControl
__nextHasNoMarginBottom
size="__unstable-large"
label={ __( 'Density' ) }
value={ view.layout?.density || 'balanced' }
onChange={ ( value ) => {
context.onChangeView( {
...view,
layout: {
...view.layout,
density: value as Density,
},
} );
} }
isBlock
>
<ToggleGroupControlOption
key="comfortable"
value="comfortable"
label={ _x(
'Comfortable',
'Density option for DataView layout'
) }
/>
<ToggleGroupControlOption
key="balanced"
value="balanced"
label={ _x( 'Balanced', 'Density option for DataView layout' ) }
/>
<ToggleGroupControlOption
key="compact"
value="compact"
label={ _x( 'Compact', 'Density option for DataView layout' ) }
/>
</ToggleGroupControl>
);
}
8 changes: 7 additions & 1 deletion packages/dataviews/src/dataviews-layouts/table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,13 @@ function ViewTable< Item >( {
return (
<>
<table
className="dataviews-view-table"
className={ clsx( 'dataviews-view-table', {
[ `has-${ view.layout?.density }-density` ]:
view.layout?.density &&
[ 'compact', 'comfortable' ].includes(
view.layout.density
),
} ) }
aria-busy={ isLoading }
aria-describedby={ tableNoticeId }
>
Expand Down
32 changes: 32 additions & 0 deletions packages/dataviews/src/dataviews-layouts/table/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,38 @@
opacity: 1;
}
}

// Density style overrides.
&.has-compact-density {
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 is where we'll add the density styles.

Choose a reason for hiding this comment

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

This is where we'll add the density styles.

@ntsekourasI was wondering if it’s possible for a density style to include a different type size (within the defined typesscale), or is it limited to just spacing variants like padding?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

include a different type size

You mean font sizes? In general I added these changes as a placeholder and designers will decide how the table should look per density.

thead {
th {
&:has(.dataviews-view-table-header-button):not(:first-child) {
padding-left: 0;
}
}
}
td,
th {
padding: $grid-unit-05 $grid-unit-10;
}
}

&.has-comfortable-density {
td,
th {
padding: $grid-unit-20 $grid-unit-15;
}
}

&.has-compact-density,
&.has-comfortable-density {
td,
th {
&.dataviews-view-table__checkbox-column {
padding-right: 0;
}
}
}
}

/* stylelint-disable-next-line scss/at-rule-no-unknown -- '@container' not globally permitted */
Expand Down
Loading
Loading