PureAdmin.Components.KpiDetail (PureAdmin v1.2.0)

Copy Markdown View Source

Shared types + helpers for KPI hover detail popovers.

Mirrors kpi-detail.ts from @keenmate/svelte-pure-admin. Used by every KPI tile / row module (kpi_tile/1, kpi_strip_row/1, kpi_sparkline_row/1, kpi_bento_tile/1, kpi_hero_main/1, kpi_hero_side/1, kpi_gauge/1, kpi_editorial_tile/1) to build the canonical popover body from typed props — Current / Previous / Δ absolute / Δ percent / Target — without forcing consumers to hand-author <dl> markup.

The detail popover itself is rendered by PureAdmin.Components.Kpi.kpi_detail/1. This module supplies the row data + sentiment colour mapping.

Summary

Types

Delta / sentiment modifier names used across KPI components. Covers every variant scale upstream emits: strip / editorial (up-strong / down-strong), sparkline / terminal (very-positive / very-negative), gauge (warning).

A single popover row: dt/dd pair with optional sentiment colour on the <dd>.

Sentiment class for a popover <dd>. Maps to the matching .pos / .neg / .warn rule inside .pa-kpi-detail (upstream _kpi-base.scss).

Functions

Build the canonical detail-popover rows from a tile / row's typed props.

Convert an underscored sentiment / variant atom or string to the kebab-case CSS modifier name upstream emits (very_positivevery-positive).

Map a delta variant modifier name onto the popover sentiment class.

CSS class for a <dd> cell given a sentiment.

Types

delta_variant()

@type delta_variant() :: String.t()

Delta / sentiment modifier names used across KPI components. Covers every variant scale upstream emits: strip / editorial (up-strong / down-strong), sparkline / terminal (very-positive / very-negative), gauge (warning).

row()

@type row() :: %{
  :label_text => String.t(),
  :value_text => String.t(),
  optional(:sentiment) => sentiment()
}

A single popover row: dt/dd pair with optional sentiment colour on the <dd>.

sentiment()

@type sentiment() :: :pos | :neg | :warn | nil

Sentiment class for a popover <dd>. Maps to the matching .pos / .neg / .warn rule inside .pa-kpi-detail (upstream _kpi-base.scss).

Functions

build_auto_rows(opts)

@spec build_auto_rows(keyword() | map()) :: [row()]

Build the canonical detail-popover rows from a tile / row's typed props.

Row order is Current → Previous → Δ absolute → Δ percent → Target. Each row is skipped when its source field is nil.

Accepts a keyword list (or map) with optional fields:

  • :prefix_text — currency / scale prefix shown before the Current value
  • :value_text — Current numeric value
  • :unit_text — unit suffix shown after the Current value
  • :previous_value_text — bare previous value (e.g. "84.2%")
  • :delta_absolute_text — absolute delta (e.g. "+4.4pp")
  • :delta_absolute_sentiment — sentiment override for the Δ absolute row
  • :delta_text — Δ percent (e.g. "+5.2%")
  • :delta_sentiment — sentiment for the Δ percent row
  • :target_text — target value (e.g. "90.0%")

Examples

iex> KpiDetail.build_auto_rows(
...>   value_text: "88.6",
...>   unit_text: "%",
...>   previous_value_text: "84.2%",
...>   delta_text: "+5.2%",
...>   delta_sentiment: :pos,
...>   target_text: "90.0%"
...> )
[
  %{label_text: "Current", value_text: "88.6%"},
  %{label_text: "Previous", value_text: "84.2%"},
  %{label_text: "Δ percent", value_text: "+5.2%", sentiment: :pos},
  %{label_text: "Target", value_text: "90.0%"}
]

dasherize(value)

@spec dasherize(String.t() | atom() | nil) :: String.t() | nil

Convert an underscored sentiment / variant atom or string to the kebab-case CSS modifier name upstream emits (very_positivevery-positive).

delta_to_sentiment(v)

@spec delta_to_sentiment(delta_variant() | nil) :: sentiment()

Map a delta variant modifier name onto the popover sentiment class.

Returns nil when the variant has no sentiment mapping (e.g. "neutral").

Examples

iex> KpiDetail.delta_to_sentiment("positive")
:pos

iex> KpiDetail.delta_to_sentiment("very_negative")
:neg

iex> KpiDetail.delta_to_sentiment("warning")
:warn

iex> KpiDetail.delta_to_sentiment("neutral")
nil

sentiment_class(arg1)

@spec sentiment_class(sentiment()) :: String.t() | nil

CSS class for a <dd> cell given a sentiment.