How to keep keyboard focus when input moves?

I’ve got a list of options. Each option has a name and buttons to move them up and down the list. It looks like this:

| Option 1 -- up - down |
| Option 2 -- up - down |
| Option 3 -- up - down |

If the user has keyboard focus on a button, I’d like that button to retain focus when the list is reordered.

e.g. if keyboard focus is on the up arrow on “option 3” above, and you press enter, and then enter again you should move option 3 up two spaces.

Unfortunately, when phoenix liveview updates the HTML the focused element is the one that is in the same location on the page (so if your focus is on the up arrow for option 3 and you press enter option 2 and 3 will swap position and your keyboard focus will be on the up arrow for option 2).

Is there an easy way to keep keyboard focus on the button for (e.g.) option 3 when it is pressed?

Things I have tried:

  • Adding unique ids to each option div (causes keyboard focus to be lost when the list updates)
  • adding unique ids to each button element (loses focus)
  • using Element.after in Javascript to move the containing div (loses focus)
  • using Element.after in Javascript to move the containing div, then explicitly call Element.focus() on the button that was clicked (works, but I’d rather not write JS for this if I don’t have to).

Things I haven’t tried:

  • Controlling the ordering of the options with CSS (I think this would work, but seems quite painful)