This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # announcements (3)
- # babashka (29)
- # beginners (95)
- # calva (109)
- # cider (16)
- # clj-kondo (6)
- # cljdoc (2)
- # cljsrn (2)
- # cljtogether (1)
- # clojure (85)
- # clojure-europe (26)
- # clojure-india (1)
- # clojure-seattle (1)
- # clojure-uk (6)
- # clojurescript (14)
- # conjure (4)
- # cursive (8)
- # datomic (6)
- # emacs (21)
- # events (1)
- # figwheel-main (5)
- # fulcro (11)
- # graalvm (32)
- # graphql (1)
- # holy-lambda (7)
- # humbleui (7)
- # jobs (3)
- # membrane (8)
- # nextjournal (31)
- # off-topic (29)
- # pathom (14)
- # polylith (6)
- # portal (16)
- # practicalli (4)
- # reitit (17)
- # releases (1)
- # remote-jobs (2)
- # ring (4)
- # sci (20)
- # shadow-cljs (24)
- # sql (1)
- # vim (12)
- # xtdb (3)
"Event Function - a pure function which receives the application state and an event and returns data specifying the user's intent (eg. add a new todo item to the todo list). This facilitates communication from the user to the application."
"Event Handler: A pure function of an Event to Intents."
These two definitions sound the same which is a little confusing. I think the example helps since the example says that
ui/mouse-down is an event function while
ui/on :mouse-down is an event handler.
Maybe something like "a pure function which receives the application state and an event and uses the event handler to return data specifying the user's intent." That's not great. I'd like something that shows the relationship between the two.
The difference is that the Event Function receives 2 arguments:
event while the Event Handler only receives
> a pure function which receives the application state and an event and uses the event handler to return data specifying the user's intent An event function need not use any helper functions. I agree that it is a little confusing. I'll try to think about how to clarify the description.
(defn my-event-function [elem [mx my]] ...) ;; vs (defn my-event-handler [[mx my]] ...)
The blog introduces
ui/on to help "bind" event handlers (the functions that turn events into intents). (I read through ui.cljc a little so I see that
on constructs a record from the handler function and the element.) In a later example
ui/on is used with a function that turns an intent into another intent.
This example is using
(def add-todo-button (ui/on :mouse-down (fn [_] [[::add-todo]]) (ui/button "Add Todo"))) ;; wrap add-todo-button ;; capture all ::add-todo intents bubbling and ;; qualify that we're adding a todo to ::work-todos (def work-add-todo-button (ui/on ::add-todo (fn  [[::add-todo ::work-todos]]) add-todo-button)) (def mpos [3 4]) (ui/mouse-down add-todo-button mpos) ;; [[::add-todo]] (ui/mouse-down work-add-todo-button mpos) ;; [[::add-todo ::work-todos]]
[::add-todo ::work-todos]. (It doesn't "turn" anything really; it uses
onto associate an event handler with the element.) I think this example is showing that you can use
onto "alter intents that are getting passed back up the chain" even though
-bubbleis the more appropriate function. I don't understand how it works. What happens in the
(ui/mouse-down work-add-todo-button mpos)call? I can imagine
-mouse-downwhich is available on the
onconstructed with the handler. Hmm. The
-bubble. Ok, maybe I get the machinery now. I think there might be some friction for me since I assume that
ononly works with events coming into the element. There's actually a dual use with bubble that's covered next but that went over my head on my first read through. I'd like to see the example with bubble. I think the impl of bubble is straightforward and would just match on the first item of each intent vector and substitute
[::add-todo ::work-todos]but I think it adds value to the blog.
> I think this example is showing that you can use
on to "alter intents that are getting passed back up the chain" even though
-bubble is the more appropriate function
You're right that
membrane.ui/on is overloaded. It can be used for input events and for bubbling. In principle, I think this is ok since
membrane.ui/on is solely for convenience and there are simpler constructs to fallback to (eg.
on-bubble, etc.). I'm not totally convinced that it's the optimal API, but I've found it convenient so far. However, I have a major bias since I'm very familiar with the full stack so your feedback is helpful.
> even though
-bubble is the more appropriate function
The simpler construct is
on-bubble rather than
-bubble. Bubbling is a crucial part of the event model's API, but
-bubble is an implementation detail. Bubbling could be implemented without the
IBubble protocol, but there are some design tradeoffs that affect performance and extensibility (eg. adding new event types) that I haven't had time to sort through.
> I'd like to see the example with bubble. I think the impl of bubble is straightforward and would just match on the first item of each intent vector and substitute
[::add-todo ::work-todos] but I think it adds value to the blog.
on-bubble was added after I wrote this post. Maybe it makes sense to start with examples that use the simpler constructs like
on-mouse-down /`on-bubble` and introduce
membrane.ui/on later as a convenient way to add event/bubble handlers. Thoughts?
I've found it difficult to explain how the event model works. I want to use familiar words like bubbling, but it makes it easy for the important differences to be overlooked. I think the event model in membrane is much more straightforward than how events work in other UI libraries, but experience with existing UI libraries can make the mindset shift harder to make.