Fermer

septembre 27, 2022

Comment implémenter un composant React Upload (DropZone)


Une zone de dépôt React prête à l’emploi ou un composant de téléchargement React peut vous faciliter la vie. Nous allons jeter un coup d’oeil!

Il existe de nombreuses situations différentes dans lesquelles les utilisateurs doivent pouvoir télécharger des fichiers sur un site Web. Par exemple, un site Web de médias sociaux peut permettre à un utilisateur de télécharger sa photo de profil, et un client de messagerie doit permettre aux utilisateurs de joindre et d’envoyer des fichiers à d’autres personnes. Un fichier peut être téléchargé à l’aide d’un élément d’entrée avec le type mis à filemais soyons honnêtes, ce n’est pas la meilleure façon de télécharger des fichiers.

Heureusement, il existe des solutions prêtes à l’emploi et riches en fonctionnalités disponibles pour les applications React, telles que Réagissez Dropzone ou la Composant React Upload trouvé dans la bibliothèque KendoReact. Dans cet article, nous expliquerons comment utiliser ce dernier pour créer une fonctionnalité de téléchargement attrayante.

Code source

Vous pouvez trouver l’exemple de code complet pour cet article dans ce référentiel GitHub. Ci-dessous, vous pouvez également trouver un exemple interactif de StackBlitz.

Configuration du projet

Si vous voulez suivre l’article, vous pouvez créer un nouveau projet React en utilisant Vite. Exécutez la commande ci-dessous dans votre terminal.

$ npm create vite@latest how-to-work-with-the-kendoreact-upload-component

Ensuite, nous devons installer les dépendances nécessaires au projet, puis démarrer le serveur de développement.

$ cd how-to-work-with-the-kendoreact-upload-component
$ npm install @progress/kendo-react-upload @progress/kendo-licensing @progress/kendo-theme-default
$ npm run dev

Enfin, faisons un peu de nettoyage et configurons le Thème par défaut de KendoReact.

src/App.jsx

import "./App.css";
 
function App() {
  return <div className="App"></div>;
}
 
export default App;

src/App.css

.App {
  max-width: 40rem;
  margin: 2rem auto;
}

src/main.jsx

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "@progress/kendo-theme-default/dist/all.css";
import "./index.css";
 
ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Voilà pour le nettoyage. Voyons comment nous pouvons utiliser le composant React Upload fourni par KendoReact.

Si vous souhaitez en savoir plus sur les thèmes de l’interface utilisateur de Kendo, consultez le Construire un système de conception avec Kendo UI article.

Ajout d’un composant de téléchargement de fichier React

Le composant Upload (également appelé dropzone) fourni par KendoReact est disponible dans le @progress/kendo-react-upload package, que nous avons installé auparavant. L’extrait de code ci-dessous montre comment il peut être utilisé.

src/App.jsx

import "./App.css";
import { Upload } from "@progress/kendo-react-upload";
 
const saveUrl = "https://demos.telerik.com/kendo-ui/service-v4/upload/save";
const removeUrl = "https://demos.telerik.com/kendo-ui/service-v4/upload/remove";
 
function App() {
  return (
    <div className="App">
      <Upload
        defaultFiles={[]}
        withCredentials={false}
        saveUrl={saveUrl}
        removeUrl={removeUrl}
      />
    </div>
  );
}
 
export default App;

Comme le montre l’image suivante, KendoReact nous fournit un élégant bloc de téléchargement.

Le composant React Upload a un bouton pour sélectionner des fichiers et toute la barre permet de déposer des fichiers ici pour les télécharger

Et voici l’élément de fichier d’entrée par défaut.

L'entrée de fichier par défaut a un bouton Choisir un fichier et signale actuellement qu'aucun fichier n'a été choisi

