Got a composable function whose purpose is to take...
# naming
s
Got a composable function whose purpose is to take as much space as the content that is being passed into it. However I do not want it to draw that content. I only need it for the size aspect of it. It then can render something in that space using it’s modifier. Here is the implementation
Copy code
@Composable
fun Foo(
  modifier: Modifier = Modifier,
  content: @Composable BoxScope.() -> Unit,
) {
  Layout(content = { Box { content() }, modifier = modifier) { measurables, constraints ->
    val placeable = measurables.first().measure(constraints)
    layout(placeable.width, placeable.height) {}
  }
}
How would you name this Layout function? 👀
y
Canvas maybe?
PlainCanvas
If you want an out-there name, maybe something that includes
Graffiti
to suggest that the content is being drawn-over.
s
With
Canvas
I’d 100% suspect to get a
DrawScope
somewhere, which is not the case here for sure
Graffiti is so out there there is 0% chance anyone naturally discovers this in the code base if they are looking for something similar I’d say 😅
r
Maybe something containing
Earmark
or
Allocate
?
Or something more descriptive like
SetAside
s
If you saw
Copy code
Allocate(
  modifier = Modifier.Color.Gray
  content = { Text("Text here") }
)
What would you expect to see on the screen? Without having any of the context of this conversation or the impl details of it? Or
Copy code
Earmark(
  modifier = Modifier.Color.Gray
  content = { Text("Text here") }
)
Or
Copy code
SetAside(
  modifier = Modifier.Color.Gray
  content = { Text("Text here") }
)
Or
Copy code
PlainCanvas(
  modifier = Modifier.Color.Gray
  content = { Text("Text here") }
)
For me none of those describe what happens.
r
That's what I meant by "something containing", (e.g.
AllocateSpace
,
SetAsideArea
,
EarmarkRegion
, etc.), not just the word on its own.
If you want more descriptive, perhaps
ConsumeMeasuredCanvasSpaceButDontActuallyDrawContent(...)
🙂
s
ConsumeMeasuredCanvasSpaceButDontActuallyDrawContent
Why Canvas here?
r
Because ultimately composables are rendering down onto a canvas, so you are saying that you are saving the space on the canvas where the composable would be rendered to, but not actually doing the rendering. I guess you could replace it with just "space" or "area", but that suggestion was meant to be tongue in cheek.
In the end, I don't know if you'll find a good, short, descriptive name for what you're trying to do, since it's kind of doing exactly the opposite of what people expect of composeables. If you're asking for user supplied content, and then specifically NOT showing that content, despite still effectively calculating/rendering it, I doubt there's an obvious "discoverable" name for that function. You'll likely have to stick with something only partly meaningful, and have to rely on documentation for a better explanation. I'd be happy to be wrong though.
s
I totally agree with you, hence I am here to discuss this because I do not think there’s a perfect name for it 😄 Doing something partly meaningful and relying on documentation + just bringing it up in PRs is probably my best bet. I might go with
LayoutWithoutPlacement
for now, which is short and starts with “Layout” which might make it a bit more discoverable. And I’ll consider renaming it after more feedback 😄
r
That's not bad. It could be confusing for anyone that doesn't know the internals of how composables work (and the accompanying terminology), but that may work in your favor here, as it might help people avoid using it accidentally.
s
Yeah, I would not suspect someone who’s not at least somewhat familiar with writing custom
Layouts
to reach for anything named
Layout
by accident. And if they are familiar with it, seeing the empty placement block
layout(placeable.width, placeable.height) {}
should hopefully be enough of a hint of what’s happening. Along with the documentation of course
👍 1
👍🏾 1
l
Your
Foo
function is not using the size and therefore seems useless. I'm confused.
s
layout(placeable.width, placeable.height)
does indeed take up the space of the
content
, it just draws nothing in that space since I never place it. Then whatever may be put on
modifier
like
.background(Color.)
will be drawn on exactly that size that
content
would’ve taken. Run it locally, give it a spin and you’ll see.
l
SizeOf
l
Or
WithSizeOf
would be my name for this function
Not 100% happy with its name, but I think it's a fair starting point
The invisible Modifier approach from Rebecca seems better to me
s
Yeah, I like this name for how well it describes what it does. It somehow does not feel like a Composable function, since those are typically not starting with words like “With”, but I’ll think about it as well. You can read more here https://kotlinlang.slack.com/archives/CJLTWPH7S/p1712667292474009 about why the invisible modifier does not work for my case. The drawing functions of the modifier will also get hidden with it.
l
Maybe just
Invisible(…) { … }
?
That plus some KDoc that clarifies the reason to be / the use cases could do.
s
It is not really invisible though, there is drawing on the modifier 😄 https://github.com/HedvigInsurance/android/blob/6233ba6b4fbe02631173fc3eda126fa275[…]lin/com/hedvig/android/core/ui/layout/LayoutWithoutPlacement.kt I in fact had a use case where it was not enough to use a modifier for my drawing efforts, but I wanted a composable for size, and then another composable for drawing and I just did this https://github.com/HedvigInsurance/android/blob/6233ba6b4fbe02631173fc3eda126fa275[…]lin/com/hedvig/android/core/ui/layout/LayoutWithoutPlacement.kt for now, just to finish what I was working on. But I still am not happy with that name there 😄 Didn’t finish the doc up there even because I was so stunlocked trying to find a better name for this 🥴 And Invisible I think would make even less sense for that API there
l
Sure, but it's expected that the Modifier comes before the content, so it's fine IMO
y
but I wanted a composable for size, and then another composable for drawing
DrawingBound
?