Liveview navigate a list using keyboard events

I am bulding the TailwindCSS combobox as a Phoenix Liveview LiveComponent (What’s with the capitals :thinking:).
When clicking inside the input element, the combobox opens and I can navigate the elements using ArrowUp/Down setting the select item in the LiveComponent’s state. However, the input element stays in focus and the active list item seems to be only artificial.

What I mean with artificial feeling is that when I hit enter, the enter event is taking place on the input element which remain in focus. Another thing which feels wrong is when an element is selected outside of the combobox popover the items is not inside focus and dissapears behind the overflow…

Am I taking a wrong route over here? Should I do this with or without Javascript?

I guess you are as confused as I was with LiveView’s behaviour, see:

1 Like

LiveView will never overwrite an active input’s value even if the client value differs from the LiveView’s rendered value

This portion of the docs is worth a read:
https://hexdocs.pm/phoenix_live_view/form-bindings.html#javascript-client-specifics

LiveView will never overwrite the input’s current value, even if it deviates from the server’s rendered updates

If I were you, I would do all of the client navigation (up, down, etc.) in just JS. when they select an item or hit enter, then send it to the LiveView.

For one, you won’t have the js/liveview source of truth collision. The second is that those server round trips are nice and snappy on local development, but are slower and feel slow once they are deployed to production.

2 Likes

Ok, thank you for the responses. Somehow I felt like 50% of the combobox was already doone and the path with LIveview only felt pretty good. I do understand the snappyness of this kind of interface would suffer from a roundtrip to the server.

For full solution reference, I went the web-components route as described in this topic: Phoenix LiveView + HeadlessUI

Thanks to @fteschke and @superchris for the inspiration.