UNPKG

wix-style-react

Version:
153 lines (136 loc) 3.84 kB
import React, { Component } from 'react'; import classNames from 'classnames'; import { DragLayer } from 'react-dnd'; import itemTypes from './itemTypes'; import { Portal } from 'react-portal'; import { dataAttributes } from '../DragAndDrop/Draggable/constants'; const defaultLayerStyles = { position: 'fixed', pointerEvents: 'none', left: 0, top: 0, }; function getItemStyles(props, clientRect, handleOffset) { const { initialOffset, currentOffset } = props; if (!initialOffset || !currentOffset) { return { display: 'none' }; } const x = currentOffset.x - handleOffset.x; const y = currentOffset.y - handleOffset.y; const { width, height } = clientRect; const transform = `translate(${x}px, ${y}px)`; return { transform, WebkitTransform: transform, width, height, }; } const defaultConnectDragSource = el => el; class CustomDragLayer extends Component { renderChildren = (items, depth) => { const { renderItem, childrenProperty, childrenStyle, theme } = this.props; if (!items || !items.length) { return null; } const classes = classNames( 'nestable-item', 'dragging-nestable-item', theme && theme.item, ); return ( <div style={childrenStyle}> {items.map((item, i) => ( <div className={classes} data-hook="dragging-nestable-item" key={i}> {React.cloneElement( renderItem({ item, isPlaceholder: false, isPreview: true, depth, connectDragSource: defaultConnectDragSource, }), { [dataAttributes.draggableSource]: true, [dataAttributes.depth]: depth - 1, [dataAttributes.id]: item.id, }, )} {!item.isCollapsed && this.renderChildren( item[childrenProperty], depth + 1, item.isCollapsed, )} </div> ))} </div> ); }; render() { const { item, itemType, renderItem, isPlaceholder, childrenProperty, isRenderDraggingChildren, theme, dragLayerZIndex, } = this.props; if (!isPlaceholder || itemType !== itemTypes.nestedItem) { return null; } const classes = classNames( 'nestable-item', 'dragging-nestable-item', theme && theme.item, ); const renderedItem = React.cloneElement( renderItem({ item: item.data, isPlaceholder: false, isPreview: true, depth: 1, connectDragSource: defaultConnectDragSource, }), { [dataAttributes.draggableSource]: true, [dataAttributes.depth]: 0, [dataAttributes.id]: item.id, }, ); // portal is used because of position fixed and transform issue return ( <Portal> <div style={{ ...defaultLayerStyles, zIndex: dragLayerZIndex }}> <div className={classes} style={getItemStyles( this.props, item.clientRect, item.handleOffset, )} > {renderedItem} {isRenderDraggingChildren && !item.data.isCollapsed && this.renderChildren(item.data[childrenProperty], 2)} </div> </div> </Portal> ); } } class PureDragLayer extends React.PureComponent { render() { return <CustomDragLayer {...this.props} />; } } export default DragLayer(monitor => ({ item: monitor.getItem(), itemType: monitor.getItemType(), initialOffset: monitor.getInitialSourceClientOffset(), currentOffset: monitor.getSourceClientOffset(), isPlaceholder: monitor.isDragging(), }))(PureDragLayer);