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

Horizontal tab navigation component for page-level and section-level routing.

`TabsNav` renders accessible tab-style navigation using `<a>` links rather
than `<button>` elements, making it suitable for route-based navigation where
each tab corresponds to a different URL or live action.

## When to use TabsNav vs Tabs

| Component  | Use case                                                       |
|------------|----------------------------------------------------------------|
| `TabsNav`  | Route-based navigation — tabs link to different pages/actions  |
| `Tabs`     | Content panels — tabs switch content on the same page          |

Use `TabsNav` with `@live_action` to highlight the current section:

    <.tabs_nav>
      <.tabs_nav_item href="/dashboard" active={@live_action == :index}>
        Dashboard
      </.tabs_nav_item>
      <.tabs_nav_item href="/analytics" active={@live_action == :analytics}>
        Analytics
      </.tabs_nav_item>
    </.tabs_nav>

## Visual variants

Three visual styles are available via the `:variant` attribute:

| Variant      | Appearance                                              | Best for                  |
|--------------|---------------------------------------------------------|---------------------------|
| `:underline` | Bottom border indicator on active tab (default)         | Standard page navigation  |
| `:pills`     | Filled primary background on active tab, rounded        | Compact section switching |
| `:segment`   | Segmented control inside a muted container, no border   | Dense dashboards          |

## Underline variant (default)

    <.tabs_nav>
      <.tabs_nav_item href="/overview" active>Overview</.tabs_nav_item>
      <.tabs_nav_item href="/analytics">Analytics</.tabs_nav_item>
      <.tabs_nav_item href="/reports">Reports</.tabs_nav_item>
    </.tabs_nav>

## Pills variant

    <.tabs_nav variant={:pills}>
      <.tabs_nav_item href="#overview" variant={:pills} active>Overview</.tabs_nav_item>
      <.tabs_nav_item href="#analytics" variant={:pills}>Analytics</.tabs_nav_item>
    </.tabs_nav>

## Segment variant

The segment variant wraps items inside a `bg-muted` container with `p-1`,
creating the look of a segmented control (similar to iOS segment pickers):

    <.tabs_nav variant={:segment}>
      <.tabs_nav_item href="#day"   variant={:segment} active>Day</.tabs_nav_item>
      <.tabs_nav_item href="#week"  variant={:segment}>Week</.tabs_nav_item>
      <.tabs_nav_item href="#month" variant={:segment}>Month</.tabs_nav_item>
    </.tabs_nav>

## Driven by live_action

    defmodule MyAppWeb.ReportsLive do
      use MyAppWeb, :live_view

      def mount(_params, _session, socket) do
        {:ok, socket}
      end

      def handle_params(%{"section" => section}, _uri, socket) do
        {:noreply, assign(socket, section: section)}
      end

      def render(assigns) do
        ~H"""
        <.tabs_nav>
          <.tabs_nav_item href="/reports" active={@section == "overview"}>
            Overview
          </.tabs_nav_item>
          <.tabs_nav_item href="/reports/revenue" active={@section == "revenue"}>
            Revenue
          </.tabs_nav_item>
          <.tabs_nav_item href="/reports/users" active={@section == "users"}>
            Users
          </.tabs_nav_item>
        </.tabs_nav>

        <%!-- Render different content based on section --%>
        <%= case @section do %>
          <% "overview" -> %> <.overview_content />
          <% "revenue"  -> %> <.revenue_report data={@revenue} />
          <% "users"    -> %> <.users_report data={@users} />
        <% end %>
        """
      end
    end

## Dashboard tabs with phx-click (no navigation)

When you want tab-like navigation without changing the URL, use `phx-click`
on an in-page anchor and drive state from LiveView assigns:

    <.tabs_nav variant={:pills}>
      <.tabs_nav_item
        href="#"
        variant={:pills}
        active={@view == "chart"}
        phx-click="set_view"
        phx-value-view="chart"
      >
        Chart
      </.tabs_nav_item>
      <.tabs_nav_item
        href="#"
        variant={:pills}
        active={@view == "table"}
        phx-click="set_view"
        phx-value-view="table"
      >
        Table
      </.tabs_nav_item>
    </.tabs_nav>

## Accessibility

- `role="tablist"` on the `<nav>` container with `aria-orientation="horizontal"`
- `role="tab"` on each `<a>` item
- `aria-selected="true|false"` reflects active state
- `tabindex="0"` on the active item; `tabindex="-1"` on inactive items
  (keyboard navigation follows the ARIA tabs pattern)
- Disabled items: no `href`, `pointer-events-none opacity-50`

# `tabs_nav`

Renders a horizontal tab navigation container.

## Variant reference

| Variant      | Container classes                              |
|--------------|------------------------------------------------|
| `:underline` | `inline-flex items-center border-b w-full gap-4` |
| `:pills`     | `inline-flex items-center gap-1`               |
| `:segment`   | `inline-flex items-center rounded-lg bg-muted p-1 gap-0.5` |

## Example

    <.tabs_nav variant={:segment}>
      <.tabs_nav_item href="#week"  variant={:segment} active>Week</.tabs_nav_item>
      <.tabs_nav_item href="#month" variant={:segment}>Month</.tabs_nav_item>
      <.tabs_nav_item href="#year"  variant={:segment}>Year</.tabs_nav_item>
    </.tabs_nav>

## Attributes

* `variant` (`:atom`) - Visual style variant for the tab navigation container.

  - `:underline` — bottom border on the container; active tab has
    `border-b-2 border-primary` indicator
  - `:pills` — no container border; active tab has `bg-primary
    text-primary-foreground` filled pill
  - `:segment` — `bg-muted p-1 rounded-lg` container; active tab has
    `bg-background text-foreground shadow-sm`
  - `:scrollable` — horizontally scrollable underline variant for many tabs

  Defaults to `:underline`. Must be one of `:underline`, `:pills`, `:segment`, or `:scrollable`.
* `class` (`:string`) - Additional CSS classes for the nav element. Defaults to `nil`.
* Global attributes are accepted. HTML attributes forwarded to the `<nav>` element (e.g. `aria-label`).
## Slots

* `inner_block` (required) - `tabs_nav_item/1` components.

# `tabs_nav_item`

Renders an individual tab navigation item inside `tabs_nav/1`.

Uses an `<a>` element (not `<button>`) so it is naturally keyboard-focusable
and screen-reader-friendly as a navigation link. The `role="tab"` attribute
overrides the link semantics to signal tablist membership.

When `disabled` is `true`, `href` is set to `nil` which prevents the browser
from navigating while keeping the element in the tab order.

## Example

    <.tabs_nav_item
      href="/reports/revenue"
      variant={:underline}
      active={@section == "revenue"}
    >
      Revenue
    </.tabs_nav_item>

## Attributes

* `href` (`:string`) - Navigation href for the anchor element. Use a real URL for route-based
  navigation (`"/analytics"`), an anchor hash for same-page navigation
  (`"#revenue"`), or `"#"` with `phx-click` for purely LiveView-driven state.

  Defaults to `"#"`.
* `active` (`:boolean`) - Whether this tab is currently selected. Drives active styles and
  `aria-selected`. Typically derived from `@live_action` or a local assign:
  `active={@live_action == :analytics}`.

  Defaults to `false`.
* `disabled` (`:boolean`) - When `true`, the tab is non-interactive: `href` is set to `nil` (preventing
  navigation), and `pointer-events-none opacity-50` is applied. Use for
  features that are coming soon or not available on the current plan.

  Defaults to `false`.
* `variant` (`:atom`) - Visual style variant. Must match the parent `tabs_nav/1` variant so the
  active/inactive styles are consistent. When using `tabs_nav/1` you are
  responsible for passing the same variant to each item.

  Defaults to `:underline`. Must be one of `:underline`, `:pills`, `:segment`, or `:scrollable`.
* `class` (`:string`) - Additional CSS classes for the anchor element. Defaults to `nil`.
* Global attributes are accepted. HTML attributes forwarded to the `<a>` element. Use `phx-click` and
  `phx-value-*` for LiveView-driven tab switching without route changes.

## Slots

* `inner_block` (required) - Tab label — text, icon, or both.

---

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