La différence dans l’interface utilisateur est stupéfiante, et ce n’est pas tout. Le composant React Upload prend en charge mondialisation, glisser déposer et zone de largage externe fonctionnalité, affiche la liste des fichiers téléchargés dans une liste bien formatée et permet restreindre la taille minimale et maximaleaussi bien que types de fichiers autorisés. De plus, la progression du téléchargement est affichée pour chaque fichier et les nouveaux fichiers peuvent facilement être supprimés.

KendoReact Téléchargement et suppression de fichiers dans le composant dropzone de téléchargement React.  Une fois ajoutés, les fichiers s'affichent dans une liste et peuvent facilement être X-ed pour les supprimer

Une autre fonctionnalité intéressante est la possibilité de réessayer. Si un téléchargement échoue, un bouton de nouvelle tentative peut être utilisé pour réessayer de télécharger un fichier.

La capacité de nouvelle tentative du composant KendoReact Upload dans le composant de zone de dépôt React Upload

Voyons comment nous pouvons utiliser certaines des fonctionnalités intéressantes du composant React Upload de KendoReact. Ensuite, nous verrons comment désactiver la fonctionnalité de téléchargement et définir des restrictions pour les fichiers téléchargés, tels que les types de fichiers et la taille minimale et maximale.

Désactivation du téléchargement et restriction des types et tailles de fichiers

C’est un jeu d’enfant de désactiver et de configurer les restrictions de taille et de type de fichier dans ce composant React Upload. Pour désactiver le composant Upload, il suffit de passer le disabled soutenir.

src/App.jsx

<Upload
  defaultFiles={[]}
  withCredentials={false}
  saveUrl={saveUrl}
  removeUrl={removeUrl}
  disabled
  />

Comme le montre l’image ci-dessous, l’ensemble du composant de téléchargement sera grisé.

React-upload-dropzone-component-disabled-state

La taille de fichier autorisée peut être restreinte en passant un objet avec minFileSize et maxFileSize au restrictions soutenir.

src/App.jsx

<Upload
  defaultFiles={[]}
  withCredentials={false}
  saveUrl={saveUrl}
  removeUrl={removeUrl}
  restrictions={{
    minFileSize: 50000,
    maxFileSize: 10000000,
  }}
/>

Une erreur s’affiche si un utilisateur essaie de télécharger un fichier dont la taille est inférieure à minFileSize ou plus grand que maxFileSize.

Fichier trop petit erreur

Les types de fichiers peuvent être limités en fournissant allowedExtensions tableau dans le cadre du restrictions objet accessoire.

src/App.jsx

<Upload
  defaultFiles={[]}
  withCredentials={false}
  saveUrl={saveUrl}
  removeUrl={removeUrl}
  restrictions={{
    minFileSize: 1000,
    maxFileSize: 10000000,
    allowedExtensions: [".jpg", ".png"],
  }}
/>

Dans l’extrait de code ci-dessus, nous avons défini que le composant Upload ne doit accepter que .jpg et .png extensions. Si nous essayons de télécharger un fichier avec une extension différente, une erreur s’affichera, comme indiqué dans le GIF ci-dessous.

Une erreur de type de fichier incorrect indique que ce type de fichier n'est pas pris en charge lorsqu'un fichier est déposé sur le composant de téléchargement

Voyons ensuite comment personnaliser la liste des éléments téléchargés.

Personnalisation de la sortie rendue avec un aperçu

Par défaut, le composant de téléchargement affiche différentes icônes en fonction des extensions de fichier des fichiers téléchargés. Mais que se passe-t-il si nous souhaitons afficher un aperçu de l’image téléchargée par un utilisateur ? Heureusement, ce composant React Dropzone nous permet de remplacer le composant utilisé pour rendre les fichiers téléchargés.

Nous pouvons le faire en passant un accessoire appelé listItemUI. Il accepte un composant personnalisé qui recevra quelques accessoires utiles, tels que files, disabled, async et des procédés pour annuler un téléchargement, réessayer et supprimer un fichier. Voici une coutume UploadFileItem composant.

