Input Group

Textarea - Phlex implementation

Examples

Default

Various input group patterns: search with results, URL with tooltip, chat input, and verified username.

12 results
https://
52% used
<div class="grid w-full max-w-sm gap-6">
  <%# 1. Search with results %>
  <%= render "ui/input_group" do %>
    <%= render "ui/input_group/input", placeholder: "Search..." %>
    <%= render "ui/input_group/addon", align: "inline-start" do %>
      <svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
    <% end %>
    <%= render "ui/input_group/addon", align: "inline-end" do %>12 results<% end %>
  <% end %>

  <%# 2. URL with tooltip %>
  <%= render "ui/input_group" do %>
    <%= render "ui/input_group/addon" do %>
      <%= render "ui/input_group/text" do %>https://<% end %>
    <% end %>
    <%= render "ui/input_group/input", placeholder: "example.com", classes: "!pl-1" %>
    <%= render "ui/tooltip", as_child: true do |tooltip_attrs| %>
      <%= render "ui/input_group/addon", align: "inline-end", attributes: tooltip_attrs do %>
        <%= render "ui/tooltip/trigger", as_child: true do |trigger_attrs| %>
          <%= render "ui/input_group/button", size: "icon-xs", classes: "rounded-full", attributes: trigger_attrs do %>
            <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
          <% end %>
        <% end %>
        <%= render "ui/tooltip/content" do %>This is content in a tooltip.<% end %>
      <% end %>
    <% end %>
  <% end %>

  <%# 3. Chat/AI input with textarea %>
  <%= render "ui/input_group" do %>
    <%= render "ui/input_group/textarea", placeholder: "Ask, Search or Chat..." %>
    <%= render "ui/input_group/addon", align: "block-end" do %>
      <%= render "ui/input_group/button", variant: "outline", size: "icon-xs", classes: "rounded-full" do %>
        <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
      <% end %>
      <%= render "ui/dropdown_menu" do %>
        <%= render "ui/dropdown_menu/trigger" do %>
          <%= render "ui/input_group/button", variant: "ghost" do %>Auto<% end %>
        <% end %>
        <%= render "ui/dropdown_menu/content", side: "top", align: "start", classes: "[--radius:0.95rem]" do %>
          <%= render "ui/dropdown_menu/item" do %>Auto<% end %>
          <%= render "ui/dropdown_menu/item" do %>Agent<% end %>
          <%= render "ui/dropdown_menu/item" do %>Manual<% end %>
        <% end %>
      <% end %>
      <%= render "ui/input_group/text", classes: "ml-auto" do %>52% used<% end %>
      <%= render "ui/separator", orientation: "vertical", classes: "!h-4" %>
      <%= render "ui/input_group/button", variant: "default", size: "icon-xs", classes: "rounded-full", attributes: { disabled: true } do %>
        <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 10l7-7m0 0l7 7m-7-7v18"/></svg>
        <span class="sr-only">Send</span>
      <% end %>
    <% end %>
  <% end %>

  <%# 4. Verified username %>
  <%= render "ui/input_group" do %>
    <%= render "ui/input_group/input", placeholder: "@shadcn" %>
    <%= render "ui/input_group/addon", align: "inline-end" do %>
      <div class="bg-primary text-primary-foreground flex size-4 items-center justify-center rounded-full">
        <svg class="size-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
      </div>
    <% end %>
  <% end %>
</div>

With Icon Addon

Input with an icon prefix.

<%= render "ui/input_group" do %>
  <%= render "ui/input_group/addon", align: "inline-start" do %>
    <svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
    </svg>
  <% end %>
  <%= render "ui/input_group/input", placeholder: "Search..." %>
<% end %>

Text Addon

Input with text prefix and suffix.

$
USD
<%= render "ui/input_group" do %>
  <%= render "ui/input_group/addon", align: "inline-start" do %>
    <%= render "ui/input_group/text", content: "$" %>
  <% end %>
  <%= render "ui/input_group/input", type: "number", placeholder: "0.00" %>
  <%= render "ui/input_group/addon", align: "inline-end" do %>
    <%= render "ui/input_group/text", content: "USD" %>
  <% end %>
<% end %>

Button Addon

Input groups with various button addons including copy, popover info, favorite, and search.

