# RippleNodeConfiguration

Artifact: [androidx.compose.material3:material3-ripple](https://developer.android.com/jetpack/androidx/releases/compose-material3) [View Source](https://cs.android.com/search?q=file:androidx/compose/material3/ripple/RippleNodeConfiguration.kt+class:androidx.compose.material3.ripple.RippleNodeConfiguration) Common/All
- Cmn

  ```
  class RippleNodeConfiguration
  ```

*** ** * ** ***

The configuration for the ripple node created by `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/package-summary#createRippleModifierNode(androidx.compose.foundation.interaction.InteractionSource,kotlin.Function0)`.

```kotlin
import androidx.compose.foundation.IndicationNodeFactory
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.material3.ripple.RippleNodeConfiguration
import androidx.compose.material3.ripple.createRippleModifierNode
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorProducer
import androidx.compose.ui.graphics.isSpecified
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
import androidx.compose.ui.node.DelegatableNode
import androidx.compose.ui.node.DelegatingNode
import androidx.compose.ui.node.ObserverModifierNode
import androidx.compose.ui.node.currentValueOf
import androidx.compose.ui.node.observeReads
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

/** Example CompositionLocals for a custom design system theme. */
val LocalCustomRippleColor: ProvidableCompositionLocal<Color> = compositionLocalOf { Color.Red }
val LocalCustomRippleEnabled: ProvidableCompositionLocal<Boolean> = compositionLocalOf { true }

/**
 * A custom [Modifier.Node] that queries design system theme values and delegates to
 * [createRippleModifierNode].
 */
class CustomRippleNode(
    private val interactionSource: InteractionSource,
    private val bounded: Boolean,
    private val radius: Dp,
    private val color: Color,
) : DelegatingNode(), CompositionLocalConsumerModifierNode, ObserverModifierNode {
    private var rippleNode: DelegatableNode? = null

    private val calculateColor = ColorProducer {
        if (color.isSpecified) {
            color
        } else {
            currentValueOf(LocalCustomRippleColor)
        }
    }

    private val rippleNodeConfiguration =
        RippleNodeConfiguration(
            isBounded = bounded,
            radius = radius,
            color = calculateColor,
            pressConfiguration =
                RippleNodeConfiguration.PressConfiguration.Opacity(alpha = 0.24f),
            focusConfiguration =
                RippleNodeConfiguration.FocusConfiguration.Opacity(alpha = 0.24f),
            hoverConfiguration =
                RippleNodeConfiguration.HoverConfiguration.Opacity(alpha = 0.08f),
            dragConfiguration =
                RippleNodeConfiguration.DragConfiguration.Opacity(alpha = 0.16f),
        )

    override fun onAttach() {
        updateConfiguration()
    }

    override fun onObservedReadsChanged() {
        updateConfiguration()
    }

    private fun updateConfiguration() {
        observeReads {
            val isEnabled = currentValueOf(LocalCustomRippleEnabled)
            if (isEnabled) {
                if (rippleNode == null) {
                    attachNewRipple()
                }
            } else {
                removeRipple()
            }
        }
    }

    private fun attachNewRipple() {
        rippleNode =
            delegate(
                createRippleModifierNode(
                    interactionSource = interactionSource,
                    rippleNodeConfiguration = { rippleNodeConfiguration },
                )
            )
    }

    private fun removeRipple() {
        rippleNode?.let { undelegate(it) }
        rippleNode = null
    }
}

/** A custom [IndicationNodeFactory] that creates a [CustomRippleNode]. */
class CustomRipple(
    private val bounded: Boolean = true,
    private val radius: Dp = Dp.Unspecified,
    private val color: Color = Color.Unspecified,
) : IndicationNodeFactory {
    override fun create(interactionSource: InteractionSource): DelegatableNode {
        return CustomRippleNode(interactionSource, bounded, radius, color)
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is CustomRipple) return false
        if (bounded != other.bounded) return false
        if (radius != other.radius) return false
        if (color != other.color) return false
        return true
    }

    override fun hashCode(): Int {
        var result = bounded.hashCode()
        result = 31 * result + radius.hashCode()
        result = 31 * result + color.hashCode()
        return result
    }
}

val interactionSource = remember { MutableInteractionSource() }

Box(
    modifier =
        Modifier.size(100.dp)
            .clickable(
                interactionSource = interactionSource,
                indication = CustomRipple(color = Color.Blue),
                onClick = {},
            )
)
```

## Summary

| ### Nested types |
|---|
| `sealed interface https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.DragConfiguration` Represents the configuration for the visual representation of drag |
| `object https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.DragConfiguration.None : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.DragConfiguration` No drag visual - the created ripple will not show anything for drag. |
| `class https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.DragConfiguration.Opacity : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.DragConfiguration` An opacity-based drag visual. |
| `sealed interface https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration` Represents the configuration for the visual representation of focus |
| `class https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration.InsetRing : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration` An inset ring focus visual - the created ripple will show an inset focus ring. |
| `object https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration.None : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration` No focus visual - the created ripple will not show anything for focus. |
| `class https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration.Opacity : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration` An opacity-based focus visual. |
| `sealed interface https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.HoverConfiguration` Represents the configuration for the visual representation of hover |
| `object https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.HoverConfiguration.None : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.HoverConfiguration` No hover visual - the created ripple will not show anything for hover. |
| `class https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.HoverConfiguration.Opacity : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.HoverConfiguration` An opacity-based hover visual. |
| `sealed interface https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration` Represents the configuration for the visual representation of a press |
| `object https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration.None : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration` No press visual - the created ripple will not show anything for press. |
| `class https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration.Opacity : https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration` An opacity-based press visual - the created ripple will show a layer with the given `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration.Opacity#(kotlin.Float)` on a press. |

| ### Public constructors |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#RippleNodeConfiguration(kotlin.Boolean,androidx.compose.ui.unit.Dp,androidx.compose.ui.graphics.ColorProducer,androidx.compose.material3.ripple.RippleNodeConfiguration.PressConfiguration,androidx.compose.material3.ripple.RippleNodeConfiguration.FocusConfiguration,androidx.compose.material3.ripple.RippleNodeConfiguration.HoverConfiguration,androidx.compose.material3.ripple.RippleNodeConfiguration.DragConfiguration)( isBounded: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html, radius: https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp, color: https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/ColorProducer, pressConfiguration: https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration, focusConfiguration: https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration, hoverConfiguration: https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.HoverConfiguration, dragConfiguration: https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.DragConfiguration )` | Cmn |

| ### Public functions |
|---|---|---|
| `open operator https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#equals(kotlin.Any)(other: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?)` | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#hashCode()()` | Cmn |

| ### Public properties |
|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/ColorProducer` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#color()` the main color of the ripple. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.DragConfiguration` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#dragConfiguration()` the configuration for the visual representation of drag. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#focusConfiguration()` the configuration for the visual representation of focus. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.HoverConfiguration` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#hoverConfiguration()` the configuration for the visual representation of hover. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#isBounded()` if true, ripples are clipped by the bounds of the target layout. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#pressConfiguration()` the configuration for the visual representation of a press. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp` | `https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration#radius()` the radius for the ripple. | Cmn |

## Public constructors

### RippleNodeConfiguration

Cmn

```
RippleNodeConfiguration(
    isBounded: Boolean,
    radius: Dp,
    color: ColorProducer,
    pressConfiguration: RippleNodeConfiguration.PressConfiguration,
    focusConfiguration: RippleNodeConfiguration.FocusConfiguration,
    hoverConfiguration: RippleNodeConfiguration.HoverConfiguration,
    dragConfiguration: RippleNodeConfiguration.DragConfiguration
)
```

| Parameters |
|---|---|
| `isBounded: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | if true, ripples are clipped by the bounds of the target layout. Unbounded ripples always animate from the target layout center, bounded ripples animate from the touch position. |
| `radius: https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp` | the radius for the ripple. If `https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp#Unspecified()` is provided then the size will be calculated based on the target layout size. |
| `color: https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/ColorProducer` | the main color of the ripple. This color is usually the same color used by the text or iconography in the component. This color will then have the various interaction type configurations applied to calculate the final color used to draw the ripple. |
| `pressConfiguration: https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.PressConfiguration` | the configuration for the visual representation of a press. |
| `focusConfiguration: https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.FocusConfiguration` | the configuration for the visual representation of focus. |
| `hoverConfiguration: https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.HoverConfiguration` | the configuration for the visual representation of hover. |
| `dragConfiguration: https://developer.android.com/reference/kotlin/androidx/compose/material3/ripple/RippleNodeConfiguration.DragConfiguration` | the configuration for the visual representation of drag. |

## Public functions

### equals

Cmn

```
open operator fun equals(other: Any?): Boolean
```

### hashCode

Cmn

```
open fun hashCode(): Int
```

## Public properties

### color

Cmn

```
val color: ColorProducer
```

the main color of the ripple. This color is usually the same color used by the text or iconography in the component. This color will then have the various interaction type configurations applied to calculate the final color used to draw the ripple.

### dragConfiguration

Cmn

```
val dragConfiguration: RippleNodeConfiguration.DragConfiguration
```

the configuration for the visual representation of drag.

### focusConfiguration

Cmn

```
val focusConfiguration: RippleNodeConfiguration.FocusConfiguration
```

the configuration for the visual representation of focus.

### hoverConfiguration

Cmn

```
val hoverConfiguration: RippleNodeConfiguration.HoverConfiguration
```

the configuration for the visual representation of hover.

### isBounded

Cmn

```
val isBounded: Boolean
```

if true, ripples are clipped by the bounds of the target layout. Unbounded ripples always animate from the target layout center, bounded ripples animate from the touch position.

### pressConfiguration

Cmn

```
val pressConfiguration: RippleNodeConfiguration.PressConfiguration
```

the configuration for the visual representation of a press.

### radius

Cmn

```
val radius: Dp
```

the radius for the ripple. If `https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp#Unspecified()` is provided then the size will be calculated based on the target layout size.