Hey everyone, I'd like to discuss an intriguing to...
# compose
s
Hey everyone, I'd like to discuss an intriguing topic regarding the order of arguments in composable functions, focusing specifically on the placement of the
Modifier
argument within a composable function invocation, rather than in its declaration. Thread 🧵:
Jetpack Compose provides clear API guidelines on the order of arguments in a composable function, as outlined in their component API guidelines: Jetpack Compose API Guidelines. According to the guidelines, the order of parameters in a component should be as follows: 1. Required parameters. 2. A single modifier:
Modifier = Modifier
.
3. Optional parameters. Furthermore, the guidelines specify that the modifier should be the first optional parameter in a
@Composable
function, must be named
modifier
, and have a default value of
Modifier
. There should be only one modifier parameter, and it should be applied to the root-most layout in the implementation.
For example:
Copy code
@Composable
fun Icon(
    bitmap: ImageBitmap, // Required
    contentDescription: String?, // Required, follows as it's considered "metadata"
    modifier: Modifier = Modifier, // First optional parameter
    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current) // Other optional parameters
)
However, what we've observed (and practiced) in most official samples, such as calling the
Icon
function with
Icon(modifier = Modifier.size(...), bitmap = ...)
, deviates from the order defined in the function declaration.
This has sparked a debate within our team regarding the placement of the modifier when calling (importantly) the composable function: should it always be the first argument, or should we adhere to the strict order in which the arguments are declared? Some team members argue that arguments should be called in the order they were declared, while others lean towards following the approach shown in samples and documentation. Unfortunately, we couldn't find explicit information on this matter in the API Guide or the developer.android.com documentation. Yet, all of the samples, codelabs, etc., seem to follow an implicit rule of having the modifier as the first argument in a composable function call. Could you help us resolve this debate by providing a clearer answer?
b
Sorry to have caused confusion, I think the order you call parameters in is up to your team and if you want to be strict on that. I can tell you though that we don't have that as an implicit rule for the samples and codelabs to call modifier first or for the order of parameters in a function call. I did a quick search based on your example (https://github.com/search?q=repo%3Aandroid%2Fcompose-samples+Icon&type=code&p=1) and couldn't find them. I am sure it exists though and if it is causing confusion then maybe we could be stricter on it.
👆 1
s
I apologize for any confusion. The "Icon" example I referenced from the guidelines page was used to illustrate the general pattern I've observed in code samples. Upon revisiting the documentation, codelabs, and other official samples, I noticed that the placement of the
modifier
argument varies. Indeed, in some instances, the
modifier
is assigned first, while in others, it follows the order in which it was defined within the function.
In Jetpack Compose, I believe the
Modifier
is crucial because it shapes how a component looks and behaves, guiding its placement and functionality. Given its importance, I usually prioritize setting the
Modifier
first in my code. This helps me grasp the component's design and behavior right away. After that, I focus on the required and then the optional parameters. Do you think prioritizing
Modifier
like this makes sense?
u
I agree that
Modifier
has priority to other params in most usage scenario. But for common case, it should be optional since some
Composable
function may have nothing to modify, e.g.
@Composable Text
. I believe it is the best solution between usage and Kotlin grammer stricts for now, and leave the rest to your team's lint rules.
v
When we are calling Composables in our code, we place Modifier as the last parameter. We've agreed that it looks better than following defined order in declaration. And chaining multiple Modifiers kinda easier if you don't have trailing comma 🤔
plus1 2