Skip to content

Dashboard Grid

The DashboardGrid component creates a responsive CSS grid layout ideal for dashboards and card-based interfaces.

Quick Start

DashboardGrid(
    StatCard("Revenue", "$12K", "+5%", delta_color="success"),
    StatCard("Users", "1.2K", "+12%"),
    StatCard("Orders", "456", "+3%"),
    cols=3,
)

Usage Scenarios

Auto-Fit Cards

DashboardGrid(
    Card("A"),
    Card("B"),
    Card("C"),
    min_card_width=240,
)

Dense Grid

DashboardGrid(
    Card("A"),
    Card("B"),
    Card("C"),
    Card("D"),
    cols=2,
    dense=True,
)

Custom Gap

DashboardGrid(
    StatCard("CPU", "45%", "+2%"),
    StatCard("RAM", "62%", "-1%"),
    gap=2,
)

Parameter Reference

Parameter Type Default Description
*children Any Required Grid items (typically Card components)
cols int \| None UNSET Fixed number of columns. When None, uses auto-fit with min_card_width.
gap str \| int \| float 1.5 Gap between items ("1.5rem", 16, etc.)
min_card_width str \| int \| float 240 Minimum card width for auto-fit mode
dense bool False Enable dense packing (grid-auto-flow: dense)
**kwargs Any - Additional HTML attributes

Accessibility

  • Grid is purely structural.
  • Content within cards maintains proper heading hierarchy.

API Reference

faststrap.components.layout.dashboard_grid.DashboardGrid(*children, cols=UNSET, gap=1.5, min_card_width=240, dense=False, **kwargs)

Responsive dashboard grid using CSS grid.

Source code in src/faststrap/components/layout/dashboard_grid.py
@register(category="layout")
@beta
def DashboardGrid(
    *children: Any,
    cols: int | None = UNSET,
    gap: str | int | float = 1.5,
    min_card_width: str | int | float = 240,
    dense: bool = False,
    **kwargs: Any,
) -> Div:
    """Responsive dashboard grid using CSS grid."""
    cfg = resolve_defaults(
        "DashboardGrid",
        cols=cols,
        gap=gap,
        min_card_width=min_card_width,
        dense=dense,
    )
    c_cols = cfg.get("cols", cols)
    c_gap = cfg.get("gap", gap)
    c_min_card_width = cfg.get("min_card_width", min_card_width)
    c_dense = cfg.get("dense", dense)

    if c_cols is not None and c_cols < 1:
        msg = f"cols must be >= 1, got {c_cols}"
        raise ValueError(msg)

    style: dict[str, Any] = {
        "display": "grid",
        "gap": _normalize_size(c_gap),
    }

    if c_cols:
        style["grid_template_columns"] = f"repeat({c_cols}, minmax(0, 1fr))"
    else:
        style["grid_template_columns"] = (
            f"repeat(auto-fit, minmax({_normalize_px(c_min_card_width)}, 1fr))"
        )

    if c_dense:
        style["grid_auto_flow"] = "dense"

    user_style = kwargs.pop("style", None)
    if isinstance(user_style, dict):
        style.update(user_style)

    user_cls = kwargs.pop("cls", "")
    wrapper_cls = merge_classes("faststrap-dashboard-grid", user_cls)

    kwargs["style"] = style

    attrs: dict[str, Any] = {"cls": wrapper_cls}
    attrs.update(convert_attrs(kwargs))

    if isinstance(user_style, str) and user_style:
        attrs["style"] = f"{attrs.get('style', '')}; {user_style}".strip("; ")

    return Div(*children, **attrs)