HextaUI

Input group

Um input com ícones, texto, botões ou uma dica de teclado anexados, compartilhando uma única borda e um único anel de foco.

"use client"

import * as React from "react"
import { IconArrowUp, IconLock, IconSearch } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupClear,
  InputGroupCount,
  InputGroupInput,
  InputGroupPasswordToggle,
  InputGroupTextarea,
} from "@/components/ui/input-group"

export function InputGroupDemo() {
  const [message, setMessage] = React.useState("")

  return (
    <div className="flex w-full max-w-sm flex-col gap-4">
      <InputGroup>
        <InputGroupInput
          type="search"
          defaultValue="Accordion"
          placeholder="Search components"
          aria-label="Search components"
        />
        <InputGroupAddon>
          <IconSearch />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <InputGroupClear />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput
          type="password"
          defaultValue="hunter2-but-longer"
          autoComplete="current-password"
          aria-label="Password"
        />
        <InputGroupAddon>
          <IconLock />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <InputGroupPasswordToggle />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupTextarea
          value={message}
          onChange={(event) => setMessage(event.target.value)}
          maxLength={140}
          placeholder="Leave a note for the team"
          aria-label="Note"
        />
        <InputGroupAddon align="block-end">
          <InputGroupCount />
          <InputGroupButton
            variant="default"
            size="icon-xs"
            aria-label="Post note"
            disabled={!message.trim()}
            className="ms-auto"
          >
            <IconArrowUp />
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/input-group.json

Adiciona o componente, os tokens de tema do HextaUI e quaisquer componentes do HextaUI dos quais ele depende.

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupClear,
  InputGroupCount,
  InputGroupInput,
  InputGroupPasswordToggle,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/ui/input-group"
<InputGroup>
  <InputGroupInput placeholder="Search…" aria-label="Search" />
  <InputGroupAddon>
    <IconSearch />
  </InputGroupAddon>
  <InputGroupAddon align="inline-end">
    <InputGroupClear />
  </InputGroupAddon>
</InputGroup>

Coloque <InputGroupInput /> ou <InputGroupTextarea /> primeiro e os addons depois. Os addons se posicionam com align, então o campo vem primeiro na ordem de tabulação e para os leitores de tela.

O grupo acompanha seu campo, então as partes inteligentes não precisam de ligação. <InputGroupClear />, <InputGroupPasswordToggle /> e <InputGroupCount /> leem o valor, o type e o maxLength do campo, seja ele controlado ou não.

InputGroup
├── InputGroupAddon
│   ├── InputGroupText
│   ├── InputGroupButton
│   ├── InputGroupClear
│   ├── InputGroupCount
│   └── InputGroupPasswordToggle
└── InputGroupInput / InputGroupTextarea

Ícone

Os ícones ficam dentro da borda em qualquer dos lados. Clicar em um ícone foca o input, então o grupo inteiro parece um único campo.

import { IconCheck, IconMail, IconSearch } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/ui/input-group"

export function InputGroupIcon() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-4">
      <InputGroup>
        <InputGroupInput placeholder="Search…" aria-label="Search" />
        <InputGroupAddon>
          <IconSearch />
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput
          type="email"
          defaultValue="[email protected]"
          aria-label="Email"
        />
        <InputGroupAddon>
          <IconMail />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <IconCheck className="text-success" aria-label="Verified" />
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Limpar

<InputGroupClear /> aparece com fade quando há um valor. Ele limpa pelo histórico de edição do navegador, então Cmd+Z traz o texto de volta, e dispara o seu onChange. Escape também limpa. Um segundo Escape fica para o diálogo ou popover ao redor.

"use client"

import * as React from "react"
import { IconSearch } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupClear,
  InputGroupInput,
} from "@/components/ui/input-group"

const fruits = ["Apple", "Apricot", "Banana", "Blackberry", "Cherry", "Fig"]

export function InputGroupClearDemo() {
  const [query, setQuery] = React.useState("ap")
  const matches = fruits.filter((fruit) =>
    fruit.toLowerCase().includes(query.trim().toLowerCase())
  )

  return (
    <div className="flex w-full max-w-sm flex-col gap-3">
      <InputGroup>
        <InputGroupInput
          type="search"
          value={query}
          onChange={(event) => setQuery(event.target.value)}
          placeholder="Filter fruit"
          aria-label="Filter fruit"
        />
        <InputGroupAddon>
          <IconSearch />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <InputGroupClear />
        </InputGroupAddon>
      </InputGroup>
      <p className="text-sm text-muted-foreground">
        {matches.length > 0 ? matches.join(", ") : "No fruit matches."}
      </p>
    </div>
  )
}

Contagem de caracteres

<InputGroupCount /> conta em relação ao maxLength do campo. Apenas os dígitos que mudam giram. A contagem escurece perto do limite e fica vermelha ao atingi-lo, e uma tecla digitada além do limite a sacode levemente. Os leitores de tela ouvem uma mensagem quando o campo se aproxima do limite e quando o atinge, nunca a cada tecla.

import { IconAt } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupCount,
  InputGroupInput,
} from "@/components/ui/input-group"

