You only need to use composed to make @Composable calls.
Note, that inside composed you should only use state annotated composables, like to save some state using remember, but not the composable views. More details can be found here.
So technically, to get rid of the warning, you could've simplified your code to this:
inline fun Modifier.debounceClickable(
debounceInterval: Long = 400,
crossinline onClick: () -> Unit,
): Modifier {
var lastClickTime = 0L
return clickable() {
val currentTime = System.currentTimeMillis()
if ((currentTime - lastClickTime) < debounceInterval) return@clickable
lastClickTime = currentTime
onClick()
}
}
And it would work the same, as your current code.
The problem is that you store data in lastClickTime, and with your code it's gonna be reset as soon as the first recomposition happens. It may work fine only if you don't change UI with the action.
You can test it with the following core:
var flag by remember { mutableStateOf(false) }
Text("clickable $flag", Modifier.debounceClickable { flag = !flag } )
That's why you actually need composed to store this value using remember and mutableStateOf, just like in any other view:
inline fun Modifier.debounceClickable(
debounceInterval: Long = 400,
crossinline onClick: () -> Unit,
): Modifier = composed {
var lastClickTime by remember { mutableStateOf(0L) }
clickable() {
val currentTime = System.currentTimeMillis()
if ((currentTime - lastClickTime) < debounceInterval) return@clickable
lastClickTime = currentTime
onClick()
}
}
I suggest you check out with state in Compose documentation, including this youtube video which explains the basic principles.