DocsComponentsInput group
Input group
An input with icons, text, buttons or a keyboard hint attached inside it.
Alpine.js6 files
<div class="grid w-full max-w-sm gap-4">
<pb-ui.input-group>
<pb-ui.input-group-input placeholder="Search…" />
<pb-ui.input-group-addon><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg></pb-ui.input-group-addon>
<pb-ui.input-group-addon align="inline-end"><pb-ui.kbd>⌘K</pb-ui.kbd></pb-ui.input-group-addon>
</pb-ui.input-group>
<pb-ui.input-group>
<pb-ui.input-group-addon><pb-ui.input-group-text>https://</pb-ui.input-group-text></pb-ui.input-group-addon>
<pb-ui.input-group-input placeholder="example.com" class="pl-0.5" />
<pb-ui.input-group-addon align="inline-end"><pb-ui.input-group-text>.fr</pb-ui.input-group-text></pb-ui.input-group-addon>
</pb-ui.input-group>
<pb-ui.input-group>
<pb-ui.input-group-addon><pb-ui.input-group-text>€</pb-ui.input-group-text></pb-ui.input-group-addon>
<pb-ui.input-group-input type="number" placeholder="0,00" />
<pb-ui.input-group-addon align="inline-end"><pb-ui.input-group-button variant="secondary">Pay</pb-ui.input-group-button></pb-ui.input-group-addon>
</pb-ui.input-group>
<pb-ui.input-group>
<pb-ui.input-group-textarea placeholder="Ask a question…"></pb-ui.input-group-textarea>
<pb-ui.input-group-addon align="block-end">
<pb-ui.input-group-text>52% used</pb-ui.input-group-text>
<pb-ui.input-group-button variant="default" size="icon-xs" class="ml-auto rounded-full" aria-label="Submit"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12 7-7 7 7"/><path d="M12 19V5"/></svg></pb-ui.input-group-button>
</pb-ui.input-group-addon>
</pb-ui.input-group>
</div>Installation
pyblade-ui add input-group- Install the dependencies
Alpine.js, loaded in your
<head>. - Copy these files into your projectcomponents/ui/input_group.html
<div role="group" data-slot="input-group" {{ attributes.cn( "group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none dark:bg-input/30", "has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-[3px] has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50", "has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>textarea]:h-auto", "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col", ) }}>{{ slot }}</div>components/ui/input_group_input.html@props({'type': 'text'}) <input type="{{ type }}" data-slot="input-group-control" {{ attributes.cn("h-full w-full min-w-0 flex-1 rounded-none border-0 bg-transparent px-3 py-1 text-base shadow-none outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 md:text-sm") }} />components/ui/input_group_textarea.html<textarea data-slot="input-group-control" {{ attributes.cn("field-sizing-content min-h-16 w-full flex-1 resize-none rounded-none border-0 bg-transparent px-3 py-2.5 text-base shadow-none outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 md:text-sm") }}>{{ slot }}</textarea>components/ui/input_group_addon.html@props({'align': 'inline-start'}) <div role="group" data-slot="input-group-addon" data-align="{{ align }}" x-data x-on:click="$event.target.closest('button') || $el.parentElement.querySelector('[data-slot=input-group-control]')?.focus()" {{ attributes.cn( "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4", { 'inline-start': 'order-first pl-3 has-[>button]:ml-[-0.45rem]', 'inline-end': 'order-last pr-3 has-[>button]:mr-[-0.45rem]', 'block-start': 'order-first w-full justify-start px-3 pt-3', 'block-end': 'order-last w-full justify-start px-3 pb-3', }[align], ) }}>{{ slot }}</div>components/ui/input_group_button.html@props({'variant': 'ghost', 'size': 'xs', 'type': 'button'}) <button type="{{ type }}" data-slot="input-group-button" {{ attributes.cn( "inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 text-sm font-medium whitespace-nowrap shadow-none transition-all outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", { 'ghost': 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50', 'secondary': 'bg-secondary text-secondary-foreground hover:bg-secondary/80', 'default': 'bg-primary text-primary-foreground hover:bg-primary/90', 'outline': 'border bg-background hover:bg-accent', }[variant], { 'xs': "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-2 has-[>svg]:px-2 [&>svg:not([class*='size-'])]:size-3.5", 'sm': 'h-8 gap-1.5 rounded-md px-2.5 has-[>svg]:px-2.5', 'icon-xs': 'size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0', 'icon-sm': 'size-8 p-0 has-[>svg]:p-0', }[size], ) }}>{{ slot }}</button>components/ui/input_group_text.html<span data-slot="input-group-text" {{ attributes.cn("flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4") }}>{{ slot }}</span> - Update the path to fit your project
The
componentsfolder is the one set inpyblade.toml.
Usage
The tags <pb-ui.input-group> <pb-ui.input-group-input> <pb-ui.input-group-textarea> <pb-ui.input-group-addon> <pb-ui.input-group-button> <pb-ui.input-group-text> are available in all your templates.
<pb-ui.input-group>
<pb-ui.input-group-input placeholder="example.com" />
<pb-ui.input-group-addon><pb-ui.input-group-text>https://</pb-ui.input-group-text></pb-ui.input-group-addon>
<pb-ui.input-group-addon align="inline-end"><pb-ui.input-group-button>Go</pb-ui.input-group-button></pb-ui.input-group-addon>
</pb-ui.input-group>Props
<pb-ui.input-group-input>
| Prop | Default |
|---|---|
| type | 'text' |
<pb-ui.input-group-addon>
| Prop | Default |
|---|---|
| align | 'inline-start' |
<pb-ui.input-group-button>
| Prop | Default |
|---|---|
| variant | 'ghost' |
| size | 'xs' |
| type | 'button' |
Any other attribute (class, id, x-on:click, hx-post…) is passed to the root element; your Tailwind classes win over the component's.