diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/AlignContent.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/AlignContent.kt index 611f9ad..4a20af6 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/properties/AlignContent.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/AlignContent.kt @@ -1,5 +1,14 @@ package nl.astraeus.css.properties +enum class AlignContentValue( + val value: String +) { + STRETCH("stretch"), + ; + + fun css() = value +} + class AlignContent( value: String ) : CssProperty(value) { diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Measurement.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Measurement.kt index 016cd3d..e58f8a1 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/properties/Measurement.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Measurement.kt @@ -1,5 +1,7 @@ package nl.astraeus.css.properties +import kotlin.time.AbstractDoubleTimeSource + open class Measurement( value: String ) : CssProperty(value) { @@ -10,6 +12,7 @@ open class Measurement( fun inherit() = Measurement("inherit") fun normal() = Measurement("normal") fun px(nr: Int) = Measurement("${nr}px") + fun px(nr: Double) = Measurement("${nr}px") fun em(nr: Int) = Measurement("${nr}em") fun em(nr: Double) = Measurement("${nr}em") fun perc(nr: Int) = Measurement("${nr}%") @@ -20,3 +23,10 @@ open class Measurement( fun cm(nr: Double) = Measurement("${nr}cm") } } + +fun Int.px(): Measurement = Measurement.px(this) +fun Double.px(): Measurement = Measurement.px(this) +fun Int.em(): Measurement = Measurement.em(this) +fun Double.em(): Measurement = Measurement.em(this) +fun Int.perc(): Measurement = Measurement.perc(this) +fun Double.perc(): Measurement = Measurement.perc(this) diff --git a/src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt b/src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt index a823b16..7845bc7 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt @@ -15,6 +15,7 @@ open class FontFace( override fun getValidator(name: String) = null +/* override fun getMapping(): Map = mapOf( "font-family" to fontFamily, "font-size" to fontSize, @@ -24,4 +25,5 @@ open class FontFace( "font-weight" to fontWeight, "unicode-range" to unicodeRange ) +*/ } diff --git a/src/commonMain/kotlin/nl/astraeus/css/style/Style.kt b/src/commonMain/kotlin/nl/astraeus/css/style/Style.kt index 6059ba4..5f9068b 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/style/Style.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/style/Style.kt @@ -10,57 +10,27 @@ annotation class CssTagMarker abstract class CssGenerator { val definitions: MutableMap = mutableMapOf() - val extentions: MutableList = mutableListOf() - - abstract fun getMapping(): Map + val properties: MutableMap> = mutableMapOf() abstract fun getValidator(name: String): List? - private fun propertyCss(indent: String, name: String, prop: CssProperty, minified: Boolean): String { + private fun propertyCss(indent: String, name: String, props: List, minified: Boolean): String { + val builder = StringBuilder() + getValidator(name)?.forEach { - if (!it.validate(prop)) { + if (!it.validate(props)) { log.warn { "Validate error '$name' - ${it.getMessage(name)}" } } } - return if (!minified) { - val paddedName = StringBuilder() - paddedName.append(indent) - paddedName.append(name) - paddedName.append(":") - while (paddedName.length < 32) { - paddedName.append(' ') - } - "$paddedName${prop.css()};\n" - } else { - "$name:${prop.css()};" - } - } - - private fun propertyCss(indent: String, name: String, props: List<*>, minified: Boolean): String { - val builder = StringBuilder() - - getValidator(name)?.forEach { - if (!it.validate(props as List)) { - log.warn { "Validate error '$name' - ${it.getListMessage(name)}" } - } - } - - for ((index, prop) in props.withIndex()) { - if (prop is CssProperty) { - getValidator(name)?.forEach { - if (!it.validate(prop)) { - log.warn { "Validate error '$name' - ${it.getMessage(name)}" } - } + for (prop in props) { + if (builder.isNotEmpty()) { + builder.append(",") + if (!minified) { + builder.append(" ") } - if (builder.isNotEmpty()) { - builder.append(",") - if (!minified) { - builder.append(" ") - } - } - builder.append(prop.css()) } + builder.append(prop.css()) } return if (!minified) { @@ -80,12 +50,8 @@ abstract class CssGenerator { fun generatePropertyCss(indent: String, minified: Boolean): String { val builder = StringBuilder() - for ((name, prop) in getMapping()) { - if (prop is List<*> && prop.isNotEmpty()) { - builder.append(propertyCss(indent, name, prop, minified)) - } else if (prop is CssProperty) { - builder.append(propertyCss(indent, name, prop, minified)) - } + for ((name, prop) in properties) { + builder.append(propertyCss(indent, name, prop, minified)) } return builder.toString() @@ -145,6 +111,7 @@ abstract class CssGenerator { @CssTagMarker open class Style( +/* var alignContent: AlignContent? = null, var alignItems: AlignItems? = null, var alignSelf: AlignSelf? = null, @@ -248,10 +215,12 @@ open class Style( var fontSize: FontSize? = null, var height: Measurement? = null, var left: Measurement? = null, + var margin: List? = null, var top: Measurement? = null, var transitionDelay: DelayDuration? = null, var transitionDuration: DelayDuration? = null, var width: Measurement? = null +*/ ) : CssGenerator() { var fontFace: FontFace? = null private val validators = mapOf>( @@ -270,6 +239,7 @@ open class Style( override fun getValidator(name: String) = validators[name] +/* override fun getMapping(): Map = mapOf( "align-content" to alignContent, "align-items" to alignItems, @@ -369,11 +339,13 @@ open class Style( "font-size" to fontSize, "height" to height, "left" to left, + "margin" to margin, "top" to top, "transition-delay" to transitionDelay, "transition-duration" to transitionDuration, "width" to width ) +*/ fun select(selector: String, style: Css) { definitions[selector] = style @@ -388,4 +360,20 @@ open class Style( face.invoke(fontFace!!) } + + fun alignContent(value: AlignContentValue) { + properties["align-content"] = listOf(CssProperty(value.css())) + } + + fun margin(all: Measurement) { + properties["margin"] = listOf(all) + } + + fun margin(topBottom: Measurement, leftRight: Measurement) { + properties["margin"] = listOf(topBottom, leftRight) + } + + fun margin(top: Measurement, right: Measurement, bottom: Measurement, left: Measurement) { + properties["margin"] = listOf(top, right, bottom, left) + } } diff --git a/src/commonMain/kotlin/nl/astraeus/css/style/Validator.kt b/src/commonMain/kotlin/nl/astraeus/css/style/Validator.kt index 7769e48..d655774 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/style/Validator.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/style/Validator.kt @@ -4,14 +4,10 @@ import nl.astraeus.css.properties.CssProperty abstract class Validator { - open fun validate(property: CssProperty): Boolean = true - open fun validate(properties: List): Boolean = true open fun getMessage(name: String): String = "'$name' validation message not defined for $this" - open fun getListMessage(name: String): String = "'$name' validation message not defined for $this" - } class MaxCountValidator( @@ -20,7 +16,7 @@ class MaxCountValidator( override fun validate(property: List): Boolean = property.size <= number - override fun getListMessage(name: String): String = "'$name' should not have more than 4 entries" + override fun getMessage(name: String): String = "'$name' should not have more than 4 entries" } @@ -36,6 +32,6 @@ class InitialInheritSingleValue: Validator() { return true } - override fun getListMessage(name: String): String = "'$name' can only have single value when 'initial' or 'inherit'" + override fun getMessage(name: String): String = "'$name' can only have single value when 'initial' or 'inherit'" } diff --git a/src/jvmMain/kotlin/nl/astraeus/css/Test.kt b/src/jvmMain/kotlin/nl/astraeus/css/Test.kt index ce6daa1..c44aa40 100644 --- a/src/jvmMain/kotlin/nl/astraeus/css/Test.kt +++ b/src/jvmMain/kotlin/nl/astraeus/css/Test.kt @@ -2,6 +2,7 @@ package nl.astraeus.css import nl.astraeus.css.properties.* import nl.astraeus.css.properties.AlignContent.Companion.flexStart +import nl.astraeus.css.properties.AlignContentValue.* import nl.astraeus.css.style.Css import nl.astraeus.css.style.Style @@ -17,10 +18,10 @@ private fun Style.sizePX( width: Int, height: Int ) { - this@sizePX.top = Measurement.px(top) - this@sizePX.left = Measurement.px(left) - this@sizePX.width = Measurement.px(width) - this@sizePX.height = Measurement.px(height) +// this@sizePX.top = Measurement.px(top) +// this@sizePX.left = Measurement.px(left) +// this@sizePX.width = Measurement.px(width) +// this@sizePX.height = Measurement.px(height) } private fun generateCss( @@ -30,34 +31,34 @@ private fun generateCss( css.style { select("body") { - fontFamily = base.mainFont - color = base.mainColor - backgroundColor = base.mainBackgroundColor +// fontFamily = base.mainFont +// color = base.mainColor +// backgroundColor = base.mainBackgroundColor } select(".test") { - top = Measurement.px(10) - left = Measurement.em(5) - backgroundColor = Color.rgba(255, 255, 255, 0.75) +// top = Measurement.px(10) +// left = Measurement.em(5) +// backgroundColor = Color.rgba(255, 255, 255, 0.75) select("> a") { - color = Color.hsl(200, 50, 50) +// color = Color.hsl(200, 50, 50) } } select("nav") { select("ul") { - color = Color.hsl(0, 100, 25) - backgroundColor = base.mainBackgroundColor +// color = Color.hsl(0, 100, 25) +// backgroundColor = base.mainBackgroundColor } select("li") { sizePX(25, 25, 200, 200) select("a") { - width = Measurement.px(725) - background = text("red initial") - backgroundColor = base.mainBackgroundColor - all = All.initial() +// width = Measurement.px(725) +// background = text("red initial") +// backgroundColor = base.mainBackgroundColor +// all = All.initial() } } } @@ -78,29 +79,29 @@ fun main() { println(css2) val border = css { - borderRadius = BorderRadius(1, 2, 3, 4) - borderColor = listOf(Color.hsl(22,66,55)) +// borderRadius = BorderRadius(1, 2, 3, 4) +// borderColor = listOf(Color.hsl(22,66,55)) select("a") { - width = Measurement.px(10) +// width = Measurement.px(10) } } val border2: Css = { - borderRadius = BorderRadius(1, 2, 3, 4) - borderColor = listOf(Color.hsl(20,60,50)) +// borderRadius = BorderRadius(1, 2, 3, 4) +// borderColor = listOf(Color.hsl(20,60,50)) } val font: Css = { - fontFamily = text("Arial, Courier") - fontSize = FontSize.larger() +// fontFamily = text("Arial, Courier") +// fontSize = FontSize.larger() } val sd = style { select("#pipo") { - backgroundColor = Color.hex("eeeeee") - fontFamily = text("Arial, Courier") - animationDelay = listOf(DelayDuration.initial()) +// backgroundColor = Color.hex("eeeeee") +// fontFamily = text("Arial, Courier") +// animationDelay = listOf(DelayDuration.initial()) select("div") { fontFace { @@ -112,56 +113,66 @@ fun main() { fontWeight = FontWeight._600() } - fontFamily = text("SanSation") - color = Color.hex("1b1b1b1") - alignContent = flexStart() - animationName = listOf( - text("foo"), - text("bar") - ) +// fontFamily = text("SanSation") +// color = Color.hex("1b1b1b1") +// alignContent = flexStart() +// animationName = listOf( +// text("foo"), +// text("bar") +// ) select("span") { - animationIterationCount = listOf( - Count.count(3), - Count.infinite() - ) - animationTimingFunction = listOf( - AnimationTimingFunction.cubicBezier(0.1, 0.2, 0.3, 0.4), - AnimationTimingFunction.easeInOut() - ) +// animationIterationCount = listOf( +// Count.count(3), +// Count.infinite() +// ) +// animationTimingFunction = listOf( +// AnimationTimingFunction.cubicBezier(0.1, 0.2, 0.3, 0.4), +// AnimationTimingFunction.easeInOut() +// ) } select("border-0") { apply(border) - borderRadius = BorderRadius(4, 5, 6, 7) +// borderRadius = BorderRadius(4, 5, 6, 7) } select("border-1") { apply(border2) - borderRadius = BorderRadius(4, 5, 6, 7) +// borderRadius = BorderRadius(4, 5, 6, 7) } select("border-2") { - borderRadius = BorderRadius(4, 5, 6, 7) +// borderRadius = BorderRadius(4, 5, 6, 7) apply(border2) - display = Display.none() - borderBottomWidth = BorderWidth.perc(13) +// display = Display.none() +// borderBottomWidth = BorderWidth.perc(13) } } } } + val borderStyle = style { select(".border") { apply(border) apply(font) select("> p") { - fontSize = FontSize.smaller() +// fontSize = FontSize.smaller() } } } + val test = style { + select("nav") { + alignContent(STRETCH) + margin(0.px(), 2.em(), 0.5.px(), Measurement.auto()) + } + } + println("======") println(sd.generateCss()) println("======") println(sd.generateCss(minified = true)) println("======") println(borderStyle.generateCss()) + println("======") + println(test.generateCss()) }