Comments (10)
@niwinz Not sure, I've actually always used css styes instead of ":style". But you can:
- Use
if
and return the default value of "inherit/transparent". - Just give the
:background-color
anil
value and see what React does with it. I thought it would ignore nil values and not emit any styles...
HTH
from hicada.
Just curious: Do you actually use dynamically created props on :div
s? What's the use case here? I'm not a big fan of meta data in general tbh.
If you do use this a lot, you might want to extends hicada to make it easier to write this case. Maybe something like :-div
or :>div
or whatever? You'd have to probably change the emitter-fn.
from hicada.
It's not only div. Some samples:
[:input (cond-> {:value @val
:on-change #(reset! val (-> % .-target .-value))
:type (or type "text")}
placeholder (assoc :placeholder (str placeholder ":")))]
[:img (if @(:loaded state)
params
(dissoc params :src))]
[:div (merge (v/inner-html "some-html-code-here") ; inner-html as a function resolving to :dangerouslySetInnerHTML construct
{:on-click (fn[] )})]
Or simply the situation when attributes are common for many elements, so I let
them to DRY
(let [a-params {:href url
:title name
:on-click (fn [] ...)}]
(html
[:div.product-box
[:a.product-box_image a-params
(product-img* p)]
price
[:a.product-box_name a-params
name]]))
I mean, if I'd like to switch from Sablono to Hicada, I would need to perform extra work just to change some syntax.
However, I think that :transform-fn
could be of use here. I can detect if first child has :attrs
metadata and move it back as attributes... Wrapping it in merge-with-class
and so on.
from hicada.
@zlorf None of these examples would work at all. Even if you wrote a custom emit-fn. The problem is that you're creating CLJS data structure (here the peristent maps) which isn't understood at all by React. React expects a JS object. Though, all of these examples can easily be rewritten and (IMO) make code even clearer at the same time. You should exploit that null
attributes by React are just ignored. So you don't need to conditionally set/unset an attribute, just set them to nil
.
Your examples would be:
(let [placeholder nil]
[:input {:value @val
:on-change #(reset! val (-> % .-target .-value))
:type (or type "text")
:placeholder (when placeholder (str placeholder ":"))}])
(let [state {}]
[:img {:other-props "foo"
:src (when (:loaded state)
"foo")}])
; inner-html as a function resolving to :dangerouslySetInnerHTML construct
[:div {:on-click (fn [])
:dangerouslySetInnerHTML {:__html "some-html"}
;; Or better: Write a custom transformer to avoid having to repeat
:inner-html "some-html-code"}]
In general: If you use a pattern a lot. Use transform-fn
to write a DSL for it. Eg. the above :inner-html
isn't supported but writing a transformer for it is ~3-4 lines of code.
from hicada.
Example:
(compile '[:div {:ihtml "<div>hi</div>"}]
{:transform-fn (fn [[tag attr ch]]
(if-some [html (:ihtml attr)]
[tag
(-> attr
(dissoc :ihtml)
(assoc :dangerouslySetInnerHTML {:__html html}))
ch]
[tag attr ch]))})
from hicada.
Since this is a macro you could do some cool stuff. Imagine:
[:div {:md "Do *this* not _that_"}]
And you can dynamically create hiccup for it by parsing the markdown string. :)
Or even:
[:div {:md true}
"# Heading 1"
"Foo *bar* _baz_"]
or:
[:div
(SomeComponent)
;; Emits a span
[:*md* {:el "p";; use p instead of default "span"
:style {:margin-left "8px"}}
"some *markdown* parsed by special handler fn"]]]
EDIT: See the wiki for an example implementation.
Lots of possibilities for a nice DSL.
from hicada.
Yep, the transformations give many possibilities for DLS (I like the :ihtml
example here).
But what about the last example, with a-params
? Have you encountered such a situation in your projects? How have you solved the problem? Have you just repeated the attributes?
from hicada.
In your last example I'd just create a fn:
(defn my-custom-ahref
[klass children]
(html
[:a {:href url
:class klass
:title name
:on-click (fn [] ...)}
children]))
(my-custom-ahref "product-box_image" (product-img* p))
(my-custom-ahref "product-box_name" name)
But if it's just twice, I usually just repeat the attributes. Or create a fn in a let
:
(let [a-params #(html [:a {:href url
:class %1
:title name
:on-click (fn [] ...)}
%2])]
(html
[:div.product-box
(a-params "product-box_image" (product-img* p))
price
(a-params "product-box_name" name)]))
from hicada.
First of all, sorry if this is unrelated but i think is related so i don't create new issue.
I'm trying to convert my project to use hicada and I found that the hicada explicitly does not supports dynamic props (at least as I understand). So lets take a example from rum examples directory: (and make the assumption that i have adapted rum to work with hicada instead of sablono):
(rum/defc bit < rum/static [n bit]
(swap! *bclock-renders inc)
[:td.bclock-bit {:style (when (bit-test n bit) {:background-color @core/*color}) }])
Since we have the when the generated code is:
return React.createElement("td",{'className':"bclock-bit",'style':((((n & (1 << bit)) != 0))?new cljs.core.PersistentArrayMap(null, 1, [new cljs.core.Keyword(null,"background-color","background-color",570434026),cljs.core.deref.call(null,rumext.examples.util._STAR_color)], null):null)});
})
Facts:
- that will not work because react does not understand cljs persistent maps.
- if I remove the when, then the style prop is correct for react.
And the question here, if hicada does not support dynamic props, how I can write this code idiomatically with hicada?
from hicada.
Closed for inactivity.
from hicada.
Related Issues (13)
- Hicada to HTML String ? HOT 2
- trouble compiling project HOT 3
- Should `compile-html` walk everything? HOT 1
- Use with Rum? HOT 4
- Private discussion HOT 1
- Isomorphic rendering? HOT 8
- Optional props for :> HOT 1
- Preserve clojurescript objects in props HOT 3
- Incorrect result on compiling `cond` with more than 4 conditions. HOT 2
- Server side rendering HOT 1
- Deploy a new version (> 0.1.8) HOT 1
- The 0.1.9 causes regression HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hicada.