1

Let's say I have a Composable that opens a popup on click:

@Composable fun SomeParent() {
  Row(Modifier.spacedBy(4.dp)) {
    DatePicker()
  }
}

@Composable
fun DatePicker(modifier: Modifier = Modifier) {
  var show by remember { mutableStateOf(false) }
  Button({ show = true }, modifier) { Text("Pick date") }
  if (show) {
    Dialog(...) // containing date picker content
  }
}

Now, if the caller uses this component inside a Row or Column that has Arrangement.spacedBy(some.dp) (as shown in the Parent function), the content will shift by that much when the dialog opens. Which makes sense, Compose doesn't know the dialog shouldn't use space in its parent.

One workaround would be to wrap both children in something:

@Composable
fun DatePicker(modifier: Modifier) {
  var show by remember { mutableStateOf(false) }
  Row(modifier) { // or Box 
    Button({ show = true }, modifier) { Text("Pick date") }
    if (show) {
      Dialog(...) // containing date picker content
    }
  }
}

but now I have a problem with the Modifier: Some parts (weights) need to go on the outer element, and some (focus) on the inner element. Which I can solve by splitting them up into two parameters, but that gets ugly quickly (and is a breaking change).

Instead, is it possible to tell Compose to ignore the parent's spacing for the Dialog?

And if it's not possible with standard Compose, would it be possible to do with a custom Modifier.layout implementation?

Jorn
  • 20,612
  • 18
  • 79
  • 126

1 Answers1

0

I think you are talking about Popup or similar composables here, since Dialog should work fine. In Compose for Desktop it creates new window with a new composition.

Anyway, I'd suggest putting it inside Button content:

@Composable
fun DatePicker(modifier: Modifier = Modifier) {
  var show by remember { mutableStateOf(false) }
  Button({ show = true }, modifier) { 
    Text("Pick date")
    if (show) {
       Popup(...) // or Dialog containing date picker content
    }
  }
}

After that you need to make sure that your Popup aligned properly, because now it will use Button as an anchor not the parent of DatePicker.