react-dropzone#DropzoneRef TypeScript Examples

The following examples show how to use react-dropzone#DropzoneRef. 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: handlers.ts    From leda with MIT License 6 votes vote down vote up
createClickHandler = (
  { onClick, isDisabled }: DropZoneProps,
  state: DropZoneState,
  ref: React.MutableRefObject<DropzoneRef | null>,
): React.MouseEventHandler => (ev: React.MouseEvent<HTMLDivElement>): void => {
  if (!isDisabled && ref.current && (ev.target as HTMLDivElement).tagName === 'BUTTON') ref.current.open();

  if (isFunction(onClick)) onClick(ev);
}
Example #2
Source File: handlers.ts    From leda with MIT License 6 votes vote down vote up
createClickHandler = (props: FileUploadProps & { fileUploadRef: React.MutableRefObject<DropzoneRef | undefined>}): CustomEventHandler<React.MouseEvent<HTMLDivElement>> => (ev) => {
  const { isLoading, onClick, fileUploadRef } = props;
  const customEvent = {
    ...ev,
    defaultPrevented: false, // somehow it is true (prevented) by default
  };

  customEvent.preventDefault = () => {
    customEvent.defaultPrevented = true;
  };

  if (isFunction(onClick)) onClick(customEvent);

  if (customEvent.defaultPrevented) return;

  if (!isLoading && fileUploadRef.current) fileUploadRef.current.open();
}
Example #3
Source File: RichEditorInternal.tsx    From clearflask with Apache License 2.0 5 votes vote down vote up
readonly dropzoneRef: React.RefObject<DropzoneRef> = React.createRef();
Example #4
Source File: InputFile.tsx    From crust-apps with Apache License 2.0 5 votes vote down vote up
function InputFile ({ accept, className = '', clearContent, help, isDisabled, isError = false, isFull, label, onChange, placeholder, withEllipsis, withLabel }: InputFileProps): React.ReactElement<InputFileProps> {
  const { t } = useTranslation();
  const dropRef = createRef<DropzoneRef>();
  const [file, setFile] = useState<FileState | undefined>();

  const _onDrop = useCallback(
    (files: File[]): void => {
      files.forEach((file): void => {
        const reader = new FileReader();

        reader.onabort = NOOP;
        reader.onerror = NOOP;

        reader.onload = ({ target }: ProgressEvent<FileReader>): void => {
          if (target && target.result) {
            const name = file.name;
            const data = convertResult(target.result as ArrayBuffer);

            onChange && onChange(data, name);
            dropRef && setFile({
              name,
              size: data.length
            });
          }
        };

        reader.readAsArrayBuffer(file);
      });
    },
    [dropRef, onChange]
  );

  const dropZone = (
    <Dropzone
      accept={accept}
      disabled={isDisabled}
      multiple={false}
      onDrop={_onDrop}
      ref={dropRef}
    >
      {({ getInputProps, getRootProps }): JSX.Element => (
        <div {...getRootProps({ className: `ui--InputFile${isError ? ' error' : ''} ${className}` })} >
          <input {...getInputProps()} />
          <em className='label' >
            {
              !file || clearContent
                ? placeholder || t<string>('click to select or drag and drop the file here')
                : placeholder || t<string>('{{name}} ({{size}} bytes)', {
                  replace: {
                    name: file.name,
                    size: formatNumber(file.size)
                  }
                })
            }
          </em>
        </div>
      )}
    </Dropzone>
  );

  return label
    ? (
      <Labelled
        help={help}
        isFull={isFull}
        label={label}
        withEllipsis={withEllipsis}
        withLabel={withLabel}
      >
        {dropZone}
      </Labelled>
    )
    : dropZone;
}
Example #5
Source File: handlers.ts    From leda with MIT License 5 votes vote down vote up
createClickHandler = (
  { onClick, isDisabled }: FileDropProps,
  ref: React.MutableRefObject<DropzoneRef | null>,
): React.MouseEventHandler => (ev: React.MouseEvent<HTMLDivElement>): void => {
  if (!isDisabled && (ev.target as HTMLElement).tagName === 'BUTTON') ref.current?.open();

  onClick?.(ev);
}
Example #6
Source File: InputFile.tsx    From subscan-multisig-react with Apache License 2.0 5 votes vote down vote up
function InputFile({
  accept,
  className = '',
  clearContent,
  help,
  isDisabled,
  isError = false,
  isFull,
  label,
  onChange,
  placeholder,
  withEllipsis,
  withLabel,
}: InputFileProps): React.ReactElement<InputFileProps> {
  const { t } = useTranslation();
  const dropRef = createRef<DropzoneRef>();
  const [file, setFile] = useState<FileState | undefined>();

  const _onDrop = useCallback(
    (files: File[]): void => {
      files.forEach((file): void => {
        const reader = new FileReader();

        reader.onabort = NOOP;
        reader.onerror = NOOP;

        reader.onload = ({ target }: ProgressEvent<FileReader>): void => {
          if (target && target.result) {
            const name = file.name;
            const data = convertResult(target.result as ArrayBuffer);

            // eslint-disable-next-line
            onChange && onChange(data, name);
            // eslint-disable-next-line
            dropRef &&
              setFile({
                name,
                size: data.length,
              });
          }
        };

        reader.readAsArrayBuffer(file);
      });
    },
    [dropRef, onChange]
  );

  const dropZone = (
    <Dropzone accept={accept} disabled={isDisabled} multiple={false} onDrop={_onDrop} ref={dropRef}>
      {({ getInputProps, getRootProps }: Record<string, any>): JSX.Element => (
        <div {...getRootProps({ className: `ui--InputFile${isError ? ' error' : ''} ${className}` })}>
          <input {...getInputProps()} />
          <em className="label">
            {!file || clearContent
              ? placeholder || t<string>('click to select or drag and drop the file here')
              : placeholder ||
                t<string>('{{name}} ({{size}} bytes)', {
                  replace: {
                    name: file.name,
                    size: formatNumber(file.size),
                  },
                })}
          </em>
        </div>
      )}
    </Dropzone>
  );

  return label ? (
    <Labelled help={help} isFull={isFull} label={label} withEllipsis={withEllipsis} withLabel={withLabel}>
      {dropZone}
    </Labelled>
  ) : (
    dropZone
  );
}
Example #7
Source File: DropZone.tsx    From leda with MIT License 4 votes vote down vote up
DropZone = React.forwardRef((props: DropZoneProps, ref: React.Ref<DropZoneRefCurrent>): React.ReactElement => {
  const {
    allowedFiles,
    className,
    dropZoneFilesNode,
    forbiddenFiles,
    isDisabled,
    isRequired,
    maxFileSize = MAX_FILE_SIZE,
    maxFilesNumber,
    minFileSize = MIN_FILE_SIZE,
    value: valueProps,
  } = useProps(props);


  const dropZoneRef = React.useRef<DropzoneRef | null>(null);

  const theme = useTheme(props.theme, 'dropZone');

  const [stateValue, setStateValue] = React.useState<DropZoneState>({
    rejectedFiles: [],
    acceptedFiles: [],
  });

  const value = valueProps || stateValue;

  const handleChange = createChangeHandler(props, stateValue, setStateValue);

  const state = React.useMemo(() => ({ value: stateValue }), [stateValue]);

  const extra = React.useMemo(() => ({ reset: () => handleChange([], []) }), [handleChange]);

  const { isValid, InvalidMessage, validateCurrent } = useValidation(props, state, extra);

  const handleClick = createClickHandler(props, stateValue, dropZoneRef);

  const combinedClassNames = getClassNames(
    className,
    theme.wrapper,
    {
      [theme.disabled]: isDisabled,
      [theme.invalid]: !isValid,
      [theme.required]: getIsEmptyAndRequired(value, isRequired),
    },
  );

  const combinedButtonClassNames = getClassNames(theme.button, { [theme.disabled]: isDisabled });

  const combinedContentClassNames = getClassNames(theme.content, { [theme.disabled]: isDisabled });

  const singleMode = maxFilesNumber && maxFilesNumber <= 1;

  const { getRootProps, getInputProps, open } = useDropzone({
    onDrop: (...args) => {
      const newValue = handleChange(...args as Parameters<ChangeEventHandler>);
      validateCurrent(newValue);
    },
    accept: allowedFiles,
    maxSize: maxFileSize,
    multiple: !singleMode,
    disabled: isDisabled,
  });

  dropZoneRef.current = { open };

  const {
    AcceptedFiles, RejectedFiles, Info, UploadButton, Wrapper,
  } = useCustomElements(props, stateValue);

  const rootProps = getRootProps();

  const restProps = useDropZoneRestProps(props);

  const inputProps = { ...restProps, ...getInputProps() };

  return (
    <>
      <Wrapper
        className={combinedClassNames}
        ref={ref && ((component) => bindFunctionalRef(component, ref, component && {
          wrapper: component.wrapper,
          input: component.wrapper && component.wrapper.querySelector('input'),
        }))}
      >
        <Div
          {...rootProps}
          onClick={handleClick}
          className={combinedContentClassNames}
          ref={(component) => {
            rootProps.ref.current = component ? component.wrapper : null;
          }}
        >
          <input {...inputProps} />
          <UploadButton
            className={combinedButtonClassNames}
          >
            Выбрать...
          </UploadButton>
          {' '}
          <Info className={theme.description}>
            <DescriptionMessage>
              Перетащите сюда файлы для загрузки.
            </DescriptionMessage>
            {' '}
            <DescriptionMessage>
              {messages.getFileSizeDescription(minFileSize, maxFileSize, 'byte')}
            </DescriptionMessage>
            {' '}
            <DescriptionMessage>
              {messages.getMaxFilesDescription(maxFilesNumber)}
            </DescriptionMessage>
            {' '}
            <DescriptionMessage>
              {messages.getFormatsDescription(allowedFiles)}
            </DescriptionMessage>
            {' '}
            <DescriptionMessage>
              {messages.getForbiddenFormatsDescription(forbiddenFiles)}
            </DescriptionMessage>
          </Info>
        </Div>
      </Wrapper>
      <InvalidMessage />
      <RejectedFiles
        className={theme.rejectedFilesWrapper}
      >
        <RejectedFilesList
          maxFilesNumber={maxFilesNumber}
          theme={theme}
          value={value}
        />
      </RejectedFiles>
      <AcceptedFiles
        dropZoneFilesNode={dropZoneFilesNode}
        onChange={handleChange}
      >
        <DropZoneFiles
          files={value.acceptedFiles}
          onChange={handleChange}
          shouldRender={value.acceptedFiles.length > 0}
          theme={theme}
          value={value}
        />
      </AcceptedFiles>
    </>
  );
}) as React.FC<DropZoneProps>
Example #8
Source File: FileDrop.tsx    From leda with MIT License 4 votes vote down vote up
FileDrop = React.forwardRef((props: FileDropProps, ref: React.Ref<FileDropRefCurrent>): React.ReactElement => {
  const {
    allowedFiles,
    className,
    error,
    isDisabled,
    isRequired,
    maxFileSize = MAX_FILE_SIZE,
    value,
  } = useProps(props);

  const fileDropRef = React.useRef<DropzoneRef | null>(null);

  const theme = useTheme(props.theme, 'fileDrop');

  const handleChange = createChangeHandler(props);

  const state = React.useMemo(() => ({ }), []);

  const extra = React.useMemo(() => ({ reset: () => handleChange([], []) }), [handleChange]);

  const { isValid, InvalidMessage, validateCurrent } = useValidation(props, state, extra);

  const handleClick = createClickHandler(props, fileDropRef);

  const combinedContentClassNames = getClassNames(theme.content, { [theme.disabled]: isDisabled });

  const { getRootProps, getInputProps, open } = useDropzone({
    onDrop: (acceptedFiles, rejectedFiles, event) => {
      const newValue = handleChange(acceptedFiles, rejectedFiles, event as React.DragEvent<HTMLDivElement>);
      validateCurrent(error ? null : newValue);
    },
    accept: allowedFiles,
    maxSize: maxFileSize,
    multiple: false,
    disabled: isDisabled,
  });

  const combinedClassNames = getClassNames(
    className,
    theme.wrapper,
    {
      [theme.disabled]: isDisabled,
      [theme.invalid]: !isValid,
      [theme.required]: getIsEmptyAndRequired(value, isRequired),
    },
  );

  fileDropRef.current = { open };

  const {
    ErrorItem, SuccessItem, DefaultItem, LoadingItem, UploadButton, Wrapper,
  } = useCustomElements(props);

  const rootProps = getRootProps();

  const restProps = useFileDropRestProps(props);

  const inputProps = { ...getInputProps(), ...restProps };

  return (
    <>
      <Wrapper
        className={combinedClassNames}
        ref={ref && ((component) => bindFunctionalRef(component, ref, component && {
          wrapper: component.wrapper,
          input: component.wrapper && component.wrapper.querySelector('input'),
        }))}
      >
        <Div
          {...rootProps}
          onClick={handleClick}
          className={combinedContentClassNames}
          ref={(component) => {
            rootProps.ref.current = component ? component.wrapper : null;
          }}
        >
          <input {...inputProps} />
          {' '}
          <SingleFileView
            {...props}
            theme={theme}
            value={value}
            UploadButton={UploadButton}
            ErrorItem={ErrorItem}
            LoadingItem={LoadingItem}
            SuccessItem={SuccessItem}
            DefaultItem={DefaultItem}
          />
        </Div>
      </Wrapper>
      <InvalidMessage />
    </>
  );
}) as React.FC<FileDropProps>
Example #9
Source File: index.tsx    From leda with MIT License 4 votes vote down vote up
FileUpload = React.forwardRef((props: FileUploadProps, ref: React.Ref<FileUploadRefCurrent>): React.ReactElement => {
  const {
    allowedFiles,
    forbiddenFiles,
    className,
    isLoading,
    maxFileSize = MAX_FILE_SIZE,
    minFileSize = MIN_FILE_SIZE,
    onChange,
    onClick,
    onFileLoad,
    ref: refProp, // exclude from restProps
    infoRender,
    wrapperRender,
    validator,
    shouldValidateUnmounted,
    isValid: isValidProp,
    isRequired,
    invalidMessage,
    invalidMessageRender,
    requiredMessage,
    ...restProps
  } = useProps(props);

  const fileUploadRef = React.useRef<DropzoneRef | undefined>();

  const handleClick = createClickHandler({ ...props, fileUploadRef });

  const handleLoad = createLoadHandler(props);
  const handleChange = createChangeHandler(props);

  const state = React.useMemo(() => ({ }), []);

  const extra = React.useMemo(() => ({ reset: () => handleLoad([], []) }), [handleLoad]);

  const { isValid, InvalidMessage, validateCurrent } = useValidation(props, state, extra);

  const { getRootProps, getInputProps, open } = useDropzone({
    accept: allowedFiles,
    maxSize: maxFileSize,
    minSize: minFileSize,
    multiple: false,
    onDrop: (acceptedFiles, rejectedFiles) => {
      const newValue = handleLoad(acceptedFiles, rejectedFiles);
      validateCurrent(newValue);
      handleChange(acceptedFiles, rejectedFiles);
    },
  });

  fileUploadRef.current = { open };

  const { Wrapper, Info } = useCustomElements(props);

  const rootProps = getRootProps();

  return (
    <>
      <Wrapper
        className={className}
        onClick={handleClick}
        aria-invalid={!isValid}
        ref={ref && ((component) => bindFunctionalRef(component, ref, component && {
          wrapper: component.wrapper || component,
        }))}
      >
        <Info>
          {isLoading ? 'Загрузка...' : 'Загрузить'}
        </Info>
        <Div
          {...rootProps}
          ref={(component) => {
            rootProps.ref.current = component ? component.wrapper : null;
          }}
        >
          <input {...restProps} {...getInputProps()} />
        </Div>
      </Wrapper>
      <InvalidMessage />
    </>
  );
}) as React.FC<FileUploadProps>
Example #10
Source File: InputFile.tsx    From contracts-ui with GNU General Public License v3.0 4 votes vote down vote up
export function InputFile({
  className = '',
  errorMessage,
  value: propsFile,
  isError,
  onChange,
  placeholder,
  onRemove,
}: Props) {
  const ref = createRef<DropzoneRef>();
  const [file, setFile] = useState<OrFalsy<FileState>>(propsFile);

  const onDrop = useCallback(
    (files: File[]): void => {
      files.forEach((file): void => {
        const reader = new FileReader();

        reader.onabort = NOOP;
        reader.onerror = NOOP;

        reader.onload = ({ target }: ProgressEvent<FileReader>): void => {
          if (target && target.result) {
            const name = file.name;
            const data = convertResult(target.result as ArrayBuffer);
            const size = data.length;

            onChange && onChange({ data, name, size });
            ref &&
              !propsFile &&
              setFile({
                data,
                name,
                size: data.length,
              });
          }
        };

        reader.readAsArrayBuffer(file);
      });
    },
    [ref, onChange, propsFile]
  );

  const removeHandler = useCallback((): void => {
    onRemove && onRemove();

    !propsFile && setFile(undefined);
  }, [onRemove, propsFile]);

  useEffect((): void => {
    if (file !== propsFile) {
      setFile(propsFile);
    }
  }, [file, propsFile]);

  return file ? (
    <div className={`${className} flex`}>
      <div className="p-6 border dark:bg-elevation-1 dark:border-gray-700 border-gray-300 inline-flex items-center rounded shadow">
        <DocumentTextIcon
          className="w-7 h-7 mr-2 text-gray-500 justify-self-start"
          aria-hidden="true"
        />
        <span className="dark:text-gray-300 text-gray-500 text-xs min-w-600 justify-self-start mr-20">
          {file.name} ({(file.size / 1000).toFixed(2)}kb)
        </span>
        {errorMessage && isError && (
          <span className="dark:text-gray-300 text-gray-500 text-xs min-w-600 justify-self-start mr-20">
            {errorMessage}
          </span>
        )}
        <XIcon
          className="w-5 h-5 mr-2 text-gray-500 justify-self-end cursor-pointer"
          aria-hidden="true"
          onClick={removeHandler}
        />
      </div>
    </div>
  ) : (
    <Dropzone multiple={false} onDrop={onDrop} ref={ref}>
      {({ getInputProps, getRootProps }) => {
        return (
          <div className={className} {...getRootProps()}>
            <label
              className="dark:text-gray-700 text-gray-400 font-normal py-2 px-4 border dark:border-gray-700 border-gray-200 rounded flex flex-col h-36 items-center cursor-pointer justify-center"
              htmlFor="file"
            >
              <svg
                xmlns="http://www.w3.org/2000/svg"
                className="h-8 mb-2 dark:text-gray-500"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"
                />
              </svg>
              <span className="text-sm dark:text-gray-500 text-gray-400">{placeholder}</span>
            </label>
            <input {...getInputProps()} data-cy="file-input" />
          </div>
        );
      }}
    </Dropzone>
  );
}