Input Group
Campo de texto composto com addon, botão ou texto acoplado, para variantes do campo combinado usado na boleta de operação.
Instalação
Recebe correções por update de versão. O caminho recomendado.
npm i @trdr/ui
import { InputGroup } from "@trdr/ui/input-group"Uso
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText } from "@trdr/ui/input-group"
export function Exemplo() {
return <InputGroup />
}Variantes
| Grupo | Valores | Padrão |
|---|---|---|
| size | defaultlg | default |
Props
InputGroupPropsestende React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof inputGroupVariants>InputGroupInputPropsestende Omit<InputProps, "size">InputGroupAddonPropsestende React.HTMLAttributes<HTMLDivElement>| Prop | Tipo | Descrição |
|---|---|---|
| align? | "start" | "end" | Lado do container onde o addon fica: `start` antes do campo, `end` depois. |
InputGroupButtonPropsestende React.ButtonHTMLAttributes<HTMLButtonElement>InputGroupTextPropsestende React.HTMLAttributes<HTMLSpanElement>Quando usar
Use o input-group quando um campo de texto precisa de algo grudado nele, com uma unica borda
compartilhada: um prefixo de moeda, um sufixo de unidade, um icone de busca, ou um botao que abre
um seletor (o caso da boleta de operacao, quantidade acoplada a unidade). Ele existe para os casos
em que o iconLeft/onClear do Input sozinho nao bastam porque o elemento acoplado precisa de
comportamento proprio (abrir algo, ser clicavel, ter o proprio rotulo).
Quando nao usar
Nao use input-group so para colocar um icone decorativo do lado do campo: se o icone e so
enfeite sem interacao propria, o iconLeft do Input sozinho ja resolve com menos partes. Nao
use para escolher entre opcoes fechadas sem campo de texto: isso e o select.
Anatomia
<InputGroup data-slot="input-group"> raiz: borda unica, fundo, altura
<InputGroupAddon data-slot="input-group-addon"> opcional, align="start" ou "end"
<InputGroupText data-slot="input-group-text" /> texto/icone estatico
<InputGroupButton data-slot="input-group-button" /> acao acoplada
</InputGroupAddon>
<InputGroupInput /> o campo, por baixo e um Input
</InputGroup>InputGroupAddon so posiciona (align="start" antes do campo, align="end" depois, via
order-first/order-last, entao a ordem no DOM nao precisa acompanhar a ordem visual). Quem tem
padding proprio sao as pecas de dentro (InputGroupText, InputGroupButton): assim um botao pode
ocupar a lateral inteira do grupo, rente a borda, do mesmo jeito que o chevron do combo input
legado tocava a borda direita.
Variantes
sizenoInputGroup:default(24px) elg(32px). OInputGroupInputnao temsizeproprio: a altura vem sempre do grupo pai, porque um campo e o addon ao lado precisam ter a mesma altura, nao alturas independentes que o consumidor tem que sincronizar a mao.alignnoInputGroupAddon:startouend.
Migracao do componente legado
O ComboInput do Hub antigo (ComboInput.tsx + .trdr-combo-input) era fechado: um state unico
(default | hover | selected-input | selected-chevron) controlava dois segmentos com borda
propria cada (o valor e o chevron), incluindo o detalhe do chevron ficar com fundo
surface-brand quando "selecionado". Isso funcionava bem para o caso especifico da boleta, mas
nao generalizava: nao dava para trocar o chevron por um icone de busca, ou adicionar um prefixo de
texto, sem reescrever o componente inteiro.
Aqui isso vira composicao sobre o Input que ja existe:
- o antigo
value/onChange(o campo, sempre texto fixo no legado) viraInputGroupInput, que por baixo e o proprioInputdo TRDR UI com a borda e o fundo neutralizados viawrapperClassName(por isso o campo renderizado carrega tantodata-slot="input"quanto o contexto do grupo ao redor:input-groupnao duplica o campo, reaproveita) - o antigo
onChevronClickvira umInputGroupButtondentro de umInputGroupAddon align="end" - o destaque de fundo do chevron "selecionado" (
state="selected-chevron") viraaria-expanded={true}noInputGroupButton: o mesmo atributo de acessibilidade que um botao controlando um menu ja precisa ter, sem inventar umdata-statenovo. OInputGroupdetecta isso sozinho viahas-[[data-slot=input-group-button][aria-expanded=true]]e tinge a borda inteira, nao so o segmento do botao
Essa e uma simplificacao deliberada do espacamento: o legado tinha os dois segmentos com bordas
independentes que se fundiam visualmente; aqui e uma borda unica ao redor do grupo inteiro, e o
espacamento interno e um pouco mais generoso por composicao (o Input de dentro mantem o proprio
px-sm). Para o encaixe mais compacto do legado, ajuste via wrapperClassName no
InputGroupInput.
Acessibilidade
- O
refdoInputGroupInputaponta para o<input>nativo, herdando o comportamento doInput. - Todo
InputGroupInputsem rotulo visivel precisa dearia-label, e todoInputGroupButtonsem texto visivel tambem (por exemplo um botao so com icone de chevron). - Estado desabilitado em qualquer peca interna (
InputGroupInputouInputGroupButton) tinge a borda do grupo inteiro viahas-[:disabled], sem precisar de uma propdisabledredundante noInputGrouppai. - Quando o
InputGroupButtoncontrola um overlay (um menu de unidade, por exemplo), usearia-expandedpara refletir o estado real: alem de ser exigido para leitor de tela, e o gancho que acende o destaque visual do grupo inteiro.
Slots e tokens
Todo elemento renderizado carrega um data-slot para estilizar partes internas sem depender de classe da biblioteca. Os tokens listados são extraídos do código fonte.
[data-slot="input"][data-slot="input-group"][data-slot="input-group-addon"][data-slot="input-group-button"][data-slot="input-group-text"]15 tokens usados
bg-surface-brandbg-surface-primarybg-surface-secondarybg-transparentborder-border-strongborder-ringoutline-nonering-offset-2ring-offset-backgroundring-ringtext-b3text-content-brandtext-content-disabledtext-content-primarytext-content-tertiary