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

[DataGrid] Add fluid columns width support #480

Merged
merged 25 commits into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b2392dd
[DataGrid] Add fluid columns width support
DanailH Oct 21, 2020
e54cb9a
Fix doc formatting
DanailH Oct 21, 2020
c77a475
Fix documentation so that it is complient to the MUI documentation st…
DanailH Oct 22, 2020
756932d
Add unit tests
DanailH Oct 26, 2020
2d23e7d
Update packages/grid/_modules_/grid/hooks/root/useColumns.ts
DanailH Oct 27, 2020
6cdced3
Update packages/grid/_modules_/grid/models/colDef/colDef.ts
DanailH Oct 27, 2020
b6cf786
Merge branch 'feature/DataGrid-347-columns-fluid-width' of github.com…
DanailH Oct 27, 2020
12fa1fa
Fix PR comments
DanailH Oct 27, 2020
3b1d8c3
Rebase from upstream master
DanailH Oct 28, 2020
9b042c6
Fix unit tests
DanailH Oct 28, 2020
e92df89
Resolve TS issues
DanailH Oct 28, 2020
ff5e963
Add // @ts-expect-error need to migrate helpers to TypeScript before …
DanailH Oct 28, 2020
5805baa
Add storybook examples
DanailH Oct 30, 2020
6e5401c
Update docs/src/pages/components/data-grid/columns/columns.md
DanailH Nov 2, 2020
bf768d3
Update docs/src/pages/components/data-grid/columns/columns.md
DanailH Nov 2, 2020
94404aa
Update docs/src/pages/components/data-grid/columns/columns.md
DanailH Nov 2, 2020
4c6a988
Update docs/src/pages/components/data-grid/columns/columns.md
DanailH Nov 2, 2020
04f336a
Update docs/src/pages/components/data-grid/columns/columns.md
DanailH Nov 2, 2020
b358751
Update packages/grid/data-grid/src/DataGrid.test.tsx
DanailH Nov 2, 2020
2219564
Fix storybook flex col width examples
DanailH Nov 2, 2020
401b7ed
rerun ci
oliviertassinari Nov 2, 2020
2bd46a0
Fix formatting
DanailH Nov 2, 2020
28baf68
Merge branch 'feature/DataGrid-347-columns-fluid-width' of github.com…
DanailH Nov 2, 2020
9672852
Update docs/src/pages/components/data-grid/columns/columns.md
mbrookes Nov 2, 2020
d300dfe
Trigger CI
DanailH Nov 3, 2020
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as React from 'react';
import { DataGrid } from '@material-ui/data-grid';

const rows = [
{
id: 1,
username: 'defunkt',
age: 38,
},
];

export default function ColumnFluidWidthGrid() {
return (
<div style={{ height: 250, width: '100%' }}>
<DataGrid
columns={[
{
field: 'id',
flex: 1,
},
{
field: 'username',
width: 300,
},
{
field: 'age',
flex: 0.2,
},
]}
rows={rows}
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as React from 'react';
import { DataGrid } from '@material-ui/data-grid';

const rows = [
{
id: 1,
username: 'defunkt',
age: 38,
},
];

export default function ColumnFluidWidthGrid() {
return (
<div style={{ height: 250, width: '100%' }}>
<DataGrid
columns={[
{
field: 'id',
flex: 1,
},
{
field: 'username',
width: 200,
},
{
field: 'age',
flex: 0.3,
},
]}
rows={rows}
/>
</div>
);
}
20 changes: 20 additions & 0 deletions docs/src/pages/components/data-grid/columns/columns.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ To change the width of a column, use the `width` property available in `ColDef`.

{{"demo": "pages/components/data-grid/columns/ColumnWidthGrid.js", "bg": "inline"}}

## Column fluid width
DanailH marked this conversation as resolved.
Show resolved Hide resolved

By default each column have a fixed width of 100 pixels but we can have fluid (responsive) columns by setting the `flex` propery avaibale in the `ColDef`.
DanailH marked this conversation as resolved.
Show resolved Hide resolved

The `flex` propery accepts values between 0 and 1.

The `flex` property works by dividing the remaining space in the grid among all flex columns in proportion to their `flex` value. For example, a grid with a total width of 500px that has three columns: the first with width: 200; the second with flex: 1; and third with flex: 0.5. The first column will be 200px wide, leaving 300px remaining. The column with flex: 1 has twice the size with flex: 0.5 which means that final sizes will be: 200px, 200px, 100px.
DanailH marked this conversation as resolved.
Show resolved Hide resolved

The `flex` configuration does not work together with the `width` configuration. If you set both the `flex` and `width` inside the `ColDef` of column the `flex` will overwrite the `width`.
DanailH marked this conversation as resolved.
Show resolved Hide resolved

The `flex` configuration does not work if the combined width of the columns that have `width` is more that the width of the grid itself. If that is the case a scroll bar will be visible and the columns that hava `flex` will default back to their base value of 100 pixels.
DanailH marked this conversation as resolved.
Show resolved Hide resolved

{{"demo": "pages/components/data-grid/columns/ColumnFluidWidthGrid.js", "bg": "inline"}}

<!--
DanailH marked this conversation as resolved.
Show resolved Hide resolved
- https://ag-grid.com/javascript-grid-resizing/#column-flex
- https://www.telerik.com/kendo-react-ui/components/grid/columns/width/
- https://react-table-omega.vercel.app/docs/api/useFlexLayout
-->

## Column resizing [<span role="img" title="Enterprise">⚡️</span>](https://material-ui.com/store/items/material-ui-x/)

By default, `XGrid` allows all columns to be resized by dragging the right portion of the column separator.
Expand Down
7 changes: 6 additions & 1 deletion packages/grid/_modules_/grid/GridComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ export const GridComponent = React.forwardRef<HTMLDivElement, GridComponentProps
}, [apiRef, props.error]);

