Fork me on GitHub
#hoplon
<
2017-02-21
>
onetom03:02:12

@mynomoto where would you expect to find this info?

thedavidmeister03:02:11

i suppose this is the problem with "alpha" code

thedavidmeister03:02:22

breaking changes are supposed to be considered normal

onetom03:02:57

im on alpha17 since it came out and im just carrying my config over to other repos as needed but since i mostly work on the same repo, i haven't encountered this issue often enough to feel its pain

thedavidmeister04:02:11

i've gotten in the habit of setting aside a ticket just to handle hoplon updates

thedavidmeister09:02:31

if you're not sure whether something is a cell or not, say it's the argument to a fn

thedavidmeister09:02:42

is @(cell= foo) idiomatic to get the value?

dm310:02:04

that doesn’t look nice but I can’t think of anything better

mynomoto13:02:04

@onetom probably a changelog file? Experienced people suffer less with this, beginners way more.

candera13:02:07

If you think it might be a cell, presumably you want to react to it. I have generally done (let [v* (cell= v)] …)

candera13:02:18

Then I use v* for everything inside the let.

candera13:02:47

If you really need the value and don’t want to treat it as a cell, I might define a value-of or maybe-deref that leverages javelin.core/cell?.

candera13:02:55

Not sure we have sufficient history to declare anything “idiomatic” yet. 🙂

thedavidmeister14:02:18

@candera yeah usually that all works, it can get a bit confusing what is a cell and what is a value sometimes

thedavidmeister14:02:21

around the edges

candera14:02:56

Agreed - I find the shift similar to the one I made (am still making, perhaps) when moving from OO to functional.

candera14:02:24

In terms of the mental shift required.

dm314:02:05

it does seem like a design problem

dm314:02:21

as some attributes might evolve value -> cell over time

dm314:02:29

usually doesn’t happen the other way around

dm314:02:06

what would a typed language do? Probably separate values and cells into different arguments or wrap all values into something cell-like automatically

candera14:02:10

On a completely separate note, I had an idea that’s probably sort of stupid. I’m imagining a (with-styles [:li :span {:background-color “white”}] content) operator. with-styles would wrap content with an element with a unique ID. Then it would modify the <head> of the document to contain a <style> element that has the styles in its first arg, but scoped to be descendants of that ID.

candera14:02:48

I feel like that would give me nice, local declaration of styles and would get rid of the need to express certain things on every element that matches. Plus, it opens up the ability to use things like nth-child and before selectors.

thedavidmeister14:02:51

@candera i played around with something like that, i figured that dynamically modifying head styles like that might be a perf hit

thedavidmeister14:02:03

but i didn't get any numbers

thedavidmeister14:02:22

although, if you did a style element per element rather than one big one that might be OK

candera14:02:37

Yeah, I don’t see any reason not to make each one its own element.

thedavidmeister14:02:10

@dm3 i'm probably way off here because i'll admit i don't totally grok them yet, but is that what monads are for?

dm314:02:29

well, Cell is a monad

dm314:02:33

but it doesn’t matter

candera14:02:35

Monads are for convincing other people you have too much free time. 🙂

candera14:02:39

(Totally kidding)

thedavidmeister14:02:57

@candera i saw a macro someone did for garden for this somewhere, hang on...

thedavidmeister14:02:11

unrelated to hoplon but related to the id generation

micha14:02:35

monad peepers!

micha14:02:47

i peeped 3 monads already today

micha14:02:59

put em in my lil log book and errthang

candera14:02:16

@thedavidmeister I would want it to be cell-aware so the styles could react to changes. But cool - I will look at that.

thedavidmeister14:02:50

@candera yup totally, this is my snippet for that

thedavidmeister14:02:53

(defmethod hoplon.core/do! :garden
  [el _ v]
  ; Replace all the inline styles on an element with css generated by Garden.
  ; Obviously does not play nice with other methods of setting inline styles.
  (let [vs (if (sequential? v) v [v])
        css (garden.compiler/compile-style vs)]
    (.setAttribute el "style" css)))

candera14:02:18

Hmm. That walks content. I want to avoid that. It rarely turns out well.

thedavidmeister14:02:26

@dm3 well i thought that part of monads was to make dealing with values inside things easier 😛

thedavidmeister14:02:12

@candera well it puts inline styles on things

thedavidmeister14:02:44

but you could tweak it pretty easy to make the string generated by garden.compiler/compile-styles dump into a style tag instead of a style attribute

candera14:02:04

Ah, I see what you’re suggesting. Yes, that’s what I had in mind.

candera14:02:53

And I like the idea of using a separate attribute for garden rather than overloading :css or detecting if something is a string or some such.