src/UploadFileItem.jsx

import { UploadFileStatus } from "@progress/kendo-react-upload";
import { useEffect, useState } from "react";
import { getTotalFilesSizeMessage } from "./getTotalFilesSizeMessage";
import { getFileExtensionIcon } from "./getFileExtensionIcon";
 
const errors = {
  invalidFileExtension: "This file type is not supported.",
  invalidMaxFileSize: "This file is too big.",
  invalidMinFileSize: "This file is too small.",
  uploadFailed: "File(s) failed to upload.",
};
 
const getFileError = file => {
  if (file.status === UploadFileStatus.UploadFailed) {
    return errors.uploadFailed;
  }
 
  if (file.validationErrors && file.validationErrors.length) {
    return errors[file.validationErrors[0]];
  }
 
  return "";
};
 
const UploadedFileItem = props => {
  const { files, onRetry, onRemove } = props;
  const [preview, setPreview] = useState(null);
  const file = files?.[0];
  const { status } = file;
 
  const isProgressVisible = status === UploadFileStatus.Uploading;
  const isValidationError =
    file.validationErrors && file.validationErrors.length;
  const isUploadError = status === UploadFileStatus.UploadFailed;
  const isActionVisible =
    isValidationError ||
    [
      UploadFileStatus.Uploaded,
      UploadFileStatus.Initial,
      UploadFileStatus.UploadFailed,
    ].includes(status);
 
  useEffect(() => {
    if (![".jpg", ".jpeg", ".png"].includes(file.extension)) return;
    const rawFile = file.getRawFile();
    
    const reader = new FileReader();
    const onLoad = e => {
      console.log("on load", e);
      setPreview(e.target.result);
    };
 
    reader.addEventListener("load", onLoad);
    reader.readAsDataURL(rawFile);
    return () => {
      reader.removeEventListener("load", onLoad);
    };
  }, [status, file]);
 
  return (
    <>
      <div className="k-file-single">
        <span className="k-file-group-wrapper">
          {preview ? (
            <span className="k-file-group">
              <img
                style={{ maxWidth: "32px", display: "block" }}
                src={preview}
                alt={`${file.name} preview image`}
              />
            </span>
          ) : (
            <span
              className={`k-file-group k-icon ${getFileExtensionIcon(file)}`}
            ></span>
          )}
        </span>
        <span className="k-file-name-size-wrapper">
          {isUploadError || isValidationError ? (
            <>
              <div className="k-file-name k-file-name-invalid">{file.name}</div>
              <div className="k-file-validation-message k-text-error">
                {getFileError(file)}
              </div>
            </>
          ) : (
            <>
              <span className="k-file-name">{file.name}</span>
              <span className="k-file-size">
                {getTotalFilesSizeMessage([file])}
              </span>
            </>
          )}
        </span>
      </div>
      <strong className="k-upload-status k-d-flex k-align-self-center">
        {isProgressVisible ? (
          <span className="k-upload-pct">{file.progress}%</span>
        ) : null}
        {isUploadError ? (
          <button
            type="button"
            className="k-button k-button-icon k-flat k-upload-action"
            onClick={() => onRetry(file.uid)}
          >
            <span className="k-icon k-retry k-i-refresh-sm" />
          </button>
        ) : null}
        {isActionVisible ? (
          <button
            type="button"
            className="k-button k-button-icon k-flat k-upload-action"
            onClick={() => onRemove(file.uid)}
          >
            <span className="k-icon k-delete k-i-x" />
          </button>
        ) : null}
      </strong>
    </>
  );
};
 
export default UploadedFileItem;

Le composant comprend un peu de logique et de balisage puisque nous devons tout réimplémenter nous-mêmes pour l’élément de liste de fichiers. Fondamentalement, le composant affiche le nom d’un fichier, une erreur, et réessayez et supprimez les boutons. Cependant, pour un fichier de type jpg, jpeg ou png, un aperçu est généré à l’aide de la FileReader. S’il n’y a pas d’image d’aperçu, l’une des icônes par défaut de l’interface utilisateur de Kendo s’affiche.

