Composition Guide
This guide covers how to compose Faststrap components to build complex UIs.
Composing Cards
from faststrap import Card, CardHeader, CardBody, CardFooter, Button, Badge
Card(
CardHeader(
"User Profile",
Badge("Admin", variant="primary"),
),
CardBody(
H4("Jane Doe"),
P("Software Engineer"),
P("San Francisco, CA", cls="text-muted"),
),
CardFooter(
Button("Edit", variant="secondary", outline=True),
Button("Delete", variant="danger"),
),
)
Composing Forms
from faststrap import Form, FormGroup, Input, Select, Checkbox, Button
Form(
FormGroup("Full Name", Input(name="name", required=True)),
FormGroup("Email", Input(name="email", type="email")),
FormGroup("Role", Select(
Option("Admin", value="admin"),
Option("User", value="user"),
name="role",
)),
FormGroup(
Checkbox(name="active", label="Active", checked=True),
label="",
),
Button("Save", type="submit", variant="primary"),
method="post",
action="/users",
)
Composing Layouts
from faststrap import Stack, Cluster, Center, Card
Stack(
# Header with actions
Cluster(
H2("Dashboard"),
Button("Add Item", variant="primary"),
justify="between",
align="center",
),
# Content area
Card(
Card.Body(
# ... content
),
),
gap=3,
)
Nested Layouts
from faststrap import Stack, Cluster, Center, Card
Center(
Stack(
Card(
Card.Header("Login"),
Card.Body(
Form(
FormGroup("Email", Input(name="email", type="email")),
FormGroup("Password", Input(name="password", type="password")),
Button("Sign In", type="submit", variant="primary"),
method="post",
action="/login",
),
),
),
P("Don't have an account?", cls="text-center"),
Cluster(
Button("Sign Up", variant="secondary", href="/register"),
justify="center",
),
gap=3,
),
min_height="100vh",
)
Composing with HTMX
from faststrap import Stack, Card, Button, Toast
Stack(
Card(
Card.Header(
Cluster(
"Tasks",
Button("Add", variant="primary", size="sm",
hx_get="/tasks/new", hx_target="#task-form"),
justify="between",
),
),
Card.Body(
Div(id="task-list"),
Div(id="task-form"),
),
),
gap=3,
)
merge_classes
Use merge_classes when building custom components:
from faststrap import merge_classes
def MyButton(text: str, *, variant: str = "primary", **kwargs):
user_cls = kwargs.pop("cls", "")
base = f"btn btn-{variant}"
return Button(text, cls=merge_classes(base, user_cls), **kwargs)
Bootstrap JS Requirements
Some Faststrap components require Bootstrap's JavaScript to function (modals, dropdowns, tabs, tooltips, etc.). These components are marked with requires_js=True in the component registry. When you use add_bootstrap(app), the JavaScript is automatically included.
Components that require Bootstrap JS include: Accordion, Alert, Carousel, Collapse, Drawer, Dropdown, Modal, Navbar, Popover, Sheet, Tabs, Toast, Tooltip, and others. The full list is available programmatically:
from faststrap import list_component_metadata
js_required = [
meta["name"]
for meta in list_component_metadata()
if meta.get("requires_js")
]
If you are building a custom component that wraps a Bootstrap JS feature, register it with requires_js=True:
from faststrap.core.registry import register
@register(requires_js=True)
def MyCustomModal(...):
...
Slot Class Convention
Faststrap components follow a naming convention for slot customization:
*_cls— CSS class for a specific slot (e.g.,header_cls,body_cls,footer_cls)*_attrs— arbitrary HTML attributes for a specific slot (e.g.,header_attrs)
For example, Card supports:
This convention applies across most composite components. Check the API reference of each component for the specific slot names it supports.
When to Create Custom Components
When to Create Custom Components
Create a custom component when: - You reuse the same composition pattern 3+ times - You need to encapsulate complex logic - You want a clean API for your team
Use composition when: - The pattern is used 1-2 times - The composition is simple - You want flexibility