Skip to content

CalendarDatePicker

CalendarDatePicker is a single-date picker built around the native HTML date input. It is intentionally lightweight and works without custom JavaScript.

Use DateRangePicker when users need a start and end date. Use CalendarDatePicker when users choose one date, such as a publish date, appointment date, or filter date.

Import

from faststrap import CalendarDatePicker

Basic Usage

CalendarDatePicker(
    "publish_date",
    label="Publish date",
    value="2026-05-07",
)

Date Limits

CalendarDatePicker(
    "appointment_date",
    label="Appointment date",
    min_date="2026-05-01",
    max_date="2026-05-31",
)

HTMX Filtering

CalendarDatePicker(
    "day",
    label="Activity day",
    endpoint="/activity",
    hx_target="#activity-feed",
    auto=True,
    push_url=True,
)

When auto=True, the picker submits after the selected date changes.

With Clear Button

CalendarDatePicker(
    "due_date",
    label="Due date",
    clear_label="Clear",
)

Parameters

Param Type Default Description
name str "date" Input name.
label str "Date" Label shown above the date input.
value str \| None None Initial date in YYYY-MM-DD format.
min_date str \| None None Earliest selectable date.
max_date str \| None None Latest selectable date.
endpoint str \| None None Optional form/HTMX endpoint.
method get \| post "get" Submission method.
auto bool False Submit on date change when an endpoint is present.
apply_label str \| None "Apply" Submit button label. Set to None to hide.
clear_label str \| None None Optional reset button label.
hx_target str \| None None HTMX target for responses.
hx_swap str \| None "outerHTML" HTMX swap style.
push_url bool False Whether HTMX should push the URL.
input_cls / form_cls str \| None None Styling hooks.
**kwargs Any Extra wrapper attributes.

faststrap.components.forms.calendar_date_picker.CalendarDatePicker(name='date', *, label='Date', value=None, min_date=None, max_date=None, endpoint=None, method='get', auto=False, apply_label='Apply', clear_label=None, hx_target=None, hx_swap='outerHTML', push_url=False, input_cls=None, form_cls=None, **kwargs)

Render a single date picker around the native HTML date input.

Source code in src/faststrap/components/forms/calendar_date_picker.py
@register(category="forms")
@beta
def CalendarDatePicker(
    name: str = "date",
    *,
    label: str = "Date",
    value: str | None = None,
    min_date: str | None = None,
    max_date: str | None = None,
    endpoint: str | None = None,
    method: CalendarMethod = "get",
    auto: bool = False,
    apply_label: str | None = "Apply",
    clear_label: str | None = None,
    hx_target: str | None = None,
    hx_swap: str | None = "outerHTML",
    push_url: bool = False,
    input_cls: str | None = None,
    form_cls: str | None = None,
    **kwargs: Any,
) -> Div:
    """Render a single date picker around the native HTML date input."""
    if method not in {"get", "post"}:
        msg = f"method must be 'get' or 'post', got {method!r}"
        raise ValueError(msg)

    user_cls = kwargs.pop("cls", "")
    attrs: dict[str, Any] = {
        "cls": merge_classes("faststrap-calendar-date-picker", user_cls),
        "data_fs_calendar_date_picker": "true",
    }
    attrs.update(convert_attrs(kwargs))

    date_input = Input(
        name,
        input_type="date",
        label=label,
        value=value,
        min=min_date,
        max=max_date,
        cls=input_cls,
    )

    form_attrs: dict[str, Any] = {
        "method": method,
        "cls": merge_classes("d-flex flex-wrap align-items-end gap-2", form_cls),
    }
    if endpoint:
        form_attrs["action"] = endpoint
        form_attrs[f"hx_{method}"] = endpoint
        if hx_target:
            form_attrs["hx_target"] = hx_target
        if hx_swap:
            form_attrs["hx_swap"] = hx_swap
        if push_url:
            form_attrs["hx_push_url"] = "true"
        if auto:
            form_attrs["hx_trigger"] = "change delay:300ms"

    controls: list[Any] = [date_input]
    if apply_label:
        controls.append(Button(apply_label, type="submit", variant="primary"))
    if clear_label:
        controls.append(Button(clear_label, type="reset", variant="secondary", outline=True))

    return Div(FTForm(*controls, **convert_attrs(form_attrs)), **attrs)