UNPKG

@bigfishtv/cockpit

Version:

134 lines (123 loc) 4.24 kB
import PropTypes from 'prop-types' import React, { Component } from 'react' import { DragSource, DropTarget } from 'react-dnd' import { getEmptyImage } from 'react-dnd-html5-backend' import classnames from 'classnames' import TreeCell from '../tree/TreeCell' import Breadrumb from '../breadcrumb/Breadcrumb' // we define this because react-docgen fails when defaultProp directly references an imported component const DefaultTreeCell = props => <TreeCell {...props} /> const treeItemSource = { beginDrag(props, monitor, component) { if (props.treeItemSource && props.treeItemSource.beginDrag) return props.treeItemSource.beginDrag(props, monitor, component) else return { id: props.id } }, endDrag(props, monitor, component) { if (props.treeItemSource && props.treeItemSource.endDrag) return props.treeItemSource.endDrag(props, monitor, component) }, canDrag(props, monitor) { if (props.treeItemSource && props.treeItemSource.canDrag) return props.treeItemSource.canDrag(props, monitor) else return true }, isDragging(props, monitor) { if (props.treeItemSource && props.treeItemSource.isDragging) return props.treeItemSource.isDragging(props, monitor) return props.id === monitor.getItem().id }, } const treeItemTarget = { drop(props, monitor, component) { if (props.treeItemTarget && props.treeItemTarget.drop) return props.treeItemTarget.drop(props, monitor, component) }, hover(props, monitor, component) { if (props.treeItemTarget && props.treeItemTarget.hover) return props.treeItemTarget.hover(props, monitor, component) }, canDrop(props, monitor, component) { if (props.treeItemTarget && props.treeItemTarget.canDrop) return props.treeItemTarget.canDrop(props, monitor, component) else return true }, } /** * Component used in tree, wraps the main TreeCell component with dragging functionality */ @DropTarget(props => props.dropTargetType, treeItemTarget, (connect, monitor) => { return { connectDropTarget: connect.dropTarget(), isOver: monitor.isOver({ shallow: true }), currentDragType: monitor.getItemType(), } }) @DragSource(props => props.dragTargetType, treeItemSource, (connect, monitor) => ({ connectDragSource: connect.dragSource(), connectDragPreview: connect.dragPreview(), })) export default class TreeItem extends Component { static propTypes = { /** Disregard -- provided by react-dnd */ beginDrag: PropTypes.func.isRequired, /** Disregard -- provided by react-dnd */ endDrag: PropTypes.func.isRequired, /** Disregard -- provided by react-dnd */ connectDragSource: PropTypes.func.isRequired, /** Disregard -- provided by react-dnd */ connectDropTarget: PropTypes.func.isRequired, /** Disregard -- provided by react-dnd */ isOver: PropTypes.bool.isRequired, onClick: PropTypes.func, onDoubleClick: PropTypes.func, onCollapse: PropTypes.func, /** Cell component to use instead of default TreeCell */ TreeCell: PropTypes.func, } static defaultProps = { TreeCell: DefaultTreeCell, } componentDidMount() { this.props.connectDragPreview(getEmptyImage(), { captureDraggingState: true }) } handleIndicatorClick = event => { event.stopPropagation() this.props.onCollapse && this.props.onCollapse() } handleIndicatorDoubleClick = event => { event.stopPropagation() } render() { const { TreeCell, children, connectDragSource, connectDropTarget, title, isOver, position, collapsed, forceExpand, currentDragType, dropTargetType, selected, breadcrumbs, } = this.props const dragging = currentDragType === dropTargetType const isCollapsed = dragging && forceExpand ? false : collapsed const selectedDrag = dragging && selected return connectDragSource( connectDropTarget( <div className={classnames('tree-node', isOver && 'drag-' + position)}> <Breadrumb title={children && breadcrumbs ? title : null}> <TreeCell {...this.props} isCollapsed={isCollapsed} selectedDrag={selectedDrag} onIndicatorClick={this.handleIndicatorClick} onIndicatorDoubleClick={this.handleIndicatorDoubleClick} /> {!isCollapsed && <div className="tree-children">{children}</div>} </Breadrumb> </div> ) ) } }