helix

https://github.com/Lokeh/helix
alidlorenzo 2020-06-09T00:01:17.166700Z

yeah, initially I was using helix.core/$ in the emitter

alidlorenzo 2020-06-09T00:02:23.167900Z

but ran into issues doing that with Hiccup, since both macros were trying to compile the component’s children. so started directly using Helixs prop impl inside a parser instead (that’s why the demo does it like that too)

alidlorenzo 2020-06-09T00:02:57.168Z

created an issue for this (https://github.com/alidlo/rewrap/issues/1) still have to figure out how to best mix the two since there’s some overlap

lilactown 2020-06-09T00:06:01.169Z

I wonder how simple it would be to do it just for helix

alidlorenzo 2020-06-09T00:07:52.170700Z

it’s not hard to do, just two macros, hard part is making it extensible

👍 1
alidlorenzo 2020-06-09T00:08:24.171100Z

@lilactown here’s link to exact code: https://github.com/alidlo/rewrap/blob/master/rewrap/src/rewrap/interop.cljc#L42-L55

alidlorenzo 2020-06-09T00:11:52.173300Z

i kinda wish Helix separated it’s hooks/dev optimizations from its interop/compilation since the former can be used with any React wrapper, whereas latter is more opinionated

alidlorenzo 2020-06-09T00:12:43.174400Z

right now, for example, I’m writing a UI library. its written in Typescript, considering writing it in Clojurescript but then I’d have to choose a React wrapper making it less useful

lilactown 2020-06-09T00:13:29.175Z

I would take a PR for a helper macro like that specific to helix. Riffing on what you have there:

(defmacro generate-native-macros
  [sym->impl]
  `(do
     ~@(for [[sym impl] sym->impl]
         `(defmacro ~sym [& args#]
            (helix/$ (with-meta ~impl {:native true}) ~@args#)))

lilactown 2020-06-09T00:14:52.176200Z

is there anything specific about helix that is stopping you from using it to build a UI library?

alidlorenzo 2020-06-09T00:19:47.177300Z

to what extend would it make sense using all of Helix with Fulcro or Reagent?

alidlorenzo 2020-06-09T00:20:56.178100Z

opting for js just bc it by default has less code/opinions, not sure if there’s way around that

lilactown 2020-06-09T00:23:44.178900Z

well, in my head, helix is so minimal and opinion-less that it’s just the same as writing in JS and using it with Fulcro or Reagent 😛

lilactown 2020-06-09T00:24:53.180100Z

but I am probably biased, so I’m curious if there’s some specific choices that helix makes for you that make it feel like it impedes use w/ Fulcro/Reagent/Rum/etc.

lilactown 2020-06-09T00:25:42.180900Z

I would also accept code size as a reasonable argument, I think that helix should be less code, for all that it does… not sure exactly how to accomplish that yet

lilactown 2020-06-09T00:26:21.181500Z

but curious if there are other problem points

alidlorenzo 2020-06-09T00:28:21.183100Z

code size and extensibility are my two arguments. e.g. above you baked in helix.core/$ as emitter macro when my whole goal was to make it custom 😜

alidlorenzo 2020-06-09T00:29:21.183800Z

it can be error prone to mix different react wrappers, e.g. mixing helix and hicada I ran into uses since they both compile props and children a certain way. so that’s why with rewrap wanted to make those things extensible

lilactown 2020-06-09T00:32:19.184700Z

hmm. I guess my expectation is that you would expose them as react components, same as what you would get with writing them in TS

lilactown 2020-06-09T00:33:26.186100Z

so e.g. if you had a component:

(defnc my-component
  [{:keys [foo bar]}]
  ,,,)
then some reagent app would use it like:
(defn app []
  [:> ui-lib/my-component
   {:foo "foo" :bar "bar"}
   ,,,])

lilactown 2020-06-09T00:34:02.186500Z

rum, fulcro I assume have similar syntax for handling external React components

alidlorenzo 2020-06-09T00:38:46.187200Z

yea, i guess in that case it’d just a small code overhead, which I guess shouldn’t matter relative to entire cljs bundle we’re bringing in but psychologically it does 😅

lilactown 2020-06-09T00:39:18.187800Z

FWIW at my previous job that’s exactly what we did: wrote our UI library components in JS/TS and then used them in our reagent app

lilactown 2020-06-09T00:39:31.188Z

it worked okay

alidlorenzo 2020-06-09T00:40:07.188900Z

yea, tbh, I just wonder what cool things I could do writing it primarily for cljs

alidlorenzo 2020-06-09T00:40:38.189600Z

plus have to consider optimizations in two languages versus one

lilactown 2020-06-09T00:40:43.189800Z

yeah

alidlorenzo 2020-06-09T00:40:58.190500Z

and TS.. i used to love it before cljs lol

lilactown 2020-06-09T00:41:08.190700Z

I still kinda like TS

lilactown 2020-06-09T00:41:21.191Z

I wrote my latest big idea in TS

lilactown 2020-06-09T00:41:33.191300Z

trying to use it in a new CLJS lib is troublesome tho

alidlorenzo 2020-06-09T00:42:10.192300Z

i like it in general too, but in complex project TS error message become indecipherable

lilactown 2020-06-09T00:42:15.192500Z

I hope CLJS implements support for goog.module sooner rather than later

lilactown 2020-06-09T00:42:28.192800Z

then you could use TS code in CLJS super super easily via tsickle

lilactown 2020-06-09T00:42:41.193Z

https://github.com/angular/tsickle

alidlorenzo 2020-06-09T00:43:21.193900Z

yea, mixing between them more easily would be great; thanks for link

fabrao 2020-06-09T00:56:07.194300Z

is that possible using helix with electron?

Aron 2020-06-09T03:48:43.194400Z

making what less useful?

Aron 2020-06-09T03:49:33.194800Z

I need zero TS

dominicm 2020-06-09T10:27:10.195Z

I know this is easier said than done, I'd really appreciate some docstrings on helix.hooks functions/macros. I could contribute some of them, but use-callback is eluding me.

Aron 2020-06-09T10:51:24.195400Z

@dominicm personally, I never saw the point of that hook

Aron 2020-06-09T10:51:45.195800Z

you need it for performance reasons?

dominicm 2020-06-09T10:52:18.195900Z

Gotta keep my re-renders down, yep

Aron 2020-06-09T10:54:16.197400Z

could you be a bit more specific please about what is elusive about use-callback

dominicm 2020-06-09T11:11:44.197500Z

I just didn't understand the arguments, I assumed it would be like use-effect, it seems like it's more like react/useCallback

dominicm 2020-06-09T11:12:06.197600Z

Use effect takes a body, but use-callback takes a fn-body, but in the arglist it's called a body too 🤕

Aron 2020-06-09T11:12:56.198100Z

I see, probably simple mistake of docs

Aron 2020-06-09T11:13:02.198300Z

arglists* sry

dominicm 2020-06-09T11:13:14.198600Z

docs could explain body must resolve to fn in this case.

Aron 2020-06-09T11:13:41.199200Z

useCallback(fn) in react is useMemo(() =>fn), so I always used useMemo because I find useCallback confusing

Aron 2020-06-09T11:14:41.199800Z

I am fairly sure helix relies a bit on the react docs

fabrao 2020-06-09T14:02:47.201200Z

I have problems to understand react hooks too, and I only used use-state and use-effect until now 🙂

Aron 2020-06-09T14:09:40.201500Z

all hooks are basically use-state

dominicm 2020-06-09T14:35:55.202200Z

> I am fairly sure helix relies a bit on the react docs This is unrelated. I understand useCallback. I didn't understand what to pass to use-callback without reading the source. Same for use-effect, which implicitly adds a fn (unlike useEffect).

Aron 2020-06-09T14:39:38.204100Z

I haven't tried, can you tell me if the answer to "what to pass to use-callback" is the same as with plain react?

dominicm 2020-06-09T14:40:35.204900Z

Not quite. There's other parameters which are valid with use-callback

Eliraz 2020-06-09T14:41:33.205400Z

just make sure you use those hooks correctly, over-using them will cause performance issues.

dominicm 2020-06-09T14:43:37.205500Z

use-callback is pretty safe afair.

dominicm 2020-06-09T14:44:06.205600Z

It's not going to consume more memory than a single callback, and re-rendering twice is relatively expensive in comparison.

Aron 2020-06-09T14:49:52.206300Z

I never worried about re-render times, paint costs way more and that is optimized by default if I use identical props to components

dominicm 2020-06-09T14:53:16.206400Z

that's what use-callback reduces too. I'm not certain, but the DOM will need updating if the callback function changes regularly.

dominicm 2020-06-09T14:53:28.206500Z

I've had it cause reagent applications to grind to a halt.

dominicm 2020-06-09T14:53:37.206600Z

Particularly with small animations.

lilactown 2020-06-09T15:00:13.206800Z

PRs welcome!

lilactown 2020-06-09T15:00:36.207300Z

honestly I regret the fancy thing I did with use-effect where it automatically wraps the body in a function

lilactown 2020-06-09T15:00:42.207500Z

it’s too clever

dominicm 2020-06-09T15:05:51.207700Z

Makes sense.

dominicm 2020-06-09T15:05:55.207800Z

helix.hooks2

☝️ 2
dominicm 2020-06-09T15:06:54.207900Z

@lilactown Cool, if I get time this afternoon will spend some time on it

lilactown 2020-06-09T15:07:34.208300Z

thanks! I bet it will help many others as well

lilactown 2020-06-09T15:08:11.208900Z

like legit tho I want to create a helix.hooks2 probably once I’m done with the defhook machinery

lilactown 2020-06-09T15:09:14.210Z

my goal for defhook is that you can add custom hooks that support for automatically filling in a deps vector and linting for unspecified deps

lilactown 2020-06-09T15:09:50.210500Z

once that’s done I can create a new hooks namespace without all the macro code in helix.hooks

dominicm 2020-06-09T15:13:38.210600Z

auto-filling the deps vector is <3, as long as you can turn it off (sometimes I want to ignore a value)

lilactown 2020-06-09T15:14:54.211100Z

yep, it would work just like it does for use-effect / use-memo / etc. today, just for custom hooks

lilactown 2020-06-09T15:15:48.212200Z

(use-custom-hook
 :auto-deps ;; auto fill
 #(foo bar))

(use-custom-hook
 [foo] ;; ignore bar
 #(foo bar))

dominicm 2020-06-09T15:17:34.212300Z

I see, very nice

alidlorenzo 2020-06-09T15:19:37.212400Z

if that cb function itself never accepts arguments seems like a good choice to just accept its body is it just bc it differs from React?

lilactown 2020-06-09T15:20:31.212600Z

yeah, it differs from react and prevents certain patterns like using higher-order functions

y.khmelevskii 2020-06-09T18:32:32.215500Z

Hi everybody. Just wanted to let you guys know that I created wrapper for emotion.js (styled component) https://github.com/khmelevskii/emotion-cljs It should be very useful to resolve problem working with css in cljs. This wrapper works good with helix.

👏 1
fabrao 2020-06-09T18:44:33.216Z

I´m using cljss.core

fabrao 2020-06-09T18:45:12.216300Z

But I´ll try to use this one

lilactown 2020-06-09T19:13:39.216800Z

nice @y.khmelevskii! this looks really similar to what we built at work but fuller featured 😄

y.khmelevskii 2020-06-09T20:03:52.217200Z

yeah, and please let me know your feedback 🙂

y.khmelevskii 2020-06-09T20:05:34.218700Z

yeah, we use it in our project and I decided that it’s not a lot of work to open source it. Happy to share it!

Aron 2020-06-09T20:26:07.219600Z

The other day I was so confident that it's easy to use render props, today I wasted more than 4 hours already on trying to use material autocomplete, and all I get is m.call is not a function. Not fun.

fabrao 2020-06-09T21:12:14.220100Z

@y.khmelevskii how do you use with cljs?

fabrao 2020-06-09T21:13:36.221Z

if I have a lib like antd , and it has its Button how do you use with this?

(defstyled Button :button
  {:display :flex
   :color :red})

fabrao 2020-06-09T21:14:30.221800Z

($ antd/Button {:className (Button)})?

y.khmelevskii 2020-06-09T21:24:27.223300Z

hey @fabrao. If antd/button is react component you can do the following:

(defstyled Button antd/Button
  {:display :flex
   :color :red})

($ Button)

fabrao 2020-06-09T21:28:57.225200Z

Oh, if I can only use Button instead of antd/Button I can call Button as MyButton , right? Thank you

lilactown 2020-06-09T21:53:59.225600Z

one thing I like about what we use at work is we add the namespace to the generated class name

lilactown 2020-06-09T21:54:03.225900Z

makes debugging styles way easier

lilactown 2020-06-09T21:55:02.226600Z

so it ends up being css-123asdf-app_some-feature_foo

lilactown 2020-06-09T21:55:43.227100Z

where evertying after css-123asdf is the namespace + var

fabrao 2020-06-09T23:32:58.228500Z

hello all, what is the minimum package.json configuration for helix?

fabrao 2020-06-09T23:34:51.228800Z

is this

{
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "start": "npx shadow-cljs watch app"
  },
  "devDependencies": {
    "shadow-cljs": "2.10.5"
  },
  "dependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-refresh": "^0.8.1",
  }
}
enougth?

lilactown 2020-06-09T23:39:39.229200Z

yep should be good