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
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
very nice
i was almost going the craigslist route
looks really spiffy
yeah i'm sold
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
lol
hahahaha
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
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
fantastic
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 🚀
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