Created
June 28, 2024 14:03
-
-
Save NikolaDespotoski/e12f15ed28064bc1b491f41298cba5b4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@file:OptIn(ExperimentalComposeUiApi::class) | |
import androidx.annotation.DrawableRes | |
import androidx.annotation.IdRes | |
import androidx.annotation.RawRes | |
import androidx.annotation.StringRes | |
import androidx.compose.ui.ExperimentalComposeUiApi | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.input.pointer.PointerEventPass | |
import androidx.compose.ui.input.pointer.PointerInputChange | |
import androidx.compose.ui.input.pointer.pointerInput | |
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode | |
import androidx.compose.ui.node.ModifierNodeElement | |
import androidx.compose.ui.node.SemanticsModifierNode | |
import androidx.compose.ui.node.currentValueOf | |
import androidx.compose.ui.platform.InspectorInfo | |
import androidx.compose.ui.platform.LocalContext | |
import androidx.compose.ui.platform.debugInspectorInfo | |
import androidx.compose.ui.semantics.SemanticsPropertyReceiver | |
import androidx.compose.ui.semantics.testTag | |
import androidx.compose.ui.semantics.testTagsAsResourceId | |
fun Modifier.testId(tag: String, useAsResourceId: Boolean = true) = | |
this then SimpleStringTagModifier(tag, useAsResourceId) | |
fun Modifier.disableInteraction(disabled: Boolean = true) = | |
this then if (disabled) { | |
pointerInput(Unit) { | |
awaitPointerEventScope { | |
// we should wait for all new pointer events | |
while (true) { | |
awaitPointerEvent(pass = PointerEventPass.Initial) | |
.changes | |
.forEach(PointerInputChange::consume) | |
} | |
} | |
} | |
} else { | |
this | |
} | |
private data class SimpleStringTagModifier( | |
private val tag: String, private val useAsResourceId: Boolean = true | |
) : ModifierNodeElement<StringTagNode>() { | |
override fun create() = StringTagNode(tag = tag, useAsResourceId = useAsResourceId) | |
override fun update(node: StringTagNode) { | |
node.tag = tag | |
node.useAsResourceId = useAsResourceId | |
} | |
override fun InspectorInfo.inspectableProperties() { | |
debugInspectorInfo { | |
name = "id-semantics-simple-string-tag" | |
properties["tag"] = tag | |
properties["useAsResourceId"] = useAsResourceId | |
} | |
} | |
} | |
private data class ResourceIdModifierNode( | |
@StringRes @IdRes @RawRes @DrawableRes private val id: Int, | |
private val useAsResourceId: Boolean = true, | |
) : ModifierNodeElement<ResourceIdNode>() { | |
override fun create(): ResourceIdNode = | |
ResourceIdNode(id = id, useAsResourceId = useAsResourceId) | |
override fun update(node: ResourceIdNode) { | |
node.id = id | |
node.useAsResourceId = useAsResourceId | |
} | |
override fun InspectorInfo.inspectableProperties() { | |
debugInspectorInfo { | |
name = "id-semantics" | |
properties["id"] = id | |
properties["useAsResourceId"] = useAsResourceId | |
} | |
} | |
} | |
private abstract class AbstractTestTagNode(private val useAsResourceId: Boolean) : SemanticsModifierNode, Modifier.Node(){ | |
override fun SemanticsPropertyReceiver.applySemantics() { | |
testTag = createTestTag() | |
testTagsAsResourceId = useAsResourceId | |
} | |
abstract fun createTestTag(): String | |
} | |
private class StringTagNode( | |
var tag: String, | |
var useAsResourceId: Boolean = true | |
) : AbstractTestTagNode(useAsResourceId) { | |
override fun createTestTag(): String = tag | |
} | |
private class ResourceIdNode( | |
var id: Int, | |
var useAsResourceId: Boolean = true | |
) : AbstractTestTagNode(useAsResourceId), CompositionLocalConsumerModifierNode { | |
override fun createTestTag(): String { | |
val tag = currentValueOf(LocalContext).resources.getResourceEntryName(id) | |
return tag | |
} | |
} | |
fun Modifier.testId( | |
@StringRes @IdRes @RawRes @DrawableRes id: Int, | |
useAsResourceId: Boolean = true | |
) = this then ResourceIdModifierNode(id, useAsResourceId) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment