![Create React App Officially Deprecated Amid React 19 Compatibility Issues](https://cdn.sanity.io/images/cgdhsj6q/production/04fa08cf844d798abc0e1a6391c129363cc7e2ab-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
react-hook-dragula
Advanced tools
Provides named parameters and strong typing + declarative usage to dragula within React.
Lightweight, strongly typed package with almost no dependencies. It uses
Dragula and React Hooks to smoothly manage the DOM state. It also adds a
context store which allows you to pass the data back and forth between
Dragula
and React
. take a look at the example project or the live
demo of the example project.
yarn add react-hook-dragula
// Typing for data which will be attached to dragula events. Yours will be different.
type Fruit = {
itemId: number;
itemName: string;
}
type DraggableStore = {
fruit: Fruit;
fruits: Fruit[];
setFruits: Dispatch<SetStateAction<Fruit[]>>;
}
const {
Dragula,
DragulaContainer,
Draggable,
DragulaHandle,
useDraggableStore,
useInternalStore,
useDrake,
} = initializeDragula<DraggableStore>();
<Dragula>
<DragulaContainer>
<Draggable>
You can move these elements between these two containers
</Draggable>
</DragulaContainer>
<DragulaContainer>
<Draggable>
There's also the possibility of moving elements around in the
same container, changing their position
</Draggable>
</DragulaContainer>
</Dragula>
<Dragula
options={{ moves: ({ container }) => !!container?.children.length > 1 }}
onDrop={() => console.log('dragula drop event!')}
>
<DragulaContainer>
<Draggable>
You can move these elements between these two containers
</Draggable>
<Draggable>
There's also the possibility of moving elements around in the
same container, changing their position
</Draggable>
<Draggable>
Anyting can be moved around. That includes images, links, or any other
nested elements.
</Draggable>
</DragulaContainer>
<DragulaContainer>
<Draggable>
This element can't be moved until a second one is added into it's container
</Draggable>
</DragulaContainer>
</Dragula>
const [fruits, setFruits] = useState<Fruit[]>([
{ itemId: 1, itemName: 'apples' },
{ itemId: 2, itemName: 'oranges' },
{ itemId: 3, itemName: 'tomatoes' },
]);
<Dragula
onDrop={({ el, source }) => {
setFruits([...source.children].map(
({ draggableStore: { fruit } }) => draggableStore,
))
console.log('Dragual drop event for: ', el.draggableStore.fruit.itemName)
}}
>
<DragulaContainer>
{fruits.map(fruit => (
<Draggable
key={fruit.id}
draggableStore={{
fruit,
fruits,
setFruits,
}}
>
<div>{fruit.itemName} - id: {fruit.id}</div>
</Draggable>
))}
</DragulaContainer>
</Dragula>
<Dragula
options={{ moves: ({ el }) => !!el?.internalStore.isMouseOverHandle }}
>
<DragulaContainer>
<Draggable>
<DragulaHandle>You can only drag this item by clicking on me!</DragulaHandle>
<div>You can move these elements between these two containers</div>
</Draggable>
<Draggable>
This item doesn't have a handle.. so it can't be moved at all!
</Draggable>
</DragulaContainer>
</Dragula>
Each <Draggable/>
node has a draggableStore
and an internalStore
object attached to it:
type InternalStore = {
isMouseOverHandle: boolean;
};
type DraggableStore<T> = T;
type ExtendedDrakeElement<T> = Element & {
draggableStore: DraggableStore<T>;
internalStore: InternalStore;
};
type ExtendedDrakeSource<T> = Element & { children: ExtendedDrakeElement<T>[] };
initializeDragula
- - - returns object
with entries:Dragula: (props: DragulaContainerProps<T>) => <Dragula<T> {...props} />
DragulaContainer: (props: HTMLProps<HTMLDivElement>) => (<DragulaContainer {...props} />)
Draggable: (props: DraggableProps<T>) => <Draggable<T> {...props} />
DragulaHandle: (props: DragulaHandleProps) => <DragulaHandle {...props} />
useDraggableStore: () => useDraggableStore<T>()
useInternalStore: () => useInternalStore()
useDrake: () => useDrake()
OnEventProps<T = typeof DraggableStore> {
clone: ExtendedDrakeElement<T>,
container: Element,
el: ExtendedDrakeElement<T>,
original: ExtendedDrakeElement<T>,
sibling: ExtendedDrakeElement<T>,
source: ExtendedDrakeSource<T>,
target: ExtendedDrakeElement<T>,
type: 'mirror' | 'copy',
}
<Dragula
options={{
isContainer: ({ el }) => false,
moves: ({ el, source, handle, sibling }) => true,
accepts: ({ el, target, source, sibling }) => true,
invalid: ({ el, handle }) => true,
direction: "vertical",
copy: false,
copySortSource: false,
revertOnSpill: false,
removeOnSpill: false,
mirrorContainer: document.body,
ignoreInputTextSelection: true,
slideFactorX: 0,
slideFactorY: 0,
}}
onDrag={({ el, source }) => {}}
onDragEnd={({ el }) => {}}
onDrop={({ el, target, source, sibling }) => {}}
onCancel={({ el, container, source }) => {}}
onRemove={({ el, container, source }) => {}}
onShadow={({ el, container, source }) => {}}
onOver={({ el, container, source }) => {}}
onOut={({ el, container, source }) => {}}
onCloned={({ clone, original, type }) => {}}
dependencyList={[]}
/>
See Dragula configuration for more info
<DragulaContainer {...props} />
HTMLProps<HTMLDivElement>
optional
<div />
element<Draggable
draggableStore={{}}
{...props}
/>
draggableStore
Object, required
<T>
from when you initialized const { Draggable } = initializeDragula<T>()
HTMLProps<HTMLDivElement>
optional
<div />
element<DragulaHandle {...props} />
HTMLProps<HTMLDivElement>
optional
<div />
element useDraggableStore: () => typeof DraggableStore<T>
useInternalStore: () => { isMouseOverHandle: boolean; }
// If Drake type & arrow functions were generic, then it would be this:
// useDrake: <T>() => Drake<ExtendedDrakeElement<T>>;
// Since they're not generic, we wind up with:
useDrake: () => ReturnType<ExtendedDragula<any>>;
Dragula
!FAQs
Provides named parameters and strong typing + declarative usage to dragula within React.
The npm package react-hook-dragula receives a total of 3,219 weekly downloads. As such, react-hook-dragula popularity was classified as popular.
We found that react-hook-dragula demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.