Add Ayu color themes

This commit is contained in:
2026-06-20 17:54:23 -04:00
parent a30d9d5dbf
commit 57f21a0edf
+64 -4
View File
@@ -60,6 +60,9 @@ pub enum AppTheme {
GruvboxDark,
SolarizedLight,
GruvboxLight,
AyuDark,
AyuMirage,
AyuLight,
}
/// Build a `Color` from a packed `0xRRGGBB` literal — keeps the palette tables
@@ -70,7 +73,7 @@ fn hex(c: u32) -> Color {
impl AppTheme {
/// Every theme, in picker order.
pub const ALL: [AppTheme; 10] = [
pub const ALL: [AppTheme; 13] = [
AppTheme::Mocha,
AppTheme::Macchiato,
AppTheme::Frappe,
@@ -81,6 +84,9 @@ impl AppTheme {
AppTheme::GruvboxDark,
AppTheme::SolarizedLight,
AppTheme::GruvboxLight,
AppTheme::AyuDark,
AppTheme::AyuMirage,
AppTheme::AyuLight,
];
/// Human-readable name for the picker.
@@ -96,6 +102,9 @@ impl AppTheme {
AppTheme::GruvboxDark => "Gruvbox Dark",
AppTheme::SolarizedLight => "Solarized Light",
AppTheme::GruvboxLight => "Gruvbox Light",
AppTheme::AyuDark => "Ayu Dark",
AppTheme::AyuMirage => "Ayu Mirage",
AppTheme::AyuLight => "Ayu Light",
}
}
@@ -103,7 +112,10 @@ impl AppTheme {
pub fn is_dark(self) -> bool {
!matches!(
self,
AppTheme::Latte | AppTheme::SolarizedLight | AppTheme::GruvboxLight
AppTheme::Latte
| AppTheme::SolarizedLight
| AppTheme::GruvboxLight
| AppTheme::AyuLight
)
}
@@ -120,6 +132,8 @@ impl AppTheme {
AppTheme::GruvboxDark => iced::Theme::GruvboxDark,
AppTheme::SolarizedLight => iced::Theme::SolarizedLight,
AppTheme::GruvboxLight => iced::Theme::GruvboxLight,
AppTheme::AyuDark | AppTheme::AyuMirage => iced::Theme::TokyoNight,
AppTheme::AyuLight => iced::Theme::Light,
}
}
@@ -281,6 +295,52 @@ impl AppTheme {
green: hex(0x79740e),
yellow: hex(0xb57614),
},
AppTheme::AyuDark => Palette {
crust: hex(0x06080a),
mantle: hex(0x0b0e14),
base: hex(0x0d1017),
surface: hex(0x1c222b),
overlay: hex(0x565b66),
text: hex(0xbfbdb6),
subtext: hex(0x9da1a6),
blue: hex(0xe6b450),
lavender: hex(0x59c2ff),
red: hex(0xf07178),
maroon: hex(0xff8f40),
green: hex(0xaad94c),
yellow: hex(0xffb454),
},
AppTheme::AyuMirage => Palette {
crust: hex(0x171b24),
mantle: hex(0x1a1f29),
base: hex(0x1f2430),
surface: hex(0x232834),
overlay: hex(0x707a8c),
text: hex(0xcccac2),
subtext: hex(0xa6abb4),
blue: hex(0xffcc66),
lavender: hex(0x73d0ff),
red: hex(0xf28779),
maroon: hex(0xffa759),
green: hex(0xd5ff80),
yellow: hex(0xffd173),
},
// Ayu Light's canonical orange is deepened for legibility on white.
AppTheme::AyuLight => Palette {
crust: hex(0xe6e9ec),
mantle: hex(0xf3f4f5),
base: hex(0xfcfcfc),
surface: hex(0xe8eaed),
overlay: hex(0x8a9199),
text: hex(0x5c6166),
subtext: hex(0x737980),
blue: hex(0xc7500e),
lavender: hex(0x399ee6),
red: hex(0xf07171),
maroon: hex(0xfa8d3e),
green: hex(0x86b300),
yellow: hex(0xff9940),
},
}
}
}
@@ -371,11 +431,11 @@ mod tests {
fn all_themes_distinct_and_labeled() {
// ALL covers exactly the variants once, each with a unique non-empty label
// and a distinct base colour (so swatches don't look identical).
assert_eq!(AppTheme::ALL.len(), 10);
assert_eq!(AppTheme::ALL.len(), 13);
let mut labels: Vec<&str> = AppTheme::ALL.iter().map(|t| t.label()).collect();
labels.sort_unstable();
labels.dedup();
assert_eq!(labels.len(), 10, "labels must be unique + non-empty");
assert_eq!(labels.len(), 13, "labels must be unique + non-empty");
assert!(labels.iter().all(|l| !l.is_empty()));
}