All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.src.components.MultipleFileUpload.MultipleFileUploadStatusItem.tsx Maven / Gradle / Ivy

Go to download

This library provides a set of common React components for use with the PatternFly reference implementation.

The newest version!
import * as React from 'react';
import styles from '@patternfly/react-styles/css/components/MultipleFileUpload/multiple-file-upload';
import { css } from '@patternfly/react-styles';
import { Progress } from '../Progress';
import { Button } from '../Button';
import FileIcon from '@patternfly/react-icons/dist/esm/icons/file-icon';
import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon';

/** Automatically reads an uploaded file to render a visual representation of it, including
 * its name, size, and read status. This sub-component also allows custom reading of files
 * via various callbacks which will override the automatic reading behavior.
 */

export interface MultipleFileUploadStatusItemProps extends React.HTMLProps {
  /** Class to add to outer div */
  className?: string;
  /** Adds accessibility text to the status item deletion button */
  buttonAriaLabel?: string;
  /** The file object being represented by the status item */
  file?: File;
  /** A callback for when a selected file starts loading */
  onReadStarted?: (fileHandle: File) => void;
  /** A callback for when a selected file finishes loading */
  onReadFinished?: (fileHandle: File) => void;
  /** A callback for when the FileReader successfully reads the file */
  onReadSuccess?: (data: string, file: File) => void;
  /** A callback for when the FileReader API fails */
  onReadFail?: (error: DOMException, onReadFail: File) => void;
  /** Clear button was clicked */
  onClearClick?: React.MouseEventHandler;

  // Props to bypass built in behavior

  /** A callback to process file reading in a custom way */
  customFileHandler?: (file: File) => void;
  /** A custom icon to show in place of the generic file icon */
  fileIcon?: React.ReactNode;
  /** A custom name to display for the file rather than using built in functionality to auto-fill it */
  fileName?: string;
  /** A custom file size to display for the file rather than using built in functionality to auto-fill it */
  fileSize?: number;
  /** A custom value to display for the progress component rather than using built in functionality to auto-fill it */
  progressValue?: number;
  /** A custom variant to apply to the progress component rather than using built in functionality to auto-fill it */
  progressVariant?: 'danger' | 'success' | 'warning';

  // Props passed through to the progress component

  /** Adds accessible text to the progress bar. Required when title not used and there is not any label associated with the progress bar */
  progressAriaLabel?: string;
  /** Associates the progress bar with it's label for accessibility purposes. Required when title not used */
  progressAriaLabelledBy?: string;
  /** Modifies the text announced by assistive technologies when the progress bar updates. */
  progressAriaLiveMessage?: string | ((loadPercentage: number) => string);
  /** Unique identifier for progress. Generated if not specified. */
  progressId?: string;
  /** Additional content related to the status item. */
  progressHelperText?: React.ReactNode;
}

export const MultipleFileUploadStatusItem: React.FunctionComponent = ({
  className,
  file,
  fileIcon,
  onReadStarted = () => {},
  onReadFinished = () => {},
  onReadSuccess = () => {},
  onReadFail = () => {},
  onClearClick = () => {},
  customFileHandler,
  fileName,
  fileSize,
  progressValue,
  progressVariant,
  progressAriaLabel,
  progressAriaLabelledBy,
  progressId,
  progressAriaLiveMessage,
  buttonAriaLabel = 'Remove from list',
  progressHelperText,
  ...props
}: MultipleFileUploadStatusItemProps) => {
  const [loadPercentage, setLoadPercentage] = React.useState(0);
  const [loadResult, setLoadResult] = React.useState();

  function readFile(file: File) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result);
      reader.onerror = () => reject(reader.error);
      reader.onprogress = (data) => {
        if (data.lengthComputable) {
          setLoadPercentage((data.loaded / data.total) * 100);
        }
      };
      reader.readAsDataURL(file);
    });
  }

  React.useEffect(() => {
    if (customFileHandler) {
      customFileHandler(file);
    } else {
      onReadStarted(file);
      readFile(file)
        .then((data) => {
          setLoadResult('success');
          setLoadPercentage(100);
          onReadFinished(file);
          onReadSuccess(data as string, file);
        })
        .catch((error: DOMException) => {
          onReadFinished(file);
          onReadFail(error, file);
          setLoadResult('danger');
        });
    }
  }, []);

  const getHumanReadableFileSize = (size: number) => {
    const prefixes = ['', 'K', 'M', 'G', 'T'];
    let prefixUnit = 0;
    while (size >= 1000) {
      prefixUnit += 1;
      size = size / 1000;
    }

    if (prefixUnit >= prefixes.length) {
      return 'File size too large';
    }

    return `${Math.round(size)}${prefixes[prefixUnit]}B`;
  };

  const value = progressValue || loadPercentage;
  const variant = progressVariant || loadResult;

  const title = (
    
      {fileName || file?.name || ''}
      
        {fileSize || getHumanReadableFileSize(file?.size || 0)}
      
    
  );

  return (
    
  • {fileIcon || }
    {progressAriaLiveMessage && typeof progressAriaLiveMessage === 'function' && progressAriaLiveMessage(+loadPercentage.toFixed(2))} {progressAriaLiveMessage && typeof progressAriaLiveMessage === 'string' && progressAriaLiveMessage} {!progressAriaLiveMessage && `Progress value is ${progressValue || Math.floor(loadPercentage)}%.`}
  • ); }; MultipleFileUploadStatusItem.displayName = 'MultipleFileUploadStatusItem';




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy