You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Application-Web/front/components/Rack.tsx

59 lines
1.8 KiB

import {Dispatch, ReactElement, RefObject, SetStateAction, useRef} from "react";
import Draggable from "react-draggable";
export interface RackInput {
id: string,
objects: [ReactElement[], Dispatch<SetStateAction<ReactElement[]>>],
canDetach: (ref: RefObject<HTMLDivElement>) => boolean,
onElementDetached: (ref: RefObject<HTMLDivElement>, el: ReactElement) => void,
}
interface RackItemInput {
item: ReactElement,
onTryDetach: (ref: RefObject<HTMLDivElement>, el: ReactElement) => void
}
/**
* A container of draggable objects
* */
export function Rack({id, objects, canDetach, onElementDetached}: RackInput) {
const [rackObjects, setRackObjects] = objects
return (
<div id={id} style={{
display: "flex"
}}>
{rackObjects.map(element => (
<RackItem key={element.key}
item={element}
onTryDetach={(ref, element) => {
if (!canDetach(ref))
return
setRackObjects(objects => {
const index = objects.findIndex(o => o.key === element.key)
return objects.toSpliced(index, 1);
})
onElementDetached(ref, element)
}}/>
))}
</div>
)
}
function RackItem({item, onTryDetach}: RackItemInput) {
const divRef = useRef<HTMLDivElement>(null);
return (
<Draggable
position={{x: 0, y: 0}}
nodeRef={divRef}
onStop={() => onTryDetach(divRef, item)}>
<div ref={divRef}>
{item}
</div>
</Draggable>
)
}