This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-04-11
Channels
- # admin-announcements (2)
- # beginners (53)
- # boot (151)
- # cider (11)
- # cljs-dev (60)
- # cljsrn (36)
- # clojure (71)
- # clojure-austin (13)
- # clojure-berlin (2)
- # clojure-czech (11)
- # clojure-dev (35)
- # clojure-dusseldorf (2)
- # clojure-france (6)
- # clojure-japan (9)
- # clojure-russia (183)
- # clojure-uk (18)
- # clojurescript (155)
- # cursive (6)
- # datomic (25)
- # euroclojure (6)
- # funcool (6)
- # hoplon (229)
- # instaparse (10)
- # jobs (9)
- # leiningen (5)
- # off-topic (70)
- # om (29)
- # onyx (18)
- # planck (1)
- # proton (5)
- # re-frame (8)
- # reagent (32)
- # untangled (4)
Oh snap, Bret Victor
and fishing around in the dom for things with string matching queries when you could just bind to variables instead
good apis are supposed to be cohesive. external stylesheets and html smear similar concerns all over the app in different languages.
it seems that with Hoplon you can have your styles encapsulated in defelems
thus avoiding the need in classes
you’re supposed to separate different concerns, like presentation from data, not content from styles (whatever that means).
the vectors are the media queries https://github.com/hoplon/ui/blob/master/tst/hoplon/ui-test-app.cljs.hl
well, not media queries (unnecessary “queries” are exactly what i’m trying to get away from), but a way of doing responsive layouts.
for example:
(u/button :w ["100%" sm 200] :h 50 :click #(swap! things conj (count @things)) "Add Thing”)
the vector after :w (width) means set the width to “100%” below the screen width contained in the var sm, and 200 pixels when the screen is above it.they give you 4 hardcoded breakpoints that you have to deal with via stylesheets. this gives you an infinite number of them.
i’ve done a few flexbox-only layouts, but i gave up on it. too many nasty edge cases.
if there are a large number of items on a page in a flexbox layout, the performance is terrible and then theres the issue where you have a few items left over that don’t quite fill a row, and you want them aligned on one side or another.
yeah, each elem
in ui actually produces three divs: the outer is display inline-table, the middle table-cell, and the inner block.
the outer div is used for sizing. the middle is used for stroke, borders, etc. the inner div is the thing itself, might be a button or whatever.
there are a number of motivations for doing this, i can’t recount them all offhand, but one big one is the ability to include the margin in the size. say you need four items across a page, this gives you the ability to simply set the width to 25% and get what you want.
it is the use of the tables and table cells that make actual vertical positioning possible.
i think this does better. the biggest feature this lib is missing is the ability to set a value like :fill, :rest, or :max on a width or height attribute to tell the browser to render the element greedily to fill up the remaining space on a line.
and, uh, the manifesto is forthcoming. right now this is just a tool to help me build my app.
i wasn’t sure if it was going to work out for a while, but it seems to have turned a corner. i’m finding it quite practical to work with now.
@jumblerg: really exciting stuff
yeah… and i think it will get even better as @micha tunes the hoplon level abstractions that make it possible.
i forgot about this thing i made, which is kinda an approach to the meaning-of-attributes discussion from the other day http://tailrecursion.com/~alan/tmp/css5000/
but not really since it's not general, more just a way to hide things on an object
one of many ways
found the explanation for the Javelin cell-based system (yesterday's discussion): http://tailrecursion.com/~alan/index.cgi/doc/tip/documents/Dipert-FRP_in_ClojureScript_with_Javelin.pdf
the only difference seems that you didn't have a distinction between input and formula cells at that point
@dm3: there was a distinction internally, but less so syntactically
since we were still high on sheets, in the same way all the boxes on a spreadsheet look the same, we thought the cell constructor should be the same regardless of whether you create input or formula
which turned out to be dumb lol
micha came up with cell=
a few months after that preso and all was right
and then cell
became a function and lined up better with atom
then like 2 yrs later lift
=> formula
hey so
potentially dumb q
if I have (cell= (if a b c))
where a, b and c are all cells
will anything happen if a
doesn’t change but b
and/or c
does?
we can't know from that expr what b and/or c do, so possibly yes
the only thing the if
determines there is the value of the outer cell=
an excellent question though, it took some thinking
does that make sense?
i think?
i’m confused by some weird behaviour
that i thought was due to javascript events
but i think is from the way cells are working
i have this
(h/defelem item-list
[attributes children]
(let [list-id (:list-id attributes)
items (j/cell= (if (integer? list-id)
(->>
(d/datoms state/conn :avet :item/list-id list-id)
(map :e)
(apply sorted-set)
vec)
[]))
items:last (j/cell= (last items))
items+final (j/cell= (conj items :new))]
(h/div
attributes
children
(j/cell= (prn "items " items))
(h/loop-tpl :bindings [id items+final]
(item/item
:list-id list-id
:id id)))))
(h/defelem item-text
[{:keys [label list-id id key entity]} children]
(h/label
(j/cell= label)
(h/input
:type "text"
:value (j/cell= (if-not (= :new id)
((keyword key) entity)
""))
:placeholder (j/cell= label)
:input #(set-item! @entity @list-id @id key (if-not (= "" @%) @%)))))
(h/defelem item
[attributes children]
(let [list-id (:list-id attributes)
id (:id attributes)
entity (j/cell= (if (integer? id)
(d/touch (d/entity state/conn id))))]
(h/div
:item-id (j/cell= id)
(j/cell= (prn "entity" entity))
(item-text
:label "Min"
:list-id list-id
:id id
:key :min
:entity entity)
(item-text
:label "Max"
:list-id list-id
:id id
:key :max
:entity entity))))
hmm, maybe that’s a bit too big...
for chat
basically, this bit
(j/cell= (if (integer? id)
(d/touch (d/entity state/conn id))))
actually, maybe i’m doing this wrong..
hang on
so basically
I get a prn
from the state/conn
changing when I transact
but not from the entity being updated
hm sounds like maybe the way you get the entity, it's not in a cell that depends on the db?
(def conn (local-storage (du/conn-cell schema) ::conn-state))
(j/cell= (prn conn))
(j/cell= (prn "e " (d/touch (d/entity conn 2))))
that prints out OK
when you do h/loop-tpl :bindings [id items+final]
i expected to see an “entity” line just under the last “e” line with the same data
but it only prints the first time i add a datom to the entity 😞
which leads to some really whacky bugs
entity (j/cell= (if (integer? id)
(d/touch (d/entity state/conn id))))
@alandipert: the state/conn
is a cell, so it should update entityi would have thought
the screenshot above is the whole log
for this
so i put “a” in max, got a bunch of logs as I expect
then I put an “a” in min, only got the log in the same ns as the connection, and nothing coming from my defelems
i can do that
no local storage
fresh page load
it doesn’t even print id
on the second go
(h/loop-tpl :bindings [id items+final]
(item/item
:list-id list-id
:id id)))))
(h/defelem item
[attributes children]
(let [list-id (:list-id attributes)
id (:id attributes)
is this bad?
actually, yeah, that’s right
id doesn’t change
but entity should
because state/conn
changed
(j/defc a true)
(j/defc b 0)
(h/with-interval 2000 (reset! b (rand-int 10)))
(j/cell= (if a (prn b)))
this happily prints out random integers
confused
entity (j/cell= (if (integer? id)
(do (prn "foo" (d/touch (d/entity state/conn id)))
(d/touch (d/entity state/conn id)))))
bar (j/cell= (prn "id" id))
foo (j/cell= (prn "entity" entity))]
I can print foo
but entity is not updating
i should deref?
not sure what i’m looking for
how could an entity break a cell=
?
tada: https://github.com/tonsky/datascript/blob/master/src/datascript/impl/entity.cljc#L151
nyoooooo
well i suppose that explains things
don’t put entities in cell=
of course, things broke even more when i made it a map, but at least I know roughly what is broken now >.<
well, if i return the entity to cell=
it will never notice that it has changed
not that useful
grr, still seeing the original bug >.<
anyway, thanks again @dm3 and @alandipert
is there a way to avoid the way that cell= doesn’t do anything if the value returned is the same?
i have the situation where i have a loop of inputs
if i delete the last character from an input, it deletes that input
if i put “a” and “b” in the first two inputs, then delete “a”, all good, “b” is left
if I put “a” in both the first two inputs, then delete the first “a”, i get bad times
i’m left with two blank inputs
afaics
it’s because :value (cell= value)
value
is “a” before and after the deletion
so hoplon does nothing, and chrome deletes the “a” from the input
actually there’s 4 inputs
but this is “a, a, a, a” vs. “a, b, c, d” then deleting the first row in both cases
i want to see “a, a” and “c, d”
i’m simplifying for the example
it’s actually
:value (j/cell= (if-not (= :new id)
((keyword key) entity)
"”))
that’s the bug
had a question about dev flow, reagent / figwheel seems quite popular, is there an equivalent for Hoplon, or am i asking the wrong question?
@micha: what do you mean by “sharing value cells”?
:value (j/cell= (if-not (= :new id)
((keyword key) entity)
"”))
that’s in a loop-tpl
with a new “entity” for each thing in the loop
(let [entity (j/cell= (if (integer? id)
(into {} (d/touch (d/entity state/conn id)))))]
what about id?
they have different id
actually, you can see that both the “a” values are in the db under :min
and :max
they just don’t render
#datascript/DB {:schema {:item/list-id {:db/valueType :db.type/ref}}, :datoms [[4 :max "a" 536870916] [4 :min "a" 536870915] [4 :item/list-id 3 536870915]]}
the only thing i can think of
is that because hoplon is re-using the input
, instead of deleting and rebuilding it
:value
doesn’t “notice” that it’s a “different input"
but i dunno, maybe that doesn’t make any sense
it’s very weird that i can reliably reproduce the bug when the “before” and “after” inputs have the same string value
but never if they have different values
i can do it in the same list too >.<
anyway, i have to crash
it’s 2am
i’ll see if i can make a smaller test case tomorrow or later in the week
single list too
hey @micha i’m using your awesome workflow machine for form processing. I have a workflow that’s broken up in to several screens on a modal popup. I’d want to do validation before moving on to the next screen. would you set that up as separate forms?
@raywillig: yeah you probably want the user to be able to reload the page for instance at any point in the process and not have to start over right?
so i'd probably organize them as if they're separate things, with their own validation, etc
@micha Chris Granger seems to be in the "Spreadsheet as fundamental UI" camp with Eve project https://groups.google.com/forum/#!topic/eve-talk/3_zgustu0r0
screenshots.. http://imgur.com/a/4jRYH
@chromalchemy: yeah totally, although i think their hiccup virtual dom thing makes it less intuitiev
Tables may be good for keyboard data entry, and regular data views. But I like to think in relational graphs, and arbitrary-formatted data with graphical semantics. Hoplon provides the means....