diff --git a/AGENTS.md b/AGENTS.md index 1bf916a..ca94289 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -162,6 +162,8 @@ Ely GPUI Component. A component library for GPUI, in light and dark. - The focus color belongs to the focus ring. A chosen or shown item takes accent, as `forms::picks` and `lists::ListItem` do. - A box that shows a host's picture takes the picture's shape from the host (`ratio`), so nothing is cropped and a point given as a share lands on the picture. A focusable one keeps its focus border on an outer box, so the picture keeps that shape exactly (`media::ImageCropper`). - A default only the component can work out, such as a crop fitted to a picture it decodes, reaches the owner once through `window.defer` after render (`media::ImageUpload`). +- A menu of times goes through `mail::times`: each row names its day and hour, a moment comes once (tomorrow is next Monday on a Sunday), and "Pick a time…" opens one dialog that waits for a time ahead of now (`ScheduleSend`, `SnoozePicker`). +- A list whose cursor a field drives marks the cursor only while the field has focus; at rest its first row would look hovered (`mail::LabelPicker`). Its rows are option rows, and `forms::marked_row` leads one with a mark such as a label's hue. ## Decisions diff --git a/TASKS.md b/TASKS.md index bedc99e..279598a 100644 --- a/TASKS.md +++ b/TASKS.md @@ -105,7 +105,7 @@ Per-component lines live in `tasks/`. Tags there: - [x] T28e Messaging · Stickers and GIFs - [x] T29a Mail · Boxes and lists - [x] T29b Mail · Reading -- [ ] T29c Mail · Writing +- [x] T29c Mail · Writing - [ ] T29d Mail · Sorting - [ ] T30 Calendar - [ ] T31 Project — `tasks/ch31-43.md` @@ -346,3 +346,5 @@ Per-component lines live in `tasks/`. Tags there: | T29a | 2 | PASS | | | T29b | 1 | FAIL | a folded message lost focus as it opened; a long name beside a long date ran past a 280px fold | | T29b | 2 | PASS | | +| T29c | 1 | FAIL | a long chip ran past its tag field at 280px | +| T29c | 2 | PASS | | diff --git a/examples/gallery/pages/mail/mod.rs b/examples/gallery/pages/mail/mod.rs index 04bb8a2..53d0bb2 100644 --- a/examples/gallery/pages/mail/mod.rs +++ b/examples/gallery/pages/mail/mod.rs @@ -3,12 +3,14 @@ use ely_gpui_component::{ feedback::EmptyState, mail::{Mail, MailList, Mailbox, MailboxList}, primitives::IconName, - theme::{ActiveTheme, Radius}, + theme::{ActiveTheme, Radius, TextSize}, + typography::format, }; use gpui::{AnyElement, App, IntoElement, ParentElement, SharedString, Styled, Window, div, px}; -use jiff::{SignedDuration, Timestamp}; +use jiff::{SignedDuration, Timestamp, tz::TimeZone}; mod read; +mod sort; mod write; use super::Page; @@ -52,8 +54,40 @@ const SCRIPT: &[Step] = &[ Step::Key("enter"), Step::Wait(200), Step::Shot("recipient-added"), + Step::DownAt("mail-labels", 150.0, 25.0), + Step::UpAt("mail-labels", 150.0, 25.0), + Step::Type("Suppliers"), + Step::Wait(200), + Step::Shot("label-new"), + Step::Key("enter"), + Step::Wait(200), + Step::Shot("label-made"), + Step::DownAt("mail-snooze", 50.0, 16.0), + Step::UpAt("mail-snooze", 50.0, 16.0), + Step::Wait(300), + Step::Shot("snooze-open"), + Step::Key("up"), + Step::Key("enter"), + Step::Wait(300), + Step::Shot("snooze-dialog"), + 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) +} + +/// A moment as the demos say it: its weekday and hour here. +fn day_and_hour(at: Timestamp) -> String { + let zone = TimeZone::try_system().expect("the gallery reads the system time zone"); + format::datetime(at, &zone, "%a %H:%M").expect("a fixed pattern formats") +} + fn boxes(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> { let open = keep("mail-open-box", || SharedString::from("inbox"), window, cx); let shown = open.read(cx).clone(); @@ -223,6 +257,8 @@ fn render(window: &mut Window, cx: &mut App) -> AnyElement { .child(read::thread(cx)) .child(write::composer(window, cx)) .child(write::signature(window, cx)) + .child(sort::labels(window, cx)) + .child(sort::snooze(window, cx)) .child(write::schedule(window, cx)) .into_any_element() } diff --git a/examples/gallery/pages/mail/sort.rs b/examples/gallery/pages/mail/sort.rs new file mode 100644 index 0000000..0ee568e --- /dev/null +++ b/examples/gallery/pages/mail/sort.rs @@ -0,0 +1,112 @@ +use ely_gpui_component::{ + mail::{Label, LabelPicker, SnoozePicker}, + theme::{ActiveTheme, Radius}, +}; +use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div, px}; + +use super::{day_and_hour, quiet}; +use crate::{ + probe::probe, + ui::{change, keep, section, set}, +}; + +/// The demo's labels and the keys on. +#[derive(Clone)] +struct Sorting { + labels: Vec