hoplon 2020-03-25

Some random thoughts: start off by optimizing ease of use/access. Don't think too much about it until something becomes annoying and then step back and think if you could benefity from changing the granularity. That's the nice thing about hoplon, you can pretty easily adjust granularity

For example if you have a flat sequence of stuff that you will want to visually sequentually like in the todo app, it makes a lot of sense to just put it all in one cell

i think of it like input cells are database tables, and formula cells are views

there is a lot of flexibility there to design the data model you want

the UI is then sort of like a chart hooked up to the tables and views

as the underlying data in the input cells change the data flows through the formulas and updates the UI

like in a database you normally wouldn't make a view for each row in a source table

ok, i’m probably doing something wrong

i just mean that if you have a cell containing a sequence of todo items, for example, the sequence itself embodies important information

like the order of the items for example

so it's natural to put the collection in a cell

(defn checkbox [& {:keys [checked?]}]
  (let [checked? (or checked? (cell false))
        $checked? checked?]
    (formula-of
     [checked?]
     (on
      :mouse-down
      (fn [_]
        (swap! $checked? not)
        nil)
      (ui/checkbox checked?)))))

(let [test-checkbox (checkbox (cell false))]
  (ui/run #(deref test-checkbox)))

(defn todo-item [& {:keys [todo]}]
  (let [todo (or todo (cell {:description ""
                             :complete? false}))
        $todo todo
        ]
    (hlayout
     (checkbox :checked? (path-cell $todo [:complete?]))
     (textarea-view :text (path-cell $todo [:description]))
     )))

(let [item (todo-item)]
  (ui/run #(deref item)))

so my thinking was that “components” could receive cells as arguments

yes that's key

so they get auto updated when their cells change

and that basically works until you get to collections

my workflow so far has been , you make complex components out of simpler components

many of the hoplon examples don’t have very many defelem components

yeah i mean it's a hard problem to engineer the foundation of your composable world

my code is currently a little clunky, but I think it could be cleaned with some syntatic sugar macros

but you can do the usual lisp approach of doing the best you can with special cases where needed

i think lisp provides the best possible platform for making an imperfect world more sane

but it's really hard to make a truly orthogonal, composable UI kit in the browser

well, let’s you weren’t targeting the browser, what would you do differently?

what i mean is like in the browser you always need some weird extra div for padding or margins, things like that

that kind of thing interferes with composition

i don't have much experience with other models

javafx seems like it might be more regular, but i haven't used it enough to really know all of its secret faults

i think maybe webcomponents could be a big improvement in the browser, with shadow dom and css isolation

but it's still vaporware

@smith.adriane have you heard of the amethyst and garnet projects in the 80s?

lisp machine kind of stuff

I have, but I haven’t revisited them in a while

those seemed like an ideal platform to me when i saw it

i started messing with hoplon/ui (https://github.com/jumblerg/ui) again pretty deep recently, and i think he really nailed a ui model there (though it's ever changing and takes some work just to get running

👀 1

yeah that is an example of an attempt for a full top-down solution to the composition problem

it's the best i've felt about making uis without being bogged down

he's put a massive amount of time into the design

it looks like it’s focused on layout. does it have a story around events and state management?

for the visual side of things we went with UIKit (http://getuikit.com)

this lets us build components like this…

do you use the uikit js too?

(modal/modal :stack true :container true
      (modal/dialog
        (modal/header
          (modal/title "Patient Information"))
        (modal/body :text/left true ::util/overflow-auto true ::section/muted true
          (grid/grid :small true :grid {:masonry true}
            ::width/width-1-1 true
            ::width/child-width-1-2 true
            (forms/form
              (patient-basic-info patient))
            (forms/form
              (patient-address-info patient))
            (forms/form
              (patient-account-info patient))
            (forms/form 
              (patient-insurance-info patient))))
        (modal/footer ::text/right true
          (button/button ::modal/close true :primary true
            "Exit"))))))

@micha yes it fits in nicely with hoplon

nice, this is what i was hoping would come from webcomponents too

haha i'm making a webapp right now

do you recommend i use ^^?

we are building some enterprise medical apps with it right now

awesome i'll give it a shot

i was almost going the craigslist route

looks really spiffy

we took the theme from the uikit documentation website, the default style without a theme is pretty bare bones

but working with elements like cards and things is so easy

i just need something that doesn't look like a ransom note

😂 1

instill just a little trust in the user

but i'm in a hurry lol

yeah our goal was to not have a designer at all, and let the devs just build

this seems pretty awesome, thanks for putting it out there

👍 1

a nice spiffy UI helps to sell the underlying tech, even tho it’s not at all related

our users are doctors who are used to like windows 95 style apps, moving to the web is a challenge enough so it had to look appealing and simple

omfg the source is in clojure

you are a king among men

like the little source tabs in the demo site

yeah I want to build out full docs but I dont have the time right now

so for

(forms/form (patient-basic-info patient))
what is patient? is that a cell or POD?

yeah patient is a cell in that example

the uikit-hl docs really need refresh, but the source is solid and in production

yea, looking through it. looks great

itself is a small hoplon app

I read in the hoplon docs about on! stuff, but I don’t think I grokked it till I just saw the examples like

(defmethod uk-progress! ::progress
  [elem _ v]
  (h/do! elem :class {:uk-progress v}))

(h/defelem progress [attr kids]
  (h/progress attr ::progress true kids))

this has made my day 🚀

👏 1

back to s3 buckets and cloudfront distributions and api gateways and things

hahah the less fun parts of app dev

it's fun to make webapps again

been a few years lol

got cognito working with facebook login, that's pretty cool

lol i tried to login to my facebook account

somehow chrome remembered my password from more than 10 years ago before i disabled my facebook account

well sort of remembered, i guess it didn't remember very well

hm i can't get the hoplon helloworld to build

@micha whats wrong with the build?

haha well for one thing i was trying to do :refer :all in cljs

because i'm an idiot

it ended up being easier to downgrade java to 1.8

so that's all good now

this is the cleanest I could come up with 😕

(defelem todo-item [& {:keys [todo]
                       :or {todo {:description ""
                                  :complete? false}}}]
  (hlayout
   (checkbox :checked? (path-cell $todo [:complete?]))
   (textarea :text (path-cell $todo [:description]))))


(defn test-todo-item []
  (let [item (todo-item :todo (cell {:description ""
                                     :complete? false}))]
    (ui/run #(do item))))


(defelem todo-list [& {:keys [todos]
                       :or {todos [{:description "first"
                                    :complete? false}
                                   {:description "second"
                                    :complete? true}]}}]
  (let [todo-count (cell= (count todos))
        new-todo-text (cell "")]
    (formula-of
     [todo-count]
     (vertical-layout
      (horizontal-layout
       (ui/button "add todo"
                  (fn []
                    (swap! $todos conj
                           {:description @new-todo-text
                            :complete? false})
                    (reset! new-todo-text nil)
                    nil))
       (textarea :text new-todo-text))
      (apply vlayout
             (for [i (range todo-count)]
               (todo-item :todo (path-cell todos [i]))))))))



(defn test-todo []
  (let [todos (cell [{:description "first"
                      :complete? false}
                     {:description "second"
                      :complete? true}
                     {:description "third"
                      :complete? true}])
        tlist (todo-list :todos todos)]
    (ui/run #(do tlist))))

it does seem like javelin really wants to have a mutable DOM-like structure under the hood.

Well there is always some mutable layer under the hood, javelin doesn’t prescribe that part tho