A text field with addons joined to it: a fixed text segment, an icon, or a button such as Copy.
InputGroup wears the TextInput box and its --input-* tokens, with addons set into either end. A string addon ("https://", "$", "kg") is drawn as a sunken text segment divided by a hairline; an element addon (an icon or an IconButton) sits inline.
Focus, invalid, read-only and disabled all draw on the whole group, addons included. The <input> takes every native attribute, and reads its id, required and error state from a surrounding Field.
Installation
npx shadcn@latest add KezLahd/rime/input-groupAlso installs: base, field, text-input.
Usage
import { InputGroup } from "@/components/ui";
<Field label="Website">
<InputGroup start="https://" placeholder="example.com" />
</Field>Examples
Text, icon and button addons
In a Field
Letters, numbers and dashes.
Enter a weight under 30 kg.
API
Generated from the component's TypeScript types and JSDoc (scripts/gen-ui-registry.mjs), so it always matches the source.
InputGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| start | ReactNode | Before the input. A string ("https://", "$") is set off as a sunken text segment with a hairline; an element (an icon, an IconButton) sits inline. | |
| end | ReactNode | After the input, the same way: a unit ("kg", ".com") or a button. | |
| size | "sm" | "md" | "md" | |
| invalid | boolean | Overrides the Field's invalid state. | |
| mono | boolean | ||
| boxClassName | string | Class for the outer box rather than the <input>. |
Also accepts the native attributes of AriaAttributes, DOMAttributes, HTMLAttributes, InputHTMLAttributes.
Theme tokens
Per-component tokens are undeclared by default, so the default shown is the fallback the CSS uses. Set one at :root (or in theme.css) to restyle every instance. Live values are read from this page, so they follow the Rime Studio.
| Token | Default | Live value |
|---|---|---|
| --field-focus-border | rgba(var(--rgb-brand), 0.7) / var(--focus-color) | … |
| --field-focus-ring | var(--focus-halo) | … |
| --field-focus-ring-invalid | 0 0 0 4px rgba(var(--rgb-danger), 0.14) | … |
| --field-hover-border | rgba(var(--rgb-brand-deep), 0.3) | … |
| --input-addon-bg | var(--recess-fill) | … |
| --input-bg | var(--surface-solid) | … |
| --input-border | var(--line-input) | … |
| --input-border-width | var(--border-w-field) | … |
| --input-font-size | var(--text-input) | … |
| --input-height-md | var(--field-h-md) | … |
| --input-height-sm | var(--field-h-sm) | … |
| --input-pad-x | calc(14px * var(--density)) | … |
| --input-radius | var(--r-md) / var(--r-sm) | … |
| --input-shadow | var(--shadow-input) | … |
System tokens it reads
| Token | Default | Live value |
|---|---|---|
| --border-w | tokens.css | … |
| --border-w-field | tokens.css | … |
| --danger-base | tokens.css | … |
| --danger-field-fill | tokens.css | … |
| --danger-line | tokens.css | … |
| --density | tokens.css | … |
| --dur | tokens.css | … |
| --ease | tokens.css | … |
| --field-h-md | tokens.css | … |
| --field-h-sm | tokens.css | … |
| --focus-color | tokens.css | … |
| --focus-halo | tokens.css | … |
| --font-body | tokens.css | … |
| --font-mono | tokens.css | … |
| --ink-body | tokens.css | … |
| --ink-brand | tokens.css | … |
| --ink-disabled | tokens.css | … |
| --ink-muted | tokens.css | … |
| --ink-placeholder | tokens.css | … |
| --ink-secondary | tokens.css | … |
| --line | tokens.css | … |
| --line-input | tokens.css | … |
| --r-md | tokens.css | … |
| --r-sm | tokens.css | … |
| --r-xs | tokens.css | … |
| --recess-fill | tokens.css | … |
| --rgb-brand | tokens.css | … |
| --rgb-brand-deep | tokens.css | … |
| --rgb-danger | tokens.css | … |
| --shadow-input | tokens.css | … |
| --surface-solid | tokens.css | … |
| --surface-sunken | tokens.css | … |
| --text-body | tokens.css | … |
| --text-input | tokens.css | … |
| --text-small | tokens.css | … |
| --wash-active | tokens.css | … |
| --wash-subtle | tokens.css | … |
Accessibility
- Text addons are visual only (aria-hidden). If the unit matters to understanding, say it in the label or hint as well ("Weight in kg").
- Button addons are real buttons with their own accessible names, after the input in tab order.
- Wrap it in <Field label=…> so the label, hint and error are wired through context.
Do and don't
Do
- Use a text addon for a fixed part the user should not type.
- Use PrefixedInput when the whole value has a fixed format.
Don't
- Don't put more than one button in an addon.
- Don't style the <input> directly; theme the box with --input-* tokens.
For AI agents
This page as markdown, rendered from the same registry entry. Point an agent at it (or add .md to this page's URL), or at /llms.txt for the index.
Open input-group.mdRelated: text-input, prefixed-input, field