-
Notifications
You must be signed in to change notification settings - Fork 8
Home
Finds usages of the modifier
parameter on non-top-level children of a composable function. This tends to happen during refactorings and often leads to incorrect rendering of a composable.
For example, imagine that Column
here used to be a top composable, but then it got wrapped by the Row
. But the modifier
parameter was moved along with it and is now applied to the wrong composable:
@Composable
fun MyComposable(modifier: Modifier) {
Row(modifier = Modifier.padding(30.dp)) {
Column(modifier = modifier.padding(20.dp)) {
}
}
}
@Composable
fun Content() {
MyComposable(modifier = Modifier.background(color = Color.Green))
}
This should be fixed by using modifier
parameter on the Row
instead:
@Composable
fun MyComposable(modifier: Modifier) {
Row(modifier = modifier.height(30.dp)) {
Column(modifier = Modifier.padding(20.dp)) {
}
}
}
Suggests hoisting event argument passing to the upper level which often simplifies individual composable components. This makes individual components less coupled to the structure of their parameters and leaves that to the parent, which in turn often leads to simplification of a composable.
For example here the PrettyButton
is unnecessary coupled to the structure of Data
— it extracts id
field inside the onClick
:
data class Data(id: Int, title: String)
fun PrettyButton(data: Data, onAction: (Int) -> Unit) {
Button(onClick = { onAction(data.id) })
}
fun Parent() {
val data = Data(id = 3, title = "foo")
PrettyButton(data = data, onAction = { id -> process(id) })
}
This "knowledge" of id
can be moved to the parent which would not only simplify the PrettyButton
by removing unnecessary lambda wrapper around onAction
call, but this also makes it easier to work with PrettyButton
later, during refactorings. Here the data.id
is hoisted into the parent:
fun PrettyButton(data: Data, onAction: () -> Unit) {
Button(onClick = onAction)
}
fun Parent() {
val data = Data(id = 3, title = "foo")
PrettyButton(data = data, onAction = { process(data.id) })
}
Ensures that all event handler parameters of composable functions are named in the same Compose-like style, i.e. they have on
prefix and do not use past tense.
This rule suggests naming improvements
fun Button(click: () -> Unit) // ❌ wrong: missing "on"
fun Button(onClick: () -> Unit) // ✅ correct
fun Box(scroll: () -> Unit) // ❌ wrong: missing "on"
fun Box(onScroll: () -> Unit) // ✅ correct
fun Box(onScrolled: () -> Unit) // ❌ wrong: using past tense
fun Box(onScroll: () -> Unit) // ✅ correct
Suggests using Modifier.heightIn()
instead of Modifier.height()
on a layouts which have Text
children, so that if the text turns out to be long and would overflow and wrap, layout will not cut it off
Row(modifier = Modifier.height(24.dp)) {
Text("hello")
}
with
Row(modifier = Modifier.heightIn(min = 24.dp)) {
Text("hello")
}
Ensure that modifier
is declared and passed as a first parameter/argument:
Button(
arrangement = Vertical,
modifier = Modifier,
)
Button(arrangement = Vertical, modifier = Modifier.padding(24.dp))
Should be replaced with:
Button(
modifier = Modifier,
arrangement = Vertical,
)
Button(modifier = Modifier.padding(24.dp), arrangement = Vertical)
Finds and reports composable previews which are not marked as private