Fork me on GitHub
#reagent
<
2017-10-23
>
cjsauer18:10:35

What are some strategies for encapsulating the functionality inside of a component, but leaving the styling of its constituents open for customization by the user? For example, a group of radio-like buttons all have the same behavior, but may differ in styling; e.g. arranged in a grid, arranged in a menu, the "none of the above" button should be a different color, etc...

cjsauer18:10:35

I'm thinking of just passing in a classes argument

cjsauer18:10:58

Wanted to see what others have tried as far as "skinnable" components go

reefersleep18:10:30

You can

(defn my-styleable-button [style]
   [:button {:on-click something
             :on-blur something-else                 
             :style style}])

reefersleep18:10:20

Seems like the most straightforward solution to me

noisesmith18:10:13

couldn’t a consumer reliably call (assoc-in (my-component) [1 :style] {.....}) and expect that to work?

noisesmith18:10:33

as long as the component returns a vector, and I’d be surprised at ones that don’t

reefersleep19:10:00

There are those that return fns 😊

reefersleep19:10:22

Which in turn returns vectors.

reefersleep19:10:25

And will your vector be a list or a vector after assoc-in? I can never tell, but it matters to reagent/render.

ajs14:10:26

vectors are associative, like maps, they are keys of their indices. therefore, assoc works, because it is associative; and it therefore returns an associative structure, in this case, a vector. lists are not associative.

noisesmith19:10:35

assoc-in breaks on lists and never returns lists

noisesmith19:10:06

yeah, it wouldn’t work if you return a fun, but that’s a decent reason not to return a fun, and let people use assoc-in (maybe…)

reefersleep19:10:15

Returning an fn is perfectly normal if you want to close over some state in Reagent. It's right there on the front page of "Introduction to Reagent". And I would say that a function with a clearly defined signature would be more straightforward in intent than some more or less implicit convention that goes against normal reagent expectations. But you could do it, sure!

reefersleep19:10:21

Meant to put a link to "Introduction to Reagent" here: https://reagent-project.github.io/ And btw, I do mean it; with Reagent code consisting mostly of native Clojure data structures, you can do whatever manipulations with them that you want. That is completely within your power. And that is awesome 😄

cjsauer19:10:17

@reefersleep is the style attribute different from class?

reefersleep19:10:21

The :style should be a map, with e.g. {:background :red, :padding "0.1em"}

reefersleep19:10:10

all of your css attributes

reefersleep19:10:35

if you want to do it with a vector of classes

reefersleep19:10:40

(defn my-classy-button [vector-of-class-names]
[:button {:on-click something
          :on-blur something-else
          :class vector-of-class-names}])

reefersleep19:10:08

omg I'm really tired of indentation in code blocks on Slack

cjsauer22:10:16

Agreeeeeeeed. So annoying...I really wish you could use Github syntax like: `Clojure

reefersleep19:10:21

Call it like [my-classy-button ["fancy-flat-styling-class" "class-for-making-stuff-draggable"]]

reefersleep19:10:21

Meant to put a link to "Introduction to Reagent" here: https://reagent-project.github.io/ And btw, I do mean it; with Reagent code consisting mostly of native Clojure data structures, you can do whatever manipulations with them that you want. That is completely within your power. And that is awesome 😄

cjsauer22:10:31

@reefersleep thanks a lot. This is really helpful! 🍻