Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • May 24 20:12
    scala-steward opened #571
  • May 24 16:42
    evbo commented #330
  • May 19 13:48
    evbo commented #196
  • May 13 10:51
    scala-steward closed #542
  • May 13 10:51
    scala-steward commented #542
  • May 13 10:51
    scala-steward opened #570
  • May 11 00:19
    evelant opened #569
  • May 10 13:53
    evbo commented #196
  • Apr 30 22:02
    shadaj demilestoned #240
  • Apr 30 22:00
    shadaj milestoned #537
  • Apr 30 22:00
    shadaj labeled #537
  • Apr 30 22:00
    shadaj commented #537
  • Apr 30 21:58
    shadaj commented #566
  • Apr 30 21:58
    shadaj milestoned #566
  • Apr 30 21:58
    shadaj labeled #566
  • Apr 30 21:57
    shadaj commented #566
  • Apr 30 21:56
    shadaj demilestoned #568
  • Apr 30 21:56
    shadaj milestoned #568
  • Apr 30 21:55
    shadaj milestoned #568
  • Apr 30 21:55
    shadaj labeled #568
shadaj
@shadaj:matrix.org
[m]
@steinybot: is your app built in Scala.js dev mode? source maps should load and the name of the component should have been updated to the name of the containing object
Jason Pickens
@steinybot
I think it is built in dev mode (I’ll double check). In previous projects I’ve had a lot of problems getting source maps and stack traces to work properly (in so far that I had to customise the webpack plugin and write a custom error mapper).
What would show the name in this case? Is it Slinky that would replace the eval with the component? Source maps by themselves would only map FunctionalComponent.js to FunctionalComponent.scala right?
jmaamo
@jmaamo
Any idea how to implement "tr:nth-child(even) {background: #CCC}
tr:nth-child(odd) {background: #FFF}" in slinky?
peterstorm
@peterstorm:matrix.org
[m]
What’s the pattern in Scala 3 without the react annotation for functional components?
Alexis Hernandez
@AlexITC
I just migrated one library to Scala 3 and I'm migrating some apps, the simplest way is to do by hand what @react does (example), this way, you don't need to change the way you create components
peterstorm
@peterstorm:matrix.org
[m]
AlexITC (Alexis Hernandez): Exactly what I was looking for, thanks!
Dan Di Spaltro
@dispalt
@shadaj:matrix.org to fix that stack trace issue @steinybot is talking about, we ended up going with this solution https://gist.github.com/dispalt/741121b9e90fc0969bcd5a2292a348f0 basically the inlining makes the stack trace point to the callsite
peterstorm
@peterstorm:matrix.org
[m]
Anyone got an example of styled-components and slinky for Scala3?
peterstorm
@peterstorm:matrix.org
[m]
Also, if anyone has an example of using cats effect with Slinky it would be immensely helpful!
Alexis Hernandez
@AlexITC
I think that's very unlikely to work decently as the approaches are somewhat incompatible, you can get better luck with https://github.com/raquo/laminar (which isn't react)
shadaj
@shadaj:matrix.org
[m]
peterstorm: shouldn't be too tricky to cross-build the existing facade to Scala 3, since we don't use too many advanced features. Will look into it!
Also for Cats Effect, you'd probably need to set up some React hooks so that events can be propagated between the two systems. I'm not super familiar with using Cats Effect however, so not super sure what would be involved in detail.
peterstorm
@peterstorm:matrix.org
[m]
Awesome, thank you!
peterstorm
@peterstorm:matrix.org
[m]
shadaj: Yeah, I’m not entirely sure on how to do that interop either. I see Scala React has some interop done. I might check out how that’s is done, and see if I can port it.
evbo
@evbo

Hi, what unit testing frameworks are people using with slinky react components?

Waiting for scalajs to transpile slows down testing. I've done some pretty extreme things, like deembedding parts of my code into cross compiled scala/scalajs projects, where pure scala unit tests execute lightening fast, but this has limitations. Anyone figure out super fast way to unit test?

shadaj
@shadaj:matrix.org
[m]
In private Slinky projects, I've just used ScalaTest for the core UI, and try to move as much code as possible into shared folders (as you described) so that more tests can run on the JVM.
2 replies
evbo
@evbo
Yeah me too, where this gets tricky though is when you need to unit test a component. What I've done is store ReactComponents as JVM Objects and then the if/else for/each and other logic structures live in JVM code that just returns the end result list of components to display. But this is the only work around I've found but it's pretty clunky
evbo
@evbo
also, I noticed my slinky code is failing CSP since my policy does not allow unsafe-inline. I have lots of react buttons that have onClick handlers as well as inline style. Are these both no-nos for CSP? What are easy work arounds? I like inline onClick and styles, is there are a way to get the best of both worlds?
shadaj
@shadaj:matrix.org
[m]
Hmm, when you set onClick handlers through React you should be fine CSP wise. But you won't be able to create inline style tags so you will have to just set style properties locally perhaps?
2 replies
evbo
@evbo
Thanks!

I'm wondering if anyone in the slinky community does any code-splitting? I've been generating some bigger bundle sizes and was just reading about React.lazy, but unfortuntely did that not get implemented in Slinky?:
shadaj/slinky#196

Are there other workarounds people use to code-split and lazy load their app progressively? This was a good read for anyone not familiar:
https://www.freecodecamp.org/news/how-to-use-react-lazy-and-suspense-for-components-lazy-loading-8d420ecac58/

shadaj
@shadaj:matrix.org
[m]
Ah yeah we should get React.lazy in now, shouldn't be too much work. On bundle splitting that's something on my backlog (I want to set up a new template that has split modules by default), but haven't put it together just yet.
evbo
@evbo
awesome! I'm looking forward to it thanks
evbo
@evbo
also, how does one know which version of React the latest slinky is compatible with. Is it safe to always assume the latest React will always work?
shadaj
@shadaj:matrix.org
[m]
yeah, React makes breaking changes very infrequently, and Slinky doesn't use any private APIs so generally the latest React will just work
shadaj
@shadaj:matrix.org
[m]

that's very cool! I think probably that would make sense as a separate project that just provides binary-compatible implementations of the Slinky APIs that run on the JVM

I think in general, having Slinky itself provide JVM implementations is going to be tricky because ensuring correct behavior would require basically reimplementing React, and in addition there would be no good way to test components that call out to external JS libraries

evbo
@evbo

yeah that's what I'm thinking too. I separate project that provides fixtures for calling hooks in the right order, which itself gets (slowly) tested using React Testing Library. Since React versions don't change often, you'd seldom have to maintain these fixtures and once they are working reliably well you use them to test hooks from the JVM in your project, which runs lightening fast.

Basically it would be a state machine that would register each function you pass it as triggering certain behavior, which in turn would decide which hooks to call (such as useEffect, etc.)

I already have a version of this working, but I didn't add React Testing Library unit tests for it yet. That part is an expense that only becomes worth it once I'm testing very nuanced behaviors

More light weight question:

What's the defacto way to display an svg from a JSImport? Do I need to use @react to turn it into a ReactElement? Or is there a shorter syntax?

evbo
@evbo

are for comprehensions not supported in slinky syntax?

(
  for { 
    current <- votes
     a <- current.votes
  } yield a.sum
).getOrElse(0)

yields:

type mismatch;
[error] found : Any
[error] required: slinky.core.facade.ReactElement
[error] ).getOrElse(0)

But if I put that same expression in a val ("a"), this works:

div( a )

evbo
@evbo

I guess this is the first time I tried passing an Int as a ReactElement. This issue goes away if I convert everything to a String

What's odd is if I type div( 4 ) it still compiles. So it seems slinky can take an Int as a ReactElement but not if using a for comprehension.

evbo
@evbo

oh, and I should add: one really bizarre side effect is that if you accidentally render an Int, any value < 0 actually gets rendered as 0! So only positive values are rendered!

Would be awesome if there was type safety catching this in Slinky at compile time. Is that possible?

shadaj
@shadaj:matrix.org
[m]
For comprehensions typically yield a sequence, so Slinky will interpret the result as just something to convert into an array before sending to React.
For ints, yeah we have an implicit conversion for auto-converting ints to react elements. It's weird that React isn't properly rendering negative values. That's not something we can check at compile-time in Scala easily, but will see if perhaps our typing assumptions are wrong somewhere.
evbo
@evbo
ok, I didn't give you a very good example to repro with, let me get back to you on that with the negative bug

Is there any way to move the Props definition into JVM? It's just a case class, but if I try:

type Props = someJVMImport.JVMProps

It works but requires I pass a case class to the component rather than having the prop args automatically tupled. Is there a trick to getting that tupled at compile-time for me: comp(like, this) instead of: comp(JVMProps(like, this))

shadaj
@shadaj:matrix.org
[m]
@evbo: due to restrictions in the macro annotation, Slinky can only give you a nice apply if the Props type is declared directly as a case class
so unfortunately if you need to use a type alias for Props you'll have to use a regular apply function
evbo
@evbo

Maybe this is an anti pattern, but I made a useCallback whereby the underlying callback takes a setState function as an argument.

Is it expected that when I call setState(true)it will re-render over and over again (even though the boolean never changes)? In other words, is React's equality checks no longer in place due to passing it as an arg to the callback rather than a dependency? Or is this not expected behavior of slinky?

Łukasz Biały
@lbialy
hi, I have been trying to set up primereact with slinky and there's a react >= 17.0 requirement, I'm wondering whether that's supported (from what I can see in slinky's ReactDOM React 18 is not yet there), I have encountered some issues with primereact components not being able to find React in the webpack bundle and I was wondering whether it's an artifact of a misconfigured webpack build or maybe a version mismatch somehow
slinky seems to work with react 18 just fine, the only issue is that you get this warning in the console: react-dom.development.js:86 Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot

on primereact front I get:

ReferenceError: React is not defined
    at Object../node_modules/primereact/button/button.js

which is quite surprising given that if I drop primereact and use a slinky.web.html.button instead it works just fine

Łukasz Biały
@lbialy
ah, fixed with:
    resolve: {
        extensions: [".cjs.js", ".js", ".css"],
    }
evbo
@evbo

@shadaj:matrix.org this one definitely feels like a bug, I'm just not sure if it's Slinky or not. What do you think, should I toss it in github issue?

tiptap is a text editor that uses proseMirror under the covers. You'r supposed to be able to pass useState setters to it's onUpdate function, but in doing so it seems the setter falls out of scope:

function $s_Lcom_tiptap_RichTextEditor$$anon$1__onUpdate__Lcom_tiptap_RichTextEditor$$anon$1__Lcom_tiptap_TipTapShim$EditorUpdate__V(this$1, update) {
    var this$ = this$1[$m_sjsr_PrivateFieldsSymbolHolder$().sjsr_PrivateFieldsSymbolHolder$__f_privateFieldsSymbol].setText$1;
    var newState = new $c_s_Some($as_T(update.editor.getHTML()));
    this$(newState)
}

fails with:

TypeError: undefined is not an object (evaluating 'this$1[$m_sjsr_PrivateFieldsSymbolHolder$().sjsr_PrivateFieldsSymbolHolder$__f_privateFieldsSymbol].setText$1')

However, I found a (disgusting) workaround by creating an intermediary object:

object propsShim {
  var fakeTheScope: Option[String] => Unit = _ => println("not set")
}

Then, inside my component, I give that object my setText:

propsShim.fakeTheScope = props.setText

    val editor: Option[Editor] = useEditor(new EditorOptions{
      val extensions = js.Array()
      val content = ""
      override def onUpdate(update: EditorUpdate): Unit = {
        // TODO: this should be just a call to props.setText
        fakeTheScope(Some(update.editor.getHTML()))
      }
    })

Here is how it should "just work" in a pure js version:
https://stackoverflow.com/questions/68822574/how-can-i-grab-the-text-value-from-content-in-tiptap-react-typescript-wysiwyg

shadaj
@shadaj:matrix.org
[m]
hmm this is very interesting, looks like the closure is not being computed correctly; this generally seems out of Slinky's scope since we don't do anything special with the useState setters, maybe it is a Scala.js bug?
also for your question before, I believe that React may re-render even when there are no actual state changes when in dev mode, but production mode shouldn't do that
evbo
@evbo
Thanks a ton for confirming! I'll get this in a sandbox repro for them