DateField#

A date input field with locale-aware display formatting and an optional calendar picker button. Supports single-date and date-range selection modes.

DateField — light theme DateField — dark theme

Usage#

Basic usage#

bs.DateField(label="Select a date")

Display formats#

The value_format= parameter controls how dates are displayed in the field. Any ICU date format pattern or named preset is accepted.

bs.DateField(value=today, value_format="longDate")     # January 15, 2025
bs.DateField(value=today, value_format="shortDate")    # 1/15/25
bs.DateField(value=today, value_format="monthAndYear") # January 2025
bs.DateField(value=today, value_format="yyyy-MM-dd")   # 2025-01-15
DateField formats — light theme DateField formats — dark theme

Range mode#

Set selection_mode='range' to let the user pick a start and end date. The entry becomes read-only in this mode — dates must be chosen via the picker. value returns a (start, end) tuple of date objects.

df = bs.DateField(
    selection_mode="range",
    range_start=date(2025, 1, 1),
    range_end=date(2025, 1, 31),
    label="Date range",
)
start, end = df.value  # tuple[date, date]
DateField range mode — light theme DateField range mode — dark theme

Date constraints#

Use min_date=, max_date=, or disabled_dates= to restrict which dates the picker shows as selectable.

from datetime import date, timedelta

today = date.today()
bs.DateField(
    label="Booking date",
    min_date=today,
    max_date=today + timedelta(days=30),
    disabled_dates=[today + timedelta(days=7)],
)

min_date, max_date, and disabled_dates are also live properties — assign to them to update the constraints (the change takes effect the next time the picker opens):

df.min_date = date.today()          # no past dates
df.disabled_dates = booked_dates

Reactive binding#

Pass a Signal[str] via textsignal= to keep the field text in sync with application state.

date_sig = bs.Signal("")
bs.DateField(label="Pick a date", textsignal=date_sig)
bs.Label(textsignal=date_sig, accent="secondary")

Handling changes#

on_change() fires whenever the selected date changes — whether by keyboard input, picker selection, or value= assignment.

df = bs.DateField(label="Appointment")
df.on_change(lambda e: print("Selected:", df.value))

States#

bs.DateField(value=today, label="Normal")
bs.DateField(value=today, label="Read only", read_only=True)
bs.DateField(value=today, label="Disabled",  disabled=True)
DateField states — light theme DateField states — dark theme

Widget sizing#

All widgets accept self-placement kwargs via **kwargs. The parent container determines which options apply — stack-based parents use stack kwargs, grid-based parents use grid kwargs. Unrecognised keys are silently ignored.

Stack#

Used inside VStack, HStack, App, and other stack containers.

fill

Fill direction: 'x', 'y', 'both', or 'none'.

expand

Grow to consume extra space in the parent. True or False.

anchor

Alignment when the widget does not fill the available slot: 'n', 's', 'e', 'w', 'center', 'nw', etc.

margin

External spacing in pixels. Accepts an integer (equal on all sides), a 2-tuple (horizontal, vertical), or a 4-tuple (left, top, right, bottom).

margin_x

Horizontal external spacing (left and right). Accepts an integer or a 2-tuple (left, right) for asymmetric spacing. Overrides the horizontal component of margin=.

margin_y

Vertical external spacing (top and bottom). Accepts an integer or a 2-tuple (top, bottom) for asymmetric spacing. Overrides the vertical component of margin=.

Grid#

Used inside a Grid container.

row / column

Zero-based row and column indices.

rowspan / columnspan

Number of rows or columns to span.

sticky

Alignment and fill within the grid cell. Any combination of 'n', 's', 'e', 'w' — e.g. 'ew' stretches horizontally, 'nsew' fills the entire cell.

margin

External spacing in pixels. Accepts an integer, a 2-tuple (horizontal, vertical), or a 4-tuple (left, top, right, bottom).

margin_x

Horizontal external spacing. Accepts an integer or (left, right).

margin_y

Vertical external spacing. Accepts an integer or (top, bottom).

See also#

API#

The complete reference for DateField lives on the Widgets API page. At a glance:

DateField

A date input field with an optional calendar picker button.

Full Example#

 1
 2with bs.App(title="DateField Demo", padding=20, gap=16) as app:
 3
 4    # Basic usage
 5    bs.Label("Basic", font="heading-sm")
 6    bs.DateField(label="Select a date")
 7
 8    # Date format presets
 9    bs.Label("Display Formats", font="heading-sm")
10    today = date.today()
11    bs.DateField(value=today, label="Long date (default)",   value_format="longDate")
12    bs.DateField(value=today, label="Short date",            value_format="shortDate")
13    bs.DateField(value=today, label="Month and year",        value_format="monthAndYear")
14
15    # Range mode
16    bs.Label("Range Mode", font="heading-sm")
17    bs.DateField(
18        selection_mode="range",
19        range_start=date(today.year, today.month, 1),
20        range_end=today,
21        label="Date range",
22        message="Select a start and end date.",
23    )
24
25    # Min / max date constraints
26    bs.Label("Constrained Dates", font="heading-sm")
27    from datetime import timedelta
28    bs.DateField(
29        label="Booking date",
30        message="Must be within the next 30 days.",
31        min_date=today,
32        max_date=today + timedelta(days=30),
33    )
34
35    # Reactive binding
36    bs.Label("Reactive Binding", font="heading-sm")
37    date_sig = bs.Signal("")
38    df = bs.DateField(label="Pick a date", textsignal=date_sig)
39    bs.Label(textsignal=date_sig, accent="secondary")
40
41    # States
42    bs.Label("States", font="heading-sm")
43    bs.DateField(value=today, label="Normal")
44    bs.DateField(value=today, label="Read only", read_only=True)
45    bs.DateField(value=today, label="Disabled",  disabled=True)
46
47    # Handling changes
48    bs.Label("Handling Changes", font="heading-sm")
49    last = bs.Signal("(none)")
50    picker = bs.DateField(label="Choose a date")
51    picker.on_change(lambda e: last.set(str(picker.value)))
52    bs.Label(textsignal=last, accent="secondary")
53
54    # Validation
55    bs.Label("Validation", font="heading-sm")
56    validated = bs.DateField(label="Required date", required=True)
57    with bs.HStack(gap=8):
58        bs.Button("Validate", on_click=lambda: validated.validate())
59
60app.run()