///|
/// Skyline-safe adaptation of RUI 0.1.1 Vega tokens (MIT). See THIRD_PARTY_NOTICES.md.
pub(all) enum ColorMode {
Light
Dark
} derive(Eq, Debug)
///|
pub(all) enum TextDirection {
Ltr
Rtl
} derive(Eq, Debug)
///|
pub(all) struct Tokens {
background : String
foreground : String
primary : String
primary_foreground : String
muted : String
muted_foreground : String
border : String
destructive : String
radius : Int
} derive(Eq, Debug)
///|
pub fn tokens(mode? : ColorMode = Light) -> Tokens {
match mode {
Light =>
{
background: "#ffffff",
foreground: "#171717",
primary: "#262626",
primary_foreground: "#fafafa",
muted: "#f5f5f5",
muted_foreground: "#737373",
border: "#e5e5e5",
destructive: "#dc2626",
radius: 10,
}
Dark =>
{
background: "#171717",
foreground: "#fafafa",
primary: "#e5e5e5",
primary_foreground: "#262626",
muted: "#262626",
muted_foreground: "#a3a3a3",
border: "#404040",
destructive: "#f87171",
radius: 10,
}
}
}
///|
pub struct Theme {
mode : ColorMode
direction : TextDirection
tokens : Tokens
} derive(Eq, Debug)
///|
pub fn theme(
mode? : ColorMode = Light,
direction? : TextDirection = Ltr,
tokens? : Tokens,
) -> Theme {
let palette = tokens.unwrap_or(default_tokens(mode))
guard palette.radius >= 0 else { abort("theme radius must be nonnegative") }
for
color in [
palette.background,
palette.foreground,
palette.primary,
palette.primary_foreground,
palette.muted,
palette.muted_foreground,
palette.border,
palette.destructive,
] {
guard color.has_prefix("#") && [4, 5, 7, 9].contains(color.length()) else {
abort("theme colors must be native hexadecimal literals")
}
let mut first = true
for character in color.iter() {
if first {
first = false
continue
}
guard (character >= '0' && character <= '9') ||
(character >= 'a' && character <= 'f') ||
(character >= 'A' && character <= 'F') else {
abort("theme colors must be native hexadecimal literals")
}
}
}
{ mode, direction, tokens: palette, }
}
///|
fn default_tokens(mode : ColorMode) -> Tokens {
tokens(mode~)
}
///|
pub fn Theme::class_name(self : Theme) -> String {
"mmui-theme mmui-vega-v1 mmui-" +
(match self.mode {
Light => "light"
Dark => "dark"
}) +
" mmui-" +
(match self.direction {
Ltr => "ltr"
Rtl => "rtl"
})
}
///|
pub fn Theme::style(self : Theme) -> String {
let t = self.tokens
"--mmui-background:" +
t.background +
";--mmui-foreground:" +
t.foreground +
";--mmui-primary:" +
t.primary +
";--mmui-primary-foreground:" +
t.primary_foreground +
";--mmui-muted:" +
t.muted +
";--mmui-muted-foreground:" +
t.muted_foreground +
";--mmui-border:" +
t.border +
";--mmui-destructive:" +
t.destructive +
";--mmui-radius:" +
t.radius.to_string() +
"px;"
}