3.9 KiB
InputGroup Variants (cva config)
Purpose
inputGroupVariants, inputGroupAddonVariants, inputGroupInputVariants, inputGroupTextareaVariants, and inputGroupButtonVariants are the five cva (class-variance-authority) configurations powering the <InputGroup> primitives. They are split from input-group.tsx into their own module so an ejected source copy under npx shadcn@latest add @suaveplan/input-group keeps the cva configurations in a dedicated file. Theme overrides flow through useThemedVariants(...).
The wrapper cva carries the shared border + focus ring; the inner <InputGroupInput> / <InputGroupTextarea> cvas strip the standard border + shadow + ring that would otherwise double up with the wrapper's own.
Features
- Wrapper
flex w-full items-center rounded-md border border-input bg-transparent shadow-smwithfocus-within:ring-2anddata-[invalid=true]:border-destructive. - Addon recipe with three positions:
start(right-border separator),end(left-border separator),none(no separator, used for inline buttons). - Input recipe strips the standard
<Input>border / shadow / focus ring (border-0 outline-none shadow-none focus:ring-0). - Textarea recipe strips the standard
<Textarea>border / shadow / focus ring with a defaultmin-height: 80px. - Button recipe carries the inline icon-button surface (
h-8 w-8 mx-1 rounded-md) with the standarddata-iconslot rules. - NEVER uses
space-x-*per the shadcn skill rule. motion-reduce:transition-nonefor users withprefers-reduced-motion: reduce.
Usage: Basic Example
import {
inputGroupVariants,
inputGroupInputVariants,
inputGroupAddonVariants,
} from "@suaveplan/react-ui";
const wrapperCls = inputGroupVariants();
const inputCls = inputGroupInputVariants();
const addonCls = inputGroupAddonVariants({ position: "start" });
Usage: Advanced Example
import {
inputGroupVariants,
inputGroupInputVariants,
cn,
} from "@suaveplan/react-ui";
export function CustomInputGroup() {
return (
<div className={cn(inputGroupVariants(), "ring-2 ring-accent")}>
<span className="px-3 text-sm text-muted-foreground">@</span>
<input className={inputGroupInputVariants()} />
</div>
);
}
API Reference
inputGroupVariants(): string
Returns the wrapper classes.
inputGroupAddonVariants(props?: { position?: "start" | "end" | "none" }): string
Returns the addon classes. Omitted position falls back to the cva defaultVariants (position: "start").
inputGroupInputVariants(): string
Returns the input classes — strips inner border / shadow / focus ring so the wrapper carries them.
inputGroupTextareaVariants(): string
Returns the textarea classes — same border-stripping treatment as the input.
inputGroupButtonVariants(): string
Returns the inline icon-button classes — h-8 w-8 mx-1 rounded-md with the standard data-icon slot rules.
Implementation Notes
- The five cvas are kept separate so consumer themes can override each independently — for example a theme that styles the wrapper as a pill while leaving the inner input untouched.
- The input's
focus:ring-0 focus-visible:ring-0is intentional: the wrapper carries the ring viafocus-within:ring-2so removing the inner ring is the only way to avoid the double-ring artefact. Consumers MUST use<InputGroupInput>(not<Input>) inside the group for this reason. - The button cva uses
mx-1so the inline button does not press flush against the input's text — a minor padding tweak that keeps the layout breathing under both LTR and RTL. - Per the shadcn skill rule, the cvas NEVER use
space-x-*/space-y-*. - Tokens reference theme-driven CSS custom properties (
border-input,bg-transparent,text-muted-foreground) so the colour palette comes from the activeThemePlugin.cssVariablespayload.