# All files / components/DragGroup DragGroupItem.js

11.76% Statements 2/17
0% Branches 0/6
0% Functions 0/5
12.5% Lines 2/16

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112

    4x

    4x

     import React from 'react';
    import PropTypes from 'prop-types';
    import ReactDOM from 'react-dom';
    import { DragSource } from 'react-dnd';
    import { getEmptyImage } from 'react-dnd-html5-backend';
    import DragItemContainer from './styles/DragItemContainer';

    /**
     * Used to wrap an item used in DragGroup. See DragGroup documentation.
     */
    class DragItem extends React.Component {
      static propTypes = {
        /**
         * Must be exactly one node. The children will be passed a
         * `wrapDragHandle` prop which MUST be used to wrap the draggable
         * portion of the child content inside the child's render function
         */
        children: PropTypes.node.isRequired,

        /**
         * Called with (fromGroupId, toGroupId) when the item is moved
         * between groups.
         */
        onMove: PropTypes.func.isRequired,

        /**
         * Provided by parent DragGroup
         * Indicates the current parent's group id.
         */
        groupId: PropTypes.func,
      };

      componentDidMount() {
        // Use empty image as a drag preview so browsers don't draw it
        // and we can draw whatever we want on the custom drag layer instead.
        this.props.connectDragPreview(getEmptyImage(), {
          // IE fallback: specify that we'd rather screenshot the node
          // when it already knows it's being dragged so we can hide it with CSS.
          captureDraggingState: true,
        });
      }

      wrapDragHandle = dragHandleNode =>
        /**
         * The element passed to connectDragSource must be a plain
         * React element, not a component. Thus, to do proper
         * vendor prefixing with styling, we assign a class name
         * and traget it from DragItemContainer's styles; see
         * styles/DragItemContainer.js
         */
        this.props.connectDragSource(
          <div
            className="DragGroupItem--handle"
            style={{
              display: this.props.canDrag ? 'block' : 'none',
            }}
          >
            {dragHandleNode}
          </div>,
        );

      render() {
        const {
          connectDragSource,
          connectDragPreview,
          isDragging,
          children,
        } = this.props;

        return (
          <DragItemContainer isDragging={isDragging}>
            {React.cloneElement(React.Children.only(children), {
              wrapDragHandle: this.wrapDragHandle,
            })}
          </DragItemContainer>
        );
      }
    }

    const itemSource = {
      beginDrag(props, monitor, component) {
        const domNode = ReactDOM.findDOMNode(component);
        const clientRect = domNode.getBoundingClientRect();
        return {
          children: props.children,
          dimensions: clientRect,
        };
      },

      endDrag(props, monitor, component) {
        if (!monitor.didDrop()) {
          return;
        }

        const item = monitor.getItem();
        const dropResult = monitor.getDropResult();
        if (dropResult.type === 'group') {
          props.onMove(props.groupId, dropResult.groupId);
        }
      },
    };

    const collect = (connect, monitor) => ({
      connectDragSource: connect.dragSource(),
      connectDragPreview: connect.dragPreview(),
      isDragging: monitor.isDragging(),
    });

    export default DragSource(props => props.itemType, itemSource, collect)(
      DragItem,
    );