Input group
Un formulario de un solo campo con el botón adentro, con esquinas concéntricas al campo.
Instalación
$ pnpm dlx shadcn@latest add @ssntl/input-groupUso
import { InputGroup, InputGroupButton, InputGroupInput } from "@/components/ui/input-group"
<InputGroup>
<InputGroupInput aria-label="Buscar" placeholder="Órdenes, clientes…" />
<InputGroupButton aria-label="Buscar"><Search /></InputGroupButton>
</InputGroup>- Esquinas anidadas: el campo es una píldora con 4px de padding alrededor de un botón píldora de 48px, y ambas curvas comparten centro.
- Solo para formularios de un campo: búsqueda, newsletter, un prompt.
- El botón solo de ícono necesita aria-label; el campo también, si no hay etiqueta visible.
Código
import * as React from "react"
import { cn } from "@/lib/utils"
import { Button } from "@/registry/ssntl/ui/button"
// A single-field form (search, newsletter, prompt) with the submit button set
// inside the field. Nested corners: a pill with 4px padding around a 48px pill
// button, so both curves share one center (outer = inner + padding).
function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="input-group"
className={cn(
"flex w-full min-w-0 items-center gap-1 rounded-full border border-input bg-card p-1 pl-5",
"transition-[border-color] duration-(--duration-fast) ease-out hover:border-muted-foreground",
"focus-within:border-foreground has-[input:focus-visible]:outline-2 has-[input:focus-visible]:outline-offset-2 has-[input:focus-visible]:outline-ring",
"has-aria-invalid:border-destructive",
className
)}
{...props}
/>
)
}
function InputGroupInput({
className,
...props
}: React.ComponentProps<"input">) {
return (
<input
data-slot="input-group-input"
className={cn(
"h-12 min-w-0 flex-1 bg-transparent text-body text-foreground outline-none placeholder:text-muted-foreground",
className
)}
{...props}
/>
)
}
function InputGroupButton({
size = "icon",
className,
...props
}: React.ComponentProps<typeof Button>) {
return (
<Button
data-slot="input-group-button"
size={size}
className={cn("shrink-0", className)}
{...props}
/>
)
}
export { InputGroup, InputGroupButton, InputGroupInput }