vrac

Template-based web library [WIP] - https://github.com/green-coder/vrac Zulip archive: https://clojurians.zulipchat.com/#narrow/stream/180378-slack-archive/topic/vrac Clojureverse archive: https://clojurians-log.clojureverse.org/vrac
2020-08-28T03:15:12.223900Z

Good morning. A small brainstorm today to review the 4 points I left yesterday.

2020-08-28T03:17:31.225900Z

> 2. getting hiccup vectors from (compute) functions. If yes, them will need to be included as `(html my-hiccup)` We don’t need compute functions to return hiccup vectors which we would include in another component : we already have the components for that.

2020-08-28T03:21:55.230100Z

> 1. passing hiccup vectors in argument of component inclusion. This also imply that we use a special syntax to include it in the hiccup, to differentiate from printable values (html my-hiccup) , but it would be more natural to include it in the form [my-hiccup] … in which case, my-hiccup is assumed to be a component and not just a piece of hiccup. This is what the case 4. already covers, so 1. is superseded by 4.

2020-08-28T04:05:38.249Z

> pre-4. passing a reference to a defc component in argument to the inclusion of another component. Yes we should support it, and it should be done in the same way than 4. > 4. passing some anonymous components `fnc` as argument of component inclusion. fnc is totally useful, I want Vrac to have it. Something to keep in mind, it’s that the template inside fnc can refer to variables from the containing components and use their value. Example:

(defc item-list [item-comp items]
  [:ul (for [item items]
         [:li [item-comp item]])])

(defc root-layout []
  (let [items (:items global)
        bg-color (:bd-color global)
        my-anonymous-comp (fnc [item]
                            [:div {:style {:bg-color bg-color}} (:name item)])]
    [item-list my-anonymous-comp items]))
Additionally, we could have a shortcut when fnc does not take arguments:
(defc strongly-said [message-comp]
  [:strong [message-comp]])

(defc root-layout []
  (let [greating-message "hello"]
    [strongly-said (fnc [] [:div greating-message])]))

;; Using a shortcut, it can be written:
(defc root-layout []
  (let [greating-message "hello"]
    [strongly-said [:div greating-message]]))
The shortcut feels a lot like the case 1. which was superseded.

2020-08-28T04:08:07.251Z

> 3. passing functions in argument of component inclusion. Maybe it would work as well as passing values, will think about it. It should work in the same way as passing other kind of values, nothing harder to implement here. I wonder how often it would be useful to the users, but it will be supported anyway.

2020-08-28T04:08:16.251200Z

— end of my daily “open brainstorming”, feedback welcome as always.

2020-08-28T04:09:13.252Z

I am pretty much done with the design and will start implementing stuffs this weekend. If you want to give feedback, now is the right time.

2020-08-28T04:50:01.254Z

I forgot to talk about the event triggering and the event handling. Basically, the event handling is done in a way very similar to the way Re-frame does. For the event triggering, it looks like that:

(defc my-button [button-id text]
  [:button {:on-click (dispatch [:button-clicked button-id])} text])
We don't need a function to wrap the dispatch. The Vrac templates are pure data, if we can understand their meaning when we read them, then the system can too - that's good enough.

2020-08-28T06:14:16.256300Z

I forgot yet another bit that I want to throw in the template: local state, for the front end view (no kidding).

2020-08-28T06:22:58.262600Z

It's created like that:

(let [init-val true
      show? (local init-val)] ;; this binding is not reactive
  (when show? [:div "hello"]))

2020-08-28T06:37:24.266100Z

It's updated via effect handling, like that:

(let [show? (local true)]
  [:div {:on-click (dispatch [:switch-show-hide show?])} "X"
    (when show? [:div "hello"])])
The effect handler uses the reference to the local state to describe the change, similarly to how it is done on the local db.

2020-08-28T06:39:10.267800Z

The effect handler does not need to know where the data is in store .. in fact, nobody needs to know. They would only need to know that it is stored globally, in some anonymous place, and it does not disturb the business logic of the application.

2020-08-28T10:53:14.273100Z

Apparently, I have more documentation work to do on the design. I would like to go back to the data model seen in the template, and how it relates to the data in the local db. Also, I might do the event handling differently than Re-frame after all.

2020-08-28T10:54:06.274100Z

Next brainstorming is tomorrow morning, Taiwan time.

2020-08-28T10:56:24.276300Z

I will try to make an example on what it feels like to build a form in Vrac.