Input Group
---import { InputGroup, InputGroupAddon, InputGroupInput,} from "@/components/starwind/input-group";import Search from "@tabler/icons/outline/search.svg";---
<InputGroup> <InputGroupInput placeholder="Search..." /> <InputGroupAddon> <Search /> </InputGroupAddon></InputGroup>Installation
pnpx starwind@latest add input-groupnpx starwind@latest add input-groupyarn dlx starwind@latest add input-groupUsage
General Notes
The essential components are InputGroup, InputGroupAddon, and either InputGroupInput or InputGroupTextarea.
InputGroupText and InputGroupButton are helper components for labels, metadata, and actions.
Focus management: Keep
InputGroupAddonafterInputGroupInputorInputGroupTextareain the DOM. Usealignto control visual placement.
Align
inline-start
Use align="inline-start" to place content at the start of the field. This is the default alignment.
---import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";import Search from "@tabler/icons/outline/search.svg";---
<InputGroup> <InputGroupInput placeholder="Search..." /> <InputGroupAddon align="inline-start"> <Search /> </InputGroupAddon></InputGroup>inline-end
Use align="inline-end" to place content at the end of the field.
---import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";import InfoCircle from "@tabler/icons/outline/info-circle.svg";---
<InputGroup> <InputGroupInput type="password" placeholder="Enter password" /> <InputGroupAddon align="inline-end"> <InfoCircle /> </InputGroupAddon></InputGroup>block-start
Use align="block-start" to place a header row above the control.
---import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea,} from "@/components/starwind/input-group";import Code from "@tabler/icons/outline/code.svg";import Copy from "@tabler/icons/outline/copy.svg";---
<div class="grid w-full max-w-sm gap-4"> <InputGroup> <InputGroupInput placeholder="Enter your name" /> <InputGroupAddon align="block-start"> <InputGroupText>Full Name</InputGroupText> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupTextarea class="font-mono text-sm" placeholder="console.log('Hello, world!');" /> <InputGroupAddon align="block-start" class="border-b"> <Code /> <InputGroupText class="font-mono">script.js</InputGroupText> <InputGroupButton size="icon-sm" class="ml-auto" aria-label="Copy code"> <Copy /> </InputGroupButton> </InputGroupAddon> </InputGroup></div>block-end
Use align="block-end" to place a footer row below the control.
---import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea,} from "@/components/starwind/input-group";---
<div class="grid w-full max-w-sm gap-4"> <InputGroup> <InputGroupInput placeholder="Enter amount" /> <InputGroupAddon align="block-end"> <InputGroupText>USD</InputGroupText> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupTextarea placeholder="Write a comment..." /> <InputGroupAddon align="block-end"> <InputGroupText>0/280</InputGroupText> <InputGroupButton variant="default" size="sm" class="ml-auto">Post</InputGroupButton> </InputGroupAddon> </InputGroup></div>Examples
Icon
---import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";import CircleCheck from "@tabler/icons/outline/circle-check.svg";import CreditCard from "@tabler/icons/outline/credit-card.svg";import InfoCircle from "@tabler/icons/outline/info-circle.svg";import Mail from "@tabler/icons/outline/mail.svg";import Search from "@tabler/icons/outline/search.svg";import Star from "@tabler/icons/outline/star.svg";---
<div class="grid w-full max-w-sm gap-6"> <InputGroup> <InputGroupInput placeholder="Search..." /> <InputGroupAddon> <Search /> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupInput type="email" placeholder="Enter your email" /> <InputGroupAddon> <Mail /> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupInput placeholder="Card number" /> <InputGroupAddon> <CreditCard /> </InputGroupAddon> <InputGroupAddon align="inline-end"> <CircleCheck /> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupInput placeholder="Favorites" /> <InputGroupAddon align="inline-end"> <Star /> <InfoCircle /> </InputGroupAddon> </InputGroup></div>Text
---import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, InputGroupTextarea,} from "@/components/starwind/input-group";---
<div class="grid w-full max-w-sm gap-6"> <InputGroup> <InputGroupInput placeholder="0.00" /> <InputGroupAddon align="inline-start"> <InputGroupText>$</InputGroupText> </InputGroupAddon> <InputGroupAddon align="inline-end"> <InputGroupText>USD</InputGroupText> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupInput placeholder="example" class="!pl-0.5" /> <InputGroupAddon align="inline-start"> <InputGroupText>https://</InputGroupText> </InputGroupAddon> <InputGroupAddon align="inline-end"> <InputGroupText>.com</InputGroupText> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupInput placeholder="Enter your username" /> <InputGroupAddon align="inline-end"> <InputGroupText>@company.com</InputGroupText> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupTextarea placeholder="Enter your message" /> <InputGroupAddon align="block-end"> <InputGroupText class="text-xs">120 characters left</InputGroupText> </InputGroupAddon> </InputGroup></div>Button
---import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText,} from "@/components/starwind/input-group";import Copy from "@tabler/icons/outline/copy.svg";import InfoCircle from "@tabler/icons/outline/info-circle.svg";import Star from "@tabler/icons/outline/star.svg";---
<div class="grid w-full max-w-sm gap-6"> <InputGroup> <InputGroupInput placeholder="https://starwind.dev" readonly /> <InputGroupAddon align="inline-end"> <InputGroupButton aria-label="Copy" title="Copy" size="icon-sm"> <Copy /> </InputGroupButton> </InputGroupAddon> </InputGroup>
<InputGroup class="[--radius:9999px]"> <InputGroupInput placeholder="secure-site" /> <InputGroupAddon align="inline-start"> <InputGroupButton variant="secondary" size="icon-sm" aria-label="Info"> <InfoCircle /> </InputGroupButton> </InputGroupAddon> <InputGroupAddon align="inline-start" class="pl-1.5"> <InputGroupText>https://</InputGroupText> </InputGroupAddon> <InputGroupAddon align="inline-end"> <InputGroupButton size="icon-sm" aria-label="Favorite"> <Star /> </InputGroupButton> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupInput placeholder="Type to search..." /> <InputGroupAddon align="inline-end"> <InputGroupButton variant="secondary">Search</InputGroupButton> </InputGroupAddon> </InputGroup></div>Kbd
---import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";import { Kbd } from "@/components/starwind/kbd";import Search from "@tabler/icons/outline/search.svg";---
<InputGroup> <InputGroupInput placeholder="Search..." /> <InputGroupAddon> <Search /> </InputGroupAddon> <InputGroupAddon align="inline-end"> <Kbd>Ctrl+K</Kbd> </InputGroupAddon></InputGroup>Dropdown
---import { Dropdown, DropdownContent, DropdownItem, DropdownTrigger } from "@/components/starwind/dropdown";import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "@/components/starwind/input-group";import ChevronDown from "@tabler/icons/outline/chevron-down.svg";---
<div class="grid w-full max-w-sm gap-4"> <InputGroup> <InputGroupInput placeholder="Enter file name" /> <InputGroupAddon align="inline-end"> <Dropdown> <DropdownTrigger asChild> <InputGroupButton aria-label="More options" size="icon-sm"> <ChevronDown /> </InputGroupButton> </DropdownTrigger> <DropdownContent align="end"> <DropdownItem>Settings</DropdownItem> <DropdownItem>Copy path</DropdownItem> <DropdownItem>Open location</DropdownItem> </DropdownContent> </Dropdown> </InputGroupAddon> </InputGroup>
<InputGroup class="[--radius:1rem]"> <InputGroupInput placeholder="Enter search query" /> <InputGroupAddon align="inline-end"> <Dropdown> <DropdownTrigger asChild> <InputGroupButton variant="ghost" class="!pr-1.5 text-xs"> Search in <ChevronDown class="size-3" /> </InputGroupButton> </DropdownTrigger> <DropdownContent align="end" class="[--radius:0.95rem]"> <DropdownItem>Documentation</DropdownItem> <DropdownItem>Blog Posts</DropdownItem> <DropdownItem>Changelog</DropdownItem> </DropdownContent> </Dropdown> </InputGroupAddon> </InputGroup></div>Spinner
---import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText,} from "@/components/starwind/input-group";import { Spinner } from "@/components/starwind/spinner";---
<div class="grid w-full max-w-sm gap-4"> <InputGroup> <InputGroupInput placeholder="Searching..." /> <InputGroupAddon align="inline-end"> <Spinner /> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupInput placeholder="Processing..." /> <InputGroupAddon> <Spinner /> </InputGroupAddon> </InputGroup>
<InputGroup> <InputGroupInput placeholder="Saving changes..." /> <InputGroupAddon align="inline-end"> <InputGroupText>Saving...</InputGroupText> <Spinner /> </InputGroupAddon> </InputGroup></div>Textarea
script.js
---import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, InputGroupTextarea,} from "@/components/starwind/input-group";import ArrowRight from "@tabler/icons/outline/arrow-right.svg";import Code from "@tabler/icons/outline/code.svg";import Copy from "@tabler/icons/outline/copy.svg";---
<InputGroup> <InputGroupTextarea id="textarea-code" placeholder="console.log('Hello, world!');" class="min-h-[180px] font-mono text-sm" /> <InputGroupAddon align="block-end" class="border-t"> <InputGroupText>Line 1, Column 1</InputGroupText> <InputGroupButton size="sm" class="ml-auto" variant="default"> Run <ArrowRight /> </InputGroupButton> </InputGroupAddon> <InputGroupAddon align="block-start" class="border-b"> <InputGroupText class="font-mono font-medium"> <Code /> script.js </InputGroupText> <InputGroupButton class="ml-auto" size="icon-sm" aria-label="Copy code"> <Copy /> </InputGroupButton> </InputGroupAddon></InputGroup>API Reference
InputGroup
The root wrapper that handles group-level border, focus ring, and invalid state styling.
| Prop | Type | Default |
|---|---|---|
class | string | - |
<InputGroup> <InputGroupInput placeholder="Search..." /> <InputGroupAddon> <Search /> </InputGroupAddon></InputGroup>Additional Notes:
- Accepts all standard HTML
<div>attributes
InputGroupAddon
A flexible container for icons, text, buttons, and status indicators.
| Prop | Type | Default |
|---|---|---|
align | "inline-start" | "inline-end" | "block-start" | "block-end" | "inline-start" |
class | string | - |
<InputGroupAddon align="inline-end"> <Search /></InputGroupAddon>Additional Notes:
- Place after the control in markup for proper focus behavior
- Use
inline-start/inline-endwithInputGroupInput - Use
block-start/block-endwithInputGroupTextarea
InputGroupButton
An input-group-tuned button with compact sizing and no shadow.
| Prop | Type | Default |
|---|---|---|
size | "sm" | "icon-sm" | "sm" |
variant | "default" | "primary" | "secondary" | "outline" | "ghost" | "info" | "success" | "warning" | "error" | "ghost" |
type | string | "button" |
class | string | - |
<InputGroupButton variant="secondary" size="icon-sm" aria-label="Copy"> <Copy /></InputGroupButton>Additional Notes:
- Inherits remaining props from
Button
InputGroupInput
Input replacement with input-group styles and focus-slot behavior pre-applied.
| Prop | Type | Default |
|---|---|---|
size | "sm" | "md" | "lg" | "md" |
type | string | "text" |
class | string | - |
<InputGroupInput placeholder="Enter text..." />Additional Notes:
- Inherits all props from
Input - Automatically applies
data-slot="input-group-control"
InputGroupText
A helper text wrapper for prefixes, suffixes, and metadata labels.
| Prop | Type | Default |
|---|---|---|
class | string | - |
<InputGroupText>@company.com</InputGroupText>InputGroupTextarea
Textarea replacement with input-group styles and focus-slot behavior pre-applied.
| Prop | Type | Default |
|---|---|---|
size | "sm" | "md" | "lg" | "md" |
class | string | - |
<InputGroupTextarea placeholder="Write a comment..." />Additional Notes:
- Inherits all props from
Textarea - Automatically applies
data-slot="input-group-control"
Changelog
v1.0.0
- Initial release with starwind v1.16.0