diff --git a/TASKS.md b/TASKS.md index ef56178..b649fbf 100644 --- a/TASKS.md +++ b/TASKS.md @@ -422,3 +422,4 @@ Per-component lines live in `tasks/`. Tags there: | T39a | 1 | FAIL | a larger text size cut the density strip at 280px; ten palette colors had no name; the density and sliders untested | | T39a | 2 | FAIL | segments split the strip equally and cut a longer label; the thumb lost its padding's height | | T39a | 3 | PASS | | +| T39b | 1 | FAIL | a long theme name pushed its badge past 280px; four-digit colors refused the theme | diff --git a/src/forms/color/mod.rs b/src/forms/color/mod.rs index 20383d8..58072bb 100644 --- a/src/forms/color/mod.rs +++ b/src/forms/color/mod.rs @@ -65,15 +65,13 @@ impl Hsva { } } -/// Reads `#rgb`, `#rrggbb` or `#rrggbbaa`, with or without the hash. +/// Reads `#rgb`, `#rgba`, `#rrggbb` or `#rrggbbaa`, with or without the hash. pub(crate) fn parse_hex(text: &str) -> Result { let digits = text.trim().trim_start_matches('#'); + let doubled = || digits.chars().flat_map(|ch| [ch, ch]); let long: String = match digits.len() { - 3 => digits - .chars() - .flat_map(|ch| [ch, ch]) - .chain("ff".chars()) - .collect(), + 3 => doubled().chain("ff".chars()).collect(), + 4 => doubled().collect(), 6 => format!("{digits}ff"), 8 => digits.to_string(), _ => return Err(format!("{text:?} is not a hex color")), @@ -149,10 +147,11 @@ mod tests { } #[test] - fn hex_reads_three_six_and_eight_digits() { + fn hex_reads_three_four_six_and_eight_digits() { assert_eq!(hex(parse_hex("#0af").unwrap()), "#00aaff"); assert_eq!(hex(parse_hex("3772bb").unwrap()), "#3772bb"); assert_eq!(hex(parse_hex("#3772bb80").unwrap()), "#3772bb80"); + assert_eq!(hex(parse_hex("#0008").unwrap()), "#00000088"); assert!(parse_hex("#12345").is_err()); assert!(parse_hex("#zzzzzz").is_err()); } diff --git a/src/settings/importer.rs b/src/settings/importer.rs index 2ffcae7..3149cca 100644 --- a/src/settings/importer.rs +++ b/src/settings/importer.rs @@ -13,6 +13,7 @@ use crate::{ forms::DropZone, primitives::Severity, theme::{ActiveTheme, Mode, TextSize}, + typography::Ellipsis, }; /// What the importer read last: a theme and the file it came from, or why the file did not read. @@ -127,13 +128,22 @@ pub(super) fn read_row( .gap_2() .child( div() + .flex_1() + .min_w_0() .font_weight(FontWeight::MEDIUM) - .child(read.name.clone().map_or(file.clone(), SharedString::from)), + .child(Ellipsis::new( + read.name.clone().map_or(file.clone(), SharedString::from), + )), ) - .child(Badge::new(match read.mode { - Mode::Light => "Light", - Mode::Dark => "Dark", - })), + .child( + div() + .flex_none() + .debug_selector(|| "theme-import-mode".into()) + .child(Badge::new(match read.mode { + Mode::Light => "Light", + Mode::Dark => "Dark", + })), + ), ) .child( div() diff --git a/src/settings/tests/theme.rs b/src/settings/tests/theme.rs index 02a1428..4de14e9 100644 --- a/src/settings/tests/theme.rs +++ b/src/settings/tests/theme.rs @@ -211,3 +211,32 @@ fn a_code_sample_stays_inside_a_narrow_card(cx: &mut TestAppContext) { "{sample:?} inside {frame:?}" ); } + +fn narrow_read_row(_: &mut Window, cx: &mut App, _: Entity) -> AnyElement { + let read = read_vscode_theme( + r##"{"name": "GitHub Dark Default Colorblind Edition", "type": "dark", "colors": {}}"##, + ) + .expect("a theme"); + let apply: OnTheme = std::rc::Rc::new(|_, _, _| {}); + gpui::div() + .debug_selector(|| "narrow".into()) + .w(gpui::px(280.0)) + .child(importer::read_row( + &read, + &"long.json".into(), + &"importer".into(), + apply, + cx, + )) + .into_any_element() +} + +/// At 280px a long theme name gives way, and its mode badge stays inside the box. +#[gpui::test] +fn a_long_theme_name_gives_way_to_its_badge(cx: &mut TestAppContext) { + let (_, cx) = desk(narrow_read_row, cx); + settle(cx); + let frame = cx.debug_bounds("narrow").expect("the box"); + let badge = cx.debug_bounds("theme-import-mode").expect("the badge"); + assert!(badge.right() <= frame.right(), "{badge:?} inside {frame:?}"); +} diff --git a/src/settings/vscode.rs b/src/settings/vscode.rs index 941f823..af7136d 100644 --- a/src/settings/vscode.rs +++ b/src/settings/vscode.rs @@ -271,7 +271,7 @@ pub fn read_vscode_theme(text: &str) -> Result { #[cfg(test)] mod tests { - use gpui::rgb; + use gpui::{rgb, rgba}; use super::{plain, read_vscode_theme}; use crate::theme::{Mode, Palette}; @@ -311,6 +311,14 @@ mod tests { assert_eq!(mode("hc-light"), Mode::Light); } + #[test] + fn a_four_digit_color_reads_with_its_alpha() { + let theme = + read_vscode_theme(r##"{"type": "dark", "colors": {"widget.shadow": "#0008"}}"##) + .expect("a theme"); + assert_eq!(theme.colors.shadow, rgba(0x00000088).into()); + } + #[test] fn a_terminal_color_reads_into_its_place() { let theme =