Feito sobre o UI SDK 0.1.0-beta.2 da Vercel. A API pode mudar.
File input
Um campo de arquivos no UI SDK da Vercel com área para soltar, colagem, verificação de tipo e tamanho, arquivos recusados com motivos, prévias de imagem e suporte a formulários.
- Componentes de formulário
- 14 partes
- 12 exemplos
@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.jsonAdiciona o componente, os tokens de tema do HextaUI e quaisquer componentes do HextaUI dos quais ele depende.
Adicione os tokens de tema ao seu CSS global, se ainda não o fez.
Instale as dependências.
pnpm add @ui-sdk/react@0.1.0-beta.2 @ui-sdk/core@0.1.0-beta.2 @tabler/icons-react class-variance-authority cnCopie e cole o código a seguir no seu projeto.
components/ui/ui-sdk-file-input.tsx components/ui/button.tsx Atualize os caminhos de importação para corresponder à configuração do seu projeto.
O UI SDK adiciona um pouco de CSS próprio em uma camada de cascata chamada ui-sdk. Declare essa camada no topo da sua folha de estilos global, acima do import do Tailwind, para que suas classes vençam.
O campo guarda os arquivos que as pessoas escolhem, soltam ou colam, e os envia com um formulário. Fazer o upload fica a cargo do seu app. FileInputItem sem filhos renderiza uma linha pronta com prévia, nome, tamanho e botão de remover, uma vez para cada arquivo da lista.
As verificações de accept, tamanhos, quantidades e validate rodam só no navegador, para dizer cedo por que um arquivo ficou de fora. Qualquer um pode pulá-las, então verifique cada upload de novo no seu servidor.
accept aceita tipos MIME, curingas e extensões. maxFiles, minSize e maxSize definem os limites, e validate adiciona verificações próprias. FileInputRejections lista cada arquivo que ficou de fora com todos os motivos, até o próximo arquivo aceito.
FileInputItemPreview mostra uma imagem a partir de uma URL de objeto que revoga quando o arquivo sai, e um ícone para outros tipos. Com layout="grid", cada arquivo é um bloco quadrado.
Um gatilho sozinho abre o seletor de arquivos do sistema. Sem multiple, um arquivo novo substitui o atual, e os filhos da raiz podem ser uma função do estado dela.
Com variant="composer", a área para soltar é o card em volta de uma caixa de mensagem, e layout="chips" lista os arquivos como chips compactos. pasteTarget pega capturas coladas na área de texto, enquanto texto colado continua texto.
Com target="document" e variant="overlay", a área cobre a página enquanto arquivos são arrastados sobre a janela, e recebe arquivos soltos em qualquer lugar. O que é solto em outra área fica nela.
directory escolhe uma pasta inteira e liga multiple. Os nomes dos itens mostram o caminho dentro da pasta.
Passe value e onValueChange. Um controller de createFileInputController() abre o seletor a partir de qualquer botão, e limpa ou adiciona arquivos.
Com um name, os arquivos são enviados por um campo de arquivo nativo, mesmo antes de a página hidratar. Arquivos recusados nunca são enviados, e o reset do formulário esvazia a lista.
invalid marca a área para soltar e o gatilho, e o gatilho avisa os leitores de tela. Aponte o aria-describedby do gatilho para a sua mensagem.
Um campo de arquivos desativado ignora seleções, arrastos e colagens, e não envia nada.
As linhas e a área se espelham, os nomes de arquivo mantêm a própria direção e os tamanhos são formatados na localidade que você passar.
| Tecla | Ação |
|---|---|
| Tab | Vai para o gatilho e depois para a lista, no último arquivo focado ou no primeiro. |
| EnterSpace | Abre o seletor de arquivos a partir do gatilho. |
| ↑↓←→ | Move entre os arquivos da lista. |
| HomeEnd | Vai para o primeiro ou o último arquivo. |
| DeleteBackspace | Remove o arquivo focado e foca o próximo. |
| ⌘V | Cola arquivos enquanto o foco está dentro da área para soltar ou do seu destino de colagem. |
A área para soltar não é um controle, então mantenha sempre um gatilho ao lado dela para quem usa teclado ou leitor de tela. A lista é uma única parada de tab, e cada botão de remover leva o nome do seu arquivo, como “Remove photo.png”, e fica fora da ordem de tab porque Delete no item faz o mesmo.
Arquivos aceitos, removidos e recusados são anunciados em inglês por uma região viva educada. Passe announcement para dizer isso no seu idioma, e getReasonLabel para FileInputRejections para os motivos. O ícone da área só sobe quando movimento é permitido, e só então as novas linhas aparecem com fade.
Cada parte envolve a parte do UI SDK de mesmo nome e aceita todas as suas props, incluindo render e um className que pode ser uma função do estado da parte.
| Prop | Tipo | Padrão |
|---|---|---|
value | File[] | – |
defaultValue | File[] | [] |
onValueChangedetails traz o motivo e os arquivos adicionados, removidos e recusados. | (value: File[], details) => void | – |
onRejectRoda quando arquivos falham nas verificações, mesmo que nenhum tenha sido aceito. | (rejected: FileRejection[], details) => void | – |
accept | string | string[] | – |
multiple | boolean | false |
maxFiles | number | – |
maxSizeEm bytes. | number | – |
minSizeEm bytes. | number | – |
validateRetorne um motivo para recusar o arquivo, depois das verificações embutidas. | (file: File) => string | null | – |
directory | boolean | false |
captureAbre a câmera nos celulares. | "user" | "environment" | boolean | – |
invalid | boolean | false |
disabled | boolean | false |
required | boolean | false |
name | string | – |
form | string | – |
announcementO que os leitores de tela ouvem após uma mudança. | (change) => string | null | – |
controllerDe createFileInputController(). | FileInputController | – |
children | ReactNode | (state) => ReactNode | – |
| Atributo | Descrição |
|---|---|
data-slot="file-input" | Mira o campo de arquivos no CSS. |
data-dragging | Presente enquanto arquivos são arrastados sobre uma das suas áreas para soltar. |
data-invalid | Presente quando inválido. |
data-required | Presente quando um arquivo é obrigatório. |
data-disabled | Presente quando desabilitado. |
| Prop | Tipo | Padrão |
|---|---|---|
variantUma área tracejada, um card que envolve um editor de mensagem ou uma sobreposição de página inteira que aparece ao arrastar. | "default" | "composer" | "overlay" | "default" |
target | "element" | "document" | "element" |
pasteTargetOutro lugar de onde pegar arquivos colados. | "document" | string | Element | () => Element | – |
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descrição |
|---|---|
data-slot="file-input-dropzone" | Mira a área para soltar no CSS. |
data-variant | A variante: default, composer ou overlay. |
data-dragging | Presente enquanto arquivos são arrastados sobre ela. |
data-drag-accept | Presente enquanto os arquivos arrastrados parecem aceitáveis pelo tipo e pela quantidade. |
data-drag-reject | Presente enquanto um arquivo arrastado tem um tipo não aceito, ou há arquivos demais. |
data-disabled | Presente quando desabilitado. |
| Prop | Tipo | Padrão |
|---|---|---|
variant | Button variant | "outline" |
size | Button size | "sm" |
controllerConecta um gatilho fora do campo, como um numa barra de ferramentas. | FileInputController | – |
render | ReactElement | (props, state) => ReactElement | – |
| Prop | Tipo | Padrão |
|---|---|---|
layoutLinhas, blocos quadrados de imagem ou chips compactos. Os itens herdam a aparência daqui. | "list" | "grid" | "chips" | "list" |
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descrição |
|---|---|
data-slot="file-input-list" | Mira a lista no CSS. |
data-layout | O layout: list, grid ou chips. Os itens também o carregam. |
| Prop | Tipo | Padrão |
|---|---|---|
childrenPor padrão, uma prévia, o nome, o tamanho e um botão de remover. O estado tem o arquivo e o índice dele. | ReactNode | (state) => ReactNode | – |
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descrição |
|---|---|
data-slot="file-input-item" | Mira a linha de um arquivo no CSS. |
data-disabled | Presente quando desabilitado. |
| Atributo | Descrição |
|---|---|
data-slot="file-input-item-preview" | Mira a prévia no CSS. |
data-kind | image para uma prévia de imagem, icon para um ícone conforme o tipo de arquivo. |
| Prop | Tipo | Padrão |
|---|---|---|
localeFormata o tamanho, como 2.4 kB, nesta localidade. Por padrão, a do navegador. | string | – |
| Prop | Tipo | Padrão |
|---|---|---|
childrenPor padrão, um ícone de X. | ReactNode | – |
render | ReactElement | (props, state) => ReactElement | – |
| Prop | Tipo | Padrão |
|---|---|---|
getReasonLabelNomeia cada motivo. Por padrão em inglês, como “Larger than 5 MB”. | (reason, rules, rejection) => string | – |
| Atributo | Descrição |
|---|---|
data-slot="file-input-rejections" | Mira a lista de arquivos recusados no CSS. |
- ButtonBotões em todas as variantes e tamanhos, com um fluxo integrado de carregamento, sucesso e erro que dispensa o spinner em requisições rápidas.
- CalendarUma grade de datas para seleção única, de intervalo e múltipla, com meses deslizantes, prévias de intervalo e dias com tamanho adequado ao toque.
- CheckboxUma caixa de seleção cujo check é desenhado na tela, com pais indeterminados, grupos e rótulos que compartilham seu hover.
- ComboboxUm select filtrável com chips, grupos e resultados assíncronos, em um popup que se redimensiona conforme você digita.
- Date pickerUm botão que abre um calendário em um popover, ou em um bottom sheet no celular, para datas únicas e intervalos.
- FieldRótulos, descrições e erros ligados ao seu controle, com estados de validação e layouts para formulários.