PhiaUi.Components.MetricGrid (phia_ui v0.1.17)

Copy Markdown View Source

Responsive CSS Grid wrapper for stat_card/1 KPI widgets.

metric_grid/1 takes care of the responsive column math so you do not have to hand-craft Tailwind breakpoint classes for every dashboard. Pass the desired maximum column count and the grid automatically collapses to fewer columns on smaller screens.

Column breakpoints

:colsMobile (< sm)Tablet (sm+)Desktop (lg+)
1111
2122
3123
4124

The single-column mobile layout ensures that stat cards never appear side-by-side when they would be too narrow to be readable.

Basic example

<.metric_grid cols={4}>
  <.stat_card title="Revenue"    value="$48,295" trend={:up}      trend_value="+18%" description="vs. last quarter" />
  <.stat_card title="New Users"  value="3,847"   trend={:up}      trend_value="+7%"  description="vs. last month"   />
  <.stat_card title="Churn Rate" value="2.4%"    trend={:down}    trend_value="-0.3%" description="vs. last month"  />
  <.stat_card title="NPS"        value="62"      trend={:neutral} trend_value="→"    description="no change"        />
</.metric_grid>

Three-column variant

When a fourth metric is not available or the layout needs more breathing room, use cols={3}:

<.metric_grid cols={3}>
  <.stat_card title="MRR"          value="$24,150" trend={:up}   trend_value="+11%" />
  <.stat_card title="Active Users" value="892"     trend={:up}   trend_value="+5%"  />
  <.stat_card title="Avg Session"  value="4m 32s"  trend={:down} trend_value="-8s"  />
</.metric_grid>

Mixed content

metric_grid/1 is a plain CSS Grid wrapper — any card-shaped element works inside it, not just stat_card/1:

<.metric_grid cols={3}>
  <.stat_card title="Revenue" value="$12,345" />
  <.chart_shell title="Trend" min_height="120px">
    <.phia_chart id="mini-chart" type={:area} series={@series} labels={@labels} height="120px" />
  </.chart_shell>
  <.stat_card title="NPS" value="68" trend={:up} trend_value="+4" />
</.metric_grid>

Integration with Shell

Place metric_grid/1 directly inside the <main> of shell/1:

<main class="overflow-y-auto p-6 space-y-6">
  <.metric_grid cols={4}>
    <%= for kpi <- @kpis do %>
      <.stat_card
        title={kpi.label}
        value={kpi.formatted_value}
        trend={kpi.trend}
        trend_value={kpi.trend_text}
        description={kpi.period}
      />
    <% end %>
  </.metric_grid>
</main>

Summary

Functions

Renders a responsive CSS Grid wrapper for dashboard KPI cards.

Functions

metric_grid(assigns)

Renders a responsive CSS Grid wrapper for dashboard KPI cards.

The grid uses gap-4 between cells. Add vertical spacing between this component and others using a wrapper class or a space-y-* parent.

Example

<.metric_grid cols={4}>
  <.stat_card title="Revenue" value="$12,345" trend={:up} trend_value="+8%" />
  <.stat_card title="Users"   value="1,024"   trend={:up} trend_value="+3%" />
  <.stat_card title="Churn"   value="2.1%"    trend={:down} trend_value="-0.4%" />
  <.stat_card title="NPS"     value="62"       trend={:neutral} trend_value="→" />
</.metric_grid>

Attributes

  • cols (:integer) - Maximum number of columns in the grid (1–4). The grid automatically collapses to fewer columns at smaller breakpoints:

    • Mobile (< sm): always 1 column
    • Tablet (sm+): up to 2 columns
    • Desktop (lg+): up to the specified :cols value

    Defaults to 4. Must be one of 1, 2, 3, or 4.

  • class (:string) - Additional CSS classes for the grid wrapper (e.g. mt-6 for vertical spacing). Defaults to nil.

  • Global attributes are accepted. HTML attributes forwarded to the wrapper div.

Slots

  • inner_block (required) - stat_card/1 components or other card-shaped children to lay out in the grid.