Theme · Importing: a long name gives way, four-digit colors read
A read theme's name is an Ellipsis that gives way beside its mode badge, so a long name keeps the badge inside a 280px box. parse_hex reads #rgba as VS Code does, each digit doubled, so a theme with a four-digit color reads. Tests hold the badge inside the box and read #0008 as black at 0x88 alpha. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d5cfaeb19c
commit
106faca970
5 files changed
+60
-13
No files matched your search
@@ -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 | 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 | 2 | FAIL | segments split the strip equally and cut a longer label; the thumb lost its padding's height |
|
||||||
| T39a | 3 | PASS | |
|
| T39a | 3 | PASS | |
|
||||||
|
| T39b | 1 | FAIL | a long theme name pushed its badge past 280px; four-digit colors refused the theme |
|
||||||
@@ -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<Rgba, String> {
|
pub(crate) fn parse_hex(text: &str) -> Result<Rgba, String> {
|
||||||
let digits = text.trim().trim_start_matches('#');
|
let digits = text.trim().trim_start_matches('#');
|
||||||
|
let doubled = || digits.chars().flat_map(|ch| [ch, ch]);
|
||||||
let long: String = match digits.len() {
|
let long: String = match digits.len() {
|
||||||
3 => digits
|
3 => doubled().chain("ff".chars()).collect(),
|
||||||
.chars()
|
4 => doubled().collect(),
|
||||||
.flat_map(|ch| [ch, ch])
|
|
||||||
.chain("ff".chars())
|
|
||||||
.collect(),
|
|
||||||
6 => format!("{digits}ff"),
|
6 => format!("{digits}ff"),
|
||||||
8 => digits.to_string(),
|
8 => digits.to_string(),
|
||||||
_ => return Err(format!("{text:?} is not a hex color")),
|
_ => return Err(format!("{text:?} is not a hex color")),
|
||||||
@@ -149,10 +147,11 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[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("#0af").unwrap()), "#00aaff");
|
||||||
assert_eq!(hex(parse_hex("3772bb").unwrap()), "#3772bb");
|
assert_eq!(hex(parse_hex("3772bb").unwrap()), "#3772bb");
|
||||||
assert_eq!(hex(parse_hex("#3772bb80").unwrap()), "#3772bb80");
|
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("#12345").is_err());
|
||||||
assert!(parse_hex("#zzzzzz").is_err());
|
assert!(parse_hex("#zzzzzz").is_err());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use crate::{
|
|||||||
forms::DropZone,
|
forms::DropZone,
|
||||||
primitives::Severity,
|
primitives::Severity,
|
||||||
theme::{ActiveTheme, Mode, TextSize},
|
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.
|
/// 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()
|
.gap_2()
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
|
.flex_1()
|
||||||
|
.min_w_0()
|
||||||
.font_weight(FontWeight::MEDIUM)
|
.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 {
|
.child(
|
||||||
Mode::Light => "Light",
|
div()
|
||||||
Mode::Dark => "Dark",
|
.flex_none()
|
||||||
})),
|
.debug_selector(|| "theme-import-mode".into())
|
||||||
|
.child(Badge::new(match read.mode {
|
||||||
|
Mode::Light => "Light",
|
||||||
|
Mode::Dark => "Dark",
|
||||||
|
})),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
|
|||||||
@@ -211,3 +211,32 @@ fn a_code_sample_stays_inside_a_narrow_card(cx: &mut TestAppContext) {
|
|||||||
"{sample:?} inside {frame:?}"
|
"{sample:?} inside {frame:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn narrow_read_row(_: &mut Window, cx: &mut App, _: Entity<Desk>) -> 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:?}");
|
||||||
|
}
|
||||||
@@ -271,7 +271,7 @@ pub fn read_vscode_theme(text: &str) -> Result<VsCodeTheme> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use gpui::rgb;
|
use gpui::{rgb, rgba};
|
||||||
|
|
||||||
use super::{plain, read_vscode_theme};
|
use super::{plain, read_vscode_theme};
|
||||||
use crate::theme::{Mode, Palette};
|
use crate::theme::{Mode, Palette};
|
||||||
@@ -311,6 +311,14 @@ mod tests {
|
|||||||
assert_eq!(mode("hc-light"), Mode::Light);
|
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]
|
#[test]
|
||||||
fn a_terminal_color_reads_into_its_place() {
|
fn a_terminal_color_reads_into_its_place() {
|
||||||
let theme =
|
let theme =
|
||||||
|
|||||||
Reference in new issue
Block a user