react-feather#Paperclip TypeScript Examples

The following examples show how to use react-feather#Paperclip. 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: FilesList.tsx    From ke with MIT License 6 votes vote down vote up
export function FilesList({
  value,
  onChange,
  listItemIcon = Paperclip,
  linkProps,
}: FilesListProps): ReactElement<FilesListProps> {
  const deleteFile = (file: FileDescriptor): void => {
    const restFiles = value.filter((f) => f.uuid !== file.uuid)
    onChange(restFiles)
  }

  return (
    <List>
      {value.map((file) => (
        <ListItem display="flex" alignItems="center" className={listItemCss} key={file.uuid}>
          <ListIcon as={listItemIcon} />
          {file?.url ? (
            <Link href={file.url} isExternal {...linkProps}>
              {file.name}
            </Link>
          ) : (
            file.name
          )}
          <IconButton
            aria-label="Удалить"
            variant="unstyled"
            size="xs"
            icon={<X color="red" size={16} />}
            ml={2}
            onClick={() => deleteFile(file)}
          />
        </ListItem>
      ))}
    </List>
  )
}
Example #2
Source File: FilesList.tsx    From ke with MIT License 6 votes vote down vote up
export function FilesList({
  value,
  listItemIcon = Paperclip,
  linkProps,
}: FilesListProps): ReactElement<FilesListProps> {
  return (
    <List>
      {value.map((file) => (
        <ListItem key={file.uuid}>
          <ListIcon as={listItemIcon} />
          {file?.url ? (
            <Link href={file.url} isExternal {...linkProps}>
              {file.name}
            </Link>
          ) : (
            file.name
          )}
        </ListItem>
      ))}
    </List>
  )
}
Example #3
Source File: UploadButton.tsx    From ke with MIT License 4 votes vote down vote up
export function UploadButton({
  onSelect,
  onUpload,
  label = 'Прикрепить ещё один файл',
  buttonProps,
  maxFileSize,
  multiple,
}: UploadButtonProps): ReactElement<UploadButtonProps> {
  const [loadingFiles, setLoadingFiles] = useState<LoadingFileDescriptor[]>([])
  const [fileErrors, setFileErrors] = useState<string[]>([])

  const hiddenFileInput = useRef<HTMLInputElement>(null)

  const handleClick = useCallback(() => {
    hiddenFileInput.current?.click()
  }, [])

  const removeFromLoading = useCallback((key: string) => {
    setLoadingFiles((prev) => prev.filter((desc) => desc.key !== key))
  }, [])

  const handleFileSelect = useCallback(
    (event: ChangeEvent<HTMLInputElement>) => {
      setFileErrors([])
      const uploadingPromises = Array.from(event.target.files || []).map(
        (file: File): Promise<CombinedFileDescriptor | null> => {
          const start = new Date()
          const key = `${file.name}-${new Date()}`
          const loadingFile: LoadingFileDescriptor = {
            key,
            name: file.name,
            loaded: 0,
            total: file.size,
            start,
          }

          if (maxFileSize && file.size > maxFileSize) {
            setFileErrors((prev) => [
              ...prev,
              `Размер файла ${file.name} превышает допустимый максимальный размер ${Filesize(maxFileSize)}`,
            ])
            return Promise.resolve(null)
          }

          setLoadingFiles((prev) => [...prev, loadingFile])

          return onSelect(file, ({ loaded, total }) => {
            setLoadingFiles((prev) => prev.map((desc) => (desc.key === key ? { ...desc, loaded, total } : desc)))
          })
            .then((loadedDesc: FileDescriptor) => ({ loadingDescriptor: loadingFile, fileDescriptor: loadedDesc }))
            .catch((error) => {
              removeFromLoading(key)
              throw error
            })
        }
      )
      Promise.allSettled(uploadingPromises)
        .then((result) =>
          result
            .filter(
              (item): item is PromiseFulfilledResult<CombinedFileDescriptor | null> => item.status === 'fulfilled'
            )
            .filter((item): item is PromiseFulfilledResult<CombinedFileDescriptor> => item.value !== null)
            .map(({ value }) => {
              removeFromLoading(value.loadingDescriptor.key)
              return value.fileDescriptor
            })
        )
        .then(onUpload)
      // eslint-disable-next-line no-param-reassign
      event.target.value = ''
    },
    [onUpload, maxFileSize, onSelect, removeFromLoading]
  )

  return (
    <>
      <UploadingList files={loadingFiles} />
      <Button
        leftIcon={<Paperclip size={18} />}
        size="sm"
        mt="5px"
        {...buttonProps}
        onClick={handleClick}
        isDisabled={buttonProps?.isDisabled || !!loadingFiles.length}
      >
        {label}
      </Button>
      {fileErrors.map((error, index) => {
        const errorIndex = index
        return (
          <Text color="red" key={errorIndex} fontSize="sm">
            {error}
          </Text>
        )
      })}
      <input
        type="file"
        ref={hiddenFileInput}
        onChange={handleFileSelect}
        style={{ display: 'none' }}
        multiple={multiple}
      />
    </>
  )
}