export function InputGroupCountDemo() {
  return (
    <InputGroup className="max-w-sm">
      <InputGroupInput
        defaultValue="hextaui"
        maxLength={15}
        autoComplete="username"
        aria-label="Username"
      />
      <InputGroupAddon>
        <IconAt />
      </InputGroupAddon>
      <InputGroupAddon align="inline-end">
        <InputGroupCount />
      </InputGroupAddon>
    </InputGroup>
  )
}

Texto

Use <InputGroupText /> para unidades, moedas e partes de URL. O padding do input diminui ao lado de um addon para que o texto seja lido como um único valor.

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/ui/input-group"

export function InputGroupTextDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-4">
      <InputGroup>
        <InputGroupInput
          placeholder="0.00"
          inputMode="decimal"
          aria-label="Price"
        />
        <InputGroupAddon>
          <InputGroupText>$</InputGroupText>
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <InputGroupText>USD</InputGroupText>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="hextaui" aria-label="Domain" />
        <InputGroupAddon>
          <InputGroupText>https://</InputGroupText>
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <InputGroupText>.com</InputGroupText>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Button

<InputGroupButton /> é um botão ghost dimensionado para caber dentro do campo. Seus cantos são concêntricos com os do grupo, e ele tem o próprio anel de foco.

"use client"

import * as React from "react"
import { IconCheck, IconCopy, IconX } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
} from "@/components/ui/input-group"

export function InputGroupButtonDemo() {
  const [copied, setCopied] = React.useState(false)
  const [query, setQuery] = React.useState("button group")

  return (
    <div className="flex w-full max-w-sm flex-col gap-4">
      <InputGroup>
        <InputGroupInput
          readOnly
          defaultValue="https://hextaui.com/docs/input-group"
          aria-label="Share link"
        />
        <InputGroupAddon align="inline-end">
          <InputGroupButton
            size="icon-xs"
            aria-label={copied ? "Copied" : "Copy link"}
            onClick={async () => {
              await navigator.clipboard
                ?.writeText("https://hextaui.com/docs/input-group")
                .catch(() => {})
              setCopied(true)
              setTimeout(() => setCopied(false), 1500)
            }}
          >
            {copied ? <IconCheck /> : <IconCopy />}
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput
          value={query}
          onChange={(event) => setQuery(event.target.value)}
          placeholder="Search components…"
          aria-label="Search components"
        />
        <InputGroupAddon align="inline-end">
          {query ? (
            <InputGroupButton
              size="icon-xs"
              aria-label="Clear search"
              onClick={() => setQuery("")}
            >
              <IconX />
            </InputGroupButton>
          ) : null}
          <InputGroupButton variant="secondary">Search</InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Dica de teclado

Um <kbd> simples dentro de um addon é estilizado como uma tecla. É apenas uma dica visual, então associe o atalho você mesmo.

import { IconSearch } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/ui/input-group"

export function InputGroupKbd() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-4">
      <InputGroup>
        <InputGroupInput placeholder="Search docs…" aria-label="Search docs" />
        <InputGroupAddon>
          <IconSearch />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <kbd>⌘</kbd>
          <kbd>K</kbd>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput
          placeholder="Jump to file…"
          aria-label="Jump to file"
        />
        <InputGroupAddon align="inline-end">
          <kbd>/</kbd>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Textarea

<InputGroupTextarea /> cresce com o conteúdo até 16rem e depois rola. A altura se ajusta suavemente entre as linhas em vez de saltar. Um addon block-end vira uma barra de ferramentas embaixo dele, e os botões nas bordas ganham o mesmo recuo do canto em que estão.

"use client"

import * as React from "react"
import { IconArrowUp, IconPaperclip } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupCount,
  InputGroupTextarea,
} from "@/components/ui/input-group"

export function InputGroupTextareaDemo() {
  const [value, setValue] = React.useState("")

  return (
    <InputGroup className="max-w-sm">
      <InputGroupTextarea
        value={value}
        onChange={(event) => setValue(event.target.value)}
        maxLength={280}
        placeholder="Write a reply…"
        aria-label="Reply"
      />
      <InputGroupAddon align="block-end">
        <InputGroupButton size="icon-xs" aria-label="Attach a file">
          <IconPaperclip />
        </InputGroupButton>
        <InputGroupCount className="ms-auto" />
        <InputGroupButton
          variant="default"
          size="icon-xs"
          aria-label="Send"
          disabled={!value.trim()}
        >
          <IconArrowUp />
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  )
}

Um addon block-start fica acima do campo. Adicione separator para desenhar uma linha fina entre eles.

import { IconCopy, IconFileCode } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupText,
  InputGroupTextarea,
} from "@/components/ui/input-group"

