Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jul 20 05:39

    shadaj on master

    Add 'textarea' to the list of c… (compare)

  • Jul 20 05:39
    shadaj closed #492
  • Jul 19 17:40
    godenji commented #461
  • Jul 17 11:24
    mn98 opened #492
  • Jul 15 09:27
    myyk edited #491
  • Jul 15 09:27
    myyk opened #491
  • Jul 12 12:03
    scala-steward opened #490
  • Jul 12 00:38
    scala-steward synchronize #463
  • Jul 11 23:05

    shadaj on master

    Update sbt-scalafmt to 2.4.3 (#… (compare)

  • Jul 11 23:05
    shadaj closed #488
  • Jul 11 23:05

    shadaj on master

    Update resources.md (#487) (compare)

  • Jul 11 23:05
    shadaj closed #487
  • Jul 11 15:03
    nizhegorodets opened #489
  • Jul 09 01:52
    scala-steward opened #488
  • Jul 07 18:19
    AlexITC opened #487
  • Jul 05 04:28
    scala-steward opened #486
  • Jul 05 03:09

    shadaj on master

    Update sbt to 1.5.4 (#485) (compare)

  • Jul 05 03:09
    shadaj closed #485
  • Jul 05 03:09

    shadaj on master

    Update sbt-pgp to 2.0.2 (#451) … (compare)

  • Jul 05 03:09
    shadaj closed #451
shadaj
@shadaj:matrix.org
[m]
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
IOW if "generating package.json from transitive metadata defined in sbt" were standalone then there can be competing plugins focused on bundling alone, that all depend on the npm-dependencies sbt plugin
onanpetrovich
@onanpetrovich
Please. How to connect akka-http with the slinky.
On current moment index.html from slinky placed to server/resources.
Inside connect script /client..../...-fastopt. js and loader/js. Not worked
1 reply
Dan Di Spaltro
@dispalt
@nafg oh man I've thought about this like 15 different ways
shadaj
@shadaj:matrix.org
[m]
@nafg: hmm, yeah that's definitely an interesting idea; I also remember there was work on a reverse mode idea where you could compile Scala.js code through a Webpack plugin
@onanpetrovich: you'll probably get a better answer in Akka HTTP rooms, since there aren't many special things that you have to do with Slinky apps as long as you can grab the bundled JS file
nafg
@nafg
@shadaj:matrix.org the problem is that doesn't help for other bundlers
peterstorm
@peterstorm:matrix.org
[m]
Does anyone have an example of ssr with slinky, where the route is dynamic? Like opening a blogpost by slug for example?
shadaj
@shadaj:matrix.org
[m]
peterstorm: the Slinky docs (although prerendered) do dynamically use the path when determining how to SSR each page (https://github.com/shadaj/slinky/blob/master/docs/src/main/scala/slinky/docs/Main.scala#L94)
peterstorm
@peterstorm:matrix.org
[m]
Ah, I didn't look close enough it seems, thank you! I'll try and figure it out :D
Yuriy Yarosh
@yuriy-yarosh

Having trouble with scala.js deps management... quite confused
scala.js mention

I'm getting value can only be used within a task or setting macro with every %%% both in build.sbt and Dependencies.scala

I'm not quite sure how to initialize a libraryDep setting via lazy val in here

lazy val web: immutable.Seq[ModuleID] = "me.shadaj" %%% "slinky-core" % SlinkyVersion ::                                                    ^
build.sbt:33: error: `value` can only be used within a task or setting macro, such as :=, +=, ++=, Def.task, or Def.setting.
  "me.shadaj" %%% "slinky-web" % SlinkyVersion ::

I've imported %%% via import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._

Yuriy Yarosh
@yuriy-yarosh
mvillafuertem
@mvillafuertem
Hi all, any example importing an image? using react-native.