GithubHelp home page GithubHelp logo

Attrs type hint about hicada HOT 10 CLOSED

zlorf avatar zlorf commented on July 19, 2024
Attrs type hint

from hicada.

Comments (10)

rauhs avatar rauhs commented on July 19, 2024 1

@niwinz Not sure, I've actually always used css styes instead of ":style". But you can:

  1. Use if and return the default value of "inherit/transparent".
  2. Just give the :background-color a nil value and see what React does with it. I thought it would ignore nil values and not emit any styles...

HTH

from hicada.

rauhs avatar rauhs commented on July 19, 2024

Just curious: Do you actually use dynamically created props on :divs? 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.

zlorf avatar zlorf commented on July 19, 2024

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.

rauhs avatar rauhs commented on July 19, 2024

@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.

rauhs avatar rauhs commented on July 19, 2024

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.

rauhs avatar rauhs commented on July 19, 2024

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.

zlorf avatar zlorf commented on July 19, 2024

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.

rauhs avatar rauhs commented on July 19, 2024

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.

niwinz avatar niwinz commented on July 19, 2024

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.

niwinz avatar niwinz commented on July 19, 2024

Closed for inactivity.

from hicada.

Related Issues (13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.