useEvents(rootContainerRef, internalOptions, apiRef);
const internalColumns = useColumns(internalOptions, props.columns, apiRef);
const internalColumns = useColumns(
internalOptions,
props.columns,
rootContainerRef.current?.clientWidth,
apiRef,
);
const internalRows = useRows(internalOptions, props.rows, initialised, apiRef);
useKeyboard(internalOptions, initialised, apiRef);
useSelection(internalOptions, props.rows, initialised, apiRef);
Expand Down
54 changes: 51 additions & 3 deletions packages/grid/_modules_/grid/hooks/root/useColumns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,45 @@ const initialState: InternalColumns = {
meta: { positions: [], totalWidth: 0 },
};

function mapColumns(
columns: Columns,
columnTypes: ColumnTypesRecord,
containerWidth: number,
): Columns {
let extendedColumns = columns.map((c) => ({ ...getColDef(columnTypes, c.type), ...c }));
const numberOfFluidColumns = columns.filter((column) => !!column.flex).length;
let flexDivider = 0;

if (numberOfFluidColumns && containerWidth) {
extendedColumns.forEach((column) => {
if (!column.flex) {
containerWidth -= column.width!;
} else {
flexDivider += column.flex;
}
});
}

if (containerWidth > 0 && numberOfFluidColumns) {
const flexMultiplier = Math.floor(containerWidth / flexDivider);
DanailH marked this conversation as resolved.
Show resolved Hide resolved
extendedColumns = extendedColumns.map((c) => {
DanailH marked this conversation as resolved.
Show resolved Hide resolved
return { ...c, width: c.flex! ? Math.floor(flexMultiplier * c.flex!) : c.width };
});
}

return extendedColumns;
}

function hydrateColumns(
columns: Columns,
columnTypes: ColumnTypesRecord,
containerWidth: number,
withCheckboxSelection: boolean,
logger: Logger,
apiRef: ApiRef,
): Columns {
logger.debug('Hydrating Columns with default definitions');
let mappedCols = columns.map((c) => ({ ...getColDef(columnTypes, c.type), ...c }));
let mappedCols = mapColumns(columns, columnTypes, containerWidth);
if (withCheckboxSelection) {
mappedCols = [checkboxSelectionColDef, ...mappedCols];
}
Expand Down Expand Up @@ -91,6 +121,7 @@ function toMeta(logger: Logger, visibleColumns: Columns): ColumnsMeta {
const resetState = (
columns: Columns,
columnTypes: ColumnTypesRecord,
containerWidth: number,
withCheckboxSelection: boolean,
logger: Logger,
apiRef: ApiRef,
Expand All @@ -99,7 +130,14 @@ const resetState = (
return initialState;
}

const all = hydrateColumns(columns, columnTypes, withCheckboxSelection, logger, apiRef);
const all = hydrateColumns(
columns,
columnTypes,
containerWidth,
withCheckboxSelection,
logger,
apiRef,
);
const visible = filterVisible(logger, all);
const meta = toMeta(logger, visible);
const lookup = toLookup(logger, all);
Expand Down Expand Up @@ -149,6 +187,7 @@ const getUpdatedColumnState = (
export function useColumns(
options: GridOptions,
columns: Columns,
containerWidth: number = 0,
apiRef: ApiRef,
): InternalColumns {
const logger = useLogger('useColumns');
Expand Down Expand Up @@ -176,12 +215,21 @@ export function useColumns(
const newState = resetState(
columns,
options.columnTypes,
containerWidth,
!!options.checkboxSelection,
logger,
apiRef,
);
updateState(newState);
}, [columns, options.columnTypes, options.checkboxSelection, logger, apiRef, updateState]);
}, [
columns,
options.columnTypes,
containerWidth,
options.checkboxSelection,
logger,
apiRef,
updateState,
]);

const getColumnFromField: (field: string) => ColDef = React.useCallback(
(field) => stateRef.current.lookup[field],
Expand Down
4 changes: 4 additions & 0 deletions packages/grid/_modules_/grid/models/colDef/colDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export interface ColDef {
* @default 100
*/
width?: number;
/**
* If set it idicates that a column has fluid width. Range [0 - 1].
DanailH marked this conversation as resolved.
Show resolved Hide resolved
*/
flex?: number;
/**
* If `true`, hide the column.
* @default false;
Expand Down