Skip to main content
The Calendar component displays a monthly calendar view for selecting dates.

Basic Usage

use freya::prelude::*;

fn app() -> impl IntoElement {
    let mut selected = use_state(|| None::<CalendarDate>);
    let mut view_date = use_state(CalendarDate::now);
    
    Calendar::new()
        .selected(selected())
        .view_date(view_date())
        .on_change(move |date| selected.set(Some(date)))
        .on_view_change(move |date| view_date.set(date))
}

CalendarDate

The CalendarDate struct represents a date:
pub struct CalendarDate {
    pub year: i32,
    pub month: u32,  // 1-12
    pub day: u32,    // 1-31
}

impl CalendarDate {
    pub fn new(year: i32, month: u32, day: u32) -> Self
    pub fn now() -> Self  // Current local date
}

Properties

selected
Option<CalendarDate>
Currently selected date (if any)
view_date
CalendarDate
default:"CalendarDate::now()"
The month/year currently being viewed
week_start
WeekStart
default:"WeekStart::Monday"
First day of the week: Monday or Sunday
on_change
EventHandler<CalendarDate>
Callback fired when a date is selected
on_view_change
EventHandler<CalendarDate>
Callback fired when navigating between months
theme
CalendarThemePartial
Custom theme for styling

Week Start Day

Choose whether weeks start on Sunday or Monday:
Calendar::new()
    .week_start(WeekStart::Sunday)
    // ...

Complete Example

Date picker with display:
use freya::prelude::*;

fn app() -> impl IntoElement {
    let mut selected = use_state(|| None::<CalendarDate>);
    let mut view_date = use_state(CalendarDate::now);
    
    rect()
        .spacing(16.)
        .child(
            Calendar::new()
                .selected(selected())
                .view_date(view_date())
                .on_change(move |date| selected.set(Some(date)))
                .on_view_change(move |date| view_date.set(date))
        )
        .child(
            match selected() {
                Some(date) => format!(
                    "Selected: {}/{}/{}",
                    date.day, date.month, date.year
                ),
                None => "No date selected".to_string(),
            }
        )
}
Combine with a popup for a compact date picker:
let mut show_calendar = use_state(|| false);
let mut selected = use_state(|| None::<CalendarDate>);
let mut view_date = use_state(CalendarDate::now);

rect()
    .spacing(8.)
    .child(
        Button::new()
            .on_press(move |_| show_calendar.toggle())
            .child(match selected() {
                Some(date) => format!("{}/{}/{}", date.day, date.month, date.year),
                None => "Select date".to_string(),
            })
    )
    .maybe_child(show_calendar().then(|| {
        rect()
            .background(Color::WHITE)
            .shadow(Shadow::new().blur(10.).color((0, 0, 0, 0.2)))
            .padding(8.)
            .corner_radius(8.)
            .child(
                Calendar::new()
                    .selected(selected())
                    .view_date(view_date())
                    .on_change(move |date| {
                        selected.set(Some(date));
                        show_calendar.set(false);
                    })
                    .on_view_change(move |date| view_date.set(date))
            )
    }))

Date Range Picker

Implement a range picker with two calendars:
let mut start_date = use_state(|| None::<CalendarDate>);
let mut end_date = use_state(|| None::<CalendarDate>);

rect()
    .horizontal()
    .spacing(16.)
    .child(
        rect()
            .spacing(8.)
            .child("Start Date")
            .child(
                Calendar::new()
                    .selected(start_date())
                    .on_change(move |date| start_date.set(Some(date)))
            )
    )
    .child(
        rect()
            .spacing(8.)
            .child("End Date")
            .child(
                Calendar::new()
                    .selected(end_date())
                    .on_change(move |date| end_date.set(Some(date)))
            )
    )
Calendar includes navigation arrows to move between months:
  • Left arrow: Previous month
  • Right arrow: Next month
The on_view_change callback is triggered when navigating.

Theming

Customize calendar appearance:
Calendar::new()
    .theme(CalendarThemePartial {
        background: Some(Color::from_rgb(250, 250, 255)),
        day_selected_background: Some(Color::from_rgb(100, 100, 255)),
        day_hover_background: Some(Color::from_rgb(220, 220, 255)),
        ..Default::default()
    })

Source

View the full implementation: calendar.rs

Build docs developers (and LLMs) love