# VelvetKit

## Input group (`UI::InputGroup`)

A text field with addons before or after it.

Add it: `bin/rails generate velvetkit:add input_group`

Also adds: `icon`, `spinner`, `button`, `label`, `form_field`, `input`

### Arguments

```ruby
UI::InputGroup.new(class: nil, **html_attrs)
```

Slots: `with_addon`, `with_field`, `with_icon`, `with_icon_button`

### Notes

UI::InputGroup — wrapper that visually merges a UI::Input with one or more
Addon decorators (icons, text, icon-buttons). The wrapper owns the border and
focus ring; the inner Field strips its own so there's no double border.

The wrapper's focus ring inherits from UI::Base::FOCUS_RING (same as Button)
wrapped in has-[] selectors, so changes propagate automatically.

Usage:
  <%= render(UI::InputGroup.new) do |g| %>
    <%= g.with_addon(align: "inline-start") { |a| a.with_icon(name: "mail") } %>
    <%= g.with_field(type: :email, placeholder: "you@example.com") %>
  <% end %>

### Example: All Addons

```erb
<%# Gallery of all addon configurations %>
<div class="flex flex-col gap-4 max-w-sm">
  <%# Icon prefix %>
  <%= render(UI::InputGroup.new) do |g| %>
    <%= g.with_addon(align: "inline-start") { |a| a.with_icon(name: "mail") } %>
    <%= g.with_field(type: :email, placeholder: "Email") %>
  <% end %>
  <%# Text prefix %>
  <%= render(UI::InputGroup.new) do |g| %>
    <%= g.with_addon(align: "inline-start") { "https://" } %>
    <%= g.with_field(placeholder: "yoursite.com") %>
  <% end %>
  <%# Icon suffix %>
  <%= render(UI::InputGroup.new) do |g| %>
    <%= g.with_field(placeholder: "Search…") %>
    <%= g.with_addon(align: "inline-end") { |a| a.with_icon(name: "search") } %>
  <% end %>
  <%# Both sides %>
  <%= render(UI::InputGroup.new) do |g| %>
    <%= g.with_addon(align: "inline-start") { "$" } %>
    <%= g.with_field(type: :number, placeholder: "0.00") %>
    <%= g.with_addon(align: "inline-end") { "USD" } %>
  <% end %>
  <%# Error state %>
  <%= render(UI::InputGroup.new) do |g| %>
    <%= g.with_addon(align: "inline-start") { |a| a.with_icon(name: "mail") } %>
    <%= g.with_field(type: :email, placeholder: "Invalid email", error: true) %>
  <% end %>
</div>
```
