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

[XGrid] Add ability to disable reorder on some columns #2085

Merged
merged 15 commits into from
Jul 21, 2021
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 @@ -286,7 +286,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 @@ -295,8 +301,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);
Copy link
Member

Choose a reason for hiding this comment

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

For another PR:

This cursorMoveDirectionX is wrong. It's always "right" the first time. We need to save the cursor position when the user starts dragging

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(
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved
(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 @@ -149,8 +149,8 @@ export function useGridColumns(apiRef: GridApiRef, { columns }: { columns: GridC
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 @@ -143,6 +143,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