Construit sur l’UI SDK 0.1.0-beta.2 de Vercel. Son API peut changer.
File input
Un champ de fichiers sur l’UI SDK de Vercel avec zone de dépôt, collage, contrôles de type et de taille, fichiers refusés avec leurs raisons, aperçus d’images et prise en charge des formulaires.
- Composants de formulaire
- 14 parties
- 12 exemples
@tabler/icons-react@ui-sdk/core@ui-sdk/reactclass-variance-authority
Drop files here
Images or PDFs, up to 5 files of 5 MB each. You can paste them too.
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-file-input.jsonAjoute le composant, les tokens de thème HextaUI et les composants HextaUI dont il dépend.
Ajoutez les tokens de thème à votre CSS global, si ce n’est pas déjà fait.
Installez les dépendances.
pnpm add @ui-sdk/react@0.1.0-beta.2 @ui-sdk/core@0.1.0-beta.2 @tabler/icons-react class-variance-authority cnCopiez et collez le code suivant dans votre projet.
components/ui/ui-sdk-file-input.tsx components/ui/button.tsx Mettez à jour les chemins d’import selon la configuration de votre projet.
UI SDK ajoute un peu de CSS dans une couche de cascade nommée ui-sdk. Déclarez cette couche en haut de votre feuille de style globale, au-dessus de l’import Tailwind, pour que vos classes l’emportent.
Le champ garde les fichiers choisis, déposés ou collés, et les envoie avec un formulaire. Les téléverser revient à votre app. FileInputItem sans enfants affiche une ligne finie avec un aperçu, le nom, la taille et un bouton de retrait, une fois par fichier de la liste.
Les contrôles de accept, des tailles, du nombre et de validate s’exécutent dans le navigateur seulement, pour dire tôt pourquoi un fichier a été écarté. N’importe qui peut les contourner, alors vérifiez chaque envoi à nouveau sur votre serveur.
accept prend des types MIME, des jokers et des extensions. maxFiles, minSize et maxSize fixent les limites, et validate ajoute vos propres contrôles. FileInputRejections liste chaque fichier écarté avec toutes ses raisons, jusqu’au prochain fichier accepté.
FileInputItemPreview affiche une image depuis une URL d’objet qu’il révoque quand le fichier part, et une icône pour les autres types. Avec layout="grid", chaque fichier est une tuile carrée.
Un déclencheur seul ouvre le sélecteur de fichiers du système. Sans multiple, un nouveau fichier remplace l’actuel, et les enfants de la racine peuvent être une fonction de son état.
Avec variant="composer", la zone de dépôt est la carte autour d’une zone de message, et layout="chips" liste les fichiers en puces compactes. pasteTarget prend les captures collées dans la zone de texte, tandis que le texte collé reste du texte.
Avec target="document" et variant="overlay", la zone couvre la page pendant qu’on glisse des fichiers sur la fenêtre, et prend les fichiers déposés n’importe où. Un dépôt sur une autre zone reste à cette zone.
directory choisit un dossier entier et active multiple. Les noms des éléments montrent le chemin dans le dossier.
Passez value et onValueChange. Un contrôleur issu de createFileInputController() ouvre le sélecteur depuis n’importe quel bouton, et vide ou ajoute des fichiers.
Avec un name, les fichiers sont envoyés par un champ de fichier natif, même avant l’hydratation de la page. Les fichiers refusés ne sont jamais envoyés, et réinitialiser le formulaire vide la liste.
invalid marque la zone de dépôt et le déclencheur, qui le signale aux lecteurs d’écran. Faites pointer l’aria-describedby du déclencheur vers votre message.
Un champ de fichiers désactivé ignore les choix, dépôts et collages, et n’envoie rien.
Les lignes et la zone s’inversent, les noms de fichiers gardent leur propre sens et les tailles se formatent dans la locale passée.
| Touche | Action |
|---|---|
| Tab | Passe au déclencheur, puis dans la liste, sur le dernier fichier ciblé ou le premier. |
| EnterSpace | Ouvre le sélecteur de fichiers depuis le déclencheur. |
| ↑↓←→ | Passe d’un fichier à l’autre dans la liste. |
| HomeEnd | Va au premier ou au dernier fichier. |
| DeleteBackspace | Retire le fichier ciblé et cible le suivant. |
| ⌘V | Colle des fichiers quand le focus est dans la zone de dépôt ou sa cible de collage. |
La zone de dépôt n’est pas un contrôle : gardez toujours un déclencheur à côté pour les personnes au clavier ou avec un lecteur d’écran. La liste est un seul arrêt de tabulation, chaque bouton de retrait porte le nom de son fichier, comme « Remove photo.png », et reste hors de l’ordre de tabulation, puisque Suppr sur l’élément fait la même chose.
Les fichiers acceptés, retirés et refusés sont annoncés en anglais par une région live polie. Passez announcement pour le dire dans votre langue, et getReasonLabel à FileInputRejections pour ses raisons. L’icône de la zone ne se soulève que si le mouvement est autorisé, et les nouvelles lignes n’apparaissent en fondu qu’à ce moment-là.
Chaque partie enveloppe la partie UI SDK du même nom et accepte toutes ses props, y compris render et un className qui peut être une fonction de son état.
| Prop | Type | Par défaut |
|---|---|---|
value | File[] | – |
defaultValue | File[] | [] |
onValueChangedetails contient la raison et les fichiers ajoutés, retirés et refusés. | (value: File[], details) => void | – |
onRejectS’exécute quand des fichiers échouent aux contrôles, même si aucun n’a été accepté. | (rejected: FileRejection[], details) => void | – |
accept | string | string[] | – |
multiple | boolean | false |
maxFiles | number | – |
maxSizeEn octets. | number | – |
minSizeEn octets. | number | – |
validateRenvoyez une raison pour refuser le fichier, après les contrôles intégrés. | (file: File) => string | null | – |
directory | boolean | false |
captureOuvre l’appareil photo sur les téléphones. | "user" | "environment" | boolean | – |
invalid | boolean | false |
disabled | boolean | false |
required | boolean | false |
name | string | – |
form | string | – |
announcementCe qu’entendent les lecteurs d’écran après un changement. | (change) => string | null | – |
controllerIssu de createFileInputController(). | FileInputController | – |
children | ReactNode | (state) => ReactNode | – |
| Attribut | Description |
|---|---|
data-slot="file-input" | Cible le champ de fichiers en CSS. |
data-dragging | Présent pendant qu’on fait glisser des fichiers sur l’une de ses zones de dépôt. |
data-invalid | Présent quand il est invalide. |
data-required | Présent quand un fichier est requis. |
data-disabled | Présent lorsque l’élément est désactivé. |
| Prop | Type | Par défaut |
|---|---|---|
variantUne zone en pointillés, une carte autour d’un éditeur de message, ou un calque pleine page affiché pendant le glisser. | "default" | "composer" | "overlay" | "default" |
target | "element" | "document" | "element" |
pasteTargetUn autre endroit d’où prendre les fichiers collés. | "document" | string | Element | () => Element | – |
render | ReactElement | (props, state) => ReactElement | – |
| Attribut | Description |
|---|---|
data-slot="file-input-dropzone" | Cible la zone de dépôt en CSS. |
data-variant | La variante : default, composer ou overlay. |
data-dragging | Présent pendant qu’on fait glisser des fichiers dessus. |
data-drag-accept | Présent tant que les fichiers glissés semblent acceptables, d’après leur type et leur nombre. |
data-drag-reject | Présent quand un fichier glissé a un type refusé, ou qu’il y en a trop. |
data-disabled | Présent lorsque l’élément est désactivé. |
| Prop | Type | Par défaut |
|---|---|---|
variant | Button variant | "outline" |
size | Button size | "sm" |
controllerRelie un déclencheur placé hors du champ, comme dans une barre d’outils. | FileInputController | – |
render | ReactElement | (props, state) => ReactElement | – |
| Prop | Type | Par défaut |
|---|---|---|
layoutDes lignes, des tuiles d’image carrées ou des puces compactes. Les éléments en prennent leur apparence. | "list" | "grid" | "chips" | "list" |
render | ReactElement | (props, state) => ReactElement | – |
| Attribut | Description |
|---|---|
data-slot="file-input-list" | Cible la liste en CSS. |
data-layout | La disposition : list, grid ou chips. Les éléments la portent aussi. |
| Prop | Type | Par défaut |
|---|---|---|
childrenPar défaut, un aperçu, le nom, la taille et un bouton de retrait. L’état contient le fichier et son index. | ReactNode | (state) => ReactNode | – |
render | ReactElement | (props, state) => ReactElement | – |
| Attribut | Description |
|---|---|
data-slot="file-input-item" | Cible la ligne d’un fichier en CSS. |
data-disabled | Présent lorsque l’élément est désactivé. |
| Attribut | Description |
|---|---|
data-slot="file-input-item-preview" | Cible l’aperçu en CSS. |
data-kind | image pour un aperçu d’image, icon pour une icône selon le type de fichier. |
| Prop | Type | Par défaut |
|---|---|---|
localeFormate la taille, comme 2.4 kB, dans cette locale. Par défaut, celle du navigateur. | string | – |
| Prop | Type | Par défaut |
|---|---|---|
childrenPar défaut, une icône X. | ReactNode | – |
render | ReactElement | (props, state) => ReactElement | – |
| Prop | Type | Par défaut |
|---|---|---|
getReasonLabelNomme chaque raison. En anglais par défaut, comme « Larger than 5 MB ». | (reason, rules, rejection) => string | – |
| Attribut | Description |
|---|---|
data-slot="file-input-rejections" | Cible la liste des fichiers refusés en CSS. |
- ButtonDes boutons dans toutes les variantes et tailles, avec un flux de chargement, de succès et d’erreur intégré qui évite le spinner pour les requêtes rapides.
- CalendarUne grille de dates pour la sélection simple, de plage et multiple, avec des mois qui défilent, des aperçus de plage et des jours à taille tactile.
- CheckboxUne case à cocher dont la coche se dessine, avec des parents indéterminés, des groupes et des libellés qui partagent son survol.
- ComboboxUn select filtrable avec chips, groupes et résultats asynchrones, dans un popup qui se redimensionne pendant la saisie.
- Date pickerUn bouton qui ouvre un calendrier dans un popover, ou une bottom sheet sur mobile, pour des dates simples et des plages.
- FieldDes libellés, descriptions et erreurs reliés à leur contrôle, avec états de validation et mises en page pour les formulaires.