Skip to main content

guise/theme/
palette.rs

1//! The Mantine / open-color palette: 14 named colors, each a 10-step shade
2//! ramp from lightest (index 0) to darkest (index 9).
3
4use super::color::Color;
5
6/// One of the named colors in the theme palette.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum ColorName {
9    Dark,
10    Gray,
11    Red,
12    Pink,
13    Grape,
14    Violet,
15    Indigo,
16    Blue,
17    Cyan,
18    Teal,
19    Green,
20    Lime,
21    Yellow,
22    Orange,
23}
24
25impl ColorName {
26    pub const ALL: [ColorName; 14] = [
27        ColorName::Dark,
28        ColorName::Gray,
29        ColorName::Red,
30        ColorName::Pink,
31        ColorName::Grape,
32        ColorName::Violet,
33        ColorName::Indigo,
34        ColorName::Blue,
35        ColorName::Cyan,
36        ColorName::Teal,
37        ColorName::Green,
38        ColorName::Lime,
39        ColorName::Yellow,
40        ColorName::Orange,
41    ];
42
43    pub fn label(self) -> &'static str {
44        match self {
45            ColorName::Dark => "dark",
46            ColorName::Gray => "gray",
47            ColorName::Red => "red",
48            ColorName::Pink => "pink",
49            ColorName::Grape => "grape",
50            ColorName::Violet => "violet",
51            ColorName::Indigo => "indigo",
52            ColorName::Blue => "blue",
53            ColorName::Cyan => "cyan",
54            ColorName::Teal => "teal",
55            ColorName::Green => "green",
56            ColorName::Lime => "lime",
57            ColorName::Yellow => "yellow",
58            ColorName::Orange => "orange",
59        }
60    }
61}
62
63/// A 10-step shade ramp for a single named color.
64#[derive(Debug, Clone, Copy)]
65pub struct Shades(pub [Color; 10]);
66
67impl Shades {
68    /// Shade by index, clamped into `0..=9`.
69    pub fn get(&self, shade: usize) -> Color {
70        self.0[shade.min(9)]
71    }
72}
73
74/// The full set of named colors. Resolved by `ColorName`.
75#[derive(Debug, Clone, Copy)]
76pub struct Palette {
77    shades: [Shades; 14],
78}
79
80impl Palette {
81    /// The shade ramp for a named color.
82    pub fn shades(&self, name: ColorName) -> Shades {
83        self.shades[name as usize]
84    }
85
86    /// A single shade of a named color.
87    pub fn get(&self, name: ColorName, shade: usize) -> Color {
88        self.shades(name).get(shade)
89    }
90
91    /// Replace the shade ramp for one named color — e.g. re-pin `Dark` to an
92    /// app's custom scale before `Theme::init`.
93    pub fn set_shades(&mut self, name: ColorName, shades: Shades) {
94        self.shades[name as usize] = shades;
95    }
96}
97
98impl Default for Palette {
99    fn default() -> Self {
100        mantine()
101    }
102}
103
104/// The default Mantine palette.
105pub fn mantine() -> Palette {
106    let ramp = |hexes: [&str; 10]| Shades(hexes.map(Color::hex));
107    Palette {
108        shades: [
109            // Dark
110            ramp([
111                "#C9C9C9", "#b8b8b8", "#828282", "#696969", "#424242", "#3b3b3b", "#2e2e2e",
112                "#242424", "#1f1f1f", "#141414",
113            ]),
114            // Gray
115            ramp([
116                "#f8f9fa", "#f1f3f5", "#e9ecef", "#dee2e6", "#ced4da", "#adb5bd", "#868e96",
117                "#495057", "#343a40", "#212529",
118            ]),
119            // Red
120            ramp([
121                "#fff5f5", "#ffe3e3", "#ffc9c9", "#ffa8a8", "#ff8787", "#ff6b6b", "#fa5252",
122                "#f03e3e", "#e03131", "#c92a2a",
123            ]),
124            // Pink
125            ramp([
126                "#fff0f6", "#ffdeeb", "#fcc2d7", "#faa2c1", "#f783ac", "#f06595", "#e64980",
127                "#d6336c", "#c2255c", "#a61e4d",
128            ]),
129            // Grape
130            ramp([
131                "#f8f0fc", "#f3d9fa", "#eebefa", "#e599f7", "#da77f2", "#cc5de8", "#be4bdb",
132                "#ae3ec9", "#9c36b5", "#862e9c",
133            ]),
134            // Violet
135            ramp([
136                "#f3f0ff", "#e5dbff", "#d0bfff", "#b197fc", "#9775fa", "#845ef7", "#7950f2",
137                "#7048e8", "#6741d9", "#5f3dc4",
138            ]),
139            // Indigo
140            ramp([
141                "#edf2ff", "#dbe4ff", "#bac8ff", "#91a7ff", "#748ffc", "#5c7cfa", "#4c6ef5",
142                "#4263eb", "#3b5bdb", "#364fc7",
143            ]),
144            // Blue
145            ramp([
146                "#e7f5ff", "#d0ebff", "#a5d8ff", "#74c0fc", "#4dabf7", "#339af0", "#228be6",
147                "#1c7ed6", "#1971c2", "#1864ab",
148            ]),
149            // Cyan
150            ramp([
151                "#e3fafc", "#c5f6fa", "#99e9f2", "#66d9e8", "#3bc9db", "#22b8cf", "#15aabf",
152                "#1098ad", "#0c8599", "#0b7285",
153            ]),
154            // Teal
155            ramp([
156                "#e6fcf5", "#c3fae8", "#96f2d7", "#63e6be", "#38d9a9", "#20c997", "#12b886",
157                "#0ca678", "#099268", "#087f5b",
158            ]),
159            // Green
160            ramp([
161                "#ebfbee", "#d3f9d8", "#b2f2bb", "#8ce99a", "#69db7c", "#51cf66", "#40c057",
162                "#37b24d", "#2f9e44", "#2b8a3e",
163            ]),
164            // Lime
165            ramp([
166                "#f4fce3", "#e9fac8", "#d8f5a2", "#c0eb75", "#a9e34b", "#94d82d", "#82c91e",
167                "#74b816", "#66a80f", "#5c940d",
168            ]),
169            // Yellow
170            ramp([
171                "#fff9db", "#fff3bf", "#ffec99", "#ffe066", "#ffd43b", "#fcc419", "#fab005",
172                "#f59f00", "#f08c00", "#e67700",
173            ]),
174            // Orange
175            ramp([
176                "#fff4e6", "#ffe8cc", "#ffd8a8", "#ffc078", "#ffa94d", "#ff922b", "#fd7e14",
177                "#f76707", "#e8590c", "#d9480f",
178            ]),
179        ],
180    }
181}