UNPKG

@mui/x-data-grid-pro

Version:

The Pro plan edition of the MUI X Data Grid components.

258 lines (252 loc) 12.7 kB
"use strict"; 'use client'; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useGridColumnReorder = exports.columnReorderStateInitializer = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses")); var _RtlProvider = require("@mui/system/RtlProvider"); var _xDataGrid = require("@mui/x-data-grid"); var _columnReorderSelector = require("./columnReorderSelector"); const CURSOR_MOVE_DIRECTION_LEFT = 'left'; const CURSOR_MOVE_DIRECTION_RIGHT = 'right'; const getCursorMoveDirectionX = (currentCoordinates, nextCoordinates) => { return currentCoordinates.x <= nextCoordinates.x ? CURSOR_MOVE_DIRECTION_RIGHT : CURSOR_MOVE_DIRECTION_LEFT; }; const hasCursorPositionChanged = (currentCoordinates, nextCoordinates) => currentCoordinates.x !== nextCoordinates.x || currentCoordinates.y !== nextCoordinates.y; const useUtilityClasses = ownerState => { const { classes } = ownerState; const slots = { columnHeaderDragging: ['columnHeader--dragging'] }; return (0, _composeClasses.default)(slots, _xDataGrid.getDataGridUtilityClass, classes); }; const columnReorderStateInitializer = state => (0, _extends2.default)({}, state, { columnReorder: { dragCol: '' } }); /** * @requires useGridColumns (method) */ exports.columnReorderStateInitializer = columnReorderStateInitializer; const useGridColumnReorder = (apiRef, props) => { const logger = (0, _xDataGrid.useGridLogger)(apiRef, 'useGridColumnReorder'); const dragColNode = React.useRef(null); const cursorPosition = React.useRef({ x: 0, y: 0 }); const originColumnIndex = React.useRef(null); const forbiddenIndexes = React.useRef({}); const removeDnDStylesTimeout = React.useRef(undefined); const ownerState = { classes: props.classes }; const classes = useUtilityClasses(ownerState); const isRtl = (0, _RtlProvider.useRtl)(); React.useEffect(() => { return () => { clearTimeout(removeDnDStylesTimeout.current); }; }, []); const handleDragEnd = React.useCallback((params, event) => { const dragColField = (0, _columnReorderSelector.gridColumnReorderDragColSelector)(apiRef); if (props.disableColumnReorder || !dragColField) { return; } logger.debug('End dragging col'); event.preventDefault(); // Prevent drag events propagation. // For more information check here https://github.com/mui/mui-x/issues/2680. event.stopPropagation(); clearTimeout(removeDnDStylesTimeout.current); // For more information check here https://github.com/mui/mui-x/issues/14678 if (dragColNode.current.classList.contains(classes.columnHeaderDragging)) { dragColNode.current.classList.remove(classes.columnHeaderDragging); } dragColNode.current = null; // Check if the column was dropped outside the grid. if (event.dataTransfer.dropEffect === 'none' && !props.keepColumnPositionIfDraggedOutside) { // Accessing params.field may contain the wrong field as header elements are reused apiRef.current.setColumnIndex(dragColField, originColumnIndex.current); originColumnIndex.current = null; } else { // Emit the columnOrderChange event only once when the reordering stops. const columnOrderChangeParams = { column: apiRef.current.getColumn(dragColField), targetIndex: apiRef.current.getColumnIndexRelativeToVisibleColumns(dragColField), oldIndex: originColumnIndex.current }; apiRef.current.publishEvent('columnOrderChange', columnOrderChangeParams); } apiRef.current.setState(state => (0, _extends2.default)({}, state, { columnReorder: (0, _extends2.default)({}, state.columnReorder, { dragCol: '' }) })); }, [apiRef, props.disableColumnReorder, props.keepColumnPositionIfDraggedOutside, logger, classes.columnHeaderDragging]); const handleDragStart = React.useCallback((params, event) => { if (props.disableColumnReorder || params.colDef.disableReorder) { return; } logger.debug(`Start dragging col ${params.field}`); // Prevent drag events propagation. // For more information check here https://github.com/mui/mui-x/issues/2680. event.stopPropagation(); dragColNode.current = event.currentTarget; dragColNode.current.classList.add(classes.columnHeaderDragging); const handleDragEndEvent = dragEndEvent => { dragColNode.current.removeEventListener('dragend', handleDragEndEvent); apiRef.current.publishEvent('columnHeaderDragEndNative', params, dragEndEvent); }; dragColNode.current.addEventListener('dragend', handleDragEndEvent); if (event.dataTransfer) { event.dataTransfer.effectAllowed = 'move'; } apiRef.current.setState(state => (0, _extends2.default)({}, state, { columnReorder: (0, _extends2.default)({}, state.columnReorder, { dragCol: params.field }) })); removeDnDStylesTimeout.current = setTimeout(() => { dragColNode.current.classList.remove(classes.columnHeaderDragging); }); originColumnIndex.current = apiRef.current.getColumnIndex(params.field, false); const draggingColumnGroupPath = apiRef.current.getColumnGroupPath(params.field); const columnIndex = originColumnIndex.current; const allColumns = apiRef.current.getAllColumns(); const groupsLookup = apiRef.current.getAllGroupDetails(); const getGroupPathFromColumnIndex = colIndex => { const field = allColumns[colIndex].field; return apiRef.current.getColumnGroupPath(field); }; // The limitingGroupId is the id of the group from which the dragged column should not escape let limitingGroupId = null; draggingColumnGroupPath.forEach(groupId => { if (!groupsLookup[groupId]?.freeReordering) { // Only consider group that are made of more than one column if (columnIndex > 0 && getGroupPathFromColumnIndex(columnIndex - 1).includes(groupId)) { limitingGroupId = groupId; } else if (columnIndex + 1 < allColumns.length && getGroupPathFromColumnIndex(columnIndex + 1).includes(groupId)) { limitingGroupId = groupId; } } }); forbiddenIndexes.current = {}; for (let indexToForbid = 0; indexToForbid < allColumns.length; indexToForbid += 1) { const leftIndex = indexToForbid <= columnIndex ? indexToForbid - 1 : indexToForbid; const rightIndex = indexToForbid < columnIndex ? indexToForbid : indexToForbid + 1; if (limitingGroupId !== null) { // verify this indexToForbid will be linked to the limiting group. Otherwise forbid it let allowIndex = false; if (leftIndex >= 0 && getGroupPathFromColumnIndex(leftIndex).includes(limitingGroupId)) { allowIndex = true; } else if (rightIndex < allColumns.length && getGroupPathFromColumnIndex(rightIndex).includes(limitingGroupId)) { allowIndex = true; } if (!allowIndex) { forbiddenIndexes.current[indexToForbid] = true; } } // Verify we are not splitting another group if (leftIndex >= 0 && rightIndex < allColumns.length) { getGroupPathFromColumnIndex(rightIndex).forEach(groupId => { if (getGroupPathFromColumnIndex(leftIndex).includes(groupId)) { if (!draggingColumnGroupPath.includes(groupId)) { // moving here split the group groupId in two distincts chunks if (!groupsLookup[groupId]?.freeReordering) { forbiddenIndexes.current[indexToForbid] = true; } } } }); } } }, [props.disableColumnReorder, classes.columnHeaderDragging, logger, apiRef]); const handleDragEnter = React.useCallback((params, event) => { event.preventDefault(); // Prevent drag events propagation. // For more information check here https://github.com/mui/mui-x/issues/2680. event.stopPropagation(); }, []); const handleDragOver = React.useCallback((params, event) => { const dragColField = (0, _columnReorderSelector.gridColumnReorderDragColSelector)(apiRef); if (!dragColField) { return; } logger.debug(`Dragging over col ${params.field}`); event.preventDefault(); // Prevent drag events propagation. // For more information check here https://github.com/mui/mui-x/issues/2680. event.stopPropagation(); const coordinates = { x: event.clientX, y: event.clientY }; if (params.field !== dragColField && hasCursorPositionChanged(cursorPosition.current, coordinates)) { const targetColIndex = apiRef.current.getColumnIndex(params.field, false); const targetColVisibleIndex = apiRef.current.getColumnIndex(params.field, true); const targetCol = apiRef.current.getColumn(params.field); const dragColIndex = apiRef.current.getColumnIndex(dragColField, false); const visibleColumns = apiRef.current.getVisibleColumns(); const allColumns = apiRef.current.getAllColumns(); const cursorMoveDirectionX = getCursorMoveDirectionX(cursorPosition.current, coordinates); const hasMovedLeft = cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_LEFT && (isRtl ? dragColIndex < targetColIndex : targetColIndex < dragColIndex); const hasMovedRight = cursorMoveDirectionX === CURSOR_MOVE_DIRECTION_RIGHT && (isRtl ? targetColIndex < dragColIndex : dragColIndex < targetColIndex); if (hasMovedLeft || hasMovedRight) { let canBeReordered; let indexOffsetInHiddenColumns = 0; if (!targetCol.disableReorder) { canBeReordered = true; } else if (hasMovedLeft) { canBeReordered = targetColVisibleIndex > 0 && !visibleColumns[targetColVisibleIndex - 1].disableReorder; } else { canBeReordered = targetColVisibleIndex < visibleColumns.length - 1 && !visibleColumns[targetColVisibleIndex + 1].disableReorder; } if (forbiddenIndexes.current[targetColIndex]) { let nextVisibleColumnField; let indexWithOffset = targetColIndex + indexOffsetInHiddenColumns; if (hasMovedLeft) { nextVisibleColumnField = targetColVisibleIndex > 0 ? visibleColumns[targetColVisibleIndex - 1].field : null; while (indexWithOffset > 0 && allColumns[indexWithOffset].field !== nextVisibleColumnField && forbiddenIndexes.current[indexWithOffset]) { indexOffsetInHiddenColumns -= 1; indexWithOffset = targetColIndex + indexOffsetInHiddenColumns; } } else { nextVisibleColumnField = targetColVisibleIndex + 1 < visibleColumns.length ? visibleColumns[targetColVisibleIndex + 1].field : null; while (indexWithOffset < allColumns.length - 1 && allColumns[indexWithOffset].field !== nextVisibleColumnField && forbiddenIndexes.current[indexWithOffset]) { indexOffsetInHiddenColumns += 1; indexWithOffset = targetColIndex + indexOffsetInHiddenColumns; } } if (forbiddenIndexes.current[indexWithOffset] || allColumns[indexWithOffset].field === nextVisibleColumnField) { // If we ended up on a visible column, or a forbidden one, we cannot do the reorder canBeReordered = false; } } const canBeReorderedProcessed = apiRef.current.unstable_applyPipeProcessors('canBeReordered', canBeReordered, { targetIndex: targetColVisibleIndex }); if (canBeReorderedProcessed) { apiRef.current.setColumnIndex(dragColField, targetColIndex + indexOffsetInHiddenColumns); } } cursorPosition.current = coordinates; } }, [apiRef, logger, isRtl]); (0, _xDataGrid.useGridEvent)(apiRef, 'columnHeaderDragStart', handleDragStart); (0, _xDataGrid.useGridEvent)(apiRef, 'columnHeaderDragEnter', handleDragEnter); (0, _xDataGrid.useGridEvent)(apiRef, 'columnHeaderDragOver', handleDragOver); (0, _xDataGrid.useGridEvent)(apiRef, 'columnHeaderDragEndNative', handleDragEnd); (0, _xDataGrid.useGridEvent)(apiRef, 'cellDragEnter', handleDragEnter); (0, _xDataGrid.useGridEvent)(apiRef, 'cellDragOver', handleDragOver); (0, _xDataGrid.useGridEventPriority)(apiRef, 'columnOrderChange', props.onColumnOrderChange); }; exports.useGridColumnReorder = useGridColumnReorder;