Open lifeofjer opened 5 years ago
I'm not sure if I'm solving the same problem as you, here's my approach for bringing forward the window currently being dragged (and leaving it at the top of the z-index — which I think accomplishes the sam thing):
(edit: this is actually buggy, the z-index values on elements can become out of sync, but the approach with a little tweaking seems clean to me)
const DraggableBlock = (props) => {
const [isDragging, setIsDragging] = useState({status: false, zIndex: 1000})
return (
<Draggable
handle=".draggable-block-container"
onStart={() => setIsDragging({...isDragging, status: true, zIndex: isDragging.zIndex + 1})}
onEnd={() => setIsDragging({...isDragging, status: false})}
>
<div
className={`draggable-block-container`}
style={{
zIndex: isDragging.zIndex
}}
>
...
</div>
</Draggable>
)
}
Dear future developers who are confused...
onStop
instead of onEnd
position: 'relative'
on <div>
if it still doesnt workI was able to find a solution. I was not happy with any approach that I was having, I tried dinamic zindex with useState but it was not being left in order after drag, I tried with classnames, timeout and I was not happy.
The code that I find best is.
const DraggableBlock = (props) => {
const [currentZIndex, setCurrentZIndex] = useState(31);
const handleZindex = (element) => {
element.style.zIndex = currentZIndex;
setCurrentZIndex((state) => state + 1);
};
return (
<Draggable
handle=".draggable-block-container"
onStart={() => handleZindex(blockRef.current)}
>
<div
className={`draggable-block-container`}
ref={blockRef}
>
...
</div>
</Draggable>
)
}
This way each component will remain in order of dragable.
Bonus:
I also needed to made sure that some components would not be able to be dragged on. For example: if we drag a component and the current z index is bigger than the component, it will be on top of the component that we don't want to. In my case, it was a cart slide panel, I handle by passing the zIndex: currentZIndex + 10
on inline style to it.
This worked for me.
"DraggableContext.tsx"
import { createContext } from "react";
export interface DraggableContextInterface {
index: number;
setIndex: (index: number) => void;
}
const initialState: DraggableContextInterface = {
index: 3,
setIndex: (index: number) => {},
};
export const DraggableContext = createContext(initialState);
"App.tsx"
const [index, setIndex] = useState(3);
return(
<DraggableContext.Provider value={{ index, setIndex }}>
<App/>
</DraggableContext.Provider>
)
"Draggable Component"
const { index, setIndex }: DraggableContextInterface = useContext(DraggableContext);
const [currentZIndex, setCurrentZIndex] = useState(1);
const onStart: DraggableEventHandler | undefined = () => {
if (index != currentZIndex + 1) {
setCurrentZIndex(index);
setIndex(index + 1);
}
};
return (
<Draggable onStart={onStart}>
<div zIndex={currentZIndex}>I'm dragable</div>
</Draggable>
)
This might not be the best solution but this is what worked for me. A simple state managed z-index draggable component.
Notice how I set position: "absolute"
in the style. This is because the Draggable component has position: "static"
which doesn't listen to z-index
changes.
import { useState } from 'react';
import Draggable from 'react-draggable';
class DragCompIndex {
static index = 0;
static updateIndex() { DragCompIndex.index++; }
}
const DraggableComponent = () => {
const [currentZIndex, setZIndex] = useState<number>(DragCompIndex.index);
const Prioritise = () => {
setZIndex(DragCompIndex.index);
}
const Deprioritise = () => {
DragCompIndex.updateIndex();
}
return (
<Draggable onStart={Prioritise} onStop={Deprioritise}>
<div style={{
zIndex: currentZIndex,
position: "absolute"
}}
>
<h1>I am always in on top!</h1>
</div>
</Draggable>
)
}
export default DraggableComponent;
Wanted to share this snippet of code I am using to bring the latest dragged window to the front. Any feedback or improvements are welcome for others looking for the same functionality.
Note: This is definitely a clunky implementation and involves a flash due to timing on when the onStop is triggered