I have a board game made in SVG. Each pieces is an SVG element.
I would like to do actions on the pieces using mouse and keyboard.
For now, I have:
data Action = Initialize | Select (Maybe Piece) | Rotate Piece | Move Piece Dir | ... data Dir = N | E | S | W Piece = ... -- Get the tile with position, events and highlight getTile :: forall w. Piece -> HTML w Action getTile piece = g [ onClick \_ -> Select $ Just piece, -- left click to select the piece onContextMenu \_ -> Rotate piece, -- right click to rotate the piece onKeyDown $ onKeyDown piece, -- arrow keys to move the piece, "r" to rotate tabIndex 0 -- allows to tab through elements and receive keyboard inputs ] [ SE.svg  $ ... ] onKeyDown :: Piece -> KeyboardEvent -> Action onKeyDown p ke = case key ke of "ArrowDown" -> Move p S "ArrowUp" -> Move p N "ArrowRight" -> Move p E "ArrowLeft" -> Move p W "r" -> Rotate p handleAction :: forall output m. MonadAff m => Action -> H.HalogenM UI Action () output m Unit handleAction a = case a of Initialize -> do ... Select se -> H.modify_ $ updateUI se select Rotate se -> H.modify_ $ updateUI se rotate Move se d -> H.modify_ $ updateUI se (move d)
The problem I have is that events “ContextMenu” and “KeyDown” are bubbling: I would like to prevent that.
For instance right clicking will open the context menu.
I understood that I should use
stopPropagation in my event handler.
However this is not ideal because I will need to pass the
Event in my
Action (for some of them anyway):
data Action = Select Piece KeyDown KeyboardEvent
I would prefer to keep
Action as everything you can do in the game.