Examples
Date Picker¶
from textual.app import App, ComposeResult
from textual_timepiece.pickers import DatePicker
class DatePickerApp(App[None]):
def compose(self) -> ComposeResult:
yield DatePicker()
def on_date_picker_date_changed(self, message: DatePicker.DateChanged) -> None:
message.stop()
if message.date:
msg = f"Date changed to {message.date.format_common_iso()}."
else:
msg = "Date was removed."
self.notify(msg)
if __name__ == "__main__":
DatePickerApp().run()
Date Range¶
from textual.app import App, ComposeResult
from textual_timepiece.pickers import DateRangePicker
from whenever import Date, weeks
class DateRangeApp(App[None]):
def compose(self) -> ComposeResult:
yield DateRangePicker(Date(2025, 2, 5), date_range=weeks(1))
if __name__ == "__main__":
DateRangeApp().run()
Date Select¶
from textual.app import App, ComposeResult
from textual import on
from textual.widgets import Label
from textual_timepiece.pickers import DatePicker, DateSelect
from whenever import Date, days
class DateSelectApp(App[None]):
def compose(self) -> ComposeResult:
yield DateSelect(Date.today_in_system_tz(), date_range=days(3))
yield Label(variant="accent")
@on(DateSelect.DateChanged)
@on(DateSelect.EndDateChanged)
def on_date_changed(self, message: DateSelect.DateChanged | DateSelect.EndDateChanged) -> None:
new_content = f" {message.widget.date} - {message.widget.end_date} "
self.query_one(Label).update(new_content)
if __name__ == "__main__":
DateSelectApp().run()
DateTime Range Picker¶
from textual.app import App, ComposeResult
from textual_timepiece.pickers import DateTimeRangePicker
from textual import on
from whenever import Date, SystemDateTime
class DTPickerRangeApp(App[None]):
def on_mount(self) -> None:
self.query_one(DateTimeRangePicker).disable_end()
self.set_timer(10, self.stop_timer)
self.notify("Started timer!")
def compose(self) -> ComposeResult:
yield DateTimeRangePicker(SystemDateTime.now().local())
def stop_timer(self) -> None:
dt_range = self.query_one(DateTimeRangePicker).disable_end(disable=False)
dt_range.end_dt = SystemDateTime.now().local()
if __name__ == "__main__":
DTPickerRangeApp().run()
Activity Heatmap¶
import random
from collections import defaultdict
from textual.app import App, ComposeResult
from textual_timepiece.activity_heatmap import ActivityHeatmap, HeatmapManager
class ActivityApp(App[None]):
def _on_heatmap_manager_year_changed(
self,
message: HeatmapManager.YearChanged,
) -> None:
message.stop()
self.set_heatmap_data(message.year)
def retrieve_data(self, year: int) -> ActivityHeatmap.ActivityData:
"""Placeholder example on how the data could be generated."""
random.seed(year)
template = ActivityHeatmap.generate_empty_activity(year)
return defaultdict(
lambda: 0,
{
day: random.randint(6000, 20000)
for week in template
for day in week
if day
},
)
def set_heatmap_data(self, year: int) -> None:
"""Sets the data based on the current data."""
self.query_one(ActivityHeatmap).values = self.retrieve_data(year)
def _on_mount(self) -> None:
self.set_heatmap_data(2025)
def compose(self) -> ComposeResult:
yield HeatmapManager(2025)
if __name__ == "__main__":
ActivityApp().run()
Single Line Picker¶
from textual.app import App, ComposeResult
from textual_timepiece.pickers import DateTimeDurationPicker
from whenever import Date, SystemDateTime, weeks
class MiniPickerApp(App[None]):
def compose(self) -> ComposeResult:
yield DateTimeDurationPicker(SystemDateTime.now().local(), classes="mini")
if __name__ == "__main__":
MiniPickerApp().run()