Open robcecil opened 2 years ago
I created a CodeSandbox to make easier to see the error messages: https://codesandbox.io/s/trusting-benz-yxpr23?file=/demo.tsx
There're a few tasks we need to do to support React-Bautiful-Dnd as well as other libs that pass custom props and need access to refs to internal components:
~GridRow
is not forwarding the received ref to the root element. This explains one of the "provided.innerRef has not been provided with a HTMLElement." errors. The following diff fixes this problem:~ (fixed by https://github.com/mui/mui-x/issues/6008)
diff --git a/packages/grid/x-data-grid/src/components/GridRow.tsx b/packages/grid/x-data-grid/src/components/GridRow.tsx
index 2a3d2fbf9..4e79c1331 100644
--- a/packages/grid/x-data-grid/src/components/GridRow.tsx
+++ b/packages/grid/x-data-grid/src/components/GridRow.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
-import { unstable_composeClasses as composeClasses } from '@mui/material';
+import { unstable_composeClasses as composeClasses, useForkRef } from '@mui/material';
import { GridRowEventLookup } from '../models/events';
import { GridRowId, GridRowModel } from '../models/gridRows';
import {
@@ -91,7 +91,10 @@ const EmptyCell = ({ width }: { width: number }) => {
return <div className="MuiDataGrid-cell" style={style} />; // TODO change to .MuiDataGrid-emptyCell or .MuiDataGrid-rowFiller
};
-function GridRow(props: React.HTMLAttributes<HTMLDivElement> & GridRowProps) {
+const GridRow = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes<HTMLDivElement> & GridRowProps
+>(function GridRow(props, refProp) {
const {
selected,
rowId,
@@ -124,6 +127,7 @@ function GridRow(props: React.HTMLAttributes<HTMLDivElement> & GridRowProps) {
const sortModel = useGridSelector(apiRef, gridSortModelSelector);
const treeDepth = useGridSelector(apiRef, gridRowTreeDepthSelector);
const headerGroupingMaxDepth = useGridSelector(apiRef, gridDensityHeaderGroupingMaxDepthSelector);
+ const handleRef = useForkRef(ref, refProp);
const ariaRowIndex = index + headerGroupingMaxDepth + 2; // 1 for the header row and 1 as it's 1-based
const { hasScrollX, hasScrollY } = apiRef.current.getRootDimensions() ?? {
@@ -472,7 +476,7 @@ function GridRow(props: React.HTMLAttributes<HTMLDivElement> & GridRowProps) {
return (
<div
- ref={ref}
+ ref={handleRef}
data-id={rowId}
data-rowindex={index}
role="row"
@@ -487,7 +491,7 @@ function GridRow(props: React.HTMLAttributes<HTMLDivElement> & GridRowProps) {
{emptyCellWidth > 0 && <EmptyCell width={emptyCellWidth} />}
</div>
);
-}
+});
GridRow.propTypes = {
// ----------------------------- Warning --------------------------------
Another "provided.innerRef has not been provided with a HTMLElement." message is because the ref passed to DataGridProp
is not being forwarded to a HTML element since the first render. It's forwarded to a HTML element but initially this ref is null
because there's a logic do detect if the component is being rendered by SSR and render nothing.
If the React.useState(false)
above is initialized with true
the error is gone. Since we can't change the default value, I propose to add a disableSSR
prop to skip this SSR logic and render the component immediadiatelly.
~Doing these changes still leaves us with the "Cannot find droppable entry with id [droppable-datagrid]" error. This happens because provided.droppableProps
passes custom props to the grid, e.g. data-rbd-droppable-id
, and these props are not forwarded to the root element. To solve that we need to get all props not used by the grid and spread them to GridRoot
, more or less like below but with all props:~ (fixed by #8845)
diff --git a/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx b/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
index 5af063bfe..a58f87c74 100644
--- a/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
+++ b/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
@@ -24,13 +24,13 @@ const DataGridProRaw = React.forwardRef(function DataGridPro<R extends GridValid
inProps: DataGridProProps<R>,
ref: React.Ref<HTMLDivElement>,
) {
- const props = useDataGridProProps(inProps);
+ const { disableColumnMenu, ...rest } = useDataGridProProps(inProps);
const apiRef = useDataGridProComponent(props.apiRef, props);
useLicenseVerifier('x-data-grid-pro', releaseInfo);
return (
<GridContextProvider apiRef={apiRef} props={props}>
- <GridRoot className={props.className} style={props.style} sx={props.sx} ref={ref}>
+ <GridRoot className={props.className} style={props.style} sx={props.sx} ref={ref} {...rest}>
<GridErrorHandler>
<GridHeaderPlaceholder />
<GridBody
Hi, I want to use react-beautiful-dnd in Mui x Datagrid (premium). It's quite problematic because Datagrid needs to be wrapped in div (that gets the ref and droppableProps), and also in Dropabble. I tried also to create custom grid row (instead of the original one).
Can someone help please? Working solution example can be also helpful.
Thanks
Did you guys end up resolving the issue? I am encountering the same problem.
Hi @robcecil, did you find a way to integrate React-Beautiful-DnD with DataGridPro? or any alternative way to do D&D?
Order ID π³
43370
Duplicates
Latest version
The problem in depth π
I wish to integrate a third party DnD library (React-beautiful-Dnd - 'RBDND') with MUI. I have used both MUI v4 and the RBDND library in the past with List and other MUI components with great success. Currently I am trying to be able to:
When I run my test project, I am getting a warning in console from RBDND:
Also, when I attempt a drag operation, I get the following warning, which stems from MUI:
I am wrapping my DataGridPro instance in a Droppable :
Even though I do not intend to drag and drop rows within the grid, the rule from RBDND is that all Draggables must be enclosed in a Droppable (hence the isDropDisabled). That is why the DataGridPro must be enclosed in a Droppable .
Next, I've implemented a DraggableGridRow thusly:
Not shown here (but in the attached zip file), is wrapping Tab instances each in Droppable wrappers.
The use case is to drag a row out of the grid and drop onto individual DroppableTab components (and yes, I don't need the Tabs container to be droppable, only the individual tabs themselves).
I've gotten a similar Proof of concept working fine between MUI TableRow and MUI Tab fine. But my difficulty is specifically with the MUI-X DataGridPro and MUI Tab.
thanks
dnd.zip
Your environment π
System: OS: Windows 10 10.0.19044 Binaries: Node: 16.13.1 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.15 - C:\Program Files\nodejs\yarn.CMD npm: 8.1.2 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: 104.0.5112.102 Edge: Spartan (44.19041.1266.0), Chromium (104.0.1293.70)