Skip to content
Esc
navigateopen⌘Jpreview
On this page

Input Group

Display additional information or actions to an input or textarea.

https://
import * as stylex from '@stylexjs/stylex';

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
  InputGroupText,
} from '@/components/ui/input-group';
import { space, container } from '@/lib/constants.stylex';

export default function InputGroupDemo() {
  return (
    <div {...stylex.props(styles.col)}>
      <InputGroup>
        <InputGroupAddon>
          <InputGroupText>https://</InputGroupText>
        </InputGroupAddon>
        <InputGroupInput placeholder="example.com" />
      </InputGroup>
      <InputGroup>
        <InputGroupInput placeholder="Search…" />
        <InputGroupAddon align="inline-end">
          <InputGroupButton>Go</InputGroupButton>
        </InputGroupAddon>
      </InputGroup>
    </div>
  );
}

const styles = stylex.create({
  col: {
    display: 'flex',
    flexDirection: 'column',
    gap: space.s3,
    width: container.sm,
  },
});

Install

npx shadcn@latest add @madeui/input-group

Usage

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

Composition

<InputGroup>
  <InputGroupAddon>
    <InputGroupText />
  </InputGroupAddon>
  <InputGroupInput />
  <InputGroupAddon align="inline-end">
    <InputGroupButton />
  </InputGroupAddon>
</InputGroup>

Icon

import * as stylex from '@stylexjs/stylex';

import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group';
import { container } from '@/lib/constants.stylex';

export default function InputGroupIcon() {
  return (
    <InputGroup style={styles.group}>
      <InputGroupAddon>
        <svg
          width="14"
          height="14"
          viewBox={`0 0 14 14`}
          fill="none"
          stroke="currentColor"
          strokeWidth="1.5"
          strokeLinecap="round"
          strokeLinejoin="round"
          aria-hidden
        >
          <circle cx="6" cy="6" r="4.5" />
          <path d={`m12 12-2.5-2.5`} />
        </svg>
      </InputGroupAddon>
      <InputGroupInput placeholder="Search…" />
    </InputGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.sm,
  },
});

Button

import * as stylex from '@stylexjs/stylex';

import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from '@/components/ui/input-group';
import { container } from '@/lib/constants.stylex';

export default function InputGroupButtonExample() {
  return (
    <InputGroup style={styles.group}>
      <InputGroupInput readOnly defaultValue="https://useblume.dev/i/8f3c1" />
      <InputGroupAddon align="inline-end">
        <InputGroupButton aria-label="Copy link">
          <svg
            width="14"
            height="14"
            viewBox={`0 0 14 14`}
            fill="none"
            stroke="currentColor"
            strokeWidth="1.5"
            strokeLinecap="round"
            strokeLinejoin="round"
            aria-hidden
          >
            <rect x="5" y="5" width="7" height="7" rx="1" />
            <path d={`M9 5V3a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h2`} />
          </svg>
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.sm,
  },
});

Kbd

Pair with the Kbd component to show a keyboard shortcut.

⌘K
import * as stylex from '@stylexjs/stylex';

import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group';
import { Kbd } from '@/components/ui/kbd';
import { container } from '@/lib/constants.stylex';

export default function InputGroupKbd() {
  return (
    <InputGroup style={styles.group}>
      <InputGroupInput placeholder="Search the docs…" />
      <InputGroupAddon align="inline-end">
        <Kbd>⌘K</Kbd>
      </InputGroupAddon>
    </InputGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.sm,
  },
});

Spinner

import * as stylex from '@stylexjs/stylex';

import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group';
import { Spinner } from '@/components/ui/spinner';
import { container } from '@/lib/constants.stylex';

export default function InputGroupSpinner() {
  return (
    <InputGroup style={styles.group}>
      <InputGroupInput placeholder="Enter a username" defaultValue="useblume" />
      <InputGroupAddon align="inline-end">
        <Spinner />
      </InputGroupAddon>
    </InputGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.sm,
  },
});

Textarea

Use InputGroupTextarea in place of InputGroupInput — pairs with align="block-start" / align="block-end" addons.

import * as stylex from '@stylexjs/stylex';

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupTextarea,
} from '@/components/ui/input-group';
import { container } from '@/lib/constants.stylex';

export default function InputGroupTextareaExample() {
  return (
    <InputGroup style={styles.group}>
      <InputGroupTextarea placeholder="Type your message…" rows={3} />
      <InputGroupAddon align="block-end">
        <InputGroupButton variant="outline" size="xs">
          Send
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.sm,
  },
});

API reference

The group draws the border and focus ring (:focus-within); the control inside renders bare. Clicking an addon focuses the input.

InputGroupAddon

Prop Type Default Description
align 'inline-start' | 'inline-end' | 'block-start' | 'block-end' 'inline-start' Block alignments need a column layout — pass style with flexDirection: 'column' on the group.

InputGroupButton

Prop Type Default Description
size 'xs' | 'iconXs' | 'iconSm' 'xs' Compact button sizes for inside the group.
variant ButtonVariant 'ghost'

All parts accept a style prop (StyleXStyles, merged last).

Was this page helpful?