parent
2a5ece19a9
commit
5439fc6c47
@ -0,0 +1,59 @@
|
|||||||
|
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>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
import React from "react";
|
||||||
|
import '../../style/player.css'
|
||||||
|
|
||||||
|
|
||||||
|
export function PlayerPiece({text}: { text: string }) {
|
||||||
|
return (
|
||||||
|
<div className="player-piece">
|
||||||
|
<p>{text}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
export interface Player {
|
||||||
|
/**
|
||||||
|
* unique identifier of the player.
|
||||||
|
* This identifier must be unique to the associated court.
|
||||||
|
*/
|
||||||
|
id: number,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* player's position
|
||||||
|
* */
|
||||||
|
position: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Percentage of the player's position to the bottom (0 means top, 1 means bottom, 0.5 means middle)
|
||||||
|
*/
|
||||||
|
bottom_percentage: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Percentage of the player's position to the right (0 means left, 1 means right, 0.5 means middle)
|
||||||
|
*/
|
||||||
|
right_percentage: number,
|
||||||
|
}
|
Loading…
Reference in new issue