Fork me on GitHub
#helix
<
2024-04-17
>
itaied12:04:18

hey all, i'm testing out some style mappers to react I am facing a problem using helix camel-case logic when passing :-webkit-background-clip to react. It is converted to WebkitBackgroundClip but react doesn't attach this style to my component. I'm not using helix directly, so I was wondering if I'm missing some transformation that happens later on. by the way, other -webkit props does work for me that's the piece of code I'm using:

(def aria-data-css-custom-prop-special-case-re #"^(aria-|data-|--).*")

#?(:cljs (def camel-regexp (js/RegExp "-(\\w)", "g")))

(defn camel-case
  "Returns camel case version of the string, e.g. \"http-equiv\" becomes \"httpEquiv\"."
  [s]
  (if (or (keyword? s)
          (string? s)
          (symbol? s))
    (let [name-str (name s)]
      ; this is hot path so we want to use low-level interop
      #?(:clj  (cond
                 (some? (re-matches aria-data-css-custom-prop-special-case-re name-str)) name-str
                 (= (subs name-str 0 1) "'") (subs name-str 1)
                 :else (string/replace name-str #"-(\w)" #(string/upper-case (second %))))
         :cljs (cond
                 (some? (.match name-str aria-data-css-custom-prop-special-case-re)) name-str
                 (= (.substring name-str 0 1) "'") (.substring name-str 1)
                 :else (.replace name-str camel-regexp #(.toUpperCase %2)))))
    s))

lilactown16:04:37

it looks like you're trying to use this for https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions which this regex wasn't originally built for. you could modify the original aria-data-css-custom-prop-special-case-re regex you're using to handle -webkit too. should be pretty easy.

lilactown16:04:23

not really sure what you're trying to do but in general, using CSS-in-JS solutions you shouldn't have to write -webkit-<style> yourself

itaied04:04:02

I'm passing these style props to my react component using vanilla react. Running the following in js works:

<button style={{ WebkitBackgroundClip: "text" }}>btn</button>
But the following doesn't
:-webkit-background-clip "text"
:-webkit-text-fill-color "transparent"
:-webkit-box-decoration-break "clone"
note that both -webkit-text-fill-color -webkit-box-decoration-break does get to the browser but -webkit-background-clip doesn't. I'm not sure where to look, but since I got my inspiration from this lib, I thought asking in this channel

itaied05:04:52

it's a real voodoo here... that's the component that gets to the browser, just before render

#js {$$typeof #object[Symbol(react.element)], :type span, :key nil, :ref nil, :props #js {:style #js {:WebkitBoxDecorationBreak clone, :boxDecorationBreak clone, :overflowY visible, :aspectRatio nil, :WebkitBackgroundClip text, :marginInlineStart nil, :transform nil, :inlineSize nil, :marginBlockEnd nil, :position relative, :marginBlockStart nil, :backgroundPosition center, :placeSelf stretch, :fontSize 12px, :borderRadius 0, :blockSize max-content, :insetInlineStart 0%, :placeContent stretch, :zIndex nil, :flexShrink 0, :backgroundSize cover, :display inline-block, :insetBlockStart 0%, :marginInlineEnd nil, :background linear-gradient(90deg,#000000,#ffffff), :textAlign nil, :WebkitTextFillColor transparent},
only the WebkitBackgroundClip is not displayed in the element css tho

itaied07:04:26

found the problem, it's the order of the map of style props, when it's more than 8 entries

lilactown14:04:57

why does the order of the styles map matter?

itaied14:04:47

because background override background-clip

itaied14:04:27

background: blue;
background-clip: text;
results in a different output from
background-clip: text;
background: blue;

lilactown18:04:45

I see. So it's not that -webkit-background-clip is converted to camel case wrong, but the order of CSS rules says that background overrides background-clip

lilactown19:04:01

not sure what to do there, other than pass in the background: blue as background-color instead