context aware values
This commit is contained in:
parent
d985d71fa4
commit
871fce954d
17
src/class.rs
17
src/class.rs
|
@ -21,10 +21,16 @@ pub(crate) struct Class<'a> {
|
|||
#[derive(PartialEq, Debug)]
|
||||
pub(crate) enum ValueType {
|
||||
/// replacements will be performed
|
||||
///
|
||||
/// eg: `m[1rem]`
|
||||
Normal,
|
||||
/// no replacements will be done. value will be output as-is
|
||||
///
|
||||
/// eg: `border{1px solid black}`
|
||||
Literal,
|
||||
/// value will be output as `var(--value)`, without any replacements
|
||||
///
|
||||
/// eg: `c(main-color)`
|
||||
Variable,
|
||||
}
|
||||
|
||||
|
@ -86,7 +92,14 @@ impl<'a> Class<'a> {
|
|||
if let Some(val) = self.value {
|
||||
let val = match self.value_type {
|
||||
ValueType::Normal => {
|
||||
replace_underscores(z.values.get(val).map(AsRef::as_ref).unwrap_or(val))
|
||||
let v = z
|
||||
.context_aware_values
|
||||
.get(property)
|
||||
.and_then(|h| h.get(val))
|
||||
.or_else(|| z.values.get(val))
|
||||
.map(AsRef::as_ref)
|
||||
.unwrap_or(val);
|
||||
replace_underscores(v)
|
||||
}
|
||||
ValueType::Literal => val.into(),
|
||||
ValueType::Variable => format!("var(--{val})").into(),
|
||||
|
@ -96,7 +109,7 @@ impl<'a> Class<'a> {
|
|||
let v = fun(&val);
|
||||
Ok(format!("{selector}{{{v}}}",))
|
||||
} else {
|
||||
Ok(format!("{selector}{{{property}:{val};}}"))
|
||||
Ok(format!("{selector}{{{property}:{val}}}"))
|
||||
}
|
||||
} else if let Some(v) = z.declarations.get(property) {
|
||||
Ok(format!("{selector}{{{v}}}"))
|
||||
|
|
|
@ -2,8 +2,14 @@ use std::collections::HashMap;
|
|||
|
||||
use crate::SpecialDeclaration;
|
||||
|
||||
fn vec_to_hashmap(v: &[(&str, &str)]) -> HashMap<String, String> {
|
||||
v.into_iter()
|
||||
.map(|(a, b)| (a.to_string(), b.to_string()))
|
||||
.collect::<HashMap<_, _>>()
|
||||
}
|
||||
|
||||
pub(crate) fn default_declarations() -> HashMap<String, String> {
|
||||
vec![
|
||||
vec_to_hashmap(&[
|
||||
("flex", "display:flex"),
|
||||
("flex-row", "display:flex;flex-direction:row"),
|
||||
("flex-col", "display:flex;flex-direction:column"),
|
||||
|
@ -16,14 +22,11 @@ pub(crate) fn default_declarations() -> HashMap<String, String> {
|
|||
("text-left", "text-align:left"),
|
||||
("text-right", "text-align:right"),
|
||||
// TODO
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(a, b)| (a.to_string(), b.to_string()))
|
||||
.collect::<HashMap<_, _>>()
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn default_properties() -> HashMap<String, String> {
|
||||
vec![
|
||||
vec_to_hashmap(&[
|
||||
("w", "width"),
|
||||
("h", "height"),
|
||||
("m", "margin"),
|
||||
|
@ -36,47 +39,89 @@ pub(crate) fn default_properties() -> HashMap<String, String> {
|
|||
("pb", "padding-bottom"),
|
||||
("pl", "padding-left"),
|
||||
("pr", "padding-right"),
|
||||
("c", "color"),
|
||||
("bg", "background"),
|
||||
("bgc", "background-color"),
|
||||
("tt", "text-transform"),
|
||||
("td", "text-decoration"),
|
||||
// TODO
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(a, b)| (a.to_string(), b.to_string()))
|
||||
.collect()
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn default_values() -> HashMap<String, String> {
|
||||
vec![
|
||||
vec_to_hashmap(&[
|
||||
("full", "100%"),
|
||||
// TODO
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn default_context_aware_values() -> HashMap<String, HashMap<String, String>> {
|
||||
[
|
||||
(
|
||||
"text-decoration",
|
||||
&[
|
||||
("u", "underline"),
|
||||
("ud", "underline dotted"),
|
||||
("uw", "underline wavy"),
|
||||
("o", "overline"),
|
||||
("od", "overline dotted"),
|
||||
("ow", "overline wavy"),
|
||||
] as &[(&str, &str)],
|
||||
),
|
||||
(
|
||||
"text-transform",
|
||||
&[("c", "capitalize"), ("u", "uppercase"), ("l", "lowercase")],
|
||||
),
|
||||
(
|
||||
"overflow",
|
||||
&[
|
||||
("v", "visible"),
|
||||
("h", "hidden"),
|
||||
("s", "scroll"),
|
||||
("c", "clip"),
|
||||
],
|
||||
),
|
||||
(
|
||||
"overflow-x",
|
||||
&[
|
||||
("v", "visible"),
|
||||
("h", "hidden"),
|
||||
("s", "scroll"),
|
||||
("c", "clip"),
|
||||
],
|
||||
),
|
||||
(
|
||||
"overflow-y",
|
||||
&[
|
||||
("v", "visible"),
|
||||
("h", "hidden"),
|
||||
("s", "scroll"),
|
||||
("c", "clip"),
|
||||
],
|
||||
),
|
||||
// TODO
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(a, b)| (a.to_string(), b.to_string()))
|
||||
.map(|(n, h)| (n.to_string(), vec_to_hashmap(h)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn default_modifiers() -> HashMap<String, String> {
|
||||
vec![
|
||||
vec_to_hashmap(&[
|
||||
("odd", "nth-child(odd)"),
|
||||
("even", "nth-child(even)"),
|
||||
("first", "first-child"),
|
||||
("last", "last-child"),
|
||||
("only", "only-child"),
|
||||
// TODO
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(a, b)| (a.to_string(), b.to_string()))
|
||||
.collect()
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn default_pseudos() -> HashMap<String, String> {
|
||||
vec![
|
||||
vec_to_hashmap(&[
|
||||
("ph", "placeholder"),
|
||||
// TODO
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(a, b)| (a.to_string(), b.to_string()))
|
||||
.collect()
|
||||
])
|
||||
}
|
||||
|
||||
macro_rules! special {
|
||||
|
@ -91,11 +136,11 @@ macro_rules! special {
|
|||
}
|
||||
|
||||
pub(crate) fn default_specials() -> HashMap<String, SpecialDeclaration> {
|
||||
vec![
|
||||
special!("mx", val, "margin-left:{val};margin-right:{val};"),
|
||||
special!("my", val, "margin-top:{val};margin-bottom:{val};"),
|
||||
special!("px", val, "padding-left:{val};padding-right:{val};"),
|
||||
special!("py", val, "padding-top:{val};padding-bottom:{val};"),
|
||||
[
|
||||
special!("mx", val, "margin-left:{val};margin-right:{val}"),
|
||||
special!("my", val, "margin-top:{val};margin-bottom:{val}"),
|
||||
special!("px", val, "padding-left:{val};padding-right:{val}"),
|
||||
special!("py", val, "padding-top:{val};padding-bottom:{val}"),
|
||||
special!("wh", val, "width:{val};height:{val};"),
|
||||
// TODO
|
||||
]
|
||||
|
|
|
@ -35,6 +35,10 @@ pub struct Zephyr {
|
|||
pub modifiers: HashMap<String, String>,
|
||||
/// list of pseudo-element short-hands
|
||||
pub pseudos: HashMap<String, String>,
|
||||
/// list of value replacements for each property
|
||||
///
|
||||
/// property -> [(short, expanded)]
|
||||
pub context_aware_values: HashMap<String, HashMap<String, String>>,
|
||||
}
|
||||
|
||||
/// value -> declarations
|
||||
|
@ -108,6 +112,7 @@ impl Zephyr {
|
|||
modifiers: default_modifiers(),
|
||||
pseudos: default_pseudos(),
|
||||
specials: default_specials(),
|
||||
context_aware_values: default_context_aware_values(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
30
src/tests.rs
30
src/tests.rs
|
@ -14,7 +14,7 @@ fn generate_margin_works() {
|
|||
value_type: class::ValueType::Normal,
|
||||
};
|
||||
let css = class.generate(&z).unwrap();
|
||||
assert_eq!(css, r#".m\[1rem\]{margin:1rem;}"#);
|
||||
assert_eq!(css, r#".m\[1rem\]{margin:1rem}"#);
|
||||
|
||||
let class = Class {
|
||||
property: "m",
|
||||
|
@ -25,7 +25,7 @@ fn generate_margin_works() {
|
|||
value_type: class::ValueType::Normal,
|
||||
};
|
||||
let css = class.generate(&z).unwrap();
|
||||
assert_eq!(css, r#".m\[1rem\]focus:focus{margin:1rem;}"#);
|
||||
assert_eq!(css, r#".m\[1rem\]focus:focus{margin:1rem}"#);
|
||||
|
||||
let class = Class {
|
||||
property: "m",
|
||||
|
@ -38,7 +38,7 @@ fn generate_margin_works() {
|
|||
let css = class.generate(&z).unwrap();
|
||||
assert_eq!(
|
||||
css,
|
||||
r#".m\[1rem\]focus,hover,odd:focus:hover:nth-child\(odd\){margin:1rem;}"#
|
||||
r#".m\[1rem\]focus,hover,odd:focus:hover:nth-child\(odd\){margin:1rem}"#
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ fn generate_classes_works() {
|
|||
let classes = z.generate_classes(["m[3rem]hover,focus$placeholder"]);
|
||||
assert_eq!(
|
||||
classes,
|
||||
r#".m\[3rem\]hover,focus\$placeholder:hover:focus::placeholder{margin:3rem;}"#
|
||||
r#".m\[3rem\]hover,focus\$placeholder:hover:focus::placeholder{margin:3rem}"#
|
||||
);
|
||||
|
||||
let classes = z.generate_classes(["flex|hover,focus$placeholder"]);
|
||||
|
@ -62,7 +62,7 @@ fn generate_classes_works() {
|
|||
);
|
||||
|
||||
let classes = z.generate_classes(["mr[0.5rem]"]);
|
||||
assert_eq!(classes, r#".mr\[0\.5rem\]{margin-right:0.5rem;}"#);
|
||||
assert_eq!(classes, r#".mr\[0\.5rem\]{margin-right:0.5rem}"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -73,7 +73,7 @@ fn generate_multiple_works() {
|
|||
let classes_separate = z.generate_classes(["flex-row", "mt[1rem]"]);
|
||||
assert_eq!(
|
||||
classes_joined,
|
||||
r#".flex-row{display:flex;flex-direction:row}.mt\[1rem\]{margin-top:1rem;}"#
|
||||
r#".flex-row{display:flex;flex-direction:row}.mt\[1rem\]{margin-top:1rem}"#
|
||||
);
|
||||
assert_eq!(classes_separate, classes_joined);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ fn generate_specials_works() {
|
|||
let classes = z.generate_classes(["mx[1rem]"]);
|
||||
assert_eq!(
|
||||
classes,
|
||||
r#".mx\[1rem\]{margin-left:1rem;margin-right:1rem;}"#
|
||||
r#".mx\[1rem\]{margin-left:1rem;margin-right:1rem}"#
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ fn generate_with_spaces_works() {
|
|||
let classes = z.generate_classes(["border[1px_solid_black]"]);
|
||||
assert_eq!(
|
||||
classes,
|
||||
r#".border\[1px_solid_black\]{border:1px solid black;}"#
|
||||
r#".border\[1px_solid_black\]{border:1px solid black}"#
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ fn generate_literals_works() {
|
|||
let classes = z.generate_classes(["border{1px_solid_black}", "w{full}"]);
|
||||
assert_eq!(
|
||||
classes,
|
||||
r#".border\{1px_solid_black\}{border:1px_solid_black;}.w\{full\}{width:full;}"#
|
||||
r#".border\{1px_solid_black\}{border:1px_solid_black}.w\{full\}{width:full}"#
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ fn generate_with_media_query() {
|
|||
let classes = z.generate_classes(["m[1rem]sm"]);
|
||||
assert_eq!(
|
||||
classes,
|
||||
r#"@media(min-width:640px){.m\[1rem\]sm{margin:1rem;}}"#
|
||||
r#"@media(min-width:640px){.m\[1rem\]sm{margin:1rem}}"#
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ fn generate_variable() {
|
|||
|
||||
// the parens indicate that it should be replaced by `var(--...)`
|
||||
let classes = z.generate_classes(["m(my-margin)"]);
|
||||
assert_eq!(classes, r#".m\(my-margin\){margin:var(--my-margin);}"#);
|
||||
assert_eq!(classes, r#".m\(my-margin\){margin:var(--my-margin)}"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -142,3 +142,11 @@ fn generate_css_colors() {
|
|||
r#".white{color:white}.blanchedalmond{color:blanchedalmond}"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_context_aware_value() {
|
||||
let z = Zephyr::new();
|
||||
|
||||
let classes = z.generate_classes(["tt[u]"]);
|
||||
assert_eq!(classes, r#".tt\[u\]{text-transform:uppercase}"#);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue