Input Group
Extend form controls by adding text, buttons, or button groups on either side of textual inputs, custom selects, and custom file inputs.
Basic usage
Place one add-on or button on either side of an input, or on both sides at once. Place
<FormLabel>s outside the input group, rather than inside it.
import { FormLabel, InputGroup, InputGroupAddon, TextInput, Textarea } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup className="mb-md">
<InputGroupAddon id="basic-addon1">@</InputGroupAddon>
<TextInput placeholder="Username" aria-label="Username" aria-describedby="basic-addon1" />
</InputGroup>
<InputGroup className="mb-md">
<TextInput
placeholder="Recipient's username"
aria-label="Recipient's username"
aria-describedby="basic-addon2"
/>
<InputGroupAddon id="basic-addon2">@example.com</InputGroupAddon>
</InputGroup>
<FormLabel htmlFor="basic-url" id="basic-url-label">
Your vanity URL
</FormLabel>
<InputGroup className="mb-md">
<InputGroupAddon id="basic-addon3">https://example.com/users/</InputGroupAddon>
<TextInput
id="basic-url"
aria-labelledby="basic-url-label"
aria-describedby="basic-addon3"
/>
</InputGroup>
<InputGroup className="mb-md">
<InputGroupAddon>$</InputGroupAddon>
<TextInput aria-label="Amount (to the nearest dollar)" />
<InputGroupAddon>.00</InputGroupAddon>
</InputGroup>
<InputGroup className="mb-md">
<TextInput placeholder="Username" aria-label="Username" />
<InputGroupAddon>@</InputGroupAddon>
<TextInput placeholder="Server" aria-label="Server" />
</InputGroup>
<InputGroup>
<InputGroupAddon>With textarea</InputGroupAddon>
<Textarea aria-label="With textarea"></Textarea>
</InputGroup>
</>
)
}Wrapping
An input group wraps by default via flex-wrap: wrap, accommodating custom form field validation
within the group. Disable this with the .flex-nowrap class.
import { InputGroup, InputGroupAddon, TextInput } from '@chassis-ui/react'
export const Example = () => {
return (
<InputGroup className="flex-nowrap">
<InputGroupAddon id="addon-wrapping">@</InputGroupAddon>
<TextInput placeholder="Username" aria-label="Username" aria-describedby="addon-wrapping" />
</InputGroup>
)
}Sizing
Add the relative form sizing classes to <InputGroup> itself, and its contents resize
automatically — no need to repeat the form control size classes on each element.
Sizing on the individual input group elements isn't supported.
import { InputGroup, InputGroupAddon, TextInput } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup size="sm" className="mb-md">
<InputGroupAddon id="inputGroup-sizing-sm">Small</InputGroupAddon>
<TextInput aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm" />
</InputGroup>
<InputGroup className="mb-md">
<InputGroupAddon id="inputGroup-sizing-default">Default</InputGroupAddon>
<TextInput aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default" />
</InputGroup>
<InputGroup size="lg">
<InputGroupAddon id="inputGroup-sizing-lg">Large</InputGroupAddon>
<TextInput aria-label="Sizing example input" aria-describedby="inputGroup-sizing-lg" />
</InputGroup>
</>
)
}Checkboxes and radios
Place a checkbox or radio option within an input group's addon instead of text.
import {
Checkbox,
TextInput,
Radio,
RadioGroup,
InputGroup,
InputGroupAddon
} from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup className="mb-md">
<InputGroupAddon>
<Checkbox value="" aria-label="Checkbox for following text input" />
</InputGroupAddon>
<TextInput aria-label="Text input with checkbox" />
</InputGroup>
<InputGroup>
<InputGroupAddon component="div">
<RadioGroup aria-label="Radio button for following text input" defaultValue="">
<Radio value="" aria-label="Radio button for following text input" />
</RadioGroup>
</InputGroupAddon>
<TextInput aria-label="Text input with radio button" />
</InputGroup>
</>
)
}Multiple inputs
Multiple <TextInput>s are supported visually, though validation styles are only available for
input groups with a single <TextInput>.
import { InputGroup, InputGroupAddon, TextInput } from '@chassis-ui/react'
export const Example = () => {
return (
<InputGroup>
<InputGroupAddon>First and last name</InputGroupAddon>
<TextInput aria-label="First name" />
<TextInput aria-label="Last name" />
</InputGroup>
)
}Multiple addons
Multiple add-ons are supported and can be mixed with checkbox and radio input versions.
import { InputGroup, InputGroupAddon, TextInput } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup className="mb-md">
<InputGroupAddon>$</InputGroupAddon>
<InputGroupAddon>0.00</InputGroupAddon>
<TextInput aria-label="Dollar amount (with dot and two decimal places)" />
</InputGroup>
<InputGroup>
<TextInput aria-label="Dollar amount (with dot and two decimal places)" />
<InputGroupAddon>$</InputGroupAddon>
<InputGroupAddon>0.00</InputGroupAddon>
</InputGroup>
</>
)
}Button addons
Buttons work as addons in place of text, on either side of the input or on both.
import { Button, InputGroup, TextInput } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup className="mb-md">
<Button type="button" color="secondary" variant="outline" id="button-addon1">
Button
</Button>
<TextInput
placeholder=""
aria-label="Example text with button addon"
aria-describedby="button-addon1"
/>
</InputGroup>
<InputGroup className="mb-md">
<TextInput
placeholder="Recipient's username"
aria-label="Recipient's username"
aria-describedby="button-addon2"
/>
<Button type="button" color="secondary" variant="outline" id="button-addon2">
Button
</Button>
</InputGroup>
<InputGroup className="mb-md">
<Button type="button" color="secondary" variant="outline">
Button
</Button>
<Button type="button" color="secondary" variant="outline">
Button
</Button>
<TextInput placeholder="" aria-label="Example text with two button addons" />
</InputGroup>
<InputGroup>
<TextInput
placeholder="Recipient's username"
aria-label="Recipient's username with two button addons"
/>
<Button type="button" color="secondary" variant="outline">
Button
</Button>
<Button type="button" color="secondary" variant="outline">
Button
</Button>
</InputGroup>
</>
)
}Buttons with menus
A <Menu> composes into an input group the same way a plain button addon does.
import {
TextInput,
InputGroup,
Menu,
MenuToggle,
MenuList,
MenuItem,
MenuDivider
} from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup className="mb-md">
<Menu>
<MenuToggle color="secondary" variant="outline">
Menu
</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
<TextInput aria-label="Text input with menu button" />
</InputGroup>
<InputGroup className="mb-md">
<TextInput aria-label="Text input with menu button" />
<Menu placement="bottom-end">
<MenuToggle color="secondary" variant="outline">
Menu
</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
</InputGroup>
<InputGroup>
<Menu>
<MenuToggle color="secondary" variant="outline">
Menu
</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
<TextInput aria-label="Text input with 2 menu buttons" />
<Menu placement="bottom-end">
<MenuToggle color="secondary" variant="outline">
Menu
</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
</InputGroup>
</>
)
}Segmented buttons
Pair a button addon with an icon-only <Menu> toggle to split a primary action from a menu of
related ones.
import {
Button,
TextInput,
InputGroup,
Menu,
MenuToggle,
MenuList,
MenuItem,
MenuDivider
} from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup className="mb-md">
<Button type="button" color="secondary" variant="outline">
Action
</Button>
<Menu>
<MenuToggle color="secondary" variant="outline">
<span className="visually-hidden">Toggle menu</span>
</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
<TextInput aria-label="Text input with segmented menu button" />
</InputGroup>
<InputGroup>
<TextInput aria-label="Text input with segmented menu button" />
<Button type="button" color="secondary" variant="outline">
Action
</Button>
<Menu placement="bottom-end">
<MenuToggle color="secondary" variant="outline">
<span className="visually-hidden">Toggle menu</span>
</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
</InputGroup>
</>
)
}Custom forms
Input groups support custom selects and custom file inputs. Browser default versions of these controls aren't supported.
Custom select
A <Select> composes into an input group the same way a <TextInput> does, with an addon on
either side.
import { Button, InputGroup, InputGroupAddon, Select } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup className="mb-md">
<InputGroupAddon component="label" htmlFor="inputGroupSelect01">
Options
</InputGroupAddon>
<Select id="inputGroupSelect01">
<option>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Select>
</InputGroup>
<InputGroup className="mb-md">
<Select id="inputGroupSelect02">
<option>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Select>
<InputGroupAddon component="label" htmlFor="inputGroupSelect02">
Options
</InputGroupAddon>
</InputGroup>
<InputGroup className="mb-md">
<Button type="button" color="secondary" variant="outline">
Button
</Button>
<Select id="inputGroupSelect03" aria-label="Example select with button addon">
<option>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Select>
</InputGroup>
<InputGroup>
<Select id="inputGroupSelect04" aria-label="Example select with button addon">
<option>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</Select>
<Button type="button" color="secondary" variant="outline">
Button
</Button>
</InputGroup>
</>
)
}Custom file input
A <FileInput> composes into an input group the same way, pairing with a label-style addon or a
button.
import { Button, FileInput, InputGroup, InputGroupAddon } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<InputGroup className="mb-md">
<InputGroupAddon component="label" htmlFor="inputGroupFile01">
Upload
</InputGroupAddon>
<FileInput id="inputGroupFile01" />
</InputGroup>
<InputGroup className="mb-md">
<FileInput id="inputGroupFile02" />
<InputGroupAddon component="label" htmlFor="inputGroupFile02">
Upload
</InputGroupAddon>
</InputGroup>
<InputGroup className="mb-md">
<Button type="button" color="secondary" variant="outline" id="inputGroupFileAddon03">
Button
</Button>
<FileInput
id="inputGroupFile03"
aria-describedby="inputGroupFileAddon03"
aria-label="Upload"
/>
</InputGroup>
<InputGroup>
<FileInput
id="inputGroupFile04"
aria-describedby="inputGroupFileAddon04"
aria-label="Upload"
/>
<Button type="button" color="secondary" variant="outline" id="inputGroupFileAddon04">
Button
</Button>
</InputGroup>
</>
)
}API
InputGroup
| Prop | Type | Default |
|---|---|---|
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
ref? | any | — |
size? | "sm" | "lg" | — |
| Size the component sm or lg. | ||
InputGroupAddon
| Prop | Type | Default |
|---|---|---|
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
htmlFor? | string | — |
The id of the form control this addon labels, when rendered as component="label". | ||
ref? | any | — |