react-drag-drop-zones
v0.1.2
Published
This is a library for creating custom drop-zones. Elements that are inside those drop-zones are draggable and Dropzone into other ones.
Downloads
10
Readme
react-drag-drop-zones
This is a library for creating custom drop-zones. Elements that are inside those drop-zones are draggable and Dropzone into other ones.
:rainbow: SUPPORTED LANGUAGES
- JavaScript
- TypeScript
:rainbow: AVAILABLE COMPONENTS
- DragDropProvider
- DropZone
:rainbow: REQUIREMENTS
- Works in React.js applications
- Prop
states
(array of objects: [{state: , setState: }, {...}, ...]) needs to be present onDragDropProvider
component
import { DropZone, DragDropProvider } from 'react-drag-drop-zones';
import { useState } from 'react';
export type ElementType = {
id: number;
title: string;
};
function App() {
const [elements_0, setElements_0] = useState<ElementType[]>([
{ id: 1, title: "Element 1" },
{ id: 2, title: "Element 2" },
]);
const [elements_1, setElements_1] = useState<ElementType[]>([
{ id: 3, title: "Element 3" },
{ id: 4, title: "Element 4" },
]);
const [elements_2, setElements_2] = useState<ElementType[]>([
{ id: 5, title: "Element 5" },
{ id: 6, title: "Element 6" },
]);
const states = [
{ state: elements_0, setState: setElements_0 },
{ state: elements_1, setState: setElements_1 },
{ state: elements_2, setState: setElements_2 },
];
return (
<DragDropProvider states={states}>
<DropZone>
{elements_0.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
<DropZone>
{elements_1.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
<DropZone>
{elements_2.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
</DragDropProvider>
);
}
export default App;
:rainbow: STYLING
- CSS native:
- Inline styling. Passing a
style
(object)
- as a prop to any component provided by library
- as an attribute to any draggable element provided by user
- Passing
className
(string)
- as a prop to any component provided by this library
- as an attribute to any draggable element provided by user
- styles by selectors in .css file
- Tailwind, SCSS or any other styling library acceptable.
:rainbow: STYLING EXAMPLE
const inlineCSS = {
display: "flex",
flexDirection: "column",
gap: "1rem",
backgroundColor: "red",
// ...
}
<DragDropProvider className="flex flex-col gap-3 bg-green-500 ..." > // styling by tailwind clasNames
<DropZone className="flex flex-col gap-2 bg-blue-300 ..."> // styling by tailwind clasNames
{elements_0.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
<DropZone style={inlineCSS}> // styling by inline CSS
{elements_1.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
<DropZone className="customClassDropZone"> // styling by custom css
{elements_2.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
</DragDropProvider>
:rainbow: AFTER DROP FUNCTIONALITY
afterDrop
function (optional) that will be executed after element is droped in one of theDropZone
's * FunctionafterDrop
receives one argument (object of type:AfterDropType
) that contains information(indexes) about dragged and droppedelement
and it'sDropzone
. It contains:- indexes of source and destination
Dropzone
(relatively to it's parent-DragDropProvider
) - index of dragged element where it was dragged from (relatively to it's parent- source
Dropzone
) - index(position) of dragged element where it was dropped into (relatively to destination
Dropzone
). If you drop element between elements with indexes 1 and 2 so index of a dropped element will be 2 (distance between elements starts and ends in the middle of them)
- indexes of source and destination
export type AfterDropType = {
sourceDropzoneIndex: number;
destinationDropzoneIndex: number;
draggedElementIndex: number;
positionDestinationIndex: number;
};
function customAfter(data: AfterDropType) { /*logic*/ }
- sourceDropzoneIndex : Index of
Dropzone
component (relatively to it's parent :DragDropProvider
) whereelement
was dragged from - destinationDropzoneIndex : Index of
Dropzone
component (relatively to it's parent :DragDropProvider
) whereelement
was dropped into - draggedElementIndex : Index of a dragged
element
(relatively to it's parent : sourceDropzone
) where it was dragged from - positionDestinationIndex : Index of a dropped
element
(relatively to it's parent : destinationDropzone
) where it was dropped into
Steps and example :
- Import
AfterDropType
: afterDrop
prop =>DragDropProvider
- create
customAfter
function and associate it to theafterDrop
prop
import { DropZone, DragDropProvider, AfterDropType } from 'react-drag-drop-zones';
function App() {
// ...
const customAfter = (data: AfterDropType) => {/*logic*/}
return (
<DragDropProvider
afterDrop={customAfter}
states={states}
>
{/* DropZones logic */}
</DragDropProvider>
);
}
export default App;
customStatesManipulation
(optional) prop(of typeboolean
) inDragDropProvider
* If prop is passed toDragDropProvider
astrue
the sates will remain unchanged and it is up to the user to make proper states manipulation thanks to an object thatafterDrop
receives. Example:
import { DropZone, DragDropProvider, AfterDropType } from 'react-drag-drop-zones';
function App() {
// ...
const customAfter = (data: AfterDropType) => {/*logic*/}
return (
<DragDropProvider
customStatesManipulation = {true}
afterDrop={customAfter}
states={states}
>
{/* DropZones logic */}
</DragDropProvider>
);
}
export default App;
:rainbow: FULL EXAMPLE
import { DropZone, DragDropProvider, AfterDropType } from 'react-drag-drop-zones';
import { useState } from 'react';
export type ElementType = {
id: number;
title: string;
};
function App() {
const [elements_0, setElements_0] = useState<ElementType[]>([
{ id: 1, title: "Element 1" },
{ id: 2, title: "Element 2" },
]);
const [elements_1, setElements_1] = useState<ElementType[]>([
{ id: 3, title: "Element 3" },
{ id: 4, title: "Element 4" },
]);
const [elements_2, setElements_2] = useState<ElementType[]>([
{ id: 5, title: "Element 5" },
{ id: 6, title: "Element 6" },
]);
const states = [
{ state: elements_0, setState: setElements_0 },
{ state: elements_1, setState: setElements_1 },
{ state: elements_2, setState: setElements_2 },
];
const afterDrop = (data: AfterDropType) => {
console.log(data)
/*after drop logic if needed*/
/*for example states manipulation
if `customStatesManipulation` is `true` and is passed to `DragDropProvider`
*/
}
return (
<DragDropProvider
afterDrop={customAfter}
// customStatesManipulation = {true}
// style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }} // inline CSS
className='flex gap-5 p-5 flex-col' // tailwind
states={states}
>
<DropZone className="flex flex-col gap-2 bg-blue-300 ..."> // styling by tailwind clasNames
{elements_0.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
<DropZone style={inlineCSS}> // styling by inline CSS
{elements_1.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
<DropZone className="customClassDropZone"> // styling by custom css
{elements_2.map(el => (<div key={el.id}>{el.title}</div>) )}
</DropZone>
</DragDropProvider>
);
}
export default App;
API
DragDropProvider
Props| prop | optional | description | | --------------------------- | --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------| |
states
| no | An array of state objects. Each object should have astate
andsetState
property | |afterDrop
| yes | A function that is executed at the end of a drag & drop action. It receives an argument(object of typeAfterDropType
) containing information about the drop | |customStatesManipulation
| yes | A boolean flag. If set to true, the drop action will not modify the states, and it's up to the user to handle state modifications in the afterDrop function |types
AfterDropType
| type | description | | ---------------------------| ---------------------------------------------------------------------------------------------------------------| |sourceDropzoneIndex
| Index ofDropzone
component (relatively to it's parent :DragDropProvider
) whereelement
was dragged from | |destinationDropzoneIndex
| Index ofDropzone
component (relatively to it's parent :DragDropProvider
) whereelement
was dropped into | |draggedElementIndex
| Index of a draggedelement
(relatively to it's parent : sourceDropzone
) where it was dragged from | |positionDestinationIndex
| Index of a droppedelement
(relatively to it's parent : destinationDropzone
) where it was dropped into |
DragDropProvider
andDropzone
Props | prop | optional | description | | ---------- | -------- | -----------------------------------------------------------------------------------------------------| |className
| yes | A string representing the aclassName
for theDragDropProvider
component | |style
| yes | An object containing CSS properties to inline style theDragDropProvider
andDropZone
components |
This project is licensed under the MIT License - see the LICENSE file for details.