Skip to content

Result Card

ResultCard presents the outcome of an action: saved settings, failed submissions, empty flows, or follow-up next steps.

It is intentionally small, semantic, and HTMX-friendly. Success and info states use role="status"; warning and error states use role="alert".

Import

from faststrap import ResultCard, Button

Basic Usage

ResultCard(
    title="Settings saved",
    message="Your preferences have been updated.",
    status="success",
)

Error State

ResultCard(
    title="Could not save",
    message="Please review the highlighted fields and try again.",
    status="error",
)

With Action

ResultCard(
    title="Invite sent",
    message="We emailed the new team member.",
    status="success",
    action=Button("View team", href="/team", variant="primary"),
)

Usage Scenarios

After Form Submission

@app.post("/settings")
def save_settings(...):
    if success:
        return ResultCard(
            title="Settings saved",
            message="Your preferences have been updated.",
            status="success",
            action=Button("Back to dashboard", href="/dashboard"),
        )
    return ResultCard(
        title="Could not save",
        message="Please review the highlighted fields and try again.",
        status="error",
    )

Empty State

ResultCard(
    title="No matching records",
    message="Try adjusting your search or filter criteria.",
    status="info",
    action=Button("Clear filters", variant="secondary"),
)

Customizing With Slot Classes

Slot classes let you restyle parts of the card without wrapping it:

ResultCard(
    title="Experiment finished",
    message="42 runs completed. 3 failed. Full logs attached.",
    status="warning",
    icon="bi-hourglass-split",
    icon_cls="fs-4 text-warning",
    title_cls="fw-semibold",
    message_cls="text-body-secondary",
)

Parameters

Param Type Description
title str Main result title.
message str | None Optional supporting message.
status success | error | warning | info Semantic result state.
icon str | None Bootstrap icon name override.
action Any | None Optional action component.
compact bool Use tighter spacing.
icon_cls str | None Extra classes for the icon slot.
title_cls str | None Extra classes for the title slot.
message_cls str | None Extra classes for the message slot.

Accessibility

  • ResultCard uses role="status" for success/info and role="alert" for warning/error.
  • Ensure action buttons have accessible names.
  • Use compact sparingly when space is constrained and content is minimal.

faststrap.components.display.result_card.ResultCard(title, message=None, *, status='success', icon=None, action=None, compact=False, icon_cls=None, title_cls=None, message_cls=None, **kwargs)

Render a focused result surface for completed actions.

Parameters:

Name Type Description Default
title str

Result heading.

required
message str | None

Optional supporting text.

None
status ResultStatus

Semantic outcome driving color and live-region role.

'success'
icon str | None

Bootstrap icon name override.

None
action Any | None

Optional action element rendered below the text.

None
compact bool

Reduce vertical padding for dense layouts.

False
icon_cls str | None

Extra classes merged onto the icon (e.g. fs-2 to reduce the icon's visual weight).

None
title_cls str | None

Extra classes merged onto the title heading.

None
message_cls str | None

Extra classes merged onto the message paragraph.

None
**kwargs Any

Additional HTML attributes.

{}
Source code in src/faststrap/components/display/result_card.py
@register(category="display")
@beta
def ResultCard(
    title: str,
    message: str | None = None,
    *,
    status: ResultStatus = "success",
    icon: str | None = None,
    action: Any | None = None,
    compact: bool = False,
    icon_cls: str | None = None,
    title_cls: str | None = None,
    message_cls: str | None = None,
    **kwargs: Any,
) -> Div:
    """Render a focused result surface for completed actions.

    Args:
        title: Result heading.
        message: Optional supporting text.
        status: Semantic outcome driving color and live-region role.
        icon: Bootstrap icon name override.
        action: Optional action element rendered below the text.
        compact: Reduce vertical padding for dense layouts.
        icon_cls: Extra classes merged onto the icon (e.g. ``fs-2`` to
            reduce the icon's visual weight).
        title_cls: Extra classes merged onto the title heading.
        message_cls: Extra classes merged onto the message paragraph.
        **kwargs: Additional HTML attributes.
    """
    variant = RESULT_VARIANTS.get(status, "secondary")
    resolved_icon = icon if icon is not None else RESULT_ICONS.get(status)
    user_cls = kwargs.pop("cls", "")

    attrs: dict[str, Any] = {
        "cls": merge_classes(
            "faststrap-result-card card border-0 shadow-sm",
            f"border-start border-4 border-{variant}",
            user_cls,
        ),
        "role": "status" if status in {"success", "info", "neutral"} else "alert",
    }
    attrs.update(convert_attrs(kwargs))

    body_cls = "card-body"
    if compact:
        body_cls = merge_classes(body_cls, "py-3")

    content = []
    if resolved_icon:
        content.append(
            Div(
                Icon(
                    resolved_icon,
                    cls=merge_classes(f"text-{variant} fs-4", icon_cls),
                    aria_hidden="true",
                ),
                cls="flex-shrink-0",
            )
        )

    text_parts: list[Any] = [H5(title, cls=merge_classes("card-title mb-1", title_cls))]
    if message:
        text_parts.append(P(message, cls=merge_classes("card-text text-muted mb-0", message_cls)))
    if action:
        text_parts.append(Div(action, cls="mt-3"))

    content.append(Div(*text_parts, cls="min-w-0"))

    return Div(Div(Div(*content, cls="d-flex gap-3 align-items-start"), cls=body_cls), **attrs)