Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Sep 15 00:26
    scala-steward closed #481
  • Sep 15 00:26
    scala-steward commented #481
  • Sep 15 00:26
    scala-steward opened #508
  • Sep 13 16:57
    Asamsig commented #456
  • Sep 13 12:28
    dkirchhof commented #498
  • Sep 13 12:27
    dkirchhof closed #498
  • Sep 13 12:27
    dkirchhof commented #498
  • Sep 12 03:49

    shadaj on v0.6.8

    (compare)

  • Sep 11 22:16

    shadaj on act-facade

    (compare)

  • Sep 11 22:16

    shadaj on external-component-export

    (compare)

  • Sep 11 22:16

    shadaj on scala-2.13-any

    (compare)

  • Sep 11 22:16

    shadaj on intellij-standalone-plugin

    (compare)

  • Sep 11 20:57

    shadaj on master

    Release v0.6.8 (compare)

  • Sep 11 20:43
    shadaj demilestoned #495
  • Sep 11 20:43
    shadaj milestoned #495
  • Sep 11 17:54

    shadaj on master

    Remove errant println (#507) (compare)

  • Sep 11 17:54
    shadaj closed #507
  • Sep 11 16:01
    dispalt opened #507
  • Sep 10 06:40
    dkirchhof commented #498
  • Sep 10 04:35
    shadaj commented #498
peterstorm
@peterstorm:matrix.org
[m]
Or do I not need that
peterstorm
@peterstorm:matrix.org
[m]
Ah, seems I don't need it
shadaj
@shadaj:matrix.org
[m]
Over the past two weeks, I've been working on extracting the Slinky IntelliJ support as a standalone plugin, and it's now available in the JetBrains Marketplace (https://plugins.jetbrains.com/plugin/15748-slinky-library-support/versions/develop/107890)! Please test it out so we can iron out any bugs before the next release (which will push the plugin into the stable channel and make it searchable).
asaadza
@asaadza
@shadaj:matrix.org - nice job: at a quick look, big reduction in false negatives/squiggles and navigation works too. Thank you! In fact, the only difference I noticed vs the previous version I had is that IJ now requires a restart after installing the plugin, as with most plugins (probably because it is now more packaged, in a folder) .
I will also get back at some point re your comment about the type-inference wrt call back refs, thanks.
mcallisto
@mcallisto
@shadaj:matrix.org works for me, awesome!
Domantas Petrauskas
@ptrdom
I tried out how hot reloading works with example project and it seems to not preserve state for functional components between reloads. Is it not supposed to work with them or is it a bug?
Alexis Hernandez
@AlexITC
I think that's documented, and its the expected behavior
shadaj
@shadaj:matrix.org
[m]
@dope9967: yeah, as @AlexITC said Slinky doesn't have support for hot reloading functional components yet since we need to implement support for the React Refresh runtime
Domantas Petrauskas
@ptrdom
oh, I've read the docs through and through but somehow didn't notice it, all good, thanks for prompt replies!
nkgm
@nkgm
@react class Tab extends StatelessComponent {
  case class Props(title: String)
  ...
}

@react class TabList extends StatelessComponent {
  case class Props(tab1: Tab)
  ...
}

// doesn't work
TabList(TabList.Props(
  Tab(Tab.Props("tab 1"))
))
Instantiating a Tab the usual way returns an instance of KeyAndRefAddingStage[Tab], which won't typecheck for the tab1: Tab prop. I am aware this isn't the usual way of doing things, but is it possible?
vonchav
@voonchav_gitlab
Hi, wondering if there will be a new release of slinky coming out soon, with support of the new plugin as well as scalajs 1.4.x :)
shadaj
@shadaj:matrix.org
[m]
@nkgm: you won't be able to typecheck it as a Tab because it's no longer an instance of the Tab type; when using components you end up with a React type instead, represented by the ReactElement type
if you need access to the underlying Tab, however, you can use a ref! Slinky will automatically typecheck the ref to the component type
@voonchav_gitlab: likely this week :) Scala.js 1.4.x might not make it till a later release depending on how easy it is to integrate bundle splitting support
vonchav
@voonchav_gitlab
oh, bundle splitting support, sweet.
nkgm
@nkgm
Thanks @shadaj:matrix.org . Not sure how to use refs to rewrite the above scenario. Could you give me an example?
shadaj
@shadaj:matrix.org
[m]
@nkgm: take a look at https://slinky.dev/docs/refs/. Basically, you can only get access to the class instance once the component has been rendered inside some parent.
nkgm
@nkgm

