Skip to main content

Import

import { InputGroup } from "@kuzenbo/core";

Usage

The InputGroup component allows you to attach text, icons, or buttons to inputs, creating visually connected input combinations.
import { InputGroup } from "@kuzenbo/core";

export default function SearchInput() {
  return (
    <InputGroup>
      <InputGroup.Input placeholder="Search account, invoice, or contract" />
    </InputGroup>
  );
}

With Addon Start

Add decorative text or icons before the input:
import { InputGroup } from "@kuzenbo/core";

export default function InvoiceInput() {
  return (
    <InputGroup>
      <InputGroup.Addon align="inline-start">
        <InputGroup.Text>INV-</InputGroup.Text>
      </InputGroup.Addon>
      <InputGroup.Input placeholder="2026-0042" />
    </InputGroup>
  );
}

With Addon Both Sides

Combine start and end addons for currency or unit inputs:
import { InputGroup } from "@kuzenbo/core";

export default function PriceInput() {
  return (
    <InputGroup>
      <InputGroup.Addon align="inline-start">
        <InputGroup.Text>$</InputGroup.Text>
      </InputGroup.Addon>
      <InputGroup.Input placeholder="25000" type="number" />
      <InputGroup.Addon align="inline-end">
        <InputGroup.Text>USD</InputGroup.Text>
      </InputGroup.Addon>
    </InputGroup>
  );
}

With Button

Add action buttons within the input group:
import { InputGroup } from "@kuzenbo/core";

export default function ValidatedInput() {
  return (
    <InputGroup>
      <InputGroup.Input placeholder="Paste purchase order number" />
      <InputGroup.Addon align="inline-end">
        <InputGroup.Button>Validate</InputGroup.Button>
      </InputGroup.Addon>
    </InputGroup>
  );
}

Sizes

InputGroup supports five size variants:
import { InputGroup } from "@kuzenbo/core";

const sizes = ["xs", "sm", "md", "lg", "xl"] as const;

export default function InputGroupSizes() {
  return (
    <div className="grid gap-3">
      {sizes.map((size) => (
        <InputGroup key={size} size={size}>
          <InputGroup.Addon align="inline-start">
            <InputGroup.Text>Seats</InputGroup.Text>
          </InputGroup.Addon>
          <InputGroup.Input placeholder={`${size.toUpperCase()} seat limit`} />
          <InputGroup.Addon align="inline-end">
            <InputGroup.Button>Save</InputGroup.Button>
          </InputGroup.Addon>
        </InputGroup>
      ))}
    </div>
  );
}

Disabled State

import { InputGroup } from "@kuzenbo/core";

export default function DisabledInputGroup() {
  return (
    <InputGroup data-disabled="true">
      <InputGroup.Addon align="inline-start">
        <InputGroup.Text>Plan</InputGroup.Text>
      </InputGroup.Addon>
      <InputGroup.Input disabled readOnly value="Enterprise Annual" />
    </InputGroup>
  );
}

Props

InputGroup

size
'xs' | 'sm' | 'md' | 'lg' | 'xl'
default:"md"
Controls the height and padding of the input group.
className
string
Additional CSS classes for the container.
children
ReactNode
Input, addons, and buttons to display within the group.

InputGroup.Input

placeholder
string
Placeholder text for the input.
type
string
default:"text"
HTML input type (text, email, number, etc.).
disabled
boolean
default:false
Disables the input.
size
'xs' | 'sm' | 'md' | 'lg' | 'xl'
Override the size from the parent InputGroup.

InputGroup.Addon

align
'inline-start' | 'inline-end' | 'block-start' | 'block-end'
default:"inline-start"
Position of the addon relative to the input.
children
ReactNode
Content of the addon, typically InputGroup.Text or InputGroup.Button.

InputGroup.Text

children
ReactNode
Text or icons to display as decorative addon content.

InputGroup.Button

Accepts all standard Button props.

InputGroup.Textarea

Similar to InputGroup.Input but renders a textarea element.

Composition

import { InputGroup } from "@kuzenbo/core";

<InputGroup>
  <InputGroup.Addon align="inline-start">
    <InputGroup.Text>https://</InputGroup.Text>
  </InputGroup.Addon>
  <InputGroup.Input placeholder="example.com" />
</InputGroup>

Types

export type InputGroupProps = ComponentProps<"div"> & {
  size?: InputSize;
};
export type InputGroupAddonProps = ComponentProps<"div">;
export type InputGroupInputProps = ComponentProps<typeof Input>;
export type InputGroupTextProps = ComponentProps<"span">;
export type InputGroupButtonProps = ComponentProps<typeof Button>;
export type InputGroupTextareaProps = ComponentProps<typeof Textarea>;

Accessibility

  • Input remains focusable and keyboard-navigable
  • Addons are properly grouped with the input visually
  • Disabled state is communicated to assistive technologies
  • Focus ring encompasses the entire group

Build docs developers (and LLMs) love