Files
Ely-GPUI-Components/examples/gallery/pages/calendar/mod.rs
T
ZacharyZhang-NY 48ff348357 Calendar · Agenda and people: an agenda, an event's details, its guests
AgendaView lists the days ahead under their names, whole days first,
then by the hour, and leaves out days with nothing; it rides on
lists::Sections, so a press or an arrow selects and Enter opens. An
empty stretch says nothing is planned.

EventPopover is an event's chip that opens its details: its title in
its hue, when and where, who is asked, and Edit and Delete when the
owner handles them. It opens through Popover::with_opener, which now
hands any element the toggle and keeps focus, placement and every way
out in the popover. AttendeeList counts the answers and lists each
guest with their answer, the organizer first. A hue worn in a row is
now data_display::color_mark, for mail labels and events alike.
2026-09-27 03:35:59 -04:00

116 lines
4.0 KiB
Rust

use ely_gpui_component::{
calendar::Event,
theme::{ActiveTheme, TextSize},
};
use gpui::{
AnyElement, App, Entity, IntoElement, ParentElement, SharedString, Styled, Window, div,
};
use jiff::{Timestamp, ToSpan, civil::Date, tz::TimeZone};
mod months;
mod people;
mod times;
use super::Page;
use crate::{script::Step, ui::keep};
pub const PAGE: Page = Page {
number: 30,
slug: "calendar",
title: "Calendar",
summary: "Days, weeks, months and years, and what happens in them.",
render,
script: SCRIPT,
};
const SCRIPT: &[Step] = &[
Step::DownAt("calendar-month", 285.0, 230.0),
Step::UpAt("calendar-month", 285.0, 230.0),
Step::Key("right"),
Step::Key("down"),
Step::Wait(150),
Step::Shot("month-cursor"),
Step::Key("pagedown"),
Step::Wait(200),
Step::Shot("month-next"),
Step::Key("pageup"),
Step::DownAt("calendar-year", 150.0, 150.0),
Step::UpAt("calendar-year", 150.0, 150.0),
Step::Key("right"),
Step::Wait(150),
Step::Shot("year-cursor"),
Step::DownAt("calendar-week", 560.0, 300.0),
Step::DragTo("calendar-week", 560.0, 380.0),
Step::Wait(150),
Step::Shot("week-drafting"),
Step::UpAt("calendar-week", 560.0, 380.0),
Step::Wait(200),
Step::Shot("week-made"),
Step::DownAt("calendar-popover", 60.0, 10.0),
Step::UpAt("calendar-popover", 60.0, 10.0),
Step::Wait(300),
Step::Shot("popover-open"),
Step::Key("escape"),
];
/// What a demo says it did, under it.
fn quiet(text: SharedString, cx: &App) -> impl IntoElement + use<> {
let theme = cx.theme();
div()
.text_size(theme.text_size(TextSize::Sm))
.text_color(theme.colors.fg_muted)
.child(text)
}
/// The gallery's zone and today in it.
fn here() -> (TimeZone, Date) {
let zone = TimeZone::try_system().expect("the gallery reads the system time zone");
let today = Timestamp::now().to_zoned(zone.clone()).date();
(zone, today)
}
/// The page's events, which a drag on the week or day adds to.
fn plan(window: &mut Window, cx: &mut App) -> Entity<Vec<Event>> {
let (zone, today) = here();
keep("calendar-events", || events(today, &zone), window, cx)
}
/// A studio's weeks around today: meetings, a crowded day, an offsite, a trip past a weekend, a night shoot past midnight.
fn events(today: Date, zone: &TimeZone) -> Vec<Event> {
let day = |offset: i64| today.checked_add(offset.days()).expect("a day nearby");
let at = |offset: i64, hour: i8, minute: i8| {
day(offset)
.at(hour, minute, 0, 0)
.to_zoned(zone.clone())
.expect("the zone holds the hour")
.timestamp()
};
vec![
Event::timed("standup", "Studio stand-up", at(0, 9, 30), at(0, 9, 45), 0),
Event::timed("review", "Design review", at(0, 11, 0), at(0, 12, 0), 3).place("Model room"),
Event::timed("lunch", "Lunch with Ana", at(0, 12, 30), at(0, 13, 30), 5),
Event::timed("samples", "Plaster samples", at(0, 15, 0), at(0, 16, 0), 2),
Event::timed("client", "Client call", at(0, 17, 0), at(0, 17, 30), 1),
Event::timed("crit", "Crit", at(-3, 14, 0), at(-3, 15, 30), 3).place("Studio 2"),
Event::timed("print", "Print run", at(-9, 10, 0), at(-9, 11, 0), 2),
Event::all_day("offsite", "Studio offsite", day(2), day(4), 4),
Event::timed("night", "Night shoot", at(5, 21, 0), at(6, 2, 0), 6).place("Atrium"),
Event::all_day("trip", "Site visit · Lisbon", day(9), day(13), 7),
Event::timed("models", "Model photos", at(11, 10, 0), at(11, 12, 0), 0),
Event::all_day("launch", "Launch", day(18), day(18), 1),
]
}
fn render(window: &mut Window, cx: &mut App) -> AnyElement {
div()
.child(months::month(window, cx))
.child(months::mini(window, cx))
.child(times::week(window, cx))
.child(times::day(window, cx))
.child(people::agenda(window, cx))
.child(people::details(window, cx))
.child(months::year(window, cx))
.child(months::marks(cx))
.into_any_element()
}