Only way I can think of is this (fails with tab1__Lslinky_core_facade_ReactRef().current is null)

object tabsWithRefs {

  @react class Tab extends StatelessComponent {
    case class Props(title: String)

    def render() = props.title
  }

  @react class TabList extends StatelessComponent {
    case class Props(tab1: ReactRef[Tab])

    def render() = props.tab1.current.render()
  }
}
...

import tabsWithRefs._
val tabRef = React.createRef[Tab.Def]
Tab("tab title").withRef(tabRef)
TabList(tabRef)

BTW, for the time being I'm using KeyAndRefAddingStage[Tab]-like props for typechecking child components.

shadaj
@shadaj:matrix.org
[m]
@nkgm: you shouldn't ever need to call .render on a component, instead your def render in TabList should be implemented as just returning a Tab(...); that way, you don't even need a ref, which is usually only needed for imperative actions
I highly recommend taking a look at the tutorial on the main React website. Although it's written in JavaScript, all the APIs will translate directly over to Slinky.
nkgm
@nkgm
@shadaj: I'm merely trying to typecheck the component instances passed as props, which isn't a React idiom. The closest React idiom would be a custom children propType. For example, react-tabs will decorate each constructor with a tabsRole property and then implement a custom childrenPropType in the top component doing a deep children validation to ensure that each component was passed children of the expected type. Of course none of that applies to Scala, so I was hoping to take advantage of the Scala type system to enforce this simple requirement: whenever someone uses a TabList, make sure they are only allowed to pass it Tab ReactElements as props. I was looking for a way to do just that, and then you said use refs, so I tried making it work with refs :smiley:
However, I found that KeyAndRefAddingStage[Component] props will work just fine to that end. Would you recommend against them?
Øyvind Raddum Berg
@oyvindberg
At that point, is there even a point of instantiating Tab outside of TabList? TabList could just get whatever it needs it pass into Tab itself
In TS it's actually possible to model this by the way, because ReactElement is (optionally) typed on the component or intrinsic that produced it. This is not done pretty much anywhere else because it's a very niche thing to want to enforce. In my view, the possibility to pass anything as children is such a core part of react that it feels wrong to constrain it
shadaj
@shadaj:matrix.org
[m]
@nkgm: ahh that makes much more sense! yeah KeyAndRefAddingStage[Component] is the only way to do that right now, though I'll try to see if it would be possible to introduce a typed ReactElement
nkgm
@nkgm
@oyvindberg: Believe me I share a lot of that sentiment. My first intuition was the same as yours: it shouldn’t matter whether I pass a Tab or a FooTab as long as they’re ReactElements. Studying react-tabs, you’ll see that the Tab component wraps its children in a <li> with the necessary aria-* attributes, that would be required to provide an accessible Tab. You’ll also find it contains some “private” props, which the main container component taps into in order to control focus, classNames for selection / disabled etc, provide matching auto-generated aria-labelledby / aria-controls attributes for Tabs and their respective TabPanels and so on.
As to why not just pass the required props and let TabList create the Tabs: you may have different templating needs for each one of these Tabs, or wish to wire some of them differently. It also saves you having to pass down these props one or more levels deep for something that is not the TabList’s responsibility.
An interesting 3rd point would be: if Tab needs its <li> template and its “private" props, why not just make Tab private and instead pass arbitrary “tab content” ReactElements which are then mapped to <Tab>tab content</Tab> internally. The reason for that, as far as I can tell, is for the sake of the non-private props (disabled, tabIndex, disabledClassName, selectedClassName) and the API user’s benefit. Again, I’m guessing you could work around these by adapting them as props on the containing TabList or so, but there’s probably more things at play. Or it could very well be the creators of the library went to great lengths to provide the very best API, for which I’ll applaud them :smile:
Having separate property slots for Tabs and TabPanels is very important though, as you shouldn't just ask your API users to pass a mix bag of children only to slice and dice them inside the main component. That would be error-prone and you’d be giving up on the compiler’s ability to help your user.
@shadaj that’s rad. Btw would you be interested in rekindling slinky-styled-components? Got a local 2.13 build going but the facade is still based upon the outdated 3.4.10 version of styled-components (also I’m forced to disable hot reloading or reloads will crash the app :scream:). I can take a stab at it but chances are I’ll need to nag you sooner or later :sweat_smile:
shadaj
@shadaj:matrix.org
[m]
@nkgm: definitely! perhaps we can start by merging in your code as a 2.12/2.13 cross build? then I can look into upgrading the version of styled-components
nkgm
@nkgm
@shadaj: you have PR
shadaj
@shadaj:matrix.org
[m]
A bit delayed, but Slinky 0.6.7 has been released! The extracted IntelliJ plugin is now available in the stable channel at https://plugins.jetbrains.com/plugin/15748-slinky-library-support
Dan Di Spaltro
@dispalt
@shadaj:matrix.org neat, thank you!
vonchav
@voonchav_gitlab
congrats! glancing through the changes, I suppose support to bundle splitting isn't in this release, yea?
shadaj
@shadaj:matrix.org
[m]
@voonchav_gitlab: unfortunately no, but I am hoping to put together a simple example of bundle splitting with Slinky soon!
1 reply
Dan Di Spaltro
@dispalt
oh great, are you going to bypass scalajs-bundler?
@shadaj:matrix.org ^
shadaj
@shadaj:matrix.org
[m]
@dispalt: yeah most likely, since it will be some time until scalajs-bundler gets support
mn98
@mn98
@shadaj thanks for 0.6.7 and the new plugin! Slinky really is a fabulous piece of kit!
Dan Di Spaltro
@dispalt
@shadaj:matrix.org i've been noodling on attempting it, but haven't worked up the courage
Eric K Richardson
@ekrich
Maybe it wouldn't be too bad :wink:
mn98
@mn98
Hi all, I'm using @react functional components with hooks and I'm trying to figure out how to define a ref (via useRef) to the child component from within the parent component. My motivation here is to then access state on the child component via childRef.current.... The child defines its state with the useState hook. Any help greatly appreciated! Thanks.
mn98
@mn98
I'm now trying to achieve the above with forwardRef to expose an imperative API to access the internal state of the child, but I'm not sure it's the right approach...
mn98
@mn98

