Input Group
---import { InputGroup, InputGroupAddon, InputGroupInput,} from "@/components/starwind/input-group";import Search from "@tabler/icons/outline/search.svg";---
<InputGroup> <InputGroupInput aria-label="Search" placeholder="Search..." /> <InputGroupAddon> <Search /> </InputGroupAddon></InputGroup>import { InputGroup, InputGroupAddon, InputGroupInput,} from "@/components/starwind/input-group";import { IconSearch } from "@tabler/icons-react";
export function Example() { return ( <InputGroup> <InputGroupInput aria-label="Search" placeholder="Search..." /> <InputGroupAddon> <IconSearch /> </InputGroupAddon> </InputGroup> );}Installation
pnpx starwind@latest add input-groupnpx starwind@latest add input-groupyarn dlx starwind@latest add input-groupUsage
---import { InputGroup, InputGroupAddon, InputGroupInput,} from "@/components/starwind/input-group";import Search from "@tabler/icons/outline/search.svg";---
<InputGroup> <InputGroupInput aria-label="Search" placeholder="Search..." /> <InputGroupAddon> <Search /> </InputGroupAddon></InputGroup>import { InputGroup, InputGroupAddon, InputGroupInput,} from "@/components/starwind/input-group";import { IconSearch } from "@tabler/icons-react";
export function Example() { return ( <InputGroup> <InputGroupInput aria-label="Search" placeholder="Search..." /> <InputGroupAddon> <IconSearch /> </InputGroupAddon> </InputGroup> );}Composition
Combine an input or textarea with the supporting parts you need:
InputGroup├── InputGroupInput or InputGroupTextarea└── InputGroupAddon ├── InputGroupButton └── InputGroupTextControl and Addon Order
InputGroupText and InputGroupButton are helper components for metadata and actions. Addons are presentational; associate a field with an external Label or an aria-label on the control.
Keep InputGroupAddon after InputGroupInput or InputGroupTextarea in the DOM. Use align to control visual placement.
Alignment
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>import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";import { IconSearch as Search } from "@tabler/icons-react";
export function Example() { return ( <> <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>import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";import { IconInfoCircle as InfoCircle } from "@tabler/icons-react";
export function Example() { return ( <> <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>import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea,} from "@/components/starwind/input-group";import { IconCode as Code } from "@tabler/icons-react";import { IconCopy as Copy } from "@tabler/icons-react";
export function Example() { return ( <> <div className="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 className="font-mono text-sm" placeholder="console.log('Hello, world!');" /> <InputGroupAddon align="block-start" className="border-b"> <Code /> <InputGroupText className="font-mono">script.js</InputGroupText> <InputGroupButton size="icon-sm" className="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>import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea,} from "@/components/starwind/input-group";
export function Example() { return ( <> <div className="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" className="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>import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";import { IconCircleCheck as CircleCheck } from "@tabler/icons-react";import { IconCreditCard as CreditCard } from "@tabler/icons-react";import { IconInfoCircle as InfoCircle } from "@tabler/icons-react";import { IconMail as Mail } from "@tabler/icons-react";import { IconSearch as Search } from "@tabler/icons-react";import { IconStar as Star } from "@tabler/icons-react";
export function Example() { return ( <> <div className="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>import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, InputGroupTextarea,} from "@/components/starwind/input-group";
export function Example() { return ( <> <div className="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" className="!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 className="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>import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText,} from "@/components/starwind/input-group";import { IconCopy as Copy } from "@tabler/icons-react";import { IconInfoCircle as InfoCircle } from "@tabler/icons-react";import { IconStar as Star } from "@tabler/icons-react";
export function Example() { return ( <> <div className="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 className="[--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" className="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>import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/starwind/input-group";import { Kbd } from "@/components/starwind/kbd";import { IconSearch as Search } from "@tabler/icons-react";
export function Example() { return ( <> <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>import { Dropdown, DropdownContent, DropdownItem, DropdownTrigger } from "@/components/starwind/dropdown";import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "@/components/starwind/input-group";import { IconChevronDown as ChevronDown } from "@tabler/icons-react";
export function Example() { return ( <> <div className="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 className="[--radius:1rem]"> <InputGroupInput placeholder="Enter search query" /> <InputGroupAddon align="inline-end"> <Dropdown> <DropdownTrigger asChild> <InputGroupButton variant="ghost" className="!pr-1.5 text-xs"> Search in <ChevronDown className="size-3" /> </InputGroupButton> </DropdownTrigger> <DropdownContent align="end" className="[--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>import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText,} from "@/components/starwind/input-group";import { Spinner } from "@/components/starwind/spinner";
export function Example() { return ( <> <div className="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>import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, InputGroupTextarea,} from "@/components/starwind/input-group";import { IconArrowRight as ArrowRight } from "@tabler/icons-react";import { IconCode as Code } from "@tabler/icons-react";import { IconCopy as Copy } from "@tabler/icons-react";
export function Example() { return ( <> <InputGroup> <InputGroupTextarea id="textarea-code" placeholder="console.log('Hello, world!');" className="min-h-[180px] font-mono text-sm" /> <InputGroupAddon align="block-end" className="border-t"> <InputGroupText>Line 1, Column 1</InputGroupText> <InputGroupButton size="sm" className="ml-auto" variant="default"> Run <ArrowRight /> </InputGroupButton> </InputGroupAddon> <InputGroupAddon align="block-start" className="border-b"> <InputGroupText className="font-mono font-medium"> <Code /> script.js </InputGroupText> <InputGroupButton className="ml-auto" size="icon-sm" aria-label="Copy code"> <Copy /> </InputGroupButton> </InputGroupAddon> </InputGroup> </> );}API Reference
Styled Component API
These props are added or materially changed by the installed styled component. Standard HTML attributes remain available through the inherited interfaces noted below. Expand a prop to see named type definitions and framework-specific imports. Follow the Primitive and Runtime links for lower-level behavior props.
Input Group Addon
Inherits div attributes.
Contains the following additional props:
align "inline-start" | "inline-end" | "block-start" | "block-end" "inline-start"
- Description
- Aligns the component within its available axis.
- Classification
- Styled variant
Input Group Button
Inherits Button props. Omits `size`.
Contains the following additional props:
size "sm" | "icon-sm" "sm"
- Description
- Selects the component's visual size.
- Classification
- Styled variant
Changelog
View version history v1.1.2 5 releases
v1.1.2
- Named the generated aggregate default export so React and Astro tooling can identify the installed component cleanly.
v1.1.1
- Aligned Astro and React attribute forwarding with the current generated adapter output.
v1.1.0
- Added contract-generated Astro and React implementations while preserving the component’s existing public API and styling.
InputGroupAddonis now presentational and no longer installs a click-to-focus script. Give the control its own accessible name, and useInputGroupButtonwhen the addon itself performs an action.
v1.0.1
- Refactor tailwind variants functions into separate
variants.tsfile
v1.0.0
- Initial release with starwind v1.16.0