Date Picker
Rust UI component that displays a date picker.
May2025
Mo | Tu | We | Th | Fr | Sa | Su |
---|---|---|---|---|---|---|
use icons::{ChevronLeft, ChevronRight}; use leptos::prelude::*; use time::{Date, Month}; use crate::components::_coming_soon::date_picker::{ DatePicker, DatePickerCell, DatePickerDay, DatePickerHeader, DatePickerNavButton, DatePickerRow, DatePickerTitle, DatePickerWeekDay, }; use crate::components::_coming_soon::date_picker_state::DatePickerState; // TODO. Normally, with just aria_current=true, classes should be applied. const CLASS_CURRENT: &str = "bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground/90"; #[component] pub fn DemoDatePicker() -> impl IntoView { let start_date = RwSignal::new(Date::from_calendar_date(2025, Month::May, 5).expect("Invalid date")); let end_date = RwSignal::new(Date::from_calendar_date(2025, Month::May, 14).expect("Invalid date")); // Function to handle day selection let handle_day_click = move |day: u8| { if day == 0 { return; } let year = start_date.get().year(); let month = start_date.get().month(); // Create new date for the selected day let new_date = Date::from_calendar_date(year, month, day).expect("Invalid date"); // Determine which date to update based on proximity let current_start = start_date.get().day(); let current_end = end_date.get().day(); if current_start.abs_diff(day) <= current_end.abs_diff(day) { start_date.set(new_date); } else { end_date.set(new_date); } }; view! { <DatePicker> <DatePickerHeader> <DatePickerTitle role="presentation"> {move || start_date.get().month().to_string()} {move || start_date.get().year()} </DatePickerTitle> <div class="flex items-center space-x-1"> <DatePickerNavButton title="previous-month" aria_label="Go to previous month" class="left-1" > <ChevronLeft class="size-4" /> </DatePickerNavButton> <DatePickerNavButton title="next-month" aria_label="Go to next month" class="right-1" > <ChevronRight class="size-4" /> </DatePickerNavButton> </div> </DatePickerHeader> {move || { let year = start_date.get().year(); let month = start_date.get().month(); let start = start_date.get().day(); let end = end_date.get().day(); let days = DatePickerState::calculate_calendar_data(year, month); let rows: Vec<_> = days .chunks(7) .map(|week| { let week_cells = week .iter() .map(|&(day, disabled, outside)| { let is_selected = !disabled && !outside && day >= start && day <= end; let class = if !disabled && (day == start || day == end) { CLASS_CURRENT.to_string() } else { "".to_string() }; view! { <DatePickerCell> <DatePickerDay disabled=disabled aria_selected=is_selected class=class on:click=move |_| { if !disabled && !outside { handle_day_click(day); } } > {day.to_string()} </DatePickerDay> </DatePickerCell> } }) .collect_view(); view! { <DatePickerRow>{week_cells}</DatePickerRow> } }) .collect(); view! { <table class="space-y-1 w-full border-collapse" role="grid"> <thead> <tr class="flex"> <DatePickerWeekDay aria_label="Monday">Mo</DatePickerWeekDay> <DatePickerWeekDay aria_label="Tuesday">Tu</DatePickerWeekDay> <DatePickerWeekDay aria_label="Wednesday">We</DatePickerWeekDay> <DatePickerWeekDay aria_label="Thursday">Th</DatePickerWeekDay> <DatePickerWeekDay aria_label="Friday">Fr</DatePickerWeekDay> <DatePickerWeekDay aria_label="Saturday">Sa</DatePickerWeekDay> <DatePickerWeekDay aria_label="Sunday">Su</DatePickerWeekDay> </tr> </thead> <tbody>{rows}</tbody> </table> } }} </DatePicker> } }
Installation
# Coming soon :)
Usage
// Coming soon 🦀