Nous devons également créer getTotalFilesSizeMessage et getFileExtensionIcon aides. Le premier calcule la taille totale de l’image et renvoie le suffixe de taille approprié, tandis que le second est chargé de renvoyer une classe d’icônes basée sur l’extension de l’extension d’un fichier.

src/getTotalFilesSizeMessage.js

export const getTotalFilesSizeMessage = files => {
  let totalSize = 0;
  let i;
  if (typeof files[0].size === "number") {
    for (i = 0; i < files.length; i++) {
      if (files[i].size) {
        totalSize += files[i].size || 0;
      }
    }
  } else {
    return "";
  }
  totalSize /= 1024;
  if (totalSize < 1024) {
    return totalSize.toFixed(2) + " KB";
  } else {
    return (totalSize / 1024).toFixed(2) + " MB";
  }
};

src/getFileExtensionIcon.js

export const getFileExtensionIcon = file => {
  switch (file.extension) {
    case ".png":
    case ".jpg":
    case ".jpeg":
    case ".tiff":
    case ".bmp":
    case ".gif":
      return "k-i-file-image";
    case ".mp3":
    case ".mp4":
    case ".wav":
      return "k-i-file-audio";
    case ".mkv":
    case ".webm":
    case ".flv":
    case ".gifv":
    case ".avi":
    case ".wmv":
      return "k-i-file-video";
    case ".txt":
      return "k-i-file-txt";
    case ".pdf":
      return "k-i-file-pdf";
    case ".ppt":
    case ".pptx":
      return "k-i-file-presentation";
    case ".csv":
    case ".xls":
    case ".xlsx":
      return "k-i-file-data";
    case ".html":
    case ".css":
    case ".js":
    case ".ts":
      return "k-i-file-programming";
    case ".exe":
      return "k-i-file-config";
    case ".zip":
    case ".rar":
      return "k-i-file-zip";
    default:
      return "k-i-file";
  }
};

Enfin, mettons à jour le App composant et passez notre nouveau UploadFileItem composant en tant qu’accessoire du composant React Upload.

src/App.jsx

import "./App.css";
import { Upload } from "@progress/kendo-react-upload";
import UploadFileItem from "./UploadFileItem";
 
const saveUrl = "https://demos.telerik.com/kendo-ui/service-v4/upload/save";
const removeUrl = "https://demos.telerik.com/kendo-ui/service-v4/upload/remove";
 
function App() {
  return (
    <div className="App">
      <Upload
        defaultFiles={[]}
        withCredentials={false}
        saveUrl={saveUrl}
        removeUrl={removeUrl}
        restrictions={{
          minFileSize: 1000,
          maxFileSize: 10000000,
          allowedExtensions: [".jpg", ".png"],
        }}
        listItemUI={UploadFileItem}
      />
    </div>
  );
}
 
export default App;     

Le GIF ci-dessous montre à quoi ressemble le composant de téléchargement avec notre personnalisé UploadFileItem composant.

Composant listItemUI personnalisé avec des aperçus d'image dans la zone de dépôt de téléchargement React

Sommaire

C’est ça! La Composant React Upload dans KendoReact est un excellent choix pour créer de belles expériences de téléchargement. Il a beaucoup de fonctionnalités prêtes à l’emploi et peut être facilement modifié pour répondre à vos besoins. De plus, si vous décidez d’aller avec KendoRéagir au lieu de l’alternative open source, React Dropzone, vous obtenez également une suite complète d’interface utilisateur de plus de 100 composants bien conçus pour tout ce dont vous pourriez avoir besoin, comme des formulaires, des graphiques, des tableaux et plus encore.




Source link

septembre 27, 2022