Is it correct to call `invoke` on composable funct...
# compose-desktop
v
Is it correct to call
invoke
on composable functions? I'm creating a desktop status bar row like this...
Copy code
@Composable
fun StatusBar(
    left: @Composable (() -> Unit)? = null,
    centre: @Composable (() -> Unit)? = null,
    right: @Composable (() -> Unit)? = null
) {
    Row(
        Modifier.fillMaxWidth().padding(2.dp).border(1.dp, Color.Gray),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Box(Modifier.padding(start = 2.dp)) { left?.invoke() }
        Box { centre?.invoke() }
        Box(Modifier.padding(end = 2.dp)) { right?.invoke() }
    }
}
I can't find an example of implementing the built in
RowScope
or
ColumnScope
or whatever functions, which is what I think I need. But not sure.
I find I really don't know what to google for with compose!
s
Not exactly sure what you're going for, but you propagate RowScope like this:
Copy code
fun StatusBar(content: RowScope.() -> Unit) {
    Row(...) { content() } // content() can only be called inside Row because it's providing a RowScope 
}
v
Maybe mentioning RowScope wasn't helpful. The StatusBar I've built above is working, but is it doing it the compose way?
Maybe I'm supposed to be creating a
rememberStatusBar
type function and a
MutableStateOf<StatusBarContent>
?
s
Ah, so creating a new state for your composable only really makes sense if the composable itself holds stateful content. Your composable is more like a layout which usually doesn't have state. See Box, Row, etc. Usually it's good practice that the first optional parameter is a
Modifier
which is passed to the immediate child. In your case it would be your
Row
. You can see that with almost every composable.
invoke()
on composables is fine. Depending on the effect you want, you might want to avoid creating the Box if a param is null
if (left != null) Box { left() }
. But in your case I think you need the boxes that the layout looks as you expect it to.
If you integrate into Material you probably also want to use a Theme color instead of
Color.Gray
.
👍 1
v
I'd have to pass the theme object in then?
s
You'd use an appropriate color inside the composable, such as
border(1.dp, Theme.colorScheme.outline)
for Material3. Or you can also pass it as a parameter into the composable
borderColor: Color = ...
if you want to make it easier modifiable. If you don't want to tie it to Material2/3 then you would also pass it in as a parameter but probably just not provide a default value, so the caller would have to provide it.