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).