# `PhiaUi.Components.ToggleGroup`
[🔗](https://github.com/charlenopires/PhiaUI/blob/v0.1.17/lib/phia_ui/components/buttons/toggle_group.ex#L1)

Coordinated group of toggle buttons for single or multi-select interactions.

`toggle_group/1` groups multiple `toggle_group_item/1` buttons into a widget
with `role="group"`. Items compute their `aria-pressed` state automatically
based on the group's current `:value`, so you never need to pass `pressed`
manually to each item.

## Sub-components

| Function            | Purpose                                                      |
|---------------------|--------------------------------------------------------------|
| `toggle_group/1`    | Container with `role="group"`, coordinates item state        |
| `toggle_group_item/1` | Individual button whose pressed state is derived from group value |

## Selection modes

### Single select (`type="single"`)

Only one item can be active at a time. The group value is a string (or `nil`
for no selection). Use for mutually exclusive choices like text alignment,
view mode, or sort direction:

    <.toggle_group type="single" value={@align} phx-change="set_align">
      <.toggle_group_item value="left">
        <.icon name="align-left" size="sm" />
      </.toggle_group_item>
      <.toggle_group_item value="center">
        <.icon name="align-center" size="sm" />
      </.toggle_group_item>
      <.toggle_group_item value="right">
        <.icon name="align-right" size="sm" />
      </.toggle_group_item>
    </.toggle_group>

### Multi-select (`type="multiple"`)

Multiple items can be active simultaneously. The group value is a list of
strings. Use for text formatting (bold + italic), filter chips, or feature
flags:

    <.toggle_group type="multiple" value={@formats} phx-change="set_format">
      <.toggle_group_item value="bold">B</.toggle_group_item>
      <.toggle_group_item value="italic">I</.toggle_group_item>
      <.toggle_group_item value="underline">U</.toggle_group_item>
      <.toggle_group_item value="strikethrough">S</.toggle_group_item>
    </.toggle_group>

## Using `:let` context

When nesting items inside the group slot, the parent passes context via
`:let`. Items use `{group}` spread to receive `group_value`, `group_type`,
`variant`, and `size` from the parent automatically:

    <.toggle_group :let={group} type="single" value={@view_mode} variant="outline">
      <.toggle_group_item value="grid"  {group}><.icon name="grid" /></.toggle_group_item>
      <.toggle_group_item value="list"  {group}><.icon name="list" /></.toggle_group_item>
      <.toggle_group_item value="table" {group}><.icon name="table" /></.toggle_group_item>
    </.toggle_group>

## View mode switcher example

    defmodule MyAppWeb.ProductsLive do
      use MyAppWeb, :live_view

      def mount(_params, _session, socket) do
        {:ok, assign(socket, view_mode: "grid", filters: [])}
      end

      def handle_event("set_view", %{"value" => mode}, socket) do
        {:noreply, assign(socket, view_mode: mode)}
      end

      def handle_event("set_filter", %{"value" => filters}, socket) do
        {:noreply, assign(socket, filters: filters)}
      end
    end

    <%!-- In the template --%>
    <.toggle_group type="single" value={@view_mode} phx-change="set_view" variant="outline">
      <.toggle_group_item value="grid">Grid</.toggle_group_item>
      <.toggle_group_item value="list">List</.toggle_group_item>
    </.toggle_group>

## Text formatting toolbar (multi-select)

    <.toggle_group type="multiple" value={@active_formats} phx-change="set_format" size="sm">
      <.toggle_group_item value="bold"          aria-label="Bold">B</.toggle_group_item>
      <.toggle_group_item value="italic"        aria-label="Italic">I</.toggle_group_item>
      <.toggle_group_item value="underline"     aria-label="Underline">U</.toggle_group_item>
      <.toggle_group_item value="strikethrough" aria-label="Strikethrough">S</.toggle_group_item>
    </.toggle_group>

## Variants and sizes

Both the `toggle_group/1` and `toggle_group_item/1` accept `:variant` and
`:size`. Setting them on the group propagates to all items via the `:let`
context — no need to set them on every item individually.

- **Variants**: `"default"` (ghost-like), `"outline"` (bordered)
- **Sizes**: `"sm"`, `"default"`, `"lg"`

# `toggle_group`

Renders a group container that coordinates a set of toggle items.

Exposes group context via `:let` so items can compute their `pressed` state
and inherit `variant`/`size` without repeating those attributes on each item:

    <.toggle_group :let={group} type="single" value={@align} variant="outline">
      <.toggle_group_item value="left"   {group}><.icon name="align-left" /></.toggle_group_item>
      <.toggle_group_item value="center" {group}><.icon name="align-center" /></.toggle_group_item>
      <.toggle_group_item value="right"  {group}><.icon name="align-right" /></.toggle_group_item>
    </.toggle_group>

The `{group}` spread is equivalent to passing:
`group_value={group.group_value} group_type={group.group_type} variant={group.variant} size={group.size}`

## Examples

    <%!-- Single select — text alignment --%>
    <.toggle_group type="single" value={@align} phx-change="set_align">
      <.toggle_group_item value="left">Left</.toggle_group_item>
      <.toggle_group_item value="center">Center</.toggle_group_item>
      <.toggle_group_item value="right">Right</.toggle_group_item>
    </.toggle_group>

    <%!-- Multi-select — active filters --%>
    <.toggle_group type="multiple" value={@active_filters} phx-change="toggle_filter" size="sm" variant="outline">
      <.toggle_group_item value="in_stock">In stock</.toggle_group_item>
      <.toggle_group_item value="on_sale">On sale</.toggle_group_item>
      <.toggle_group_item value="new_arrivals">New arrivals</.toggle_group_item>
    </.toggle_group>

## Attributes

* `type` (`:string`) - Selection mode:
  - `"single"` — only one item can be active; `:value` is a string or `nil`
  - `"multiple"` — several items can be active; `:value` is a list of strings

  Defaults to `"single"`. Must be one of `"single"`, or `"multiple"`.
* `value` (`:any`) - Currently selected value(s). Type depends on `:type`:
  - For `"single"`: a string matching one item's `:value`, or `nil` for no selection
  - For `"multiple"`: a list of strings, e.g. `["bold", "italic"]`

  This is passed down to each item via the slot context so items can compute
  their own `pressed` state.

  Defaults to `nil`.
* `variant` (`:string`) - Visual style propagated to all items:
  - `"default"` — ghost-like, transparent background
  - `"outline"` — bordered with `border-input`

  Defaults to `"default"`. Must be one of `"default"`, or `"outline"`.
* `size` (`:string`) - Button size propagated to all items:
  - `"sm"` — `h-9 px-2.5 text-xs` (compact toolbars)
  - `"default"` — `h-10 px-3`
  - `"lg"` — `h-11 px-5`

  Defaults to `"default"`. Must be one of `"default"`, `"sm"`, or `"lg"`.
* `class` (`:string`) - Additional CSS classes applied to the group container `<div>`. Defaults to `nil`.
* Global attributes are accepted. HTML attributes forwarded to the group `<div>`. Typically used for
  `phx-change` to notify the LiveView when the selection changes.

## Slots

* `inner_block` (required) - One or more `toggle_group_item/1` components. Use `:let={group}` on the
  parent to capture the context map, then spread `{group}` onto each item
  to propagate `group_value`, `group_type`, `variant`, and `size`.

# `toggle_group_item`

Renders a single pressable item within a `toggle_group/1`.

The `:pressed` state is computed at render time from `:group_type` and
`:group_value`, so the template stays declarative. In normal usage, pass
context from the parent via `{group}` spread:

    <.toggle_group :let={group} type="multiple" value={@formats}>
      <.toggle_group_item value="bold"   {group}>B</.toggle_group_item>
      <.toggle_group_item value="italic" {group}>I</.toggle_group_item>
    </.toggle_group>

## Examples

    <%!-- Inside a single-select group --%>
    <.toggle_group :let={g} type="single" value={@mode}>
      <.toggle_group_item value="grid"  {g}><.icon name="grid" /></.toggle_group_item>
      <.toggle_group_item value="list"  {g}><.icon name="list" /></.toggle_group_item>
    </.toggle_group>

    <%!-- Manual usage (no group context) --%>
    <.toggle_group_item
      value="bold"
      group_value={@active_formats}
      group_type="multiple"
    >
      Bold
    </.toggle_group_item>

    <%!-- Disabled item within a group --%>
    <.toggle_group :let={g} type="single" value={@mode}>
      <.toggle_group_item value="grid" {g}>Grid</.toggle_group_item>
      <.toggle_group_item value="table" {g} disabled>Table (coming soon)</.toggle_group_item>
    </.toggle_group>

## Attributes

* `value` (`:string`) (required) - The value this item represents within the group. For `type="single"`, this
  string is compared against the group value. For `type="multiple"`, membership
  in the group value list is checked.

* `group_value` (`:any`) - The group's current selected value(s). Used to compute this item's `pressed`
  state. In typical usage, this is passed via the `{group}` spread from the
  parent's `:let` context — you do not need to set it manually.

  Defaults to `nil`.
* `group_type` (`:string`) - The parent group's selection type. Used for the `pressed` calculation:
  - `"single"`: pressed when `group_value == value`
  - `"multiple"`: pressed when `value in group_value`
  Inherited from the group context via `{group}` spread in typical usage.

  Defaults to `"single"`. Must be one of `"single"`, or `"multiple"`.
* `variant` (`:string`) - Visual style of the button. Normally inherited from the group via `{group}` spread.
  Override per-item only when you need a different style than the group default.

  Defaults to `"default"`. Must be one of `"default"`, or `"outline"`.
* `size` (`:string`) - Button size. Normally inherited from the group via `{group}` spread.
  Override per-item only when individual sizing is needed.

  Defaults to `"default"`. Must be one of `"default"`, `"sm"`, or `"lg"`.
* `disabled` (`:boolean`) - When `true`, disables this item. It becomes non-interactive and renders at 50% opacity. Defaults to `false`.
* `class` (`:string`) - Additional CSS classes applied to the `<button>` element via `cn/1`. Defaults to `nil`.
* Global attributes are accepted. HTML attributes forwarded to the `<button>` element. Typically used for
  per-item `phx-click` handlers when items need individual event handling
  rather than a group-level `phx-change`.
 Supports all globals plus: `["phx-click", "phx-value"]`.
## Slots

* `inner_block` (required) - Item content — typically a short text label or an icon component.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
