はじめに
今回は、MUI DataGrid × dnd kitで、指定したrenderCellのコンポーネントのみドラッグが反応するようにする方法を紹介します。
正直、かなり無理矢理な方法なのでもっと良い方法があればコメントで教えていただけると幸いです🙇♂️
バージョン
- @dnd-kit/core: ^6.3.1
- @dnd-kit/sortable: ^10.0.0
- @mui/x-data-grid: ^7.22.3
- react: 18.3.1
- next: 15.0.3
サンプルコード
import { useSortable } from '@dnd-kit/sortable';
import Box from '@mui/material/Box';
import {
GridRow,
type GridRowProps,
type GridRenderCellParams,
} from '@mui/x-data-grid';
import { cloneElement, isValidElement, memo } from 'react';
import { CSS } from '@dnd-kit/utilities';
const DraggableGridRow = memo((params: GridRowProps) => {
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id: params.rowId });
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
const enhancedParam = (param: GridRowProps) => {
const updatedVisibleColumns = [...param.visibleColumns];
if (updatedVisibleColumns[0]?.renderCell) {
const originalRenderCell = updatedVisibleColumns[0].renderCell;
// renderCellをラップして新しいものに置き換え
updatedVisibleColumns[0] = {
...updatedVisibleColumns[0], // renderCell以外のプロパティを維持
renderCell: (cellParams: GridRenderCellParams) => {
// 元のrenderCellが返す要素を取得
const originalElement = originalRenderCell(cellParams);
if (isValidElement(originalElement)) {
// ドラッグ用の属性を追加し要素をクローンして返す
return cloneElement(originalElement, {
...attributes,
...listeners,
});
}
return originalElement;
},
};
}
return {
...param,
visibleColumns: updatedVisibleColumns,
};
};
const updatedParams = enhancedParam(params);
return (
<Box ref={setNodeRef} style={style}>
<GridRow {...updatedParams} />
</Box>
);
});
DraggableGridRow.displayName = 'DraggableGridRow';
export default DraggableGridRow;
ちょこっと解説
useSortableで返されるattributesとlistenersを、GridRowのrenderCellで返されるコンポーネントに渡すことで、行の中でそのコンポーネント部分のみドラッグできるようになります。
他の列をドラッグできるようにしたい場合は、updatedVisibleColumns[0]
の部分のインデックスを変更してください。
おわりに
短いですが、以上がMUI DataGrid × dnd kitで、指定したrenderCellのコンポーネントのみドラッグが反応するようにする方法の紹介でした。
もっと良い方法があればコメントで教えていただけると幸いです!
最後まで読んでいただき、ありがとうございました!