dm314:02:11

that’s the guy with his own React-based cljs stack

candera14:02:58

That defstyled thing is just functions, though...

thedavidmeister14:02:09

soooo, this might be controversial, but i don't find myself having issues with css selectors generally

candera14:02:45

Right, I run into it rarely. But e.g. wanting to make every other row of a table a color. It’s also often more convenient programatically than setting the style on stuff.

thedavidmeister14:02:05

the problems i usually have are around organisation

candera14:02:13

I retract the “just functions” comment - not sure I absorbed what he’s doing correctly.

thedavidmeister14:02:21

like, "the css for this thing is nested deep in that file over there somewhere"

candera14:02:51

Yes - that’s the motivation for wanting with-styles - so that the CSS is with the thing its styling.

thedavidmeister14:02:17

i've just made a styles.cljc file that i put next to my dom.cljs file in my component's folders

thedavidmeister14:02:40

(def ^:screen title
  [(s/attr= :data-key ":title")
   styles.spacing/full-width
   {:position "relative"
    :margin-bottom styles.spacing/mini-pad}])

(def ^:screen current-item
  [(s/attr= :data-current :item)
   styles.form/currently])

(def ^:screen item
  [:.item
    styles.form/form-card])

thedavidmeister14:02:02

and something vacuums up all the things with ^:screen and spits it into the final css file

candera14:02:01

But if you had local styles you could put that around the constructor for the elements you’re styling.

candera14:02:14

But of course if you have multiple orthogonal styles then this is better.

thedavidmeister14:02:24

yes you could definitely do that

thedavidmeister14:02:39

i have a mix of inline :garden attributes and things like the above

thedavidmeister14:02:29

and even though i'm pretty casual about what goes where, it's already proven to be way easier to find stuff than having a giant SASS project running in parallel to everything else

thedavidmeister14:02:59

if you get the with-garden or with-styles thing working, ping me

thedavidmeister14:02:03

i'm definitely interested 🙂

dm314:02:52

that shadow.markdown thing generates a React component, the CSS and the class name (based on ns + defstyled name)

dm314:02:26

puts the CSS into a single style container and you then use the defstyled name as a React component constructor

dm314:02:45

so the idea seems similar

dm314:02:50

like defstyledelem

thedavidmeister14:02:06

also, wouldn't you want the bulk of your css to be in a file that can be cached?

thedavidmeister14:02:22

and only dynamically mess with things that are too specific to an element to go in a master file?

dm314:02:28

he also supports rendering it into just CSS

dm314:02:33

supposedly for that purpose

candera14:02:10

I’m writing a desktop app. My startup time, so far, is not a problem.

dm314:02:50

so you could have a defstyledelem with similar syntax. That would produce an elem which would then be used to wrap other elems and make them stylish

thedavidmeister14:02:33

i also like that my solution is ~60 LOC including boot compiling task, namespace scanner and hoplon/garden integration

dm314:02:12

your solution is nice too

thedavidmeister14:02:20

and honestly, my namespace scanning is terrible because i didn't realise i could just copy the deftest implementation until later

thedavidmeister14:02:59

so i have about 20 LOC reimplementing "scan namespaces in this directory" when something already exists for that 😛

thedavidmeister14:02:51

surely if you had the with-styles working it would be pretty easy to make that defstyledelem on top of it

thedavidmeister14:02:08

i think it would be nice to have both

thedavidmeister14:02:37

support wrapping anonymous elements in styles 🙂

thedavidmeister14:02:35

soooo, i'm going to go ahead and assume that implementing deref for primitives like strings and numbers is A Bad Idea

thedavidmeister14:02:59

i don't know why, i just feel like if it was a good idea it would already be setup that way

dm314:02:38

maybe wrapping all attrs into cells is a good idea?

dm314:02:47

I think defelem+ does that, no?

thedavidmeister15:02:08

mmm, i think it is just a confusing thing

thedavidmeister15:02:31

i have similar problems deciding where to put conn and db in my functions when working with datascript

candera15:02:03

On that one, I generally have a layer that deals with connections, and another layer that only deals with db.

thedavidmeister15:02:48

reading vs writing?

candera15:02:03

No. The db layer can return transaction data or results of queries.

candera15:02:15

But the next layer out handles getting the db and transacting the data.

candera15:02:19

Then you always have a pure layer.

candera15:02:28

Easy to test. And the conn layer is close to trivial.

dm315:02:02

ahh, the Datomic monad

candera15:02:14

Datomonad is my new band name.

thedavidmeister15:02:59

what do you mean "getting the db"?

thedavidmeister15:02:08

what would that look like if you had an element that renders children based on a query, and those children need the conn to transact against (like, user input going into the db)

thedavidmeister15:02:22

you'd have to pass the conn into the parent element, which can query on it and forward the conn to its children, right?

thedavidmeister15:02:06

i feel like @dm3 nailed describing the problem, which is that i want a db (value) right up until a child of the element wants to transact to respond to user input and i need a conn (a cell in my case)

thedavidmeister15:02:22

so i end up defensively celling everything "just in case"

thedavidmeister15:02:53

just because that works for cells and values, not because i specifically need one or the other

eoliphant15:02:03

hi. I’m using hoplon with a luminus setup (leiningen, etc). Everything works fine, but I’m trying to use an add on library for semantic-ui [degree/semui-hl]. I’ve not been able to import the its namespaces. In looking at the .jar it appears to contain .hl files. I’m new to the boot/hoplon ecosystem, but I was under the impression that .hl files were more of a build time artifact that should get compiled in to .cljs files, and presumably distributed that way in a library?

thedavidmeister15:02:01

@flyboarder ^^ i think this is yours?

flyboarder15:02:08

@eoliphant .hl files should be compiled In Your application not in the libraries

candera15:02:41

@thedavidmeister I’m not sure I have the situation totally pictured, but generally when decomposing problems like this, I find that going from "A calls B calls C" to “A calls B and then calls C” is helpful. Sorry - sort of distracted right now.

thedavidmeister15:02:10

np, i gotta go to bed anyway >.<

flyboarder15:02:13

@eoliphant make sure you add the hoplon task to your build

thedavidmeister15:02:25

but i don't think i can have "A sequentially calls the entire DOM hierarchy that might want to use a conn" 😕

thedavidmeister15:02:37

think i need to mull on this a bit more

eoliphant15:02:54

ah, gotcha @flyboarder thanks, will look at that

chromalchemy17:02:04

@alandipert @jjttjj @mynomoto @laforge49 @flyboarder ':require [hoplon.jquery]' Worked for me too. I am using .hl and assumed that was included. That change knocked me out for a few days.

chromalchemy17:02:38

@alandipert Thanks for the printing functions tho

chromalchemy17:02:44

What is good practice on when to include jquery?

chromalchemy17:02:16

.. and [cljsjs.jquery]?

flyboarder17:02:48

@chromalchemy make sure you are using the correct version of boot-hoplon

flyboarder17:02:10

I.e. Remove the dependency and use the built-in version in alpha17

chromalchemy17:02:09

Ok. I had it that way.

chromalchemy17:02:41

So when do you need to require jquery? When using % in inline function in attribute?

flyboarder17:02:19

@chromalchemy You should only need it if you are using cljs files instead of hl files

flyboarder17:02:47

But basically if you use attributes that you don't want to directly pass to the HTML output you need an attribute provider

flyboarder17:02:08

Things like event attributes

chromalchemy17:02:54

Ok thanks. Somethings up. I needed it and im using .hl. Maybe a UI thing?

chromalchemy18:02:22

using '(elem (input))'

chromalchemy18:02:53

@jumblerg Do you have a simple example of using a '(line)' element. Getting a value out of it. Im fuzzy on what attr keywords to use. Maybe a (pick) too? Thx!

jjttjj18:02:39

unfortunately I think the ui form stuff is not finished or in a very usable state right now

jjttjj18:02:40

i mean, you can use the elems like line/pick etc but i mean that I don't think the built in form state management stuff is ready

chromalchemy18:02:55

@jjttjj Ok, noted. What does :key :foo do?

jjttjj18:02:36

a map will be passed to the function on the :submit key of the form that will look like {:foo "value of foo"}

jjttjj18:02:14

I think there is presently some issue with the ui/write element though. I haven't been able to get forms to submit besides pressing the enter key while the cursor is in a form element. I haven't dug into this too deeply yet though

chromalchemy18:02:21

Thx. will try it out :)

chromalchemy19:02:24

@candera @thedavidmeister I like declaring styles with first class attrs in UI Elems. Makes me less shy of using events to create dynamism (compared to the walled-off css mentality). And the minimal syntax makes it fast to write/prototype styles. I am saving combo styles as named maps. But this approach currently lacks vendor prefixes and caching. But these are performance optimizations, and i want to orient my thinking to higher level workflows that point the way out of the tarpit of CSS,and it's (artificial) separation from control code. That being said, Garden helps bridge the gap. Thanks @thedavidmeister for the Do method. I also want a way to aggregate locally-defined classes (in the head/style tag i guess). Can this have reasonable performance for dynamic style rules?

candera19:02:00

I have no idea, although my experience with performance work in other contexts suggests that perf is always relative, and answering the question probably requires a definition of “reasonable”.