🌈 Create new beautiful Compose Gradients with our new wesite ->
Function

traverseDescendants

Conditionally executes block for each descendant with a matching key.

traverseDescendantsWithKeyDemo

@Sampled
fun traverseDescendantsWithKeyDemo() {
    val customTraversableModifierNode = CustomTraversableModifierNode()

    with(customTraversableModifierNode) {
        traverseDescendants(traverseKey) {
            if (it is CustomTraversableModifierNode) {
                it.doSomethingWithDescendant()
            }

            // [traverseDescendants()] actually has three options:
            // - ContinueTraversal
            // - SkipSubtreeAndContinueTraversal - rarely used
            // - CancelTraversal
            // They are pretty self explanatory. Usually, you just want to continue or cancel the
            // search. In some rare cases, you might want to skip the subtree but continue searching
            // the tree.
            TraverseDescendantsAction.ContinueTraversal
        }
    }
}

/**
 * Simplified example of traverseDescendants. For a full featured sample, look below at
 * [TraverseModifierDemo].
 */

traverseDescendantsDemo

@Sampled
fun traverseDescendantsDemo() {
    val customTraversableModifierNode = CustomTraversableModifierNode()

    with(customTraversableModifierNode) {
        traverseDescendants {
            // Because I use the existing key of the class, I can guarantee 'it' will be of the same
            // type as the class, so I can call my functions directly.
            it.doSomethingWithDescendant()

            // [traverseDescendants()] actually has three options:
            // - ContinueTraversal
            // - SkipSubtreeAndContinueTraversal - rarely used
            // - CancelTraversal
            // They are pretty self explanatory. Usually, you just want to continue or cancel the
            // search. In some rare cases, you might want to skip the subtree but continue searching
            // the tree.
            TraverseDescendantsAction.ContinueTraversal
        }
    }
}

/**
 * Demonstrates how to use TraversableNode to traverse Modifier.Node ancestors, children, and
 * descendants of the same key. This is done in 5 main steps:
 *
 * Step 1: Create a unique key for your TraversableNode. Step 2: Create a custom Modifier.Node class
 * that implements TraversableNode. Step 3: Create a custom Modifier.Element class that uses that
 * custom Modifier.Node. Step 4: Create an extension function on Modifier that uses the
 * Modifier.Element. Step 5: Traverse the Modifier chain when you need to find your node(s).
 *
 * You can see the impact visually of traversing a particular direction from a TraversableNode by
 * the TraversableNode(s) above or below changing their color to green. You can always reset the
 * colors to try out a different traversal methods or nodes.
 *
 * Important Note: References are maintained to all the TraversableNode(s) in this UI, so we can
 * directly call the traversable functions to see how they impact the tree. (We see this visually by
 * the nodes changing color to green.) However, you most likely won't need a block parameter in your
 * code to assign a reference. You will probably just trigger your traversals based on some other
 * event (like a PointerEvent).
 *
 * See Compose Foundation's PointerHoverIconModifierNode or the DragAndDropNode implementations for
 * real life examples. (PointerHoverIconModifierNode also skips subtrees.)
 *
 * You can also see more examples in TraversableModifierNodeTest (where we use multiple
 * TraversableNodes with different keys).
 *
 * Simplified UI hierarchy for this demo (starts at first TraversableNode and ignores
 * non-traversable Row, Spacers, and Text label composables along the way):
 *
 * Column Root (TraversableBackgroundModifierNode) ⤷ Column A (TraversableBackgroundModifierNode) ⤷
 * Box A (TraversableBackgroundModifierNode) ⤷ Box B (NON-TRAVERSABLE Box) ⤷ Box C
 * (TraversableBackgroundModifierNode)
 *
 * ⤷ Column B (TraversableBackgroundModifierNode) ⤷ Box D (NON-TRAVERSABLE Box) ⤷ Box E
 * (TraversableBackgroundModifierNode) ⤷ Box F (NON-TRAVERSABLE Box)
 */