Your connection is not secure.

You should not enter any sensitive information on this site.

https://
<div class="grid w-full max-w-sm gap-6">
  <%# Copy to clipboard %>
  <%= render "ui/input_group" do %>
    <%= render "ui/input_group/input", placeholder: "https://x.com/shadcn", attributes: { readonly: true } %>
    <%= render "ui/input_group/addon", align: "inline-end" do %>
      <%= render "ui/input_group/button", size: "icon-xs", attributes: { "aria-label": "Copy", title: "Copy" } do %>
        <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
        </svg>
      <% end %>
    <% end %>
  <% end %>

  <%# Popover info + favorite star %>
  <%= render "ui/input_group", classes: "[--radius:9999px]" do %>
    <%= render "ui/popover", as_child: true do |popover_attrs| %>
      <%= render "ui/input_group/addon", attributes: popover_attrs do %>
        <%= render "ui/popover/trigger", as_child: true do |trigger_attrs| %>
          <%= render "ui/input_group/button", variant: "secondary", size: "icon-xs", attributes: trigger_attrs do %>
            <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
            </svg>
          <% end %>
        <% end %>
        <%= render "ui/popover/content", align: "start", classes: "flex flex-col gap-1 rounded-xl text-sm" do %>
          <p class="font-medium">Your connection is not secure.</p>
          <p>You should not enter any sensitive information on this site.</p>
        <% end %>
      <% end %>
    <% end %>
    <%= render "ui/input_group/addon", classes: "text-muted-foreground pl-1.5" do %>https://<% end %>
    <%= render "ui/input_group/input", id: "input-secure-19" %>
    <%= render "ui/input_group/addon", align: "inline-end" do %>
      <%= render "ui/input_group/button", size: "icon-xs" do %>
        <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"/>
        </svg>
      <% end %>
    <% end %>
  <% end %>

  <%# Search button %>
  <%= render "ui/input_group" do %>
    <%= render "ui/input_group/input", placeholder: "Type to search..." %>
    <%= render "ui/input_group/addon", align: "inline-end" do %>
      <%= render "ui/input_group/button", variant: "secondary" do %>Search<% end %>
    <% end %>
  <% end %>
</div>

With Tooltip

Input with a tooltip for additional context.

<%= render "ui/input_group" do %>
  <%= render "ui/input_group/input", placeholder: "Enter password", type: "password" %>
  <%= render "ui/input_group/addon", align: "inline-end" do %>
    <%= render "ui/tooltip" do %>
      <%= render "ui/tooltip/trigger", attributes: { class: "inline-flex items-center justify-center border-0 bg-transparent p-0 shadow-none hover:bg-transparent focus:ring-0" } do %>
        <svg class="size-4 text-muted-foreground hover:text-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
        </svg>
      <% end %>
      <%= render "ui/tooltip/content" do %>Password must be at least 8 characters<% end %>
    <% end %>
  <% end %>
<% end %>

Textarea

A mini code editor with header and footer using block-start and block-end alignments.

script.js
Line 1, Column 1
<%= render "ui/input_group", classes: "w-full max-w-md" do %>
  <%# Header with filename and actions %>
  <%= render "ui/input_group/addon", align: "block-start", classes: "border-b" do %>
    <%= render "ui/input_group/text", classes: "font-mono font-medium gap-1.5" do %>
      <svg class="size-4 text-gray-400" viewBox="0 0 24 24" fill="currentColor"><path d="M3 3h18v18H3V3m4.73 15.04c.4.85 1.19 1.55 2.54 1.55 1.5 0 2.53-.8 2.53-2.55v-5.78h-1.7V17c0 .86-.35 1.08-.9 1.08-.58 0-.82-.4-1.09-.87l-1.38.83m5.98-.18c.5.98 1.51 1.73 3.09 1.73 1.6 0 2.8-.83 2.8-2.36 0-1.41-.81-2.04-2.25-2.66l-.42-.18c-.73-.31-1.04-.52-1.04-1.02 0-.41.31-.73.81-.73.48 0 .8.21 1.09.73l1.31-.87c-.55-.96-1.33-1.33-2.4-1.33-1.51 0-2.48.96-2.48 2.23 0 1.38.81 2.03 2.03 2.55l.42.18c.78.34 1.24.55 1.24 1.13 0 .48-.45.83-1.15.83-.83 0-1.31-.43-1.67-1.03l-1.38.8z"/></svg>
      script.js
    <% end %>
    <%= render "ui/input_group/button", size: "icon-xs", classes: "ml-auto", attributes: { title: "Refresh" } do %>
      <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
    <% end %>
    <%= render "ui/input_group/button", size: "icon-xs", attributes: { title: "Copy" } do %>
      <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
    <% end %>
  <% end %>
  <%# Code textarea %>
  <%= render "ui/input_group/textarea", placeholder: "console.log('Hello, world!');", classes: "min-h-[200px] font-mono text-sm", attributes: { rows: 8 } %>
  <%# Footer with line info and run button %>
  <%= render "ui/input_group/addon", align: "block-end", classes: "border-t" do %>
    <%= render "ui/input_group/text" do %>Line 1, Column 1<% end %>
    <%= render "ui/input_group/button", size: "sm", variant: "default", classes: "ml-auto gap-1" do %>
      Run
      <svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5"/></svg>
    <% end %>
  <% end %>
<% end %>

Spinner

Input with a loading spinner.

<%= render "ui/input_group" do %>
  <%= render "ui/input_group/input", placeholder: "Loading..." %>
  <%= render "ui/input_group/addon", align: "inline-end" do %>
    <%= render "ui/spinner", size: "sm" %>
  <% end %>
<% end %>

With Label

Input group with an integrated label.

<%= render "ui/input_group" do %>
  <%= render "ui/input_group/addon", align: "inline-start" do %>
    <%= render "ui/label", for: "website", classes: "text-sm font-medium" do %>Website<% end %>
  <% end %>
  <%= render "ui/input_group/input", id: "website", placeholder: "example.com" %>
<% end %>

Dropdown

Input group with a dropdown menu.

<%= render "ui/input_group" do %>
  <%= render "ui/input_group/input", placeholder: "Enter file name" %>
  <%= render "ui/input_group/addon", align: "inline-end" do %>
    <%= render "ui/dropdown_menu" do %>
      <%= render "ui/dropdown_menu/trigger" do %>
        <%= render "ui/input_group/button", variant: "ghost", size: "icon-xs" do %>
          <svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z"/>
          </svg>
        <% end %>
      <% end %>
      <%= render "ui/dropdown_menu/content", align: "end" do %>
        <%= render "ui/dropdown_menu/item" do %>Settings<% end %>
        <%= render "ui/dropdown_menu/item" do %>Copy path<% end %>
        <%= render "ui/dropdown_menu/item" do %>Open location<% end %>
      <% end %>
    <% end %>
  <% end %>
<% end %>

Dropdown Rounded

Input group with custom radius and dropdown trigger.

<%= render "ui/input_group", classes: "[--radius:1rem]" do %>
  <%= render "ui/input_group/input", placeholder: "Enter search query" %>
  <%= render "ui/dropdown_menu", as_child: true do |dropdown_attrs| %>
    <%= render "ui/input_group/addon", align: "inline-end", attributes: dropdown_attrs do %>
      <%= render "ui/dropdown_menu/trigger", as_child: true do |trigger_attrs| %>
        <%= render "ui/input_group/button", variant: "ghost", classes: "!pr-1.5 text-xs gap-1", attributes: trigger_attrs do %>
          Search In...
          <svg class="size-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
          </svg>
        <% end %>
      <% end %>
      <%= render "ui/dropdown_menu/content", align: "end", classes: "[--radius:0.95rem]" do %>
        <%= render "ui/dropdown_menu/item" do %>Documentation<% end %>
        <%= render "ui/dropdown_menu/item" do %>Blog Posts<% end %>
        <%= render "ui/dropdown_menu/item" do %>Changelog<% end %>
      <% end %>
    <% end %>
  <% end %>
<% end %>

Features

  • Custom styling with Tailwind classes

API Reference

Input Group Textarea

A textarea element styled for use within input groups.

Parameters

NameTypeDefaultDescription
placeholderStringnilPlaceholder text when no value is selected
valueStringnilThe current value
nameStringnilForm field name
idStringnilHTML id attribute
rowsStringnilThe rows