Primitives
Input group
Joined input wrapper for addons, icons, and a shared focus indicator.
Composition
Input with addons
- <InputGroup>
- <InputGroupAddon>
- addon content
- <Input />
- <InputGroupAddon>
Installation
First install and activate one skin. Core deliberately contains no visual token defaults.
The Control UI source installs this primitive from src/registry/sources/control-ui/ui/input-group.tsx.
npx shadcn@latest add https://control-ui.dev/r/input-group.jsonDependencies
Control variants
src/registry/sources/control-ui/control-variants.tsSupportRaw code
Primary installed source
"use client";import { useRender } from "@base-ui/react/use-render";import type { ComponentProps, CSSProperties } from "react";import { createContext, use } from "react";import type { RenderProp } from "@/components/control-ui/control-props";import type { ControlSize } from "@/components/control-ui/control-variants";import type { FieldKnobStyle } from "@/components/control-ui/knob-contracts/field-knobs";import { cn } from "@/components/control-ui/lib/cn";export type InputGroupProps = Omit<ComponentProps<"div">, "style"> & { style?: CSSProperties & FieldKnobStyle } & { render?: RenderProp<ComponentProps<"div">>; size?: ControlSize;};export type InputGroupAddonProps = ComponentProps<"span"> & { style?: CSSProperties & FieldKnobStyle };const InputGroupSurfaceContext = createContext(false);export function useIsInsideInputGroup() { return use(InputGroupSurfaceContext);}export function InputGroup({ size = "md", className, render, children, ...props }: InputGroupProps) { const classes = cn("flex min-w-0 w-full items-center overflow-hidden", className); const group = useRender({ defaultTagName: "div", render, props: { ...props, "data-control-ui": "input-group", "data-slot": "root", "data-control-family": "field", "data-control": "true", "data-size": size, className: classes, children, }, }); return <InputGroupSurfaceContext value={true}>{group}</InputGroupSurfaceContext>;}export function InputGroupAddon({ className, ...props }: InputGroupAddonProps) { return ( <span {...props} data-control-ui="input-group" data-control-family="field" data-field-kind="input-group" data-slot="addon" className={cn("inline-flex shrink-0 items-center", className)} /> );}Knobs
Typed custom properties the recipe paints with. Set one on the root — style, a utility class, or a skin — and every slot inherits it.
--cui-field-* · 15 knobsHow the cascade resolves--cui-field-radius<length-percentage>var(--nest-radius, var(--radius-control))--cui-field-background<color>var(--control-fill)--cui-field-hover-background<color>var(--hover-fill)--cui-field-affordance-background<color>transparent--cui-field-affordance-shadow*0 0 transparent--cui-field-affordance-foreground<color>var(--muted-foreground)--cui-field-affordance-hover-background<color>var(--hover-fill)--cui-field-foreground<color>var(--foreground)--cui-field-border-color<color>var(--control-rim)--cui-field-border-width<length>var(--control-rim-width)--cui-field-shadow*var(--shadow-inset)--cui-field-backdrop-filter*blur(0px)--cui-field-height<length-percentage>var(--control-h-md)--cui-field-padding-inline<length-percentage>var(--padding-x)--cui-field-font-size<length-percentage>var(--text-body)