export function InputGroupBlockStart() {
  return (
    <InputGroup className="max-w-sm">
      <InputGroupTextarea
        defaultValue={'console.log("Hello from HextaUI")'}
        aria-label="script.js"
      />
      <InputGroupAddon align="block-start" separator>
        <InputGroupText>
          <IconFileCode />
          script.js
        </InputGroupText>
        <InputGroupButton size="icon-xs" aria-label="Copy" className="ms-auto">
          <IconCopy />
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  )
}

Senha

<InputGroupPasswordToggle /> alterna um campo type="password" para texto e de volta. O cursor e a seleção permanecem onde estavam, um clique do mouse mantém o foco no campo, e a senha é ocultada de novo quando o formulário é enviado. Controle com revealed.

import { IconLock } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupPasswordToggle,
} from "@/components/ui/input-group"

export function InputGroupPassword() {
  return (
    <InputGroup className="max-w-sm">
      <InputGroupInput
        type="password"
        defaultValue="correct horse battery staple"
        autoComplete="current-password"
        aria-label="Password"
      />
      <InputGroupAddon>
        <IconLock />
      </InputGroupAddon>
      <InputGroupAddon align="inline-end">
        <InputGroupPasswordToggle />
      </InputGroupAddon>
    </InputGroup>
  )
}

Tamanhos

size no grupo define a altura e a repassa ao input, correspondendo aos tamanhos de <Input />. Os botões mantêm cantos concêntricos em todos os tamanhos.

import { IconSearch } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
} from "@/components/ui/input-group"

export function InputGroupSizes() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-4">
      {(["sm", "default", "lg"] as const).map((size) => (
        <InputGroup key={size} size={size}>
          <InputGroupInput
            placeholder={`Size ${size}`}
            aria-label={`Size ${size}`}
          />
          <InputGroupAddon>
            <IconSearch />
          </InputGroupAddon>
          <InputGroupAddon align="inline-end">
            <InputGroupButton>Go</InputGroupButton>
          </InputGroupAddon>
        </InputGroup>
      ))}
    </div>
  )
}

Inválido

Defina aria-invalid no input e o grupo inteiro fica vermelho, inclusive seu anel de foco. Vincule a mensagem com aria-describedby.

import { IconAt, IconAlertCircle } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/ui/input-group"

export function InputGroupInvalid() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <InputGroup>
        <InputGroupInput
          defaultValue="preet@"
          aria-label="Email"
          aria-invalid
          aria-describedby="email-error"
        />
        <InputGroupAddon>
          <IconAt />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <IconAlertCircle className="text-destructive" aria-hidden />
        </InputGroupAddon>
      </InputGroup>
      <p id="email-error" className="text-sm text-destructive">
        Enter a complete email address.
      </p>
    </div>
  )
}

Desabilitado

Um input desativado esmaece o grupo inteiro e mostra o cursor not-allowed sobre ele. Desative também os botões dos addons, pois do contrário continuam utilizáveis.

import { IconLink } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
} from "@/components/ui/input-group"

export function InputGroupDisabled() {
  return (
    <InputGroup className="max-w-sm">
      <InputGroupInput
        disabled
        defaultValue="https://hextaui.com"
        aria-label="Link"
      />
      <InputGroupAddon>
        <IconLink />
      </InputGroupAddon>
      <InputGroupAddon align="inline-end">
        <InputGroupButton disabled>Copy</InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  )
}

Carregando

Os addons inline se ajustam suavemente à nova largura quando o conteúdo muda, então o campo nunca salta quando um spinner vira uma contagem de resultados. O spinner só gira quando o movimento é permitido, e role="status" anuncia o texto.

"use client"

import * as React from "react"
import { IconLoader2, IconSearch } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/ui/input-group"

const packages = ["react", "react-dom", "react-hook-form", "redux", "remix"]

