Browse Source

fix Style composable and CSSRulesHolderState (#1889)

Co-authored-by: Oleksandr Karpovich <oleksandr.karpovich@jetbrains.com>
pull/1770/merge
Oleksandr Karpovich 2 years ago committed by GitHub
parent
commit
1ab63ed995
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      examples/web-landing/src/jsMain/kotlin/com/sample/content/CodeSnippets.kt
  2. 1
      examples/web-landing/src/jsMain/kotlin/com/sample/content/IntroSection.kt
  3. 11
      web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheet.kt
  4. 2
      web/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/Elements.kt
  5. 77
      web/core/src/jsTest/kotlin/CSSStylesheetTests.kt

1
examples/web-landing/src/jsMain/kotlin/com/sample/content/CodeSnippets.kt

@ -263,6 +263,7 @@ fun FormattedCodeSnippet(code: String, language: String = "kotlin") {
backgroundColor(Color("transparent"))
}
}) {
@Suppress("DEPRECATION")
DomSideEffect(code) {
it.setHighlightedCode(code)
}

1
examples/web-landing/src/jsMain/kotlin/com/sample/content/IntroSection.kt

@ -2,7 +2,6 @@ package com.sample.content
import androidx.compose.runtime.*
import org.jetbrains.compose.web.attributes.ATarget
import org.jetbrains.compose.web.attributes.AttrsBuilder
import org.jetbrains.compose.web.attributes.target
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.*

11
web/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleSheet.kt

@ -1,20 +1,19 @@
package org.jetbrains.compose.web.css
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.mutableStateListOf
import org.jetbrains.compose.web.ExperimentalComposeWebStyleApi
import org.jetbrains.compose.web.css.selectors.CSSSelector
import org.jetbrains.compose.web.dom.Style
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class CSSRulesHolderState : CSSRulesHolder {
override var cssRules: CSSRuleDeclarationList by mutableStateOf(listOf())
override val cssRules = mutableStateListOf<CSSRuleDeclaration>()
override fun add(cssRule: CSSRuleDeclaration) {
@Suppress("SuspiciousCollectionReassignment")
cssRules += cssRule
cssRules.add(cssRule)
}
}

2
web/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/Elements.kt

@ -947,7 +947,7 @@ fun Style(
}
},
) {
DisposableEffect(cssRules) {
DisposableEffect(cssRules, cssRules.size) {
val cssStylesheet = scopeElement.sheet as? CSSStyleSheet
cssStylesheet?.setCSSRules(cssRules)
onDispose {

77
web/core/src/jsTest/kotlin/CSSStylesheetTests.kt

@ -5,12 +5,17 @@
package org.jetbrains.compose.web.core.tests
import androidx.compose.runtime.mutableStateOf
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.dom.stringPresentation
import org.w3c.dom.HTMLElement
import org.w3c.dom.get
import org.jetbrains.compose.web.testutils.*
import org.w3c.dom.HTMLDivElement
import org.w3c.dom.HTMLStyleElement
import org.w3c.dom.css.CSSStyleSheet
import org.w3c.dom.css.get
import kotlin.test.*
object AppCSSVariables {
@ -320,4 +325,76 @@ class CSSVariableTests {
}
}
}
@Test
fun testChildStylesheetsGetApplied() = runTest {
val showContent = mutableStateOf(false)
composition {
Style(TestRootStylesheet2)
if (showContent.value) {
Div(attrs = {
classes(ChildStylesheet2.content)
}) {}
}
}
val styleElem = root.children[0] as HTMLStyleElement
val cssStyleSheet = styleElem.sheet as CSSStyleSheet
assertEquals(1, cssStyleSheet.cssRules.length)
assertEquals(".cls1 { padding: 10px; }", cssStyleSheet.cssRules[0]!!.cssText)
showContent.value = true
waitForRecompositionComplete()
with(root.children[1] as HTMLDivElement) {
assertEquals("content", getAttribute("class"))
}
// 2nd recomposition occurs since TestRootStylesheet2 was changed during recomposition
// when ChildStylesheet2 was initialised after showContent was set into "true"
waitForRecompositionComplete()
val styleElem2 = root.children[0] as HTMLStyleElement
val cssStyleSheet2 = styleElem2.sheet as CSSStyleSheet
assertEquals(".cls1 { padding: 10px; }", cssStyleSheet2.cssRules[0]!!.cssText)
assertEquals(2, cssStyleSheet2.cssRules.length)
assertEquals(".content { color: red; }", cssStyleSheet2.cssRules[1]!!.cssText)
}
@Test
fun testChildStylesheetsGetApplied2() = runTest {
composition {
Style(TestRootStylesheet)
Div(attrs = { classes(ChildStylesheet.content) })
}
val styleElem = root.children[0] as HTMLStyleElement
val cssStyleSheet = styleElem.sheet as CSSStyleSheet
assertEquals(2, cssStyleSheet.cssRules.length)
assertEquals(".cls1 { padding: 10px; }", cssStyleSheet.cssRules[0]!!.cssText)
assertEquals(".content { color: red; }", cssStyleSheet.cssRules[1]!!.cssText)
}
}
private object TestRootStylesheet : StyleSheet(usePrefix = false) {
val cls1 by style {
padding(10.px)
}
}
private object ChildStylesheet : StyleSheet(TestRootStylesheet, usePrefix = false) {
val content by style {
color(Color.red)
}
}
// Use duplicates for another test to ensure uninitialized objects will be used
private object TestRootStylesheet2 : StyleSheet(usePrefix = false) {
val cls1 by style {
padding(10.px)
}
}
private object ChildStylesheet2 : StyleSheet(TestRootStylesheet2, usePrefix = false) {
val content by style {
color(Color.red)
}
}

Loading…
Cancel
Save