Feito sobre o UI SDK 0.1.0-beta.1 da Vercel. A API pode mudar.
Token input
Um campo de texto sobre o UI SDK da Vercel que mistura texto digitado com tokens de pessoas, arquivos e comandos, com sugestões de @ e /.
- Componentes de formulário
- 15 partes
- 10 exemplos
@tabler/icons-react@ui-sdk/core@ui-sdk/react
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-token-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.1 @ui-sdk/core@0.1.0-beta.1 @tabler/icons-react cnCopie e cole o código a seguir no seu projeto.
components/ui/ui-sdk-token-input.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.
Um valor é um array de texto e tokens. Cada token tem um type, um value para seu app e um label que as pessoas leem. O editor cuida do conteúdo, da seleção e do desfazer, então deixe-o renderizar e passe renderToken para mudar a aparência de um token. Sem ele, cada token mostra o label e um botão de remover.
Um TriggerMenu dentro do input sugere tokens quando alguém digita um gatilho como @ ou /. Deixe-o de fora quando seu código fornecer os tokens.
Digite @ para arquivos ou / no início para skills. Um arquivo fica pendente enquanto carrega, e ao enviar cada skill é marcada como em execução e depois concluída com updateToken(). Enter envia e Shift+Enter adiciona uma linha.
tokenDeletion define o que o Backspace faz em um token. whole o remove, select o seleciona primeiro e revert o transforma de volta em texto.
Um controlador de createTokenInputController() insere, atualiza e remove tokens pelo código. Passe uma promise como resolve para manter um token pendente até ela terminar.
Com um name, o input envia o texto com cada token escrito como [@label](type:value). required bloqueia envio vazio, e o reset volta para defaultValue.
Com submitShortcut="mod+enter", Enter adiciona uma linha e Command ou Control+Enter envia, o que muitas pessoas que escrevem em japonês e chinês preferem.
Um codec transforma tokens em texto e de volta, aqui como <@id>. Com copy="label", copiar escreve o que as pessoas leem, e colar de volta ainda restaura os tokens.
Um input desativado não recebe foco nem muda, oculta os botões de remover e não envia nada.
Com readOnly, o texto continua focável, selecionável e enviado, mas digitar, colar e soltar não o alteram.
O editor segue a direção da página, e um token continua sendo uma peça só dentro de texto da direita para a esquerda.
| Tecla | Ação |
|---|---|
| BackspaceDelete | Remove o token antes ou depois do cursor, conforme tokenDeletion. |
| ←→ | Move o cursor para além de um token com um toque. Ele nunca para dentro de um. |
| ↑↓ | Percorre as sugestões enquanto o menu está aberto. |
| Enter | Envia. Com o menu aberto, escolhe a sugestão destacada. |
| Shift + Enter | Inicia uma nova linha. |
| ⌘ + EnterCtrl + Enter | Envia quando submitShortcut é mod+enter. Enter então começa uma nova linha. |
| ⌘ + ZCtrl + Z | Desfaz o último passo. A digitação é agrupada, e colagens e mudanças de token são passos próprios. |
| Esc | Fecha as sugestões. |
O editor é uma caixa de texto multilinha. Um menu de gatilhos dentro dele adiciona aria-autocomplete e aria-haspopup, e o foco fica no texto enquanto as setas percorrem as sugestões. Cada token é lido como label e tipo, como “routes.ts arquivo”, e inserir ou remover um é anunciado. Nomeie o editor com aria-label ou com um rótulo ao redor.
Os botões de remover ficam ocultos para leitores de tela, já que o Backspace remove um token pelo teclado. A área de toque cresce em telas sensíveis ao toque, um token pendente só pulsa quando o movimento é permitido, e um token selecionado ganha uma borda de destaque do sistema no modo de cores forçadas.
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 | TokenInputValue | – |
defaultValue | TokenInputValue | – |
onValueChangeExecuta ao digitar, colar, usar menus, desfazer e em chamadas do controlador. details traz o motivo e os tokens removidos. | (value, details) => void | – |
onSubmitExecuta no atalho de envio, a menos que um menu esteja aberto ou um método de entrada esteja compondo. | (value, details) => void | – |
submitShortcut | "enter" | "mod+enter" | "enter" |
tokenDeletion | "whole" | "select" | "revert" | "whole" |
renderTokenRenderiza um token. Por padrão, um TokenInputToken com o label e um botão de remover. | (token: Token) => ReactNode | – |
copy | "codec" | "label" | "codec" |
codec | TokenCodec | – |
getTokenDescriptionO que um token diz aos leitores de tela além do label. | (token: Token) => string | – |
history | { limit, groupDelay } | – |
name | string | – |
form | string | – |
required | boolean | false |
disabled | boolean | false |
readOnly | boolean | false |
controllerDe createTokenInputController(). | TokenInputController | – |
| Prop | Tipo | Padrão |
|---|---|---|
placeholderExibido por aria-placeholder enquanto o input está vazio. | string | – |
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descrição |
|---|---|
data-slot="token-input-editor" | Para selecionar o editor no CSS. |
data-empty | Presente enquanto o input está vazio. |
data-disabled | Presente quando desabilitado. |
data-readonly | Presente quando somente leitura. |
| Atributo | Descrição |
|---|---|
data-slot="token-input-token" | Para selecionar um token no CSS. |
data-token-type | O tipo do token, como file ou mention. |
data-selected | Presente enquanto o token está na seleção ou selecionado para remoção. |
data-pending | Presente enquanto o token carrega. |
data-unresolved | Presente enquanto o token precisa da pessoa, como uma menção ambígua. |
Remove seu token e mantém o foco no editor. Renderiza um ícone X do Tabler, a menos que você passe children, e se oculta enquanto o input está desativado ou somente leitura.
| Prop | Tipo | Padrão |
|---|---|---|
triggersOs caracteres que abrem o menu, o tipo de token que cada um insere e seus itens. | TriggerDefinition[] | – |
onSelectExecuta quando um item é escolhido. Retorne uma promise para inserir o token como pendente. | (value, details) => void | Promise | – |
autoHighlight | boolean | true |
loop | boolean | true |
| Prop | Tipo | Padrão |
|---|---|---|
align | "start" | "center" | "end" | "start" |
sideOffset | number | 6 |
collisionPadding | number | 8 |
| Atributo | Descrição |
|---|---|
data-slot="trigger-menu-content" | Para selecionar o popup no CSS. |
data-trigger | O gatilho da correspondência atual, como @, para que cada lista possa ter outra aparência. |
data-starting-style | Presente enquanto o popup anima a entrada. |
data-ending-style | Presente enquanto o popup anima a saída. |
| Prop | Tipo | Padrão |
|---|---|---|
value | T | – |
labelO texto inserido e comparado, quando o conteúdo não é texto simples. | string | – |
disabled | boolean | false |
| Atributo | Descrição |
|---|---|
data-highlighted | Presente no item destacado. O foco fica no editor. |
data-disabled | Presente quando o item não pode ser escolhido. |
- 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.
- InputUm campo de texto com três tamanhos, estados inválido e somente leitura, estilo de validação nativa e fonte de 16px no toque para que os celulares nunca façam zoom.