Fork me on GitHub
#hyperfiddle
<
2024-01-23
>
Ketan09:01:50

Are there instructions somewhere on how to add electric to a project? I'm trying to follow electric-fiddle but just wanted to check if there's an easier way

deep_thinking 1
Geoffrey Gaillard15:01:59

We are working on a minimal ("brutalist") starter app that contains the bare minimum to run an electric program. We want it to be a reference on the minimum things one need to copy over an existing project.

Geoffrey Gaillard11:01:56

We have a new starter app. The readme should help you integrate into an existing project. https://github.com/hyperfiddle/electric-starter-app

😀 1
wei20:01:44

is there a good drag and drop library that works well with electric? something like https://shopify.github.io/draggable/ that can do sorting, swapping, drop targets, etc. the problem with that one is it wants to manage the DOM too, so i'm assuming it's incompatible

grounded_sage21:01:57

I don’t see anything in here that wouldn’t be take much effort to do from scratch. My experience is most JavaScript libraries just save people from having to write a bunch of JavaScript and it takes very little code when done in Electric

👍 1
henrik07:01:11

I used https://dndkit.com/ in the UIX version of our app and got pretty familiar with it. While I agree that basic DnD isn’t hard in Electric, some of the more advanced stuff isn’t so straightforward. Like https://master--5fc05e08a4a65d0021ae0bf2.chromatic.com/?path=/story/examples-tree-sortable--all-features I think the optimistic stuff in DE will be a great foundation for building a general DnD solution though.

🙏 1
wei18:01:39

was your app react+electric?

wei18:01:27

what are the considerations for using react in an electric app? is there a large performance hit? i've avoided it so far since i didn't want to introduce another dependency. but the react ecosystem has a lot of useful, nontrivial libraries.

henrik07:01:14

No, the old app was straight up UIx. I wouldn’t code large parts of the app in React, because Electric is better. But for lifting a React component off the shelf and using it, it’s fine, both usage-wise and performance-wise.

👍 1
henrik07:01:13

FWIW, this is the macro we use to mount React components with UIx. Usage is like:

(uix CircularProgressbar
  {:value     …
   :className …
   :styles    …})

🙏 1
wei00:01:03

thanks for your notes on usability and the macro, i think it will be very useful. i'm trying to get this test running (your code is under app.util.uix):

(ns app.test
  #?(:cljs (:require-macros [app.util.uix :refer [uix]]))
  (:require [hyperfiddle.electric :as e]
            [hyperfiddle.electric-dom2 :refer [div]]
            #?(:cljs ["@heroicons/react/20/solid" :as heroicons])))

(e/defn Test2 []
  (e/client (div (uix heroicons/ChevronUpDownIcon {}))))
which compiles but produces this js error:
#object[TypeError TypeError: Cannot read properties of undefined (reading 'create_root')]
what am i missing? i don't know which create_root it's referring to and there's no stacktrace. apologies if this is an elementary question but i'm new to UIx.

henrik08:01:36

Ah, weird. Are you on the latest maven artifact/master? This macro took a considerable amount of tweaking to get it to compile under IC.

henrik09:01:50

Oh, also, try [app.util.uix :as uix] and uix/uix.

👍 1
wei15:01:18

that worked, thanks! turns out i didn't need require-macros, and i did need other non-macro functions.

wei16:01:50

when using something like UIx, what's a good way to call an e/fn from a React component? for example, I'd like to use electric to update some server atom when the user interacts with the component.

henrik17:01:06

You can only call Electric indirectly using a state machine from within a React component. The flow would be something like this: 1. Create an atom outside of the React component. e/watch it. 2. Create a switching mechanism that reacts to the state value, e.g. with when/`cond`/`condp`. 3. Create a Clojure (non-Electric) function that sets the state. Provide it to the React component. Now your React function can set the state of the atom, and Electric will react to it.

wei17:01:55

thanks, makes sense. i also found a janky way to do react-component->electric by dispatching custom events within the component and using dom/on to listen for them

wei17:01:36

my problem with #3 is you need electric to set a server-side atom (unless you want to handle network manually like the bad old days)

henrik17:01:35

Not necessarily, consider this:

(e/defn Something
  []
  (e/client
    (let [!state (atom nil)
          [action payload] (e/watch !state)]
      (condp = action
        :save (e/server (transact! db payload …) …))
      (uix/uix ui-some-component 
        {:save-fn (fn [evt] (reset! !state [:save (.. evt -target -value)]))
         …}))))

henrik17:01:09

Wrote this off the cuff, so there may be mistakes, but the principle is there.

wei17:01:45

i see, that's cool!

👍 1