diff --git a/js/components/DropTarget.tsx b/js/components/DropTarget.tsx index c9dddcf4..29d61e71 100644 --- a/js/components/DropTarget.tsx +++ b/js/components/DropTarget.tsx @@ -1,4 +1,5 @@ -import React from "react"; +// @ts-ignore #hook-types +import React, { useCallback } from "react"; interface Coord { x: number; @@ -9,41 +10,44 @@ interface Props extends React.HTMLAttributes { handleDrop(e: React.DragEvent, coord: Coord): void; } -export default class DropTarget extends React.Component { - supress(e: React.DragEvent) { - e.stopPropagation(); - e.preventDefault(); - e.dataTransfer.dropEffect = "link"; - e.dataTransfer.effectAllowed = "link"; - } - - handleDrop = (e: React.DragEvent) => { - this.supress(e); - // TODO: We could probably move this coordinate logic into the playlist. - // I think that's the only place it gets used. - const { currentTarget } = e; - if (!(currentTarget instanceof Element)) { - return; - } - - const { left: x, top: y } = currentTarget.getBoundingClientRect(); - this.props.handleDrop(e, { x, y }); - }; - - render() { - const { - // eslint-disable-next-line no-shadow, no-unused-vars - handleDrop, - ...passThroughProps - } = this.props; - return ( -
- ); - } +function supress(e: React.DragEvent) { + e.stopPropagation(); + e.preventDefault(); + e.dataTransfer.dropEffect = "link"; + e.dataTransfer.effectAllowed = "link"; } + +const DropTarget = (props: Props) => { + const onDrop = useCallback( + (e: React.DragEvent) => { + supress(e); + // TODO: We could probably move this coordinate logic into the playlist. + // I think that's the only place it gets used. + const { currentTarget } = e; + if (!(currentTarget instanceof Element)) { + return; + } + + const { left: x, top: y } = currentTarget.getBoundingClientRect(); + props.handleDrop(e, { x, y }); + }, + [props.handleDrop] + ); + + const { + // eslint-disable-next-line no-shadow, no-unused-vars + handleDrop, + ...passThroughProps + } = props; + return ( +
+ ); +}; + +export default DropTarget;