Input group
Displays supplementary information or interactive elements alongside input fields or textareas.
Usage
The Input Group component displays supplementary information or interactive elements alongside input fields or textareas, enabling richer form interactions.
Examples
52% used
<div class="grid w-full max-w-sm gap-6"> <twig:ui:InputGroup> <twig:ui:InputGroup:Addon> <twig:ux:icon name="lucide:search" class="size-4"/> </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Input placeholder="Search..."/> <twig:ui:InputGroup:Addon align="inline-end"> 12 results </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="example.com" class="!pl-1"/> <twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Text>https://</twig:ui:InputGroup:Text> </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Button class="rounded-full" size="icon-xs" data-tooltip="info-tooltip"> <twig:ux:icon name="lucide:info"/> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Textarea placeholder="Ask, Search or Chat..."/> <twig:ui:InputGroup:Addon align="block-end"> <twig:ui:InputGroup:Button variant="outline" class="rounded-full" size="icon-xs"> <twig:ux:icon name="lucide:plus"/> </twig:ui:InputGroup:Button> <twig:ui:InputGroup:Button variant="ghost" popovertarget="mode-dropdown"> Auto </twig:ui:InputGroup:Button> <twig:ui:InputGroup:Text class="ml-auto">52% used</twig:ui:InputGroup:Text> <twig:ui:Separator orientation="vertical" class="!h-4"/> <twig:ui:InputGroup:Button class="rounded-full" size="icon-xs" variant="primary" disabled> <twig:ux:icon name="lucide:arrow-up"/> <span class="sr-only">Send</span> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="@nicolaslps"/> <twig:ui:InputGroup:Addon align="inline-end"> <div class="bg-primary text-primary-foreground flex size-4 items-center justify-center rounded-full"> <twig:ux:icon name="lucide:check" class="size-3"/> </div> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div> <twig:ui:Tooltip id="info-tooltip"> <twig:ui:Tooltip:Content class="max-w-sm"> <p class="text-sm">This is content in a tooltip.</p> </twig:ui:Tooltip:Content> <twig:ui:Tooltip:Arrow/> </twig:ui:Tooltip> <twig:ui:DropdownMenu id="mode-dropdown" position="top"> <twig:ui:DropdownMenu:Content class="w-32"> <twig:ui:DropdownMenu:Item>Auto</twig:ui:DropdownMenu:Item> <twig:ui:DropdownMenu:Item>Agent</twig:ui:DropdownMenu:Item> <twig:ui:DropdownMenu:Item>Manual</twig:ui:DropdownMenu:Item> </twig:ui:DropdownMenu:Content> </twig:ui:DropdownMenu>
Icon
<div class="grid w-full max-w-sm gap-6"> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Search..." /> <twig:ui:InputGroup:Addon> <twig:ux:icon name="lucide:search" /> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input type="email" placeholder="Enter your email" /> <twig:ui:InputGroup:Addon> <twig:ux:icon name="lucide:mail" /> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Card number" /> <twig:ui:InputGroup:Addon> <twig:ux:icon name="lucide:credit-card" /> </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ux:icon name="lucide:check" /> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Card number" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ux:icon name="lucide:star" /> <twig:ux:icon name="lucide:info" /> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div>
Text
120 characters left
<div class="grid w-full max-w-sm gap-6"> <twig:ui:InputGroup> <twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Text>€</twig:ui:InputGroup:Text> </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Input placeholder="0.00" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Text>EUR</twig:ui:InputGroup:Text> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Text>https://</twig:ui:InputGroup:Text> </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Input placeholder="example.com" class="!pl-0.5" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Text>.com</twig:ui:InputGroup:Text> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Enter your username" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Text>@company.com</twig:ui:InputGroup:Text> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Textarea placeholder="Enter your message" /> <twig:ui:InputGroup:Addon align="block-end"> <twig:ui:InputGroup:Text class="text-muted-foreground text-xs"> 120 characters left </twig:ui:InputGroup:Text> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div>
Button
<div class="grid w-full max-w-sm gap-6"> {# TODO fix overflow #} <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="https://x.com/shadcn" readonly/> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Button aria-label="Copy" title="Copy" size="icon-xs"> <twig:ux:icon name="lucide:copy"/> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup class="[--radius:9999px]"> <twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Button variant="secondary" size="icon-xs" popovertarget="secure-popover"> <twig:ux:icon name="lucide:info"/> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Addon class="text-muted-foreground pl-1.5"> https:// </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Input/> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Button size="icon-xs"> <twig:ux:icon name="lucide:star"/> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Type to search..."/> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Button variant="secondary">Search</twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div> <twig:ui:Popover id="secure-popover"> <twig:ui:Popover:Content align="start" class="flex flex-col gap-1 rounded-xl text-sm"> <p class="font-medium">Your connection is not secure.</p> <p>You should not enter any sensitive information on this site.</p> </twig:ui:Popover:Content> </twig:ui:Popover>
Tooltip
<div class="grid w-full max-w-sm gap-4"> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Enter password" type="password" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Button variant="ghost" aria-label="Info" size="icon-xs" data-tooltip="password-tooltip"> <twig:ux:icon name="lucide:info" /> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Your email address" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Button variant="ghost" aria-label="Help" size="icon-xs" data-tooltip="email-tooltip"> <twig:ux:icon name="lucide:help-circle" /> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Enter API key" /> <twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Button variant="ghost" aria-label="Help" size="icon-xs" data-tooltip="api-tooltip"> <twig:ux:icon name="lucide:help-circle" /> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div> <twig:ui:Tooltip id="password-tooltip"> <twig:ui:Tooltip:Content> <p class="text-sm">Password must be at least 8 characters</p> <twig:ui:Tooltip:Arrow/> </twig:ui:Tooltip:Content> </twig:ui:Tooltip> <twig:ui:Tooltip id="email-tooltip"> <twig:ui:Tooltip:Content> <p class="text-sm">We'll use this to send you notifications</p> <twig:ui:Tooltip:Arrow/> </twig:ui:Tooltip:Content> </twig:ui:Tooltip> <twig:ui:Tooltip id="api-tooltip" position="left"> <twig:ui:Tooltip:Content> <p class="text-sm">Click for help with API keys</p> <twig:ui:Tooltip:Arrow/> </twig:ui:Tooltip:Content> </twig:ui:Tooltip>
Textarea
Line 1, Column 1
script.js
<div class="grid w-full max-w-md gap-4"> <twig:ui:InputGroup> <twig:ui:InputGroup:Textarea placeholder="console.log('Hello, world!');" class="min-h-[200px]" /> <twig:ui:InputGroup:Addon align="block-end" class="border-t"> <twig:ui:InputGroup:Text>Line 1, Column 1</twig:ui:InputGroup:Text> <twig:ui:InputGroup:Button size="sm" class="ml-auto" variant="primary"> Run <twig:ux:icon name="lucide:corner-down-left" /> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Addon align="block-start" class="border-b"> <twig:ui:InputGroup:Text class="font-mono font-medium"> <twig:ux:icon name="tabler:brand-javascript" /> script.js </twig:ui:InputGroup:Text> <twig:ui:InputGroup:Button class="ml-auto" size="icon-xs"> <twig:ux:icon name="lucide:refresh-cw" /> </twig:ui:InputGroup:Button> <twig:ui:InputGroup:Button variant="ghost" size="icon-xs"> <twig:ux:icon name="lucide:copy" /> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div>
Spinner
<div class="grid w-full max-w-sm gap-4"> <twig:ui:InputGroup data-disabled="true"> <twig:ui:InputGroup:Input placeholder="Searching..." disabled/> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:Spinner/> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup data-disabled="true"> <twig:ui:InputGroup:Input placeholder="Processing..." disabled/> <twig:ui:InputGroup:Addon> <twig:ui:Spinner/> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup data-disabled="true"> <twig:ui:InputGroup:Input placeholder="Saving changes..." disabled/> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Text>Saving...</twig:ui:InputGroup:Text> <twig:ui:Spinner/> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup data-disabled="true"> <twig:ui:InputGroup:Input placeholder="Refreshing data..." disabled/> <twig:ui:InputGroup:Addon> <twig:ui:Spinner icon="lucide:loader"/> </twig:ui:InputGroup:Addon> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Text class="text-muted-foreground"> Please wait... </twig:ui:InputGroup:Text> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div>
Label
<div class="grid w-full max-w-sm gap-4"> <twig:ui:InputGroup> <twig:ui:InputGroup:Input id="username" placeholder="nicolaslps" /> <twig:ui:InputGroup:Addon> <twig:ui:Label for="username">@</twig:ui:Label> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> {# TODO fix interaction avec label #} <twig:ui:InputGroup> <twig:ui:InputGroup:Input id="email-2" placeholder="[email protected]" /> <twig:ui:InputGroup:Addon align="block-start"> <twig:ui:Label for="email-2" class="text-foreground"> Email </twig:ui:Label> <twig:ui:InputGroup:Button variant="ghost" aria-label="Help" class="ml-auto rounded-full" size="icon-xs" data-tooltip="email-help-tooltip"> <twig:ux:icon name="lucide:info" /> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div> <twig:ui:Tooltip id="email-help-tooltip"> <twig:ui:Tooltip:Content> <p class="text-sm">We'll use this to send you notifications</p> <twig:ui:Tooltip:Arrow/> </twig:ui:Tooltip:Content> </twig:ui:Tooltip>
Dropdown
<div class="grid w-full max-w-sm gap-4"> <twig:ui:InputGroup> <twig:ui:InputGroup:Input placeholder="Enter file name" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Button variant="ghost" aria-label="More" size="icon-xs" popovertarget="file-dropdown"> <twig:ux:icon name="lucide:more-horizontal" /> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:InputGroup class="[--radius:1rem]"> <twig:ui:InputGroup:Input placeholder="Enter search query" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ui:InputGroup:Button variant="ghost" class="!pr-1.5 text-xs" popovertarget="search-dropdown"> Search In... <twig:ux:icon name="lucide:chevron-down" class="size-3" /> </twig:ui:InputGroup:Button> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> </div> <twig:ui:DropdownMenu id="file-dropdown" position="bottom-end"> <twig:ui:DropdownMenu:Content align="end"> <twig:ui:DropdownMenu:Item>Settings</twig:ui:DropdownMenu:Item> <twig:ui:DropdownMenu:Item>Copy path</twig:ui:DropdownMenu:Item> <twig:ui:DropdownMenu:Item>Open location</twig:ui:DropdownMenu:Item> </twig:ui:DropdownMenu:Content> </twig:ui:DropdownMenu> <twig:ui:DropdownMenu id="search-dropdown" position="bottom-end"> <twig:ui:DropdownMenu:Content align="end" class="[--radius:0.95rem]"> <twig:ui:DropdownMenu:Item>Documentation</twig:ui:DropdownMenu:Item> <twig:ui:DropdownMenu:Item>Blog Posts</twig:ui:DropdownMenu:Item> <twig:ui:DropdownMenu:Item>Changelog</twig:ui:DropdownMenu:Item> </twig:ui:DropdownMenu:Content> </twig:ui:DropdownMenu>
Button Group
<div class="grid w-full max-w-sm gap-6"> <twig:ui:ButtonGroup> <twig:ui:ButtonGroup:Text> <twig:ui:Label for="url">https://</twig:ui:Label> </twig:ui:ButtonGroup:Text> <twig:ui:InputGroup> <twig:ui:InputGroup:Input id="url" /> <twig:ui:InputGroup:Addon align="inline-end"> <twig:ux:icon name="lucide:link-2" /> </twig:ui:InputGroup:Addon> </twig:ui:InputGroup> <twig:ui:ButtonGroup:Text> .com </twig:ui:ButtonGroup:Text> </twig:ui:ButtonGroup> </div>