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

Loading skeleton, empty state, and error state for table components.

These three components cover the three non-data states a table can be in:
loading (skeleton shimmer), empty (no rows match), and error (fetch failed).

## Sub-components

| Function         | Purpose                                        |
|------------------|------------------------------------------------|
| `table_skeleton/1` | Animated shimmer rows while data loads       |
| `table_empty/1`    | Empty state with icon, title, and CTA        |
| `table_error/1`    | Error state with retry action slot           |

## Usage

    <%# Loading state %>
    <%= if @loading do %>
      <.table_skeleton rows={5} cols={4} />
    <% end %>

    <%# Empty state (inside a tbody) %>
    <%= if @rows == [] do %>
      <.table_empty title="No users found" description="Try adjusting your search filters.">
        <:action>
          <.button phx-click="clear_filters" variant={:outline} size={:sm}>Clear filters</.button>
        </:action>
      </.table_empty>
    <% end %>

    <%# Error state (inside a tbody) %>
    <%= if @error do %>
      <.table_error message="Failed to load users.">
        <:action>
          <.button phx-click="retry" size={:sm}>Retry</.button>
        </:action>
      </.table_error>
    <% end %>

# `table_empty`

Renders an empty-state row suitable for use inside a `<tbody>`.

The `<td colspan="100">` trick spans all columns regardless of how many
columns the table has. Works as a drop-in inside any `<tbody>`.

## Example

    <.table_empty
      title="No invoices found"
      description="Create your first invoice to get started."
      icon="file-text"
    >
      <:action>
        <.button phx-click="new_invoice" size={:sm}>New Invoice</.button>
      </:action>
    </.table_empty>

## Attributes

* `title` (`:string`) - Primary heading of the empty state. Defaults to `"No results"`.
* `description` (`:string`) - Optional secondary text beneath the title. Defaults to `nil`.
* `icon` (`:string`) - Lucide icon name for the decorative icon (e.g. `"search"`, `"filter"`, `"inbox"`). Defaults to `"inbox"`.
* `class` (`:string`) - Additional CSS classes for the `<tr>`. Defaults to `nil`.
## Slots

* `action` - Optional CTA placed below the description — typically a button or link.

# `table_error`

Renders an error-state row suitable for use inside a `<tbody>`.

Uses destructive colour tokens to make the error visually distinct from the
empty state. Provide a `retry` action slot to let users recover inline.

## Example

    <.table_error message="Failed to load users. Please try again.">
      <:action>
        <.button phx-click="retry" variant={:outline} size={:sm}>Retry</.button>
      </:action>
    </.table_error>

## Attributes

* `message` (`:string`) - Error message shown in the error state. Defaults to `"Failed to load data"`.
* `class` (`:string`) - Additional CSS classes for the `<tr>`. Defaults to `nil`.
## Slots

* `action` - Optional retry button or recovery action placed below the error message.

# `table_skeleton`

Renders an animated shimmer table skeleton while data is loading.

All cells use `motion-safe:animate-pulse` so users who prefer reduced motion
see static placeholder blocks instead of animation.

## Example

    <.table_skeleton rows={5} cols={4} />

    <%# Wider skeleton with no header %>
    <.table_skeleton rows={8} cols={6} show_header={false} />

## Attributes

* `rows` (`:integer`) - Number of skeleton rows to render. Defaults to `5`.
* `cols` (`:integer`) - Number of skeleton columns to render. Defaults to `4`.
* `show_header` (`:boolean`) - Whether to render a skeleton thead with shimmer header cells. Defaults to `true`.
* `class` (`:string`) - Additional CSS classes for the outer wrapper div. Defaults to `nil`.

---

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