UNPKG

wix-style-react

Version:
144 lines (142 loc) 5.77 kB
import React from 'react'; import PropTypes from 'prop-types'; import shallowEqual from 'shallowequal'; import DraggableSource from './components/DraggableSource'; import DraggableTarget from './components/DraggableTarget'; import DraggableManager from './components/DraggableManager'; export class Draggable extends React.Component { constructor() { super(...arguments); this.state = { delayed: false, }; this.delayTimer = null; this.resetDelayState = () => { if (!!this.props.delay) { this.setState({ delayed: false }); this.resetDelayTimer(); } }; this.resetDelayTimer = () => { clearTimeout(this.delayTimer); this.delayTimer = null; }; this.countDelay = () => { if (!!this.props.delay) { this.setState({ delayed: true }); this.resetDelayTimer(); this.delayTimer = setTimeout(() => this.setState({ delayed: false }), this.props.delay); } }; this.onDragStart = ({ id, index, containerId, groupName, item }) => { if (this.props.onDragStart) { this.props.onDragStart({ id, index, containerId, groupName, item }); } this.resetDelayTimer(); }; this.onDragEnd = ({ id, index, containerId, groupName, item }) => { if (this.props.onDragEnd) { this.props.onDragEnd({ id, index, containerId, groupName, item }); } this.resetDelayState(); }; this.canDrag = ({ id, index, containerId, groupName, item }) => { const canDragByDelay = !!this.props.delay ? !this.state.delayed : true; const propsCanDrag = this.props.canDrag ? this.props.canDrag({ id, index, containerId, groupName, item, }) : true; if (!canDragByDelay) { this.resetDelayState(); } return canDragByDelay && propsCanDrag; }; } shouldComponentUpdate({ listOfPropsThatAffectItems, ...nextProps }, nextState) { const { listOfPropsThatAffectItems: prevListOfPropsThatAffectItems, ...prevProps } = this.props; if (!shallowEqual(nextProps, prevProps) || !shallowEqual(listOfPropsThatAffectItems, prevListOfPropsThatAffectItems)) { return true; } if (!shallowEqual(nextState, this.state)) { return true; } return false; } componentWillUnmount() { this.resetDelayTimer(); } render() { const { hasDragged, ...restProps } = this.props; return (React.createElement(DraggableTarget, { ...restProps }, React.createElement("div", { onMouseDown: this.countDelay, onMouseUp: this.resetDelayState, "data-hook": "delay-wrapper" }, React.createElement(DraggableSource, { ...restProps, ignoreMouseEvents: hasDragged, onDragStart: this.onDragStart, onDragEnd: this.onDragEnd, canDrag: this.canDrag, delayed: !!this.props.delay && this.state.delayed })))); } } Draggable.defaultProps = { droppable: true, }; Draggable.propTypes = { /** indicates if element can be drop at this place */ droppable: PropTypes.bool, /** decide whether to render a handle using `connectHandle` (see below) */ withHandle: PropTypes.bool, /** uniq id of container that contain current draggable item */ containerId: PropTypes.string, /* name of group between inside of each dnd is allowed */ groupName: PropTypes.string, /* custom renderer for item */ renderItem: PropTypes.func, /* position of item in container items array */ index: PropTypes.number, /* uniq id of an item */ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), /* model that represent item */ item: PropTypes.object, /** callback when item was moved out from current container to another container */ onMoveOut: PropTypes.func, /** callback when item was dropped in a new location */ onDrop: PropTypes.func, /** callback when item is hovered*/ onHover: PropTypes.func, /** callback for drag start */ onDragStart: PropTypes.func, /** callback for drag end */ onDragEnd: PropTypes.func, /** visual positioning shifting for an element (transform: translate) without moving it from its real position at DOM (left, top) */ shift: PropTypes.arrayOf(PropTypes.number), /** flag that indicates that there's an item being dragged */ hasDragged: PropTypes.bool, /** sets draggable item node & additional info for animation positions calculations */ setWrapperNode: PropTypes.func, /** animation duration in ms, default = 0 - disabled */ animationDuration: PropTypes.number, /** animation timing function, default = linear */ animationTiming: PropTypes.string, /** callback that could prevent item from dragging */ canDrag: PropTypes.func, delay: PropTypes.number, /** In case that you are using some external props inside of renderItems method, you need to define them here. renderItem = ({ item }) => <div key={item.id}>{this.props.myAwesomeProp}</div> render() { return ( <SortableListBase ... listOfPropsThatAffectItems={[this.props.myAwesomeProp]} /> ) } */ listOfPropsThatAffectItems: PropTypes.array, }; Draggable.Item = Draggable; Draggable.Manager = DraggableManager; export default Draggable; //# sourceMappingURL=Draggable.js.map