varabyte / kobweb

A modern framework for full stack web apps in Kotlin, built upon Compose HTML
https://kobweb.varabyte.com
Apache License 2.0
1.46k stars 65 forks source link

Add support for clamping font sizes #161

Closed bitspittle closed 1 year ago

bitspittle commented 1 year ago

A suggestion from the Discord!

What about a clamp() function for font-sizes. I think it would be really useful 🙂 With that you could define: min, max and normal font size. So for example: --fs-xl: clamp(3.5rem, 12vw + 1rem, 12rem)

Would mean that the font is 12vw + 1rem big, but can shrink to min. 3.5rem and grow to a maximum of 12rem. That would make it a lot easier to create websites with Kobweb (without using so many Breakpoints for fonts) 🙂

I'm not a big CSS or HTML expert so Idk if that is a common thing but I think it's awesome... 🤷 Maybe let me know what you guys think about an implementation of clamp().

ps: The possibility to set a .fontSize(min, normal, max) - just like in the clamp() func - would do it too I think ^^

I wrote some code as a workaround for those of you that may also need it ^^. Should work perfectly.

data class Clamp(val min: CSSNumeric, val normal: CSSNumeric, val max: CSSNumeric) {
    override fun toString(): String = "clamp(${this.min}, ${this.normal}, ${this.max})"
}

fun Modifier.fontSize(clamp: Clamp) = styleModifier { fontSize(clamp) }
fun StyleScope.fontSize(clamp: Clamp) = property("font-size", clamp.toString())
}

The "Clamp" data class is optional. It can also be replaced with just three simple parameters (min, normal, max) in the Modifier.fontSize() and StyleScope.fontSize() functions.

See also: https://developer.mozilla.org/en-US/docs/Web/CSS/clamp

bitspittle commented 1 year ago

So, after digging into this a bit more, I think it's a great idea that deserves getting done right. The approach should support more functions than just "clamp", so the above suggested code but a bit more abstract.

I'm thinking of doing something like this:

package com.varabyte.kobweb.compose.css.functions

import org.jetbrains.compose.web.css.StylePropertyString

interface CSSFunction : StylePropertyString
interface CSSNumericFunction : CSSFunction
// Later, CSSFilterFunction, etc.

data class Clamp(val min: CSSNumeric, val value: CSSNumeric, val max: CSSNumeric): CSSNumericFunction {
    override fun toString(): String = "clamp($min, $value, $max)"
}

data class Min(val first: CSSNumeric, val second: CSSNumeric): CSSNumericFunction { ... }

fun StyleScope.fontSize(numericFunc: CSSNumericFunction) = property("font-size", numericFunc)
fun Modifier.fontSize(numericFunc: CSSNumericFunction) = styleModifier { fontSize(numericFunc) }
bitspittle commented 1 year ago

After talking on the Kotlin slack, found a developer shared their own approach which makes CSSClamp directly a CSSNumeric, which I think is really nice.

Reference: https://github.com/Ayfri/Ayfri.github.io/blob/master/src/main/kotlin/style/utils/CSSFunctions.kt

conradboehnke commented 1 year ago

Awesome! Thanks for supporting this feature :)