Skip to content
ghostui

Preview

Design guidance

Use a group when a field needs a prefix, unit, or nearby action. Keep the label outside the boundary. Addons follow their DOM order, so visual and keyboard order agree. Use Composer for chat sending and Date Picker for calendar selection.

A group does not own validation, clipboard access, tool execution, or application state. It reuses Input and Textarea. Its actions use the regular Button and Dropdown Menu components.

Installation

Install

The labeled examples also use Field. Action examples use Button and Dropdown Menu; install those owners when you use their parts. Icon examples use lucide-react.

Basic usage

Structures

Control renders the canonical Input. Multiline renders the canonical Textarea. Place either inside Root and add caller-owned content before or after it. For a textarea and footer, use layout="multiline".

Examples

Icon

Give a workspace email field a quiet visual cue.

Fixed text

Keep the protocol and deployment suffix separate from the editable name.

https://.workers.dev

Copy action

Copy a model endpoint. A failed clipboard write keeps a manual recovery message visible.

Password visibility

Reveal a provider key without changing its value. The action has a changing accessible name and pressed state.

Multiline with bottom actions

Keep a review note and Save action in one outlined boundary. The four-row default and native textarea attributes come from Textarea. The group keeps space for those rows and the action row when resized smaller. Resize the outer group vertically from its corner; the action row stays at the bottom. The corner mark doubles along both edges on hover and extends across the bottom while dragging; the right mark keeps its hover length. Set style={{ resize: "none" }} on InputGroup.Root for a fixed group.

Masked input

These optional recipes format as you type, paste, or edit. Install react-number-format for the examples below and compose NumericFormat or PatternFormat with customInput={InputGroup.Control}. The group itself has no masking dependency. A mask constrains the input shape; the application still validates its meaning. Native values and form submissions contain the displayed format. Their onValueChange callbacks expose an unformatted value string for application state.

Currency

Format a monthly budget with a leading symbol, thousands separators, and two decimal places. USD uses 1,250.00; IDR and EUR use 1.250,00. Changing the menu preserves the numeric amount and changes its presentation; it does not convert currencies.

Phone number

Choose an explicit national format. Changing the region clears the current number. The example formats US and UK ten-digit numbers and an Indonesian twelve-digit national number; it does not cover every valid number in those countries.

Payment card

Detect the network while typing and follow its digit grouping, including American Express’s four-six-five groups. credit-card-type supplies network patterns, gaps, and supported lengths. Ambiguous or unknown prefixes remain editable without a guessed label. Identifying a network does not validate or authorize the card.

The optional logo components show the detected network’s simplified mark. The payment icon library supplies the assets; InputGroup has no card or logo dependency.

Date

Insert separators for DD / MM / YYYY while typing. On blur, reject incomplete and impossible dates. Editing clears the previous validation error.

Time

Insert : for HH:MM. On blur, validate the 24-hour range.

API reference

Give the control an accessible name through Field.Label, aria-label, or aria-labelledby. Give icon-only actions their own names. Decorative icons use aria-hidden. The group reflects focus, invalid, and disabled states from the control.