export function InputGroupLoading() {
  const [query, setQuery] = React.useState("re")
  const [pending, setPending] = React.useState(false)
  const timer = React.useRef<ReturnType<typeof setTimeout>>(undefined)
  const results = packages.filter((name) => name.includes(query.trim()))

  React.useEffect(() => () => clearTimeout(timer.current), [])

  return (
    <InputGroup className="max-w-sm">
      <InputGroupInput
        value={query}
        onChange={(event) => {
          setQuery(event.target.value)
          setPending(true)
          clearTimeout(timer.current)
          timer.current = setTimeout(() => setPending(false), 600)
        }}
        aria-label="Search packages"
        aria-busy={pending}
      />
      <InputGroupAddon>
        <IconSearch />
      </InputGroupAddon>
      <InputGroupAddon align="inline-end">
        <InputGroupText role="status">
          {pending ? (
            <>
              <IconLoader2 className="motion-safe:animate-spin" aria-hidden />
              Searching
            </>
          ) : results.length === 1 ? (
            "1 package"
          ) : (
            `${results.length} packages`
          )}
        </InputGroupText>
      </InputGroupAddon>
    </InputGroup>
  )
}

Renderize um <InputGroupButton /> como gatilho de dropdown para delimitar o escopo do input.

import { IconChevronDown } from "@tabler/icons-react"

import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
} from "@/components/ui/input-group"

export function InputGroupDropdown() {
  return (
    <InputGroup className="max-w-sm">
      <InputGroupInput placeholder="Enter a search term" aria-label="Search" />
      <InputGroupAddon align="inline-end">
        <DropdownMenu>
          <DropdownMenuTrigger render={<InputGroupButton />}>
            Everywhere
            <IconChevronDown data-icon="inline-end" />
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuGroup>
              <DropdownMenuItem>Everywhere</DropdownMenuItem>
              <DropdownMenuItem>This project</DropdownMenuItem>
              <DropdownMenuItem>Documentation</DropdownMenuItem>
            </DropdownMenuGroup>
          </DropdownMenuContent>
        </DropdownMenu>
      </InputGroupAddon>
    </InputGroup>
  )
}

Conteúdo longo

Valores longos rolam dentro do input em vez de esticar o grupo. Envolva textos longos de addon em um span com truncamento e largura máxima.

import { IconWorld } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/ui/input-group"

export function InputGroupLongContent() {
  return (
    <div className="flex w-72 flex-col gap-4">
      <InputGroup>
        <InputGroupInput
          defaultValue="averyveryverylongunbrokenvaluethatkeepsgoingandgoing"
          aria-label="Value"
        />
        <InputGroupAddon>
          <IconWorld />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <InputGroupText>.example.com</InputGroupText>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="name" aria-label="Subdomain" />
        <InputGroupAddon>
          <InputGroupText className="max-w-28">
            <span className="truncate">
              https://workspace-with-a-long-name.
            </span>
          </InputGroupText>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}

Da direita para a esquerda

Os addons, o padding e os raios dos cantos usam lados lógicos, então inline-start fica à direita.

import { IconArrowUp, IconSearch } from "@tabler/icons-react"

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
} from "@/components/ui/input-group"

export function InputGroupRtl() {
  return (
    <div dir="rtl" className="flex w-full max-w-sm flex-col gap-4">
      <InputGroup>
        <InputGroupInput placeholder="ابحث…" aria-label="بحث" />
        <InputGroupAddon>
          <IconSearch />
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <kbd>⌘K</kbd>
        </InputGroupAddon>
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="0.00" aria-label="السعر" />
        <InputGroupAddon>
          <InputGroupText>ر.س</InputGroupText>
        </InputGroupAddon>
        <InputGroupAddon align="inline-end">
          <InputGroupButton variant="default" size="icon-xs" aria-label="إرسال">
            <IconArrowUp />
          </InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </div>
  )
}
TeclaAção
TabVai do campo a cada botão de addon, na ordem do código-fonte.
ShiftTabVolta pelos botões e pelo campo.
EscapeCom um InputGroupClear, limpa o campo. Quando já está vazio, Escape passa adiante.
  • Todo campo precisa de um nome. Use um rótulo visível, um Field ou aria-label. Ícones e textos de addon não fazem parte do nome do campo.
  • Dê aos botões só com ícone um aria-label.
  • Quando o texto de um addon carrega significado, como uma moeda ou um domínio, adicione-o ao rótulo ou referencie-o com aria-describedby.
  • <InputGroupClear /> é ignorado na ordem de tabulação porque Escape faz a mesma coisa. O alternador de senha continua tabulável e mantém o mesmo nome, com aria-pressed informando seu estado.
  • Quando um envio encontra o campo inválido, o grupo balança uma vez. Com movimento reduzido, a borda vermelha é a única pista.
  • Em telas sensíveis ao toque, o texto do campo tem pelo menos 16px para que os celulares não apliquem zoom quando ele recebe foco.

<InputGroupInput /> e <InputGroupTextarea /> aceitam as props dos elementos que renderizam. As outras partes aceitam os atributos do seu elemento.

PropTipoPadrão
sizeAltura do grupo, repassada ao input.
"sm" | "default" | "lg""default"
AtributoDescrição
data-slot="input-group"Seleciona o grupo no CSS. Renderiza role="group".
data-sizeO tamanho atual.
data-filledPresente enquanto o campo tem um valor.
data-shakePresente enquanto o grupo balança após um envio malsucedido.
data-disabledDefina você mesmo para esmaecer o grupo quando apenas os addons estão desativados.
--input-group-radiusRaio dos cantos do grupo. Botões e teclas derivam o raio deles a partir dele.
--input-group-heightAltura do grupo para o size atual.
PropTipoPadrão
sizeHerdado do grupo.
"sm" | "default" | "lg"–
aria-invalid
boolean–
disabled
booleanfalse
readOnly
booleanfalse
AtributoDescrição
data-slot="input-group-control"Marca o campo. O grupo lê dele os estados de foco, inválido, desativado e somente leitura.
data-invalidPresente quando um Field ao redor marca o valor como inválido.
data-disabledPresente quando o campo está desativado.
data-focusedPresente enquanto o campo tem foco.
data-filledPresente quando o campo tem um valor.
data-dirtyPresente quando o valor difere do inicial.
data-touchedPresente depois que o campo recebeu foco e o perdeu.
PropTipoPadrão
autoResizeCresce com o conteúdo até 16rem, ajustando-se suavemente entre as alturas.
booleantrue
shakeBalança o grupo quando um envio o encontra inválido.
booleantrue
rows
number–
aria-invalid
boolean–
disabled
booleanfalse
AtributoDescrição
data-slot="input-group-control"Marca o campo. O grupo lê dele os estados de foco, inválido, desativado e somente leitura.
data-invalidPresente quando um Field ao redor marca o valor como inválido.
data-disabledPresente quando o campo está desativado.
data-focusedPresente enquanto o campo tem foco.
data-filledPresente quando o campo tem um valor.
data-dirtyPresente quando o valor difere do inicial.
data-touchedPresente depois que o campo recebeu foco e o perdeu.
PropTipoPadrão
align
"inline-start" | "inline-end" | "block-start" | "block-end""inline-start"
separatorDesenha uma linha fina entre um addon de bloco e o campo.
booleanfalse
AtributoDescrição
data-slot="input-group-addon"Seleciona os addons no CSS.
data-alignO alinhamento atual.
data-separatorPresente quando separator está definido.
--input-group-addon-insetEspaço entre a borda do grupo e um botão ou tecla dentro dele.
PropTipoPadrão
variant
"default" | "outline" | "secondary" | "ghost" | "destructive" | "link""ghost"
size
"xs" | "sm" | "icon-xs" | "icon-sm""xs"
type
string"button"
feedbackToda prop de Button funciona, inclusive o fluxo de carregamento e sucesso.
booleanfalse
AtributoDescrição
data-slot="input-group-button"Seleciona os botões de addon no CSS.
data-sizeO tamanho atual.
PropTipoPadrão
onClearChamado depois que o campo é limpo.
() => void–
aria-label
string"Clear"
children
ReactNode<IconX />
AtributoDescrição
data-slot="input-group-clear"Seleciona o botão de limpar no CSS.
data-visiblePresente enquanto o campo tem um valor e é editável.
PropTipoPadrão
revealedEstado controlado. Deixe sem definir para que ele se gerencie sozinho.
boolean–
onRevealedChange
(revealed: boolean) => void–
aria-label
string"Show password"
AtributoDescrição
data-slot="input-group-password-toggle"Seleciona o alternador no CSS.
data-revealedPresente enquanto a senha está visível.
PropTipoPadrão
thresholdCaracteres restantes a partir dos quais a contagem se destaca.
number10% of maxLength, at most 20
announcementMensagem para leitores de tela quando a contagem cruza o limite ou atinge o máximo.
(remaining: number) => string–
AtributoDescrição
data-slot="input-group-count"Selecione a contagem no CSS.
data-state="near" | "limit"Presente dentro do limite e quando não restam caracteres.
data-bumpPresente brevemente quando uma tecla é pressionada no limite.
AtributoDescrição
data-slot="input-group-text"Seleciona o texto de addon no CSS.

Usado em blocos

Blocos que se baseiam em Input group.