With Alpine if you start having anything bigger than a snippet you should pull the JS out into a component using Alpine.data()[1] which can live in a <script> tag or a JS module.
In particular, scan past the data in that example and you will see things like @keydown.down="if(selectOpen){ selectableItemActiveNext(); } else { selectOpen=true; } event.preventDefault();"
which tells you what is happening right there. So if you eliminate the data outside the component, as one should, I think it becomes a very nice readable interface.
[1] https://alpinejs.dev/globals/alpine-data