From 6dd25a311152abf3e0938c9a59e54c98e2a327a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orhun=20Parmaks=C4=B1z?= Date: Sun, 1 Dec 2024 14:12:06 +0300 Subject: [PATCH] docs(widgets): add example for calendar (#1532) related #1512 --- ratatui-widgets/examples/calendar.rs | 92 ++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 ratatui-widgets/examples/calendar.rs diff --git a/ratatui-widgets/examples/calendar.rs b/ratatui-widgets/examples/calendar.rs new file mode 100644 index 00000000..ceececf4 --- /dev/null +++ b/ratatui-widgets/examples/calendar.rs @@ -0,0 +1,92 @@ +//! # [Ratatui] `Calendar` example +//! +//! The latest version of this example is available in the [widget examples] folder in the +//! repository. +//! +//! Please note that the examples are designed to be run against the `main` branch of the Github +//! repository. This means that you may not be able to compile with the latest release version on +//! crates.io, or the one that you have installed locally. +//! +//! See the [examples readme] for more information on finding examples that match the version of the +//! library you are using. +//! +//! [Ratatui]: https://github.com/ratatui/ratatui +//! [widget examples]: https://github.com/ratatui/ratatui/blob/main/ratatui-widgets/examples +//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md + +use color_eyre::Result; +use ratatui::{ + crossterm::event::{self, Event}, + layout::{Constraint, Layout, Rect}, + style::{Color, Modifier, Style, Stylize}, + text::{Line, Span}, + widgets::{Block, Padding}, + DefaultTerminal, Frame, +}; +use ratatui_widgets::calendar::{CalendarEventStore, Monthly}; +use time::{Date, Month, OffsetDateTime}; + +fn main() -> Result<()> { + color_eyre::install()?; + let terminal = ratatui::init(); + let result = run(terminal); + ratatui::restore(); + result +} + +/// Run the application. +fn run(mut terminal: DefaultTerminal) -> Result<()> { + loop { + terminal.draw(draw)?; + if matches!(event::read()?, Event::Key(_)) { + break Ok(()); + } + } +} + +/// Draw the UI with 2 monthly calendars side by side. +fn draw(frame: &mut Frame) { + let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1); + let horizontal = Layout::horizontal([Constraint::Percentage(50); 2]).spacing(1); + let [top, main] = vertical.areas(frame.area()); + let [left, right] = horizontal.areas(main); + + let title = Line::from_iter([ + Span::from("Calendar Widget").bold(), + Span::from(" (Press 'q' to quit)"), + ]); + frame.render_widget(title.centered(), top); + + render_current_month(frame, left); + render_styled_month(frame, right); +} + +/// Render the current month calendar. +fn render_current_month(frame: &mut Frame, area: Rect) { + let date = OffsetDateTime::now_utc().date(); + + let monthly = Monthly::new( + date, + CalendarEventStore::today(Style::default().red().bold()), + ) + .block(Block::new().padding(Padding::new(0, 0, 2, 0))) + .show_month_header(Modifier::BOLD) + .show_weekdays_header(Modifier::ITALIC); + frame.render_widget(monthly, area); +} + +/// Render an arbitrary month with more styles. +fn render_styled_month(frame: &mut Frame, area: Rect) { + // Release date of the movie Ratatouille. + let date = Date::from_calendar_date(2007, Month::June, 29).unwrap(); + + let mut event_store = CalendarEventStore::today(Style::default().red().bold()); + event_store.add(date, Style::default().blue().italic()); + + let monthly = Monthly::new(date, event_store) + .show_surrounding(Modifier::DIM) + .show_month_header(Modifier::BOLD) + .show_weekdays_header(Style::default().bold().green()) + .default_style(Style::default().bold().bg(Color::Rgb(50, 50, 50))); + frame.render_widget(monthly, area); +}