react-dnd-html5-backend#NativeTypes TypeScript Examples

The following examples show how to use react-dnd-html5-backend#NativeTypes. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DropTarget.tsx    From gear-js with GNU General Public License v3.0 4 votes vote down vote up
DropTarget = ({ type, setDroppedFile }: Props) => {
  const alert = useAlert();

  const [wrongFormat, setWrongFormat] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  if (wrongFormat) {
    setTimeout(() => setWrongFormat(false), 3000);
  }

  const checkFileFormat = useCallback((files: any) => {
    if (typeof files[0]?.name === 'string') {
      const fileExt: string = files[0].name.split('.').pop().toLowerCase();
      return fileExt !== 'wasm';
    }
    return true;
  }, []);

  const handleFilesUpload = useCallback(
    (file: File) => {
      setDroppedFile({ file, type });
    },
    [setDroppedFile, type]
  );

  const emulateInputClick = () => {
    inputRef.current?.click();
  };

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const {
      target: { files },
    } = event;
    if (files?.length) {
      const isCorrectFormat = checkFileFormat(files);
      setWrongFormat(isCorrectFormat);
      if (!isCorrectFormat) {
        handleFilesUpload(files[0]);
        // since type='file' input can't be controlled,
        // reset it's value to trigger onChange again in case the same file selected twice
        event.target.value = '';
      } else {
        alert.error('Wrong file format');
        setWrongFormat(false);
      }
    }
  };

  const handleFileDrop = useCallback(
    (item) => {
      if (item) {
        const { files } = item;
        const isCorrectFormat = checkFileFormat(files);
        setWrongFormat(isCorrectFormat);
        if (!isCorrectFormat) {
          handleFilesUpload(files[0]);
        } else {
          alert.error('Wrong file format');
          setWrongFormat(false);
        }
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [checkFileFormat, handleFilesUpload]
  );

  const [{ canDrop, isOver }, drop] = useDrop(
    () => ({
      accept: [NativeTypes.FILE],
      drop(item: { files: any[] }) {
        if (handleFileDrop) {
          handleFileDrop(item);
        }
      },
      collect: (monitor: DropTargetMonitor) => ({
        isOver: monitor.isOver(),
        canDrop: monitor.canDrop(),
      }),
    }),
    [handleFileDrop]
  );

  const isActive = canDrop && isOver;
  const className = clsx(styles.drop, isActive && styles.active);
  const isProgramUpload = type === UploadTypes.PROGRAM;
  const buttonText = `Upload ${type}`;

  return (
    <div className={className} ref={drop}>
      {isActive ? (
        <div className={styles.file}>
          <span className={styles.text}>Drop your .wasm files here to upload</span>
        </div>
      ) : (
        <div className={styles.noFile}>
          <input className={styles.input} ref={inputRef} type="file" onChange={handleChange} />
          <Button
            text={buttonText}
            icon={isProgramUpload ? upload : editor}
            color={isProgramUpload ? 'primary' : 'secondary'}
            onClick={emulateInputClick}
          />
          <div className={styles.text}>{`Click “${buttonText}” to browse or drag and drop your .wasm files here`}</div>
        </div>
      )}
    </div>
  );
}
Example #2
Source File: FileUploaderArea.tsx    From querybook with Apache License 2.0 4 votes vote down vote up
FileUploaderArea: React.FC<IFileUploaderAreaProps> = ({
    onUpload,
    file: selectedFile,
}) => {
    const noDropReasonRef = React.useRef('');

    const [{ canDrop, isOver, noDropReason }, dropRef] = useDrop<
        IDragObjectFiles,
        unknown,
        {
            isOver: boolean;
            canDrop: boolean;
            noDropReason: string;
        }
    >({
        accept: NativeTypes.FILE,
        drop: (fileDropped) => {
            const file = fileDropped.items[0].getAsFile();
            onUpload(file);
        },
        canDrop: (fileToBeDropped) => {
            let rejectReason = '';

            // Not sure why but sometimes items is empty or files is empty
            // So we just check whichever one that is not empty
            if (fileToBeDropped.items.length > 1) {
                rejectReason = 'Cannot drop multiple files';
            } else if (
                fileToBeDropped.items.length > 0 &&
                !(fileToBeDropped.items[0].type in AllowedMimeTypesDict)
            ) {
                rejectReason = `Allowed types: ${AllowedFileTypes}`;
            }

            noDropReasonRef.current = rejectReason;

            return rejectReason === '';
        },
        collect: (monitor) => {
            const canDrop = monitor.canDrop();
            return {
                isOver: monitor.isOver(),
                canDrop,
                noDropReason: canDrop ? '' : noDropReasonRef.current,
            };
        },
    });

    let innerMessageDOM: React.ReactNode;
    let uploadedFileDOM: React.ReactNode;
    if (!isOver) {
        innerMessageDOM = (
            <div>
                <div className="mb8">
                    <StyledText untitled>
                        Drag a file here to upload (Allowed types:{' '}
                        {AllowedFileTypes})
                    </StyledText>
                </div>

                <FileUploaderButton onUpload={onUpload} />
            </div>
        );
        uploadedFileDOM = selectedFile && (
            <div className="mt4 flex-row">
                <div className="flex-row">
                    <Icon name="File" className="mr4" size="16" />
                    <StyledText>{selectedFile.name}</StyledText>
                </div>

                <IconButton icon="X" onClick={() => onUpload(null)} />
            </div>
        );
    } else {
        if (canDrop) {
            innerMessageDOM = <StyledText>Release to upload</StyledText>;
        } else {
            innerMessageDOM = (
                <StyledText>Not allowed to drop: {noDropReason}</StyledText>
            );
        }
    }

    return (
        <StyledDropArea ref={dropRef} isActive={isOver && canDrop}>
            {innerMessageDOM}
            {uploadedFileDOM}
        </StyledDropArea>
    );
}