Suppose I have a button and a square, like this:
main = mainWidget $ do
x <- button "Change color."
y <- toggle False x
z <- mapDyn style y
elDynAttr "div" z blank
style :: Bool -> Map String String
style b | b = "style" =: "height: 10ex; width: 10ex; background-color: #f00;"
| otherwise = "style" =: "height: 10ex; width: 10ex; background-color: #900;"
The colour of the square will alternate between bright and dark red when the button is pressed.
I want to replace the button with a green rectangle in such a way that, when mouse pointer is over it, the red square is bright, otherwise dark. For bonus points, I would like the green rectangle to be a div tabindex=0
and to make sure the red square is bright when it has focus, but, once I understand the general approach, I will likely be able to figure that out by myself.
My guess is that there is some API that allows adding event handlers to el
, but I did not find one so far. And maybe there is a different approch altogether, that I could not know?
The stuff you need is all found in
Reflex.Dom.Widget.Basic
. If you create a widget with a function that has a prime in its name, such asel'
, you can get a hold of an object of typeEl
, which is a member ofHasDomEvent
.domEvent
, the only method of this class, lets you extract an event stream corresponding to one of a selection of event names. Mixing the events together and converting them to an appropriateDynamic
is then done with some usual Reflex tooling found inReflex.Class
andReflex.Dynamic
. You do need to familiarize yourself with these interfaces, but there is a helpful quick reference.(Make sure to use the documentation matching the version of Reflex you build against, as there are significant changes between versions.)
One way to encode your case is as follows:
What we do here is create a widget for the green box that returns a Dynamic indicating whether it is "activated". Everything else is just as it were in your initial example.
Thanks to /u/dalaing for advising me on this.