Hecho sobre el UI SDK 0.1.0-beta.2 de Vercel. Su API puede cambiar.
File input
Un campo de archivos sobre el UI SDK de Vercel con zona para soltar, pegado, comprobación de tipo y tamaño, archivos rechazados con motivos, vistas previas de imágenes y soporte de formularios.
- Componentes de formulario
- 14 partes
- 12 ejemplos
@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.jsonAñade el componente, los tokens del tema de HextaUI y los componentes de HextaUI de los que depende.
Añade los tokens del tema a tu CSS global, si aún no lo has hecho.
Instala las dependencias.
pnpm add @ui-sdk/react@0.1.0-beta.2 @ui-sdk/core@0.1.0-beta.2 @tabler/icons-react class-variance-authority cnCopia y pega el siguiente código en tu proyecto.
components/ui/ui-sdk-file-input.tsx components/ui/button.tsx Actualiza las rutas de importación para que coincidan con la configuración de tu proyecto.
UI SDK añade un poco de CSS propio en una capa de cascada llamada ui-sdk. Declara esa capa al principio de tu hoja de estilos global, encima del import de Tailwind, para que tus clases ganen.
El campo guarda los archivos que la gente elige, suelta o pega, y los envía con un formulario. Subirlos le corresponde a tu app. FileInputItem sin hijos dibuja una fila terminada con vista previa, nombre, tamaño y botón para quitar, una vez por cada archivo de la lista.
Las comprobaciones de accept, tamaños, cantidades y validate solo corren en el navegador, para decir pronto por qué se dejó fuera un archivo. Cualquiera puede saltárselas, así que vuelve a comprobar cada subida en tu servidor.
accept admite tipos MIME, comodines y extensiones. maxFiles, minSize y maxSize fijan los límites, y validate añade comprobaciones propias. FileInputRejections lista cada archivo que quedó fuera con todos sus motivos, hasta el siguiente archivo aceptado.
FileInputItemPreview muestra una imagen desde una URL de objeto que revoca cuando el archivo se va, y un icono para otros tipos. Con layout="grid", cada archivo es un mosaico cuadrado.
Un disparador solo abre el selector de archivos del sistema. Sin multiple, un archivo nuevo sustituye al actual, y los hijos de la raíz pueden ser una función de su estado.
Con variant="composer", la zona para soltar es la tarjeta alrededor de un cuadro de mensaje, y layout="chips" lista los archivos como chips compactos. pasteTarget toma las capturas pegadas en el área de texto, mientras el texto pegado sigue siendo texto.
Con target="document" y variant="overlay", la zona cubre la página mientras se arrastran archivos sobre la ventana, y toma los archivos soltados en cualquier parte. Lo que se suelta en otra zona se queda en esa zona.
directory elige una carpeta entera y activa multiple. Los nombres de los elementos muestran la ruta dentro de la carpeta.
Pasa value y onValueChange. Un controlador de createFileInputController() abre el selector desde cualquier botón, y vacía o añade archivos.
Con un name, los archivos se envían por un campo de archivos nativo, incluso antes de que la página se hidrate. Los archivos rechazados nunca se envían, y reiniciar el formulario vacía la lista.
invalid marca la zona para soltar y el disparador, y el disparador lo comunica a los lectores de pantalla. Apunta el aria-describedby del disparador a tu mensaje.
Un campo de archivos desactivado ignora selecciones, soltadas y pegados, y no envía nada.
Las filas y la zona se reflejan, los nombres de archivo conservan su propia dirección y los tamaños se formatean en la configuración regional que pases.
| Key | Acción |
|---|---|
| Tab | Va al disparador y luego a la lista, al último archivo enfocado o al primero. |
| EnterSpace | Abre el selector de archivos desde el disparador. |
| ↑↓←→ | Se mueve entre los archivos de la lista. |
| HomeEnd | Va al primer o al último archivo. |
| DeleteBackspace | Quita el archivo enfocado y enfoca el siguiente. |
| ⌘V | Pega archivos mientras el foco está dentro de la zona para soltar o de su destino de pegado. |
La zona para soltar no es un control, así que deja siempre un disparador a su lado para quien usa teclado o lector de pantalla. La lista es una sola parada de tabulación, y cada botón para quitar lleva el nombre de su archivo, como “Remove photo.png”, y queda fuera del orden de tabulación porque Supr sobre el elemento hace lo mismo.
Los archivos aceptados, quitados y rechazados se anuncian en inglés con una región viva cortés. Pasa announcement para decirlo en tu idioma, y getReasonLabel a FileInputRejections para sus motivos. El icono de la zona solo se eleva si se permite el movimiento, y las filas nuevas solo aparecen con fundido en ese caso.
Cada parte envuelve la parte de UI SDK del mismo nombre y acepta todas sus props, incluidas render y un className que puede ser una función del estado de la parte.
| Prop | Tipo | Predeterminado |
|---|---|---|
value | File[] | – |
defaultValue | File[] | [] |
onValueChangedetails trae el motivo y los archivos añadidos, quitados y rechazados. | (value: File[], details) => void | – |
onRejectSe ejecuta cuando hay archivos que no pasan las comprobaciones, aunque no se haya aceptado ninguno. | (rejected: FileRejection[], details) => void | – |
accept | string | string[] | – |
multiple | boolean | false |
maxFiles | number | – |
maxSizeEn bytes. | number | – |
minSizeEn bytes. | number | – |
validateDevuelve un motivo para rechazar el archivo, tras las comprobaciones integradas. | (file: File) => string | null | – |
directory | boolean | false |
captureAbre la cámara en los teléfonos. | "user" | "environment" | boolean | – |
invalid | boolean | false |
disabled | boolean | false |
required | boolean | false |
name | string | – |
form | string | – |
announcementLo que oyen los lectores de pantalla tras un cambio. | (change) => string | null | – |
controllerDe createFileInputController(). | FileInputController | – |
children | ReactNode | (state) => ReactNode | – |
| Atributo | Descripción |
|---|---|
data-slot="file-input" | Apunta al campo de archivos en CSS. |
data-dragging | Presente mientras se arrastran archivos sobre una de sus zonas para soltar. |
data-invalid | Presente cuando no es válido. |
data-required | Presente cuando se exige un archivo. |
data-disabled | Presente cuando está deshabilitado. |
| Prop | Tipo | Predeterminado |
|---|---|---|
variantUna zona discontinua, una tarjeta que envuelve un editor de mensajes o una capa a página completa que aparece al arrastrar. | "default" | "composer" | "overlay" | "default" |
target | "element" | "document" | "element" |
pasteTargetOtro lugar del que tomar archivos pegados. | "document" | string | Element | () => Element | – |
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descripción |
|---|---|
data-slot="file-input-dropzone" | Apunta a la zona para soltar en CSS. |
data-variant | La variante: default, composer u overlay. |
data-dragging | Presente mientras se arrastran archivos sobre ella. |
data-drag-accept | Presente mientras los archivos arrastrados parecen aceptables por su tipo y cantidad. |
data-drag-reject | Presente mientras un archivo arrastrado tiene un tipo no aceptado, o hay demasiados. |
data-disabled | Presente cuando está deshabilitado. |
| Prop | Tipo | Predeterminado |
|---|---|---|
variant | Button variant | "outline" |
size | Button size | "sm" |
controllerConecta un disparador fuera del campo, como uno en una barra de herramientas. | FileInputController | – |
render | ReactElement | (props, state) => ReactElement | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
layoutFilas, mosaicos cuadrados de imagen o chips compactos. Los elementos toman su aspecto de aquí. | "list" | "grid" | "chips" | "list" |
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descripción |
|---|---|
data-slot="file-input-list" | Apunta a la lista en CSS. |
data-layout | El diseño: list, grid o chips. Los elementos también lo llevan. |
| Prop | Tipo | Predeterminado |
|---|---|---|
childrenPor defecto, una vista previa, el nombre, el tamaño y un botón para quitar. El estado tiene el archivo y su índice. | ReactNode | (state) => ReactNode | – |
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descripción |
|---|---|
data-slot="file-input-item" | Apunta a la fila de un archivo en CSS. |
data-disabled | Presente cuando está deshabilitado. |
| Atributo | Descripción |
|---|---|
data-slot="file-input-item-preview" | Apunta a la vista previa en CSS. |
data-kind | image para una vista previa de imagen, icon para un icono según el tipo de archivo. |
| Prop | Tipo | Predeterminado |
|---|---|---|
localeDa formato al tamaño, como 2.4 kB, en esta configuración regional. Por defecto, la del navegador. | string | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
childrenPor defecto, un icono de X. | ReactNode | – |
render | ReactElement | (props, state) => ReactElement | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
getReasonLabelNombra cada motivo. Por defecto en inglés, como “Larger than 5 MB”. | (reason, rules, rejection) => string | – |
| Atributo | Descripción |
|---|---|
data-slot="file-input-rejections" | Apunta a la lista de archivos rechazados en CSS. |
- ButtonBotones en todas las variantes y tamaños, con un flujo integrado de carga, éxito y error que omite el spinner en las peticiones rápidas.
- CalendarUna cuadrícula de fechas para selección única, de rango y múltiple, con meses deslizantes, vistas previas de rango y días de tamaño táctil.
- CheckboxUna casilla de verificación cuya marca se dibuja, con padres indeterminados, grupos y etiquetas que comparten su hover.
- ComboboxUn select filtrable con chips, grupos y resultados asíncronos, en un popup que cambia de tamaño mientras escribes.
- Date pickerUn botón que abre un calendario en un popover, o en una hoja inferior en móviles, para fechas únicas y rangos.
- FieldEtiquetas, descripciones y errores conectados a su control, con estados de validación y diseños para formularios.