helix

https://github.com/Lokeh/helix
Aron 2020-04-14T06:51:57.130Z

Hi, is there an easy to follow example on how to integrate helix components with devcards so that I can use :history true I feel this should be easy, but there are so many new things everywhere, I find it hard to orient myself in what is relevant and what is not, spending hours googling without results

Aron 2020-04-14T08:13:21.130900Z

I asked this on beginners, but I don't know if it isn't just something specific to helix: https://clojurians.slack.com/archives/C053AK3F9/p1586851549325700

Aron 2020-04-14T09:27:37.131800Z

So yeah, I don't see how I could pass state hooks from outside when they can't be created, just on the inside. So history with use-state is probably never going to work

lilactown 2020-04-14T15:47:34.132600Z

hey @ashnur. helix is doing some magic that prevents you from passing in a dynamic map as the first argument

lilactown 2020-04-14T15:51:56.136300Z

the reason is that a React element needs to be created in a way that differentiates between props and children. A React element is basically an object like:

#js {:type AssetSelectControl
     :props #js {}
     :children #js [,,,]}
when you create an element with $, it has a couple rules: • if the first argument is a literal map ($ AssetSelectControl {}) it will convert the map to a JS object and put it in the :props key • if the first argument is not a literal map ($ AssetSelectControl foo bar), it will add it to the :children key it does this logic at compile time, to avoid doing a bunch of runtime checks to see if the first argument is a map or not (and slowing down your code, if you’re creating a lot of elements over and over again)

lilactown 2020-04-14T15:52:51.137200Z

if you want to pass in a dynamically created map (like your @state value) you can use a special keyword or symbol, & to merge them in

lilactown 2020-04-14T15:53:13.137600Z

all of this and the & keyword/symbol are explained in the docs: https://github.com/Lokeh/helix/blob/master/docs/creating-elements.md#dynamic-props

Aron 2020-04-14T15:55:19.138300Z

@lilactown Hi, I figured the {:& @state} trick to solve my props problem

Aron 2020-04-14T15:55:58.139200Z

right now I am trying to somehow use devcards and helix together, but I am not sure how. I think with use-state it's not even possible

Aron 2020-04-14T15:56:06.139500Z

But maybe with use-reducer?

Aron 2020-04-14T15:56:11.139700Z

and a context hook

lilactown 2020-04-14T15:59:04.139900Z

helix and devcards are 💯 compatible

lilactown 2020-04-14T15:59:13.140200Z

helix uses devcards for test cases and examples

lilactown 2020-04-14T16:00:18.140900Z

the trick is that you cannot use hooks inside the devcard

lilactown 2020-04-14T16:00:33.141400Z

you need to use hooks inside of a component, and then pass an element to the devcard

Aron 2020-04-14T17:22:42.143500Z

@lilactown I am not sure we talk about the same thing. I would like to be able to use :inspect-data true and :history true with functional components that get the return value of a useState() call passed to them through props.

Aron 2020-04-14T17:23:06.144Z

This would allow me to feed whatever data to the component while not maintaining the state myself

lilactown 2020-04-14T17:23:31.144400Z

can you give me some example code?

lilactown 2020-04-14T17:24:01.145Z

“the return value of useState ” is just a tuple [state set-state]. there’s nothing special about it

lilactown 2020-04-14T17:25:28.146900Z

your component should be designed in a way that it doesn’t depend on the exact shape. instead, you should have a prop that takes a value and a prop that takes a callback that updates the state

lilactown 2020-04-14T17:28:02.147700Z

e.g. take the input component:

(helix.dom/input
 {:value state
  :on-change #(set-state (.. % -target -value))})

Aron 2020-04-14T17:43:09.149500Z

This of course works, I found it. I've been playing with helix for days now, I got almost everything working. I can't define a defcard to use a component and pass the state to it because React doesn't allow hook calls outside of it

Aron 2020-04-14T17:45:51.150Z

something similar to the state-reset example here http://rigsomelight.com/devcards/#!/devdemos.custom_cards

lilactown 2020-04-14T17:54:39.150400Z

you can totally do this. you must not pass in the state atom directly

lilactown 2020-04-14T17:56:50.152Z

(defcard state-over-time-view
  (fn [state _]
    ($ your-component
       {:value @state
        :on-change #(swap! state ,,,)}))
  {:x 0})

lilactown 2020-04-14T17:57:44.152700Z

devcards listens to changes to state and will call the (fn [state _] ,,,) again anytime it changes

lilactown 2020-04-14T17:59:34.153600Z

it doesn’t call use-state but that’s OK, because a parent component calling use-state and passing the value/setter into your-component would behave the exact same as it does here

Aron 2020-04-14T19:18:33.155700Z

totally works as you said. It shows how clueless I am : (. Thanks @lilactown, I owe you big time.

Aron 2020-04-14T19:19:26.156800Z

been trying to do this for almost two days now, although in the beginning I didn't even know how to pass props, I tried ($ ComponentName @state) and was wondering why it didn't work

Aron 2020-04-14T19:20:25.157700Z

then some kind people in the beginners explaind the whole thing with macros, and literals and reader form and then I foun dynamics props, but I was still trying to somehow wrap devcards in react...

lilactown 2020-04-14T19:25:17.158500Z

helix isn’t the most beginner friendly yet. the best advice I can give is to read the documentation carefully, and let me know if there’s anything that is confusing. I’ll try and improve it as I get more feedback!

lilactown 2020-04-14T19:25:42.159Z

I’ve mostly written helix for myself and a group of people who are fairly familiar with ClojureScript already, so I’m sure there’s things that I have missed or not explained well

lilactown 2020-04-14T19:25:56.159300Z

that is to say, I’m sure it’s not just you 😄

Aron 2020-04-14T19:35:16.159700Z

so, the situation is that, I am a beginner in clojure for the 8th year now

Aron 2020-04-14T19:35:27.160Z

I used datascript in javascript in 2015

Aron 2020-04-14T19:35:55.160600Z

I know React because I regularly read the source code : )

Aron 2020-04-14T19:36:35.161400Z

It's just that until now I was unable to set up the dev env, and the only reason I was able to get something going right now was because of this package https://github.com/filipesilva/create-cljs-app

Aron 2020-04-14T19:37:51.162800Z

I really like the architecture of om-next, but it's a bit heavy. I wanted something that uses hooks well, and helix was one of the first things I found and when I read the thing about hiccup I knew I will like it. I was just very lost about how to use devcards.

Aron 2020-04-14T19:45:46.165Z

now the question is, if I start adding specs to this codebase, can I run frontend tests inside devcards? Because I saw it here that maybe that's not the case. https://github.com/bhauman/devcards/issues/157#issuecomment-468375929 Or what is my best option to runt spec based tests? Just follow official docs?

lilactown 2020-04-14T20:03:26.165300Z

hmm I’m not sure

lilactown 2020-04-14T20:03:37.165600Z

currently, helix components are not spec-able

lilactown 2020-04-14T20:04:04.165900Z

i.e. you cannot fdef a component

lilactown 2020-04-14T20:04:15.166200Z

I have a task in my backlog to explore how to properly spec a component

Aron 2020-04-14T20:11:52.170900Z

I know how to do it in javascript land with json schema, you need 3 different schemas, • app/local schema that describes state that is important for the component to write (not probably read also, but the write is the key, every state has only one writer/owner, right?) • UI schema that describes what needs to be displayed and how it can be displayed, this can be just an image or a full form validation, but it's not about application state, it's just about what the U in the UI does, so the writer is the "user" in a way, derived data might be part of the previous category • remote state, for each different endpoint you want to write state you can describe the shape it expects That's all. I actually prefer react components to not control any state just dispatch actions, but the above works with local state too. And I claim that's a complete analysis, there is no fourth category and these categories do not overlap.

Aron 2020-04-14T20:12:50.171700Z

But right now I would be fine to just have some pure functions specced and tested, the components if they are not fully tested is ok.