///|
fn typography_size_value(value : String) -> Bool {
let units = [
"px", "rem", "em", "ch", "ex", "cap", "ic", "lh", "rlh", "vw", "vh", "vmin",
"vmax", "svw", "svh", "lvw", "lvh", "dvw", "dvh", "%",
]
for unit in units {
if value.has_suffix(unit) {
return true
}
}
value.has_prefix("calc(") ||
value.has_prefix("clamp(") ||
value.has_prefix("min(") ||
value.has_prefix("max(") ||
value.has_prefix("var(")
}
///|
fn typography_modifier_value(
theme : Map[String, String],
modifier : String,
) -> String? {
match arbitrary_value(modifier) {
Some(value) => Some(value)
None =>
match theme_css_value(theme, "--leading-\{modifier}") {
Some(value) => Some(value)
None => resolved_value(theme, modifier, "--leading", true)
}
}
}
///|
fn font_family_utility(
theme : Map[String, String],
name : String,
) -> Array[Declaration]? {
guard prefixed_value(name, "font") is Some(key) else { return None }
match arbitrary_value(key) {
Some(value) => Some([decl("font-family", value)])
None =>
match theme_css_value(theme, "--font-\{key}") {
None => None
Some(value) => {
let declarations : Array[Declaration] = [decl("font-family", value)]
match theme_css_value(theme, "--font-\{key}--font-feature-settings") {
Some(settings) =>
declarations.push(decl("font-feature-settings", settings))
None => ()
}
match
theme_css_value(theme, "--font-\{key}--font-variation-settings") {
Some(settings) =>
declarations.push(decl("font-variation-settings", settings))
None => ()
}
Some(declarations)
}
}
}
}
///|
fn font_size_utility(
theme : Map[String, String],
name : String,
modifier : String?,
) -> Array[Declaration]? {
guard prefixed_value(name, "text") is Some(key) else { return None }
let (size, named_key) = match arbitrary_value(key) {
Some(value) =>
if typography_size_value(value) {
(value, None)
} else {
return None
}
None =>
match theme_css_value(theme, "--text-\{key}") {
Some(value) => (value, Some(key))
None => return None
}
}
let declarations : Array[Declaration] = [decl("font-size", size)]
match modifier {
Some(modifier) =>
match typography_modifier_value(theme, modifier) {
Some(value) => declarations.push(decl("line-height", value))
None => return None
}
None =>
match named_key {
Some(key) => {
match theme_css_value(theme, "--text-\{key}--line-height") {
Some(value) =>
declarations.push(
decl("line-height", "var(--tw-leading, \{value})"),
)
None => ()
}
match theme_css_value(theme, "--text-\{key}--letter-spacing") {
Some(value) =>
declarations.push(
decl("letter-spacing", "var(--tw-tracking, \{value})"),
)
None => ()
}
match theme_css_value(theme, "--text-\{key}--font-weight") {
Some(value) =>
declarations.push(
decl("font-weight", "var(--tw-font-weight, \{value})"),
)
None => ()
}
}
None => ()
}
}
Some(declarations)
}
///|
fn leading_utility(
theme : Map[String, String],
name : String,
) -> Array[Declaration]? {
guard prefixed_value(name, "leading") is Some(key) else { return None }
let value = match arbitrary_value(key) {
Some(value) => Some(value)
None =>
match theme_css_value(theme, "--leading-\{key}") {
Some(value) => Some(value)
None => resolved_value(theme, key, "--leading", true)
}
}
value.map(fn(value) {
[decl("--tw-leading", value), decl("line-height", value)]
})
}
///|
fn tracking_utility(
theme : Map[String, String],
name : String,
) -> Array[Declaration]? {
guard prefixed_value(name, "tracking") is Some(key) else { return None }
let value = match arbitrary_value(key) {
Some(value) => Some(value)
None => theme_css_value(theme, "--tracking-\{key}")
}
value.map(fn(value) {
[decl("--tw-tracking", value), decl("letter-spacing", value)]
})
}
///|
fn text_indent_utility(
theme : Map[String, String],
name : String,
) -> Array[Declaration]? {
guard prefixed_value(name, "indent") is Some(key) else { return None }
let value = match arbitrary_value(key) {
Some(value) => Some(value)
None =>
match theme_css_value(theme, "--text-indent-\{key}") {
Some(value) => Some(value)
None => resolved_value(theme, key, "--text-indent", true)
}
}
value.map(fn(value) { [decl("text-indent", value)] })
}
///|
fn decoration_shape_utility(
theme : Map[String, String],
name : String,
) -> Array[Declaration]? {
let styles = ["solid", "double", "dotted", "dashed", "wavy"]
if name.has_prefix("decoration-") {
let key = name[11:].to_owned()
if styles.contains(key) {
return Some([decl("text-decoration-style", key)])
}
if key == "auto" || key == "from-font" {
return Some([decl("text-decoration-thickness", key)])
}
let value = match arbitrary_value(key) {
Some(value) => Some(value)
None =>
match theme_css_value(theme, "--text-decoration-thickness-\{key}") {
Some(value) => Some(value)
None =>
if is_nonnegative_integer(key) {
Some("\{key}px")
} else {
None
}
}
}
return value.map(fn(value) { [decl("text-decoration-thickness", value)] })
}
guard name.has_prefix("underline-offset-") else { return None }
let key = name[17:].to_owned()
if key == "auto" {
return Some([decl("text-underline-offset", "auto")])
}
let value = match arbitrary_value(key) {
Some(value) => Some(value)
None =>
match theme_css_value(theme, "--text-underline-offset-\{key}") {
Some(value) => Some(value)
None =>
if is_nonnegative_integer(key) {
Some("\{key}px")
} else {
None
}
}
}
value.map(fn(value) { [decl("text-underline-offset", value)] })
}
///|
fn numeric_variant_utility(name : String) -> Array[Declaration]? {
let property = match name {
"ordinal" => Some(("--tw-ordinal", "ordinal"))
"slashed-zero" => Some(("--tw-slashed-zero", "slashed-zero"))
"lining-nums" => Some(("--tw-numeric-figure", "lining-nums"))
"oldstyle-nums" => Some(("--tw-numeric-figure", "oldstyle-nums"))
"proportional-nums" => Some(("--tw-numeric-spacing", "proportional-nums"))
"tabular-nums" => Some(("--tw-numeric-spacing", "tabular-nums"))
"diagonal-fractions" =>
Some(("--tw-numeric-fraction", "diagonal-fractions"))
"stacked-fractions" => Some(("--tw-numeric-fraction", "stacked-fractions"))
"normal-nums" => return Some([decl("font-variant-numeric", "normal")])
_ => None
}
guard property is Some((custom_property, value)) else { return None }
Some([
decl(custom_property, value),
decl(
"font-variant-numeric", "var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)",
),
])
}
///|
fn typography_utility(
theme : Map[String, String],
name : String,
modifier : String?,
) -> Array[Declaration]? {
match font_family_utility(theme, name) {
Some(value) => return Some(value)
None => ()
}
match font_size_utility(theme, name, modifier) {
Some(value) => return Some(value)
None => ()
}
match leading_utility(theme, name) {
Some(value) => return Some(value)
None => ()
}
match tracking_utility(theme, name) {
Some(value) => return Some(value)
None => ()
}
match text_indent_utility(theme, name) {
Some(value) => return Some(value)
None => ()
}
match decoration_shape_utility(theme, name) {
Some(value) => return Some(value)
None => numeric_variant_utility(name)
}
}