PhiaUi.Components.EmptyState (phia_ui v0.1.17)

Copy Markdown View Source

Empty state component for displaying when a list, table, or view has no data.

Use this component to replace empty tables, lists, or content areas with a helpful, visually consistent message that guides users toward a next action. Pure HEEx — no JavaScript required.

Slots

SlotRequiredPurpose
:iconNoLeading illustration icon (e.g. <.icon name="inbox">)
:titleYesPrimary heading for the empty state
:descriptionNoSupporting text with additional context
:actionNoCall-to-action button, link, or other control

Basic example

<.empty>
  <:icon><.icon name="inbox" size={:lg} /></:icon>
  <:title>No notifications</:title>
  <:description>You're all caught up! Check back later.</:description>
</.empty>

With a call-to-action

<.empty>
  <:icon><.icon name="folder-open" size={:lg} /></:icon>
  <:title>No projects yet</:title>
  <:description>Get started by creating your first project.</:description>
  <:action>
    <.button phx-click="new_project">
      <.icon name="plus" size={:sm} />
      New Project
    </.button>
  </:action>
</.empty>

Inside a table (colspan)

Replace the table body when there are no rows. Use colspan to span all columns so the empty state is centred across the full table width:

<tbody>
  <%= if @posts == [] do %>
    <tr>
      <td colspan="5" class="p-0">
        <.empty>
          <:icon><.icon name="file-text" size={:lg} /></:icon>
          <:title>No posts published</:title>
          <:description>Publish your first post to see it here.</:description>
          <:action>
            <.button phx-click="new_post">Write a post</.button>
          </:action>
        </.empty>
      </td>
    </tr>
  <% else %>
    <%= for post <- @posts do %>
      <tr>...</tr>
    <% end %>
  <% end %>
</tbody>

Search results with no matches

<.empty>
  <:icon><.icon name="search-x" size={:lg} /></:icon>
  <:title>No results for "{@search_query}"</:title>
  <:description>Try a different search term or remove your filters.</:description>
  <:action>
    <.button variant={:outline} phx-click="clear_search">Clear search</.button>
  </:action>
</.empty>

Error / access denied state

<.empty>
  <:icon><.icon name="shield-off" size={:lg} /></:icon>
  <:title>Access restricted</:title>
  <:description>You don't have permission to view this content.</:description>
  <:action>
    <.button navigate={~p"/dashboard"}>Go to Dashboard</.button>
  </:action>
</.empty>

Summary

Functions

Renders a centred empty state with optional icon, title, description, and action.

Functions

empty(assigns)

Renders a centred empty state with optional icon, title, description, and action.

All slots are purely optional except :title. The layout is a vertical flex column centred both horizontally and vertically inside the container.

Attributes

  • class (:string) - Additional CSS classes applied to the outer container <div>. Use min-h-[N] to control minimum height. Defaults to nil.
  • Global attributes are accepted. HTML attributes forwarded to the root <div> element.

Slots

  • icon - Optional leading icon or illustration. Rendered in text-muted-foreground with bottom margin.
  • title (required) - Primary heading text for the empty state. Rendered as a bold <h3>.
  • description - Optional supporting text with additional context. Rendered in muted small type, max width constrained for readability.
  • action - Optional call-to-action area. Place a button, link, or any interactive element here.