Skip to content

Stat Card

Stat cards are used on dashboards and reports to highlight key metrics. They typically include a title, a value, an optional icon, and a trend indicator (up/down).


Quick Start

Live Preview

Total Revenue

$45,231.89 +20.1%

StatCard(
    title="Total Revenue",
    value="$45,231.89",
    icon=BI("currency-dollar"),
    trend="+20.1%",
    trend_type="up"
)

v0.6.0 Metric Cards

FastStrap also ships specialized dashboard cards:

MetricCard("Revenue", "$128k", delta="+12%", delta_type="up")
TrendCard("Active Users", "9,842", sparkline="<svg></svg>", sparkline_safe=True)
KPICard(
    "KPIs",
    metrics=[("Retention", "84%", "+2%", "up"), ("Churn", "3.1%", "-0.4%", "down")],
)

MetricCard

MetricCard extends StatCard with a compact delta indicator.

MetricCard(
    "Revenue",
    "$128k",
    delta="+12%",
    delta_type="up",
)

TrendCard

TrendCard adds a sparkline slot. Use sparkline_safe=True only with trusted SVG or HTML.

TrendCard(
    "Active Users",
    "9,842",
    sparkline="<svg></svg>",
    sparkline_safe=True,
)

KPICard

KPICard renders multiple metrics inside one card.

KPICard(
    "KPIs",
    metrics=[
        ("Retention", "84%", "+2%", "up"),
        ("Churn", "3.1%", "-0.4%", "down"),
    ],
)

Visual Examples & Use Cases

Use trend_variant="danger" for decreases in metrics.

Live Preview (Negative Trend)

Active Users

1,234 -5%

from last month

StatCard(
    title="Active Users",
    value="1,234",
    trend="-5%",
    trend_type="down",
    icon=BI("people"),
    footer=P("from last month", cls="text-muted small mb-0")
)

2. Branding (Variants)

Apply color to the icon or card borders using the variant argument.

Code & Output

StatCard(..., variant="primary", bg_variant="soft-primary")

Parameter Reference

FastStrap Param Type Description
title str Title of the metric, such as "Total Sales".
value str | int | float The main display number or value.
icon Any | None Optional icon/component slot.
trend str | None Percentage or text indicating change, such as "+12%".
trend_type "up" | "down" | "neutral" Semantic trend color.
delta str | int | float | None Alias for trend, useful when composing KPI-style APIs.
delta_type "up" | "down" | "neutral" | None Alias for trend_type when using delta.
variant str | None Bootstrap card background variant.
inverse bool Use inverse text colors for dark variant cards.
icon_bg str | None Bootstrap class for the icon background.

StatCard also adds the faststrap-stat-card class so apps can theme metric cards consistently.

faststrap.components.display.stat_card.StatCard(title, value, icon=None, trend=None, trend_type='neutral', variant=UNSET, inverse=False, icon_bg=UNSET, delta=None, delta_type=None, **kwargs)

Bootstrap Statistic Card component.

Display a metric with optional icon and trend.

Parameters:

Name Type Description Default
title str

Label for the statistic

required
value str | int | float

The numeric or text value

required
icon Any | None

Icon component to display

None
trend str | None

Trend text (e.g. "+5%")

None
trend_type Literal['up', 'down', 'neutral']

"up" (green), "down" (red), or "neutral" (muted)

'neutral'
variant VariantType | None

Card background variant

UNSET
inverse bool

Invert text colors (white text)

False
icon_bg str | None

Background color class for icon (e.g. "bg-primary-subtle")

UNSET
delta str | int | float | None

Alias for trend, useful for KPI-style APIs

None
delta_type Literal['up', 'down', 'neutral'] | None

Alias for trend_type when using delta

None
**kwargs Any

Additional HTML attributes

{}

Returns:

Type Description
Div

Card component

Examples:

>>> StatCard("Revenue", "$50k", trend="+12%", trend_type="up")
Source code in src/faststrap/components/display/stat_card.py
@register(category="display")
@stable
def StatCard(
    title: str,
    value: str | int | float,
    icon: Any | None = None,
    trend: str | None = None,
    trend_type: Literal["up", "down", "neutral"] = "neutral",
    variant: VariantType | None = UNSET,
    inverse: bool = False,
    icon_bg: str | None = UNSET,
    delta: str | int | float | None = None,
    delta_type: Literal["up", "down", "neutral"] | None = None,
    **kwargs: Any,
) -> Div:
    """Bootstrap Statistic Card component.

    Display a metric with optional icon and trend.

    Args:
        title: Label for the statistic
        value: The numeric or text value
        icon: Icon component to display
        trend: Trend text (e.g. "+5%")
        trend_type: "up" (green), "down" (red), or "neutral" (muted)
        variant: Card background variant
        inverse: Invert text colors (white text)
        icon_bg: Background color class for icon (e.g. "bg-primary-subtle")
        delta: Alias for trend, useful for KPI-style APIs
        delta_type: Alias for trend_type when using delta
        **kwargs: Additional HTML attributes

    Returns:
        Card component

    Examples:
        >>> StatCard("Revenue", "$50k", trend="+12%", trend_type="up")
    """
    user_cls = kwargs.pop("cls", "")
    kwargs["cls"] = merge_classes("faststrap-stat-card", user_cls)

    cfg = resolve_defaults(
        "StatCard",
        trend_type=trend_type,
        variant=variant,
        inverse=inverse,
        icon_bg=icon_bg,
    )
    c_trend_type = cfg.get("trend_type", trend_type)
    c_variant = cfg.get("variant", variant)
    c_inverse = cfg.get("inverse", inverse)
    c_icon_bg = cfg.get("icon_bg", icon_bg)

    if trend is None and delta is not None:
        trend = str(delta)
        c_trend_type = delta_type or c_trend_type

    # Trend logic
    trend_cls = "text-muted"
    if c_trend_type == "up":
        trend_cls = "text-success"
    elif c_trend_type == "down":
        trend_cls = "text-danger"

    trend_el = Span(trend, cls=f"{trend_cls} small fw-bold ms-2") if trend else None

    # Value wrapper
    value_el = H3(value, trend_el, cls="mb-0 fw-bold")

    # Title
    title_cls = "text-muted small text-uppercase fw-semibold"
    if c_inverse:
        title_cls = "text-white-50 small text-uppercase fw-semibold"

    title_el = P(title, cls=title_cls)

    # Icon logic
    icon_el = None
    if icon:
        icon_wrapper_cls = "d-flex align-items-center justify-content-center rounded p-3"
        if c_icon_bg:
            icon_wrapper_cls = f"{icon_wrapper_cls} {c_icon_bg}"
        else:
            icon_wrapper_cls = f"{icon_wrapper_cls} bg-body-tertiary"

        icon_el = Div(icon, cls=icon_wrapper_cls)

    # Layout: Row with col for text, col-auto for icon
    if icon_el:
        body_content = Div(
            Div(title_el, value_el, cls="flex-grow-1"),
            icon_el,
            cls="d-flex align-items-center justify-content-between",
        )
    else:
        body_content = Div(title_el, value_el)

    return Card(body_content, variant=c_variant, inverse=c_inverse, **kwargs)