saagie-ui
Version:
Saagie UI from Saagie Design System
91 lines (80 loc) • 2.37 kB
JavaScript
import React, {
useCallback, useRef, useState, useContext,
} from 'react';
import PropTypes from 'prop-types';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import { useId } from '@reach/auto-id';
const propTypes = {
children: PropTypes.node,
/**
* onDragEnd({ oldIndex, newIndex })
*/
onDragEnd: PropTypes.func,
};
const defaultProps = {
children: '',
onDragEnd: () => {},
};
export const DragContainerContext = React.createContext({});
export const useDragContainerContext = () => useContext(DragContainerContext);
export const PipelineDragContainer = ({ children, onDragEnd }) => {
const id = useId();
const containerRef = useRef();
const [isDragging, setIsDragging] = useState(false);
const [placeholderStyle, setPlaceholderStyle] = useState({
width: 0,
height: 0,
});
const handleDragStart = useCallback(() => {
setIsDragging(true);
}, []);
const handleDragEnd = useCallback(({ source, destination }) => {
setIsDragging(false);
if (!destination) {
return;
}
onDragEnd({ oldIndex: source.index, newIndex: destination.index });
}, []);
return (
<DragContainerContext.Provider
value={{
containerEl: containerRef.current,
setPlaceholderStyle,
isDragging,
}}
>
<DragDropContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
<Droppable
droppableId={`droppable-${id}`}
direction="horizontal"
>
{(provided) => (
<div
ref={(el) => {
provided.innerRef(el);
containerRef.current = el;
}}
className="sui-prj-pipeline-drag-list"
{...provided.droppableProps}
>
{children}
{isDragging && (
<div
style={{
width: placeholderStyle.width || 0,
height: placeholderStyle.height || 0,
}}
/>
)}
<div style={{ display: 'none' }}>
{provided.placeholder}
</div>
</div>
)}
</Droppable>
</DragDropContext>
</DragContainerContext.Provider>
);
};
PipelineDragContainer.propTypes = propTypes;
PipelineDragContainer.defaultProps = defaultProps;