Fork me on GitHub
#hyperfiddle
<
2023-02-17
>
vincent00:02:37

Opa looks awesome if i still practiced necromancy

vincent00:02:54

re: npm deps x)

tatut19:02:26

I tried to make a hiccup like macro, but that interferes with the electric macro (would need to make a macro that wraps the e/defn and processes things before that I guess), and a function that does dom/elementcalls doesn’t seem to work properly in a dynamic case (says hyperfiddle.electric-dom2/node not declared ^:dynamic )

Dustin Getz19:02:46

yeah there are good reasons that we haven't provided hiccup

Dustin Getz19:02:03

though im not sure what error you're seeing

tatut19:02:56

I can make a snippet of my quick hack experiment

Dustin Getz19:02:06

i can probably help you resolve any issues with dynamics, the boundary between photon dynamics and clojure dynamics has to be explicitly managed currently

Dustin Getz19:02:18

yes please show snippet

tatut19:02:14

it seems to mostly work tho

Dustin Getz19:02:25

that's really cute, we have not considered that style

Dustin Getz19:02:47

i like it a lot

tatut19:02:47

I mostly just want the :div.some-class to make classes, if that was provided builtin, that would be enough

tatut19:02:54

feel free to take that 😄

tatut19:02:20

I often use tailwindcss so I want a convenient syntax for adding the static classnames

Dustin Getz19:02:10

yeah the current dom syntax has been a frequently reported issue

Dustin Getz19:02:23

we agree with you btw

Dustin Getz19:02:29

just tricky to do right

tatut19:02:30

the compiler is giving me warnings for each of the content count cases like

90 |          0 (dom/element e (when attrs (dom/props attrs)) (doseq [[h b] handlers] (dom/on h b)))
------------------^-------------------------------------------------------------
 hyperfiddle.electric-dom2/node not declared ^:dynamic
--------------------------------------------------------------------------------

Dustin Getz19:02:31

turn <% into defmacro not defn

tatut19:02:46

I tried that first, but that didn’t work

Dustin Getz19:02:53

e/def is not visible in ordinary clojure, only from e/defn and e/def etc

tatut19:02:56

if failed to analyze

tatut19:02:03

but I can try again

Dustin Getz19:02:23

i will take a closer look over the weekend

thanks 2
tatut19:02:51

(defmacro <% [elt & attrs-and-content]
  (let [[attrs content] (if (map? (first attrs-and-content))
                          [(first attrs-and-content) (rest attrs-and-content)]
                          [nil attrs-and-content])
        handlers (keep (fn [[key val]]
                         (when (str/starts-with? (str key) ":on-")
                           [(subs (str key) 4) val]))
                       (seq attrs))
        classes (element-class-names elt)
        attrs (cond-> (apply dissoc attrs (map first handlers))
                (seq classes)
                (update :class (fn [class]
                                 (let [class-names (str/join " " classes)]
                                   (if class
                                     (str class-names " " ~class)
                                     class-names)))))
        e (element-name elt)]
    `(dom/element
      ~e
      ~(when attrs
         `(dom/props ~attrs))
      ~@(for [[h b] handlers]
          `(dom/on ~h ~b))
      ~@(for [c content]
          (if (string? c)
            `(dom/text ~c)
            c)))))
here’s the macro version, I must have made some mistake 1st time… now it worked

👀 2
🎉 2
Dustin Getz19:02:33

there are also small syntax gaps that photon compiler doesn't understand yet, not all interop forms are handled correctly for example

Dustin Getz19:02:53

i will play with it! thank you for sharing

xificurC20:02:18

A minimal solution for simpler classes

tatut04:02:17

there seems to be a contrib namespace, I can make a properly documented version of that macro as a PR if you think it will be helpful for others

JAtkins23:02:03

what’s the reason for extensive use of binding forms? Prolly a doc somewhere I missed I guess

Dustin Getz23:02:47

i don’t think we’ve explained that yet

JAtkins23:02:15

main e.g. I'm looking at:

(e/defn Main []
  (binding [router/encode contrib.ednish/encode-uri
            router/decode #(or (contrib.ednish/decode-path % hf/read-edn-str)
                               [`user.demo-index/Demos]
                               #_[[`user.demo-index/Demos . . .]]
                               #_{`user.demo-index/Demos {0 . 1 . 2 .}})]
    (router/router (html5/HTML5-History.)
      (set-page-title! router/route)
      (binding [dom/node js/document.body]
        (dom/pre (dom/text (contrib.str/pprint-str router/route)))
        (let [[page & args] router/route]
          (e/server (new (Pages. page #_args))))))))

Dustin Getz23:02:42

reactive dynamic scope is really cool, it is sufficient for dependency injection of the kind that DI libs like Component etc do

Dustin Getz23:02:40

we view it as composable DI basically

👍 4
tatut05:02:14

so instead of libraries like component or mount, you would bind a db connection pool at your app root?

Geoffrey Gaillard08:02:24

Yes, these DI libs: 1. track dependencies to start/stop elements in the right order 2. Inject references in dependent components Electric clojure does 1 out of the box.