https://kotlinlang.org logo
#compose
Title
# compose
c

Colton Idle

01/19/2022, 1:39 PM
I'm trying to have an InputField on the screen, but the input field is just a button that opens up a modal (my designers decision) Any idea why something like this doesn't actually function properly. The onclick is never called and it just leave you to type in the field.
Copy code
@Composable
fun FakeInputFieldButton(modifier: Modifier, onClick: () -> Unit, valueText: String) {
  val someFunc = {}
  OutlinedTextField("text", {}, modifier.clickable { someFunc() })
}
z

Zach Klippenstein (he/him) [MOD]

01/19/2022, 1:43 PM
Probably because the text field consumes those touch events before
clickable
gets a chance to.
It might work if you set
readonly
to true, or
enabled
to false, i always forget which does what
🙌 1
Or better yet, just draw the fake text field yourself so you don’t have to swim upstream
💯 1
c

Colton Idle

01/19/2022, 2:08 PM
I've thought about just drawing myself, but my designer wants the focus color (purple in materials case) to be enabled when the modal is open. And a few other minor things (like error messages), but yes I agree that that's probably easier. Even so, I was curious how a parent clickable doesn't get the click event before the text field.
+ my designer wants this in our design system as an "input field" and so if they change it, it should change everywhere == more motivation to have it in a single place. But anyway. Just saying I get your point. It's just a text label with a rounded border that I could def make clickable as well.
Enabled false did the trick. I did try with a parent Box setting the clickable and that didn't work either. Which I think is also weird. Seemingly a text field always wins no matter how many click listeneres are above it.
z

Zach Klippenstein (he/him) [MOD]

01/19/2022, 2:22 PM
You could also probably write your own clickable implementation that listens on the initial-pass instead of the main one, but even if that works for this case it doesn't recurse.
One thing we don't have yet but comes up fairly frequently is some way to just disable all pointer inputs for all the children of a node. I think we even have an issue filed for that somewhere
Although I'm not sure that would be the best option here because in your case you also want the accessibility text actions disabled for the fake field, which seems like something the component itself should be responsible for
c

Colton Idle

01/19/2022, 2:27 PM
write your own clickable implementation that listens on the initial-pass instead of the main one,
TIL that there are different passes in clickable
a

Adam Powell

01/19/2022, 3:26 PM
I was curious how a parent clickable doesn't get the click event before the text field.
Because if you put a button as a child of a clickable card, it would be weird if you tapped the button and the card is what clicked
c

Colton Idle

01/19/2022, 3:30 PM
Hm. Okay. Actually yeah. Thats a good point that clickables should pick the clickable that you can drill down into the most. In that case then... I should be able to set clickable to null on the TextField, and give the parent a clickable, and I'd be back in business? Already submitted my PR, but I will try this later today. Not the biggest deal if my intended behavior doesn't work. I realize it's kinda hacky, but figured I'd ask to make sure I wasn't missing any magical arg or something (and I got to learn about readOnly arg too.) 😃
a

Adam Powell

01/19/2022, 3:31 PM
it helps to think in terms of additive behavior instead of subtractive, and we've followed this through the compose API surfaces. If you find yourself wanting <some component> but without <x> then the cleaner answer is always going to be to find out how <some component> does everything except X and do that, rather than try to figure out how to stop <some component> from doing <x>