Skip to content

Commit

Permalink
[XGrid] Add ability to disable reorder on some columns (#2085)
Browse files Browse the repository at this point in the history
* [DataGrid] Add ability to disable reorder on some columns

* Write tests

* Run prettier

* Fix

* Fix

* Add doc

* Code review

* Code review

* Fix

* Build doc

* Fix

* Fix

* Code review
  • Loading branch information
flaviendelangle authored Jul 21, 2021
1 parent ee36b05 commit 7e93d3f
Show file tree
Hide file tree
Showing 11 changed files with 290 additions and 46 deletions.
1 change: 1 addition & 0 deletions docs/pages/api-docs/data-grid/grid-col-def.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { GridColDef } from '@material-ui/data-grid';
| <span class="prop-name optional">description<sup><abbr title="optional">?</abbr></sup></span> | <span class="prop-type">string</span> | | The description of the column rendered as tooltip if the column header name is not fully displayed. |
| <span class="prop-name optional">disableColumnMenu<sup><abbr title="optional">?</abbr></sup></span> | <span class="prop-type">boolean</span> | <span class="prop-default">false<br /></span> | If `true`, the column menu is disabled for this column. |
| <span class="prop-name optional">disableExport<sup><abbr title="optional">?</abbr></sup></span> | <span class="prop-type">boolean</span> | <span class="prop-default">false<br /></span> | If `true`, this column will not be included in exports. |
| <span class="prop-name optional">disableReorder<sup><abbr title="optional">?</abbr></sup></span> | <span class="prop-type">boolean</span> | <span class="prop-default">false<br /></span> | If `true`, this column cannot be reordered. |
| <span class="prop-name optional">editable<sup><abbr title="optional">?</abbr></sup></span> | <span class="prop-type">boolean</span> | <span class="prop-default">false<br /></span> | If `true`, the cells of the column are editable. |
| <span class="prop-name">field</span> | <span class="prop-type">string</span> | | The column identifier. It's used to map with GridRowData values. |
| <span class="prop-name optional">filterOperators<sup><abbr title="optional">?</abbr></sup></span> | <span class="prop-type">GridFilterOperator[]</span> | | Allows setting the filter operators for this column. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as React from 'react';
import { XGrid } from '@material-ui/x-grid';

const rows = [
{
id: 1,
username: '@MaterialUI',
age: 20,
},
];

export default function ColumnOrderingDisabledGrid() {
return (
<div style={{ height: 250, width: '100%' }}>
<XGrid
columns={[
{ field: 'id' },
{ field: 'username' },
{ field: 'age', disableReorder: true },
]}
rows={rows}
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as React from 'react';
import { XGrid } from '@material-ui/x-grid';

const rows = [
{
id: 1,
username: '@MaterialUI',
age: 20,
},
];

export default function ColumnOrderingDisabledGrid() {
return (
<div style={{ height: 250, width: '100%' }}>
<XGrid
columns={[
{ field: 'id' },
{ field: 'username' },
{ field: 'age', disableReorder: true },
]}
rows={rows}
/>
</div>
);
}
10 changes: 7 additions & 3 deletions docs/src/pages/components/data-grid/columns/columns.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,13 @@ To disable the column selector, set the prop `disableColumnSelector={true}`.

By default, `XGrid` allows all column reordering by dragging the header cells and moving them left or right.

To disable column reordering, set the prop `disableColumnReorder={true}`.
{{"demo": "pages/components/data-grid/columns/ColumnOrderingGrid.js", "disableAd": true, "bg": "inline"}}

To disable reordering on all columns, set the prop `disableColumnReorder={true}`.

To disable reordering in a specific column, set the `disableReorder` property to true in the `GridColDef` of the respective column.

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

In addition, column reordering emits the following events that can be imported:

Expand All @@ -307,8 +313,6 @@ In addition, column reordering emits the following events that can be imported:
- `columnHeaderDragOver`: emitted when dragging a header cell over another header cell.
- `columnHeaderDragEnd`: emitted when dragging of a header cell stops.

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

## 🚧 Column groups

> ⚠️ This feature isn't implemented yet. It's coming.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export function GridColumnHeaderItem(props: GridColumnHeaderItemProps) {
>
<div
className="MuiDataGrid-columnHeaderDraggableContainer"
draggable={!disableColumnReorder}
draggable={!disableColumnReorder && !column.disableReorder}
{...draggableEventHandlers}
>
<div className="MuiDataGrid-columnHeaderTitleContainer">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const useGridColumnReorder = (apiRef: GridApiRef): void => {
const logger = useLogger('useGridColumnReorder');

const [, setGridState, forceUpdate] = useGridState(apiRef);
const dragCol = useGridSelector(apiRef, gridColumnReorderDragColSelector);
const dragColField = useGridSelector(apiRef, gridColumnReorderDragColSelector);
const options = useGridSelector(apiRef, optionsSelector);
const dragColNode = React.useRef<HTMLElement | null>(null);
const cursorPosition = React.useRef<CursorCoordinates>({
Expand All @@ -60,7 +60,7 @@ export const useGridColumnReorder = (apiRef: GridApiRef): void => {

const handleColumnHeaderDragStart = React.useCallback(
(params: GridColumnHeaderParams, event: React.MouseEvent<HTMLElement>) => {
if (options.disableColumnReorder) {
if (options.disableColumnReorder || params.colDef.disableReorder) {
return;
}

Expand Down Expand Up @@ -93,7 +93,7 @@ export const useGridColumnReorder = (apiRef: GridApiRef): void => {

const handleDragOver = React.useCallback(
(params: GridColumnHeaderParams | GridCellParams, event: React.DragEvent) => {
if (!dragCol) {
if (!dragColField) {
return;
}

Expand All @@ -103,32 +103,38 @@ export const useGridColumnReorder = (apiRef: GridApiRef): void => {
const coordinates = { x: event.clientX, y: event.clientY };

if (
params.field !== dragCol &&
params.field !== dragColField &&
hasCursorPositionChanged(cursorPosition.current, coordinates)
) {
const targetColIndex = apiRef.current.getColumnIndex(params.field, false);
const dragColIndex = apiRef.current.getColumnIndex(dragCol, false);

if (
(getCursorMoveDirectionX(cursorPosition.current, coordinates) ===
CURSOR_MOVE_DIRECTION_RIGHT &&
dragColIndex < targetColIndex) ||
(getCursorMoveDirectionX(cursorPosition.current, coordinates) ===
CURSOR_MOVE_DIRECTION_LEFT &&
targetColIndex < dragColIndex)
) {
apiRef.current.setColumnIndex(dragCol, targetColIndex);
const targetColVisibleIndex = apiRef.current.getColumnIndex(params.field, true);
const targetCol = apiRef.current.getColumn(params.field);
const dragColIndex = apiRef.current.getColumnIndex(dragColField, false);
const visibleColumnAmount = apiRef.current.getVisibleColumns().length;

const canBeReordered =
!targetCol.disableReorder ||
(targetColVisibleIndex > 0 && targetColVisibleIndex < visibleColumnAmount - 1);

const cursorMoveDirectionX = getCursorMoveDirectionX(cursorPosition.current, coordinates);
const hasMovedLeft =
cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_LEFT && targetColIndex < dragColIndex;
const hasMovedRight =
cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_RIGHT && dragColIndex < targetColIndex;

if (canBeReordered && (hasMovedLeft || hasMovedRight)) {
apiRef.current.setColumnIndex(dragColField, targetColIndex);
}

cursorPosition.current = coordinates;
}
},
[apiRef, dragCol, logger],
[apiRef, dragColField, logger],
);

const handleDragEnd = React.useCallback(
(params: GridColumnHeaderParams | GridCellParams, event: React.DragEvent): void => {
if (options.disableColumnReorder) {
if (options.disableColumnReorder || !dragColField) {
return;
}

Expand All @@ -150,7 +156,7 @@ export const useGridColumnReorder = (apiRef: GridApiRef): void => {
}));
forceUpdate();
},
[options.disableColumnReorder, logger, setGridState, forceUpdate, apiRef],
[options.disableColumnReorder, logger, setGridState, forceUpdate, apiRef, dragColField],
);

useGridApiEventHandler(apiRef, GRID_COLUMN_HEADER_DRAG_START, handleColumnHeaderDragStart);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ export function useGridColumns(
const getVisibleColumns = React.useCallback(() => visibleColumns, [visibleColumns]);
const getColumnsMeta: () => GridColumnsMeta = React.useCallback(() => columnsMeta, [columnsMeta]);

const getColumnIndex: (field: string, useVisibleColumns?: boolean) => number = React.useCallback(
(field, useVisibleColumns = true) =>
const getColumnIndex = React.useCallback(
(field: string, useVisibleColumns: boolean = true): number =>
useVisibleColumns
? visibleColumns.findIndex((col) => col.field === field)
: allColumns.findIndex((col) => col.field === field),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const gridCheckboxSelectionColDef: GridColDef = {
sortable: false,
filterable: false,
disableColumnMenu: true,
disableReorder: true,
valueGetter: (params) => {
const selectionLookup = selectedIdsLookupSelector(params.api.getState());
return selectionLookup[params.id] !== undefined;
Expand Down
5 changes: 5 additions & 0 deletions packages/grid/_modules_/grid/models/colDef/gridColDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ export interface GridColDef {
* Allows setting the filter operators for this column.
*/
filterOperators?: GridFilterOperator[];
/**
* If `true`, this column cannot be reordered.
* @default false
*/
disableReorder?: boolean;
/**
* If `true`, this column will not be included in exports.
* @default false
Expand Down
Loading

0 comments on commit 7e93d3f

Please sign in to comment.