Overview

A comprehensive collection of Phoenix LiveView components built with Tailwind CSS.

Tabs

Tab components for organizing content into navigable sections. Includes examples using colocated hooks for client-side interactions.

Basic Tabs

Simple tab navigation with active state managed by LiveView.

Active tab: account

<div class="border-b border-border">
  <nav class="flex gap-1" aria-label="Tabs">
    <button
      :for={tab <- ["account", "password", "notifications"]}
      phx-click="switch_tab"
      phx-value-tab={tab}
      class={[
        "px-4 py-2 text-sm font-medium border-b-2",
        @active_tab == tab && \
          "border-primary text-primary",
        @active_tab != tab && \
          "border-transparent text-muted-foreground"
      ]}
    >
      {String.capitalize(tab)}
    </button>
  </nav>
</div>

Tabs with Content

Tabs that display different content based on the active tab.

Profile Settings

Manage your profile information and public visibility.

<div class="border-b border-border">
  <nav class="flex gap-1" aria-label="Tabs">
    <button
      phx-click="switch_tab"
      phx-value-tab="profile"
      class={[
        "px-4 py-2 text-sm font-medium",
        @active_tab == "profile" && \
          "border-b-2 border-primary text-primary",
        @active_tab != "profile" && \
          "text-muted-foreground hover:text-foreground"
      ]}
    >
      Profile
    </button>
  </nav>
</div>

<div class="p-6 rounded-lg border border-border">
  <div :if={@active_tab == "profile"}>
    Profile content here...
  </div>
</div>

Tab Navigation

Pill-style tab navigation for a different visual style.

<nav class="flex gap-2 p-1 rounded-lg bg-muted w-fit">
  <button
    :for={{id, label} <- [{"overview", "Overview"}, ...]}
    phx-click="switch_tab"
    phx-value-tab={id}
    class={[
      "px-4 py-2 text-sm font-medium rounded-md",
      @active_tab == id && \
        "bg-background text-foreground shadow-sm",
      @active_tab != id && \
        "text-muted-foreground hover:text-foreground"
    ]}
  >
    {label}
  </button>
</nav>

Colocated Hooks

Example of using colocated hooks with tabs for client-side interactions.

This example demonstrates Phoenix LiveView's colocated hooks feature, allowing JavaScript hooks to be defined directly in the template. Click the button to trigger client-side logging.

<div id="tab-hok" phx-hook=".TabHook">
  <.button phx-click="incr">
    Count: {@count}
  </.button>
</div>

<script :type={Phoenix.LiveView.ColocatedHook} name=".TabHook">
  export default {
    mounted() {
      console.log("hook mounted")
    },
    beforeUpdate(from, to) {
      console.log("hook updated", {from, to})
    }
  }
</script>

Implementation Notes

Tips for building tab interfaces with PUI components.

State Management

Use LiveView state (@active_tab) to track the currently selected tab. Send phx-click events to switch tabs.

Accessibility

Include aria-label="Tabs" on the navigation container and use proper button elements for keyboard navigation support.

Styling

Use Tailwind's conditional classes with the class attribute and the && operator for active/inactive states.