Skip to content

Commit

Permalink
New "Recompose" playground page and recomposition fixes
Browse files Browse the repository at this point in the history
Useful for verifying that we aren't seeing excessive
recompositions

Bug #554
  • Loading branch information
bitspittle committed Jun 18, 2024
1 parent 3a7e06c commit 26ba2d5
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.jetbrains.compose.web.dom.Div
import org.w3c.dom.HTMLElement

@LayoutScopeMarker
@Immutable // TODO(#554): Remove annotation after upstream fix
interface BoxScope {
fun Modifier.align(alignment: Alignment) = attrsModifier {
classes("${alignment.toClassName()}-self")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.jetbrains.compose.web.dom.Div
import org.w3c.dom.HTMLElement

@LayoutScopeMarker
@Immutable // TODO(#554): Remove annotation after upstream fix
interface ColumnScope : FlexScope {
fun Modifier.align(alignment: Alignment.Horizontal) = attrsModifier {
classes("${alignment.toClassName()}-self")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.varabyte.kobweb.compose.foundation.layout

import androidx.compose.runtime.*
import com.varabyte.kobweb.compose.ui.Modifier
import com.varabyte.kobweb.compose.ui.modifiers.*

@LayoutScopeMarker
@Immutable // TODO(#554): Remove annotation after upstream fix
interface FlexScope {
// Convenient remapping to "flexGrow" for users coming from the world of Android
fun Modifier.weight(value: Number) = this.flexGrow(value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.jetbrains.compose.web.dom.Div
import org.w3c.dom.HTMLElement

@LayoutScopeMarker
@Immutable // TODO(#554): Remove annotation after upstream fix
interface RowScope : FlexScope {
fun Modifier.align(alignment: Alignment.Vertical) = attrsModifier {
classes("${alignment.toClassName()}-self")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.varabyte.kobweb.silk.components.overlay

import androidx.compose.runtime.*
import com.varabyte.kobweb.browser.dom.observers.ResizeObserver
import com.varabyte.kobweb.compose.css.*
import com.varabyte.kobweb.compose.css.Transition
Expand Down Expand Up @@ -73,6 +74,7 @@ enum class PopupPlacement {
* Note that this is essentially a [BoxScope] with some extra information added to it relevant to popups.
*/
@LayoutScopeMarker
@Immutable // TODO(#554): Remove annotation after upstream fix
class PopupScope(val placement: PopupPlacement?) : BoxScope

private fun HTMLElement.updatePosition(position: PopupPlacementStrategy.Position) {
Expand Down
89 changes: 89 additions & 0 deletions playground/site/src/jsMain/kotlin/playground/pages/Recompose.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
@file:Suppress("NOTHING_TO_INLINE")

package playground.pages

import androidx.compose.runtime.*
import com.varabyte.kobweb.compose.css.*
import com.varabyte.kobweb.compose.foundation.layout.Arrangement
import com.varabyte.kobweb.compose.foundation.layout.Box
import com.varabyte.kobweb.compose.foundation.layout.Column
import com.varabyte.kobweb.compose.foundation.layout.Row
import com.varabyte.kobweb.compose.ui.Alignment
import com.varabyte.kobweb.compose.ui.Modifier
import com.varabyte.kobweb.compose.ui.modifiers.*
import com.varabyte.kobweb.core.Page
import com.varabyte.kobweb.silk.components.forms.Button
import com.varabyte.kobweb.silk.components.forms.Checkbox
import com.varabyte.kobweb.silk.components.forms.TextInput
import com.varabyte.kobweb.silk.components.text.SpanText
import com.varabyte.kobweb.silk.style.CssStyle
import com.varabyte.kobweb.silk.style.selectors.descendants
import com.varabyte.kobweb.silk.style.toAttrs
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.P
import org.jetbrains.compose.web.dom.Table
import org.jetbrains.compose.web.dom.Td
import org.jetbrains.compose.web.dom.Text
import org.jetbrains.compose.web.dom.Th
import org.jetbrains.compose.web.dom.Tr
import playground.components.layouts.PageLayout

@Composable
private inline fun RecomposeCount() {
var recomposeCount by remember { mutableStateOf(0) }
recomposeCount++
Text(recomposeCount.toString())
}

@Composable
private inline fun CodeText(text: String) {
SpanText(text, Modifier.fontFamily("monospace"))
}



// This page is for testing that we don't get unexpected unecessary recompositions which can happen if we screw up
// composable parameters.
@Page
@Composable
fun RecomposePage() {
PageLayout("Recompose") {
var msg by remember { mutableStateOf("") }
TextInput(msg, onTextChange = { msg = it }, Modifier.width(350.px).margin(bottom = 2.cssRem), placeholder = "Type text here to test sibling recompositions")

SpanText(
"The following blocks show code being run plus its recompose count when the above text input's text changes. If everything is healthy with our library code, the recompose count will stay at 1.",
Modifier.width(400.px).fontStyle(FontStyle.Italic)
)
P()

// All code below here should follow the template:
// CodeText(...)
// Code { RecomposeCount() }
// P()
//
// If we notice a case where the recompose count increments unexpectedly, we should add an entry below and fix
// it in the library code.

// Fixed by marking BoxScope @Immutable
CodeText("Box(Modifier.width(...))")
Box(Modifier.width(100.px), contentAlignment = Alignment.Center) {
RecomposeCount()
}
P()

// Fixed by marking RowScope @Immutable
CodeText("Row(Arrangement.spacedBy(...))")
Row(horizontalArrangement = Arrangement.spacedBy(10.px)) {
RecomposeCount()
}
P()

// Fixed by marking ColumnScope @Immutable
CodeText("Column(Arrangement.spacedBy(...))")
Column(verticalArrangement = Arrangement.spacedBy(10.px)) {
RecomposeCount()
}
P()
}
}

0 comments on commit 26ba2d5

Please sign in to comment.