diff --git a/src/App.css b/src/App.css index 34b5d3364..d69b8e72d 100644 --- a/src/App.css +++ b/src/App.css @@ -11,5 +11,5 @@ body { height: -webkit-fill-available; } #root { - height: 100%; + height: 100vh; } diff --git a/src/common/FileDropTarget.tsx b/src/common/FileDropTarget.tsx index c508ee9b7..25301b434 100644 --- a/src/common/FileDropTarget.tsx +++ b/src/common/FileDropTarget.tsx @@ -1,5 +1,6 @@ -import { Box, BoxProps } from "@chakra-ui/layout"; -import { ReactNode, useCallback } from "react"; +import { Box, BoxProps, Center } from "@chakra-ui/layout"; +import { ReactNode, useCallback, useState } from "react"; +import { RiFolderOpenLine } from "react-icons/ri"; interface FileDropTargetProps extends BoxProps { children: ReactNode; @@ -11,8 +12,11 @@ const FileDropTarget = ({ onFileDrop, ...props }: FileDropTargetProps) => { + const [dragOver, setDragOver] = useState(false); + const handleDrop = useCallback( (event: React.DragEvent) => { + setDragOver(false); const file = event.dataTransfer.files[0]; if (file) { event.preventDefault(); @@ -24,10 +28,45 @@ const FileDropTarget = ({ ); const handleDragOver = useCallback((event: React.DragEvent) => { event.preventDefault(); + setDragOver(true); event.dataTransfer.dropEffect = "copy"; }, []); + const handleDragLeave = useCallback((event: React.DragEvent) => { + setDragOver(false); + }, []); return ( - + + {dragOver && ( +
+ +
+ )} {children}
); diff --git a/src/e2e/app.ts b/src/e2e/app.ts index 4ca863e4e..0de3050d8 100644 --- a/src/e2e/app.ts +++ b/src/e2e/app.ts @@ -51,6 +51,8 @@ export class App { const page = await this.page; // Puppeteer doesn't have file drio support but we can use an input // to grab a file and trigger an event that's good enough. + // It's a bit of a pain as the drop happens on an element created by + // the drag-over. // https://github.com/puppeteer/puppeteer/issues/1376 const inputId = "simulated-drop-input"; await page.evaluate((inputId) => { @@ -59,17 +61,27 @@ export class App { input.type = "file"; input.id = inputId; input.onchange = (e: any) => { - const dropZone = document.querySelector( + const dragOverZone = document.querySelector( "[data-testid=project-drop-target]" ); - if (!dropZone) { + if (!dragOverZone) { throw new Error(); } + const dragOverEvent = new Event("dragover", { + bubbles: true, + }); const dropEvent = new Event("drop", { bubbles: true, }); + (dragOverEvent as any).dataTransfer = { files: e.target.files }; (dropEvent as any).dataTransfer = { files: e.target.files }; - dropZone.dispatchEvent(dropEvent); + dragOverZone.dispatchEvent(dragOverEvent); + + const dropZone = document.querySelector( + "[data-testid=project-drop-target-overlay]" + ); + dropZone!.dispatchEvent(dropEvent); + input.remove(); }; document.body.appendChild(input);