@biem/ui

Input Group

A field that joins an input with icons, text or buttons that help users enter a value.

An input group joins an input or a textarea with addons inside one border, so users read them as a single field. Addons hold icons, text, buttons or keyboard shortcuts and sit before, after, above or below the control. A click on an addon, outside of its buttons, moves the focus to the input.

Usage

input-group-default.tsx
import {
	InputGroup,
	InputGroupAddon,
	InputGroupInput,
} from "@biem/ui/components/ui/input-group";
import { IconSearch } from "@tabler/icons-react";

export function InputGroupDefault() {
	return (
		<div className="w-full max-w-sm">
			<InputGroup>
				<InputGroupInput aria-label="Search items" placeholder="Search items"/>
				<InputGroupAddon>
					<IconSearch stroke={1.5}/>
				</InputGroupAddon>
			</InputGroup>
		</div>
	);
}

Examples

Inline Start Alignment

Some values need context before users enter them, such as the currency of an amount. Every addon sits before the control in the same row unless set otherwise, and align with the value "inline-start" states this place explicitly, so users know what the value refers to before they type.

CHF

Inline End Alignment

Units usually follow the figure they belong to, as kilograms follow a weight. With align set to "inline-end", the addon moves after the control in the same row, so users enter the figure in the order in which they read it.

CHF

Block Start Alignment

Context that needs a full sentence, such as the basis on which a value is calculated, would crowd the row beside the control. Set to "block-start", align gives the addon a row of its own above the control, whatever its position in the markup, and users take in the context before they reach the value.

Price per case in CHF

Block End Alignment

Hints and actions that refer to the complete entry fit best after it. Through align set to "block-end", the addon takes a row of its own below the control, where users reach it once they have finished typing.

Price per case in CHF

With Text

Many figures only gain their meaning through a unit or a currency. Inside an addon, InputGroupText keeps that unit in the field without making it part of the value, so users type the figure alone and still read it in context.

CHF
per case

With Textarea

Notes, instructions and messages need room for more than one line. Taking the place of the input, InputGroupTextarea gives them that room, and the group adopts its height, so addons above or below frame the longer text as one field.

Printed on the delivery note

With Button

An action often belongs to the value it works with, such as checking a code or applying a discount. Placed in an addon, InputGroupButton keeps that action within the field, and since its type is "button" unless set otherwise, a click does not submit a form around the group.

Extra Small Button

Actions inside a field should support the entry rather than outweigh it. Unless another size is set, a button in the group takes the size "xs", which fits beside the control in the same row and leaves the attention on the entry.

Small Button

Once an action has a row of its own above or below the control, it can claim more presence, such as submitting a longer entry. With size set to "sm", the button is as high as a single-line field, so the action that completes the entry becomes easier to find and to hit.

With Keyboard Shortcut

Fields that users return to all day deserve a way in without the pointer. A Kbd in an addon names the keys that lead there, so users learn the shortcut in passing. The hint only names it, and the application listens for the keys itself.

⌘K

Controlled

Sometimes the application needs the entry while users are still typing, for example to filter a list with every keystroke. Through value and onChange on InputGroupInput it holds the text itself, so other parts of the interface can fill or clear the field as well.

Disabled

A value can be locked for a while, for example while an order awaits approval. The group follows the disabled attribute of its control, so users can no longer edit the value, and the whole field, addons included, shows that state while the value stays readable.

CHF

Disabled Button

Until an entry is complete, the action that uses it may have to wait. Marked as disabled, the button accepts no interaction and exposes its state to assistive technology, while the control stays editable, so users can finish the entry that makes the action available.

Invalid

Entries outside what a process accepts, such as a negative quantity, need a correction before users move on. Once the input carries aria-invalid, the group signals the error across the whole field, including its addons, and assistive technology reports the entry as invalid.

CHF

API Reference

InputGroup

InputGroup frames the control and its addons as one field and shows when the control is focused, disabled or invalid. It renders a div and has no props of its own.

InputGroupAddon

Propalign
Type"inline-start" | "inline-end" | "block-start" | "block-end"
Default"inline-start"
DescriptionSets where the addon sits. Inline start and inline end place it before or after the control in the same row. Block start and block end place it in a row of its own above or below the control. The addon takes this place whatever its position in the markup.

InputGroupButton

Propvariant
Type"default" | "outline" | "secondary" | "ghost" | "destructive" | "link"
Default"ghost"
DescriptionControls the visual emphasis and semantic role of the button.
Propsize
Type"xs" | "sm" | "icon-xs" | "icon-sm"
Default"xs"
DescriptionControls the dimensions and spacing of the button. "icon-xs" and "icon-sm" make it square for a single icon. "xs" and "icon-xs" fit beside the control. "sm" and "icon-sm" are as high as a single-line group, so they fit in an addon above or below the control.
Proptype
Type"button" | "submit" | "reset"
Default"button"
DescriptionSets the type of the native button. The default keeps the button from submitting a form that the group sits in.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the button with another component.
PropnativeButton
Typeboolean
Defaulttrue
DescriptionDeclares whether the rendered element is a native button. Set it to false when render returns a different element.
Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents interaction and exposes the disabled state to assistive technology. The group dims as a whole while one of its buttons is disabled.
PropfocusableWhenDisabled
Typeboolean
Defaultfalse
DescriptionKeeps the button focusable while it is disabled.

InputGroupText

InputGroupText holds text inside an addon, such as a currency or a unit. It renders a span and has no props of its own.

InputGroupInput

InputGroupInput is the control for a single line of text, and the group follows its disabled and aria-invalid attributes. It renders an input and has no props of its own.

InputGroupTextarea

InputGroupTextarea is the control for several lines of text, and the group follows its disabled and aria-invalid attributes. It renders a textarea and has no props of its own.