ilshad / combo

Message driven component for Om

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Combo: message driven component for Om

Clojars Project

Combo Demo: simple Spreadsheet and Presentation Authoring

What It Is

Combo is a library for ClojureScript framework Om. It turns local state management into function, which takes state and message and returns new state and a sequence of messages:

(defn behavior [state message]
  ...
  [state [message-1 message-2 ...])

The state is not managed by Om and its updates do not cause any re-rendering.

Messages income from nested components and sent to them, but we do not have to write these components, as we usually do. Instead, we describe them as units in a declarative spec:

(def units
  [{:id :foo :render foo}
   {:id :bar :render combo/button}
   {:id :baz :render combo/textarea}])

where :render is a function:

(defn foo [{:keys [input! class]}]
  (dom/input #js {:className class}
                  :onChange (fn [e]
				              (let [x (.. % -target -value)]
	                            (input! [:foo x])))))

The messages sent from render function to behavior with :input! procedure. It is up to developer of render function to decide what is the actual format of these messages. They are collected as input in behavior, so you have to build control flow on them:

(defn behavior [state message]
  (core.match/match message
	[:foo x] [state [[:foo :class (if (= x "q") "success" "error")]]]
    ...
	:else [state []]))

Outcoming messsages (from behavior) should be triplets [unit-id, key, value], and the value will appear under the key as input to the corresponding render function.

In other words, instead of writing full Om components, we have to code only rendering part and manage state with kind of event hub.

To rule them all, there is an entry point, combo.api/viewwhich is just Om component:

(om/build combo/view app
  {:opts {:behavior behavior :units units})

In summary, Combo is a library for developing some of your complex Om components by another way: render functions for rendering subcomponents and single function on messages for state management.

Motivation

Single place and pure function

It helps to control complexity of composite components by keeping the logic centralized: all significant computations happen in behavior function. Instead of tangled wires of core.async channels streched between nested components, go-routines, local states and cursors, developers describe entire logic:

  1. In a single place.
  2. With pure function.
  3. By transforming plain data.

Reusability

We have discovered that render functions is much simplier to reuse and they are more pluggalbe thing than full components. Actually, Combo API provides few standard render functions (see API Documentation), and you can see that they are pretty flexible and customizable. Entire applications can be built with only standard render functions, so developers write only declarative spec and behavior.

Use cases

Good reasons to adopt Combo are:

  • multiple tangled relations between widgets
  • similar widgets and different composite views containing them

It is intended to be used within Om-based application along with other Om components, but also, it is possible to develop apps entirely with Combo.

Getting started

  1. Start with Tutorial (this is not started yet).
  2. Take a look at source code of Demo.
  3. Write your code using API Documentation (this is not started yet).

Full documentation is here.

License

Copyright © 2015 Ilshad Khabibullin.

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

About

Message driven component for Om

License:Eclipse Public License 1.0


Languages

Language:Clojure 85.7%Language:CSS 11.0%Language:HTML 2.3%Language:JavaScript 0.9%