Fork me on GitHub
#hoplon
<
2020-03-25
>
jjttjj00:03:49

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

jjttjj00:03:26

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

micha00:03:57

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

micha00:03:10

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

micha00:03:45

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

micha00:03:21

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

micha00:03:01

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

phronmophobic00:03:11

ok, i’m probably doing something wrong

micha00:03:55

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

micha00:03:06

like the order of the items for example

micha00:03:30

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

phronmophobic00:03:31

(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)))

phronmophobic00:03:36

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

micha00:03:47

yes that's key

phronmophobic00:03:49

so they get auto updated when their cells change

phronmophobic00:03:07

and that basically works until you get to collections

phronmophobic00:03:42

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

phronmophobic00:03:04

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

micha00:03:16

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

phronmophobic00:03:38

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

micha00:03:44

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

micha00:03:16

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

micha00:03:56

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

phronmophobic00:03:55

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

micha00:03:48

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

micha00:03:06

that kind of thing interferes with composition

micha00:03:38

i don't have much experience with other models

micha00:03:59

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

micha01:03:25

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

micha01:03:54

but it's still vaporware

micha01:03:54

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

micha01:03:02

lisp machine kind of stuff

phronmophobic01:03:08

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

micha01:03:23

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

jjttjj01:03:31

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

👀 4
micha01:03:18

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

jjttjj01:03:19

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

micha01:03:15

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

phronmophobic01:03:28

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

flyboarder01:03:47

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

flyboarder01:03:58

this lets us build components like this…

micha01:03:08

do you use the uikit js too?

flyboarder01:03:19

(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"))))))

flyboarder01:03:34

@micha yes it fits in nicely with hoplon

micha01:03:55

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

micha01:03:12

haha i'm making a webapp right now

micha01:03:24

do you recommend i use ^^?

flyboarder01:03:38

we are building some enterprise medical apps with it right now

micha01:03:58

awesome i'll give it a shot

micha01:03:48

very nice

micha01:03:55

i was almost going the craigslist route

phronmophobic01:03:16

looks really spiffy

micha01:03:29

yeah i'm sold

flyboarder01:03:58

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

flyboarder01:03:24

but working with elements like cards and things is so easy

micha01:03:37

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

😂 4
micha01:03:54

instill just a little trust in the user

micha01:03:12

but i'm in a hurry lol

flyboarder01:03:16

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

micha01:03:28

this seems pretty awesome, thanks for putting it out there

👍 4
flyboarder01:03:03

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

flyboarder01:03:54

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

micha01:03:58

omfg the source is in clojure

micha01:03:06

you are a king among men

micha01:03:37

like the little source tabs in the demo site

micha01:03:43

fantastic

flyboarder01:03:56

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

phronmophobic01:03:10

so for

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

flyboarder01:03:53

yeah patient is a cell in that example

flyboarder01:03:21

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

phronmophobic01:03:41

yea, looking through it. looks great

flyboarder01:03:58

itself is a small hoplon app

phronmophobic01:03:28

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))

micha01:03:50

this has made my day 🚀

👏 4
micha01:03:29

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

flyboarder01:03:50

hahah the less fun parts of app dev

micha01:03:54

it's fun to make webapps again

micha01:03:02

been a few years lol

micha01:03:31

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

micha01:03:22

lol i tried to login to my facebook account

micha01:03:03

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

micha01:03:23

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

micha05:03:46

hm i can't get the hoplon helloworld to build

flyboarder17:03:50

@micha whats wrong with the build?

micha19:03:53

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

micha19:03:06

because i'm an idiot

micha19:03:37

it ended up being easier to downgrade java to 1.8

micha19:03:47

so that's all good now

phronmophobic22:03:56

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))))

phronmophobic22:03:17

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

flyboarder23:03:01

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