Browse Source

Add support of important in compose html css dsl (#5439)

Fixes https://youtrack.jetbrains.com/issue/CMP-8992

## Testing

Add test in `org.jetbrains.compose.web.core.tests.css.StyleSheetTests`

## Release Notes

### HTML - CSS DSL

- Add support of
[`important`](https://developer.mozilla.org/en-US/docs/Web/CSS/important)
keyword for CSS properties

---------

Co-authored-by: Oleksandr Karpovich <a.n.karpovich@gmail.com>
shish/switch-to-embeddable-compose-compiler-plugin-rebased v1.10.0-beta01+dev3171
InsanusMokrassar 2 months ago committed by GitHub
parent
commit
ebab3739c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 42
      html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleScope.kt
  2. 4
      html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Base.kt
  3. 13
      html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Style.kt
  4. 27
      html/core/src/jsTest/kotlin/css/StyleSheetTests.kt

42
html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleScope.kt

@ -43,10 +43,31 @@ interface StyleScope { @@ -43,10 +43,31 @@ interface StyleScope {
* ```
*/
fun property(propertyName: String, value: StylePropertyValue)
/**
* Adds arbitrary CSS property to the inline style of the element. By default throws an error for backward compatibility
* @param propertyName - the name of css property as [per spec](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference)
* @param value - the value, it can be either String or specialized type like [CSSNumeric] or [CSSColorValue]
* @param important - the flag which will be passed to property call in CSS
*
* Most frequent CSS property values can be set via specialized methods, like [width], [display] etc.
*
* Example:
* ```
* Div({
* style {
* property("some-exotic-css-property", "I am a string value", true)
* property("some-exotic-css-property-width", 5.px, false)
* }
* })
* ```
*/
fun property(propertyName: String, value: StylePropertyValue, important: Boolean): Unit = error("!important is not supported by this implementation")
fun variable(variableName: String, value: StylePropertyValue)
fun property(propertyName: String, value: String) = property(propertyName, StylePropertyValue(value))
fun property(propertyName: String, value: String, important: Boolean) = property(propertyName, StylePropertyValue(value), important)
fun property(propertyName: String, value: Number) = property(propertyName, StylePropertyValue(value))
fun property(propertyName: String, value: Number, important: Boolean) = property(propertyName, StylePropertyValue(value), important)
fun variable(variableName: String, value: String) = variable(variableName, StylePropertyValue(value))
fun variable(variableName: String, value: Number) = variable(variableName, StylePropertyValue(value))
@ -150,8 +171,12 @@ open class StyleScopeBuilder : StyleScope, StyleHolder { @@ -150,8 +171,12 @@ open class StyleScopeBuilder : StyleScope, StyleHolder {
override val properties: MutableStylePropertyList = mutableListOf()
override val variables: MutableStylePropertyList = mutableListOf()
override fun property(propertyName: String, value: StylePropertyValue, important: Boolean) {
properties.add(StylePropertyDeclaration(propertyName, value, important))
}
override fun property(propertyName: String, value: StylePropertyValue) {
properties.add(StylePropertyDeclaration(propertyName, value))
property(propertyName = propertyName, value = value, important = false)
}
override fun variable(variableName: String, value: StylePropertyValue) {
@ -175,10 +200,16 @@ open class StyleScopeBuilder : StyleScope, StyleHolder { @@ -175,10 +200,16 @@ open class StyleScopeBuilder : StyleScope, StyleHolder {
data class StylePropertyDeclaration(
val name: String,
val value: StylePropertyValue
val value: StylePropertyValue,
val important: Boolean,
) {
constructor(name: String, value: String) : this(name, value.unsafeCast<StylePropertyValue>())
constructor(name: String, value: Number) : this(name, value.unsafeCast<StylePropertyValue>())
constructor(name: String, value: StylePropertyValue) : this(name, value, false)
constructor(name: String, value: String, important: Boolean) : this(name, value.unsafeCast<StylePropertyValue>(), important)
constructor(name: String, value: String) : this(name, value, false)
constructor(name: String, value: Number, important: Boolean) : this(name, value.unsafeCast<StylePropertyValue>(), important)
constructor(name: String, value: Number) : this(name, value, false)
}
typealias StylePropertyList = List<StylePropertyDeclaration>
typealias MutableStylePropertyList = MutableList<StylePropertyDeclaration>
@ -190,6 +221,7 @@ internal fun StylePropertyList.nativeEquals(properties: StylePropertyList): Bool @@ -190,6 +221,7 @@ internal fun StylePropertyList.nativeEquals(properties: StylePropertyList): Bool
return all { prop ->
val otherProp = properties[index++]
prop.name == otherProp.name &&
prop.value.toString() == otherProp.value.toString()
prop.important == otherProp.important && prop.value.toString() == otherProp.value.toString()
}
}

4
html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Base.kt

@ -67,8 +67,8 @@ private class DomElementWrapper(override val node: Element): DomNodeWrapper(node @@ -67,8 +67,8 @@ private class DomElementWrapper(override val node: Element): DomNodeWrapper(node
val style = node.unsafeCast<ElementCSSInlineStyle>().style
styleApplier.properties.forEach { (name, value) ->
style.setProperty(name, value.toString())
styleApplier.properties.forEach { (name, value, important) ->
style.setProperty(name, value.toString(), if (important) "important" else "")
}
styleApplier.variables.forEach { (name, value) ->

13
html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Style.kt

@ -54,8 +54,8 @@ private fun fillRule( @@ -54,8 +54,8 @@ private fun fillRule(
when (cssRuleDeclaration) {
is CSSStyledRuleDeclaration -> {
val cssStyleRule = cssRule.unsafeCast<CSSStyleRule>()
cssRuleDeclaration.style.properties.forEach { (name, value) ->
setProperty(cssStyleRule.style, name, value)
cssRuleDeclaration.style.properties.forEach { (name, value, important) ->
setProperty(cssStyleRule.style, name, value, important)
}
cssRuleDeclaration.style.variables.forEach { (name, value) ->
setVariable(cssStyleRule.style, name, value)
@ -86,8 +86,8 @@ fun CSSRuleDeclaration.stringPresentation( @@ -86,8 +86,8 @@ fun CSSRuleDeclaration.stringPresentation(
strings.add("$baseIndent${cssRuleDeclaration.header} {")
when (cssRuleDeclaration) {
is CSSStyledRuleDeclaration -> {
cssRuleDeclaration.style.properties.forEach { (name, value) ->
strings.add("$baseIndent$indent$name: $value;")
cssRuleDeclaration.style.properties.forEach { (name, value, important) ->
strings.add("$baseIndent$indent$name: $value${if (important) " !important" else ""};")
}
cssRuleDeclaration.style.variables.forEach { (name, value) ->
strings.add("$baseIndent$indent--$name: $value;")
@ -111,9 +111,10 @@ fun CSSRuleDeclaration.stringPresentation( @@ -111,9 +111,10 @@ fun CSSRuleDeclaration.stringPresentation(
internal fun setProperty(
style: CSSStyleDeclaration,
name: String,
value: StylePropertyValue
value: StylePropertyValue,
important: Boolean
) {
style.setProperty(name, value.toString())
style.setProperty(name, value.toString(), if (important) "important" else "")
}
internal fun setVariable(

27
html/core/src/jsTest/kotlin/css/StyleSheetTests.kt

@ -42,6 +42,33 @@ class StyleSheetTests { @@ -42,6 +42,33 @@ class StyleSheetTests {
)
}
@Test
fun useImportantStyleSheet() {
val styleSheet = object : StyleSheet(usePrefix = false) {
val someClassName by style {
property("color", "red", true)
}
}
val childStyleSheet = object : StyleSheet(styleSheet, usePrefix = false) {
val someClassName by style {
property("color", "green", false)
}
}
assertContentEquals(
listOf(".someClassName { color: red !important;}", ".someClassName { color: green;}"),
styleSheet.serializeRules(),
"styleSheet rules"
)
assertContentEquals(
listOf(".someClassName { color: red !important;}", ".someClassName { color: green;}"),
childStyleSheet.serializeRules(),
"childStyleSheet rules"
)
}
@Test
fun stylesheetCorrectlyUsingIncomingPrefix() {
val testPrefixParent = "test_prefix_parent-"

Loading…
Cancel
Save