UNPKG

@bigfishtv/cockpit

Version:

107 lines (94 loc) 2.83 kB
import PropTypes from 'prop-types' import React, { Component } from 'react' import ReactDOM from 'react-dom' import classnames from 'classnames' import { DragSource, DropTarget } from 'react-dnd' import * as DragTypes from '../../constants/DragTypes' import _CellControl from './CellControl' import DefaultIcon from '../Icon' import Spinner from '../Spinner' // we define this because react-docgen fails when defaultProp directly references an imported component const DefaultCellControl = props => <_CellControl {...props} /> const cellSource = { beginDrag(props) { return { id: props.id, } }, } const cellTarget = { hover(props, monitor, component) { const ownId = props.id const draggedId = monitor.getItem().id if (draggedId === ownId) return const ownIndex = props.index const draggedIndex = monitor.getItem().index const boundingRect = ReactDOM.findDOMNode(component).getBoundingClientRect() const clientOffset = monitor.getClientOffset() const ownMiddleY = (boundingRect.bottom - boundingRect.top) / 2 const offsetY = clientOffset.y - boundingRect.top if (draggedIndex < ownIndex && offsetY < ownMiddleY) return if (draggedIndex > ownIndex && offsetY > ownMiddleY) return props.onMove(draggedId, ownId) }, } /** * Default Cell component used in things like Tree and RepeatableFieldset */ @DropTarget(DragTypes.CELL, cellTarget, connect => ({ connectDropTarget: connect.dropTarget(), })) @DragSource(DragTypes.CELL, cellSource, (connect, monitor) => ({ connectDragSource: connect.dragSource(), isDragging: monitor.isDragging(), })) export default class Cell extends Component { static propTypes = { title: PropTypes.node, CellControl: PropTypes.func, Icon: PropTypes.node, icon: PropTypes.string, className: PropTypes.string, reorderable: PropTypes.bool, } static defaultProps = { loading: false, CellControl: DefaultCellControl, } render() { const { reorderable, loading, onEdit, CellControl, Icon, icon, connectDragSource, connectDropTarget, isDragging, className, } = this.props const returnNode = ( <div className={classnames('cell', className, { dragging: isDragging, reorderable: reorderable })} onDoubleClick={onEdit}> {Icon ? ( <div className="cell-icon">{Icon}</div> ) : ( icon && ( <div className="cell-icon"> <DefaultIcon name={icon} /> </div> ) )} {loading && <Spinner color="#9696A3" spinnerName="circle" />} <div className="cell-content">{this.props.title}</div> <div className="cell-control"> {CellControl ? <CellControl {...this.props} /> : <div style={{ height: 30, display: 'inline-block' }} />} </div> </div> ) if (reorderable) return connectDragSource(connectDropTarget(returnNode)) else return returnNode } }