I still haven't figured this out. In my 'parent' functional component I have something like:

val thingPicker = useRef[FunctionalComponent[ThingPicker.Props]](null) // doesn't compile because of the 'null'
...
def usePickedThing = { val thing = thingPicker.current.pickedThing; ... }
...
div(ref := thingPicker)(ThingPicker(...))

If I'm missing something really obvious here regarding how to access a child's state from the parent using functional components, I would be very grateful for some pointers!

mn98
@mn98

When I attempt the forwardRef approach to access the internal state it is always null in the imperative handler when child's state is changed.
Within the child, a ThingPicker:

      useImperativeHandle(ref, () => {
        new PickedThing {
          override def pickedThing: Thing = thing // <-- this always throws saying thing is null
        }
      })

Within the parent:

div(ThingPicker().withRef(r => setLocalState(r.pickedThing)))

It's probably right that the imperative code throws given state is updated asynchronously, but I still need educating on this.

Øyvind Raddum Berg
@oyvindberg
Consider ref your last option, possibly before Context. Try to give the child component an onPicked callback prop
mn98
@mn98
I’ll look into that, thanks very much!
zetashift
@zetashift
I created a basic slinky project using create-react-scala.g8 and am getting the following error: https://dpaste.com/5XKC6NGPV do I have something set up incorrectly?
mn98
@mn98
@oyvindberg thanks again for the tip, a callback prop worked well. In my case the callback sets some state on the parent.
My whole Ref approach stemmed from the Refs on Slinky Components example. I thought there might be an equivalent approach for functional components.
mn98
@mn98
I wanted to avoid duplicating the child's state within the parent.
nafg
@nafg
@shadaj:matrix.org suggestion, fork scalajs-bundler and delete all the parts not related to generating package.json (i.e. keeping just npmDependencies functionality) and publish that as its own plugin. Later scalajs-bundler could be refactored to use it if they want, or they could move the npm-dependencies plugin back in but publish it as a standalone artifact.
Then you can build a plugin that's focused on bundling, perhaps via snowpack, that will be easy to switch to/from scalajs-bundler