Use material-ui table with react-beautiful-dnd

后端 未结 3 514
迷失自我
迷失自我 2020-12-30 12:31

I\'m looking to use material-ui in combination with react-beautiful-dnd in order to make a sortable table. However, using material-ui\'s table components causes trouble as T

相关标签:
3条回答
  • 2020-12-30 12:52

    I came across this while working on a similar task. Re the OP's question, TableRow and TableBody both support a ref prop (vs. innerRef) that forwards to the root element.

    Refer to the FAQ:

    • https://material-ui.com/getting-started/faq/#how-can-i-access-the-dom-element

    This is mentioned in the docs for both TableRow and TableBody:

    • https://material-ui.com/api/table-row/
    • https://material-ui.com/api/table-body/

    Therefore you do not necessarily need to move the Draggable/Droppable parts into their own components per the answers from @Bryant and @funql.org.

    You also don't necessarily need to pass isDragging to your TableRow (though you could if you created a custom wrapper component that accepts this prop). If your use-case is styling the row when dragged, you can add a className or style prop to your TableRow and apply conditional styling when isDragging is true.

    Here's a working example of a Material UI table that features sortable rows with react-beautiful-dnd:

    • https://codesandbox.io/s/react-material-ui-and-react-beautiful-dnd-uofv4

    Incidentally I created it as part of an issue report because I'm not sure why there is a 1 pixel jump (the thickness of the border-bottom on table cells) when a given table row is dragged, but that's another issue! The implementation is solid enough to support the many cases where a minor 1px visual glitch is acceptable.

    0 讨论(0)
  • 2020-12-30 12:53

    I had this same problem. What you have to do is move the Draggable/Droppable part into a component and pass that in via the component attribute.

    For example, I wanted to be able to re-order columns in a table header. Row is my droppable area, and Cell is Draggable.

    public render() {
        return (
            <TableHead component="div">
                <TableRow component={DroppableComponent(this.onDragEnd)}>{headerCells}</TableRow>
            </TableHead>
        );
    }
    
    const DroppableComponent = (
        onDragEnd: (result: DropResult, provided: ResponderProvided) => void
    ) => (props: any) => {
        return (
            <DragDropContext onDragEnd={onDragEnd}>
                <Droppable droppableId={'1'} direction="horizontal">
                    {(provided) => {
                        return (
                            <div ref={provided.innerRef} {...provided.droppableProps} {...props}>
                                {props.children}
                                {provided.placeholder}
                            </div>
                        );
                    }}
                </Droppable>
            </DragDropContext>
        );
    };
    

    Notice I made Droppable Component be a function that returns a function. That was so that I could pass in the onDragEnd method from my main component. I tried putting my DroppableComponent in the component attribute as JSX and I was getting an error, so this is what I ended up with.

    For the Draggable part I had the following:

    <TableCell
        component={DraggableComponent(column.id, index)}
        key={column.id}
    >
        ...
    </TableCell>
    
    const DraggableComponent = (id: string, index: number) => (props: any) => {
        return (
            <Draggable draggableId={id} index={index}>
                {(provided) => (
                    <div
                        ref={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        {...props}
                    >
                        {props.children}
                    </div>
                )}
            </Draggable>
        );
    };
    

    Hope this helps!

    0 讨论(0)
  • 2020-12-30 13:00

    I have created a github example repo using @Bryant's solution. https://github.com/hmarggraff/react-material-ui-table-row-drag-and-drop

    It shows how to combine Bryants solution with react-material-ui. It also shows row vs colums dnd and visual feedback during dnd. It is a complete reusable solution.

    0 讨论(0)
提交回复
热议问题