0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ひとりアドベントカレンダーチャレンジAdvent Calendar 2024

Day 14

【MUI DataGrid × dnd kit】 指定したrenderCellのコンポーネントのみドラッグが反応するようにする

Posted at

はじめに

今回は、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のコンポーネントのみドラッグが反応するようにする方法の紹介でした。

もっと良い方法があればコメントで教えていただけると幸いです!

最後まで読んでいただき、ありがとうございました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?