All Downloads are FREE. Search and download functionalities are using the official Maven repository.

japgolly.scalajs.react.extra.router.ActionF.scala Maven / Gradle / Ivy

package japgolly.scalajs.react.extra.router

import japgolly.scalajs.react.util.Effect.Sync
import japgolly.scalajs.react.vdom.VdomElement

// If we don't extend Product with Serializable here, a method that returns both a Renderer[P] and a Redirect[P] will
// be type-inferred to "Product with Serializable with Action[Page, Props]" which breaks the Renderable & Actionable implicits.
sealed trait ActionF[+F[_], Page, -Props] extends Product with Serializable {
  def map[A](f: Page => A): ActionF[F, A, Props]
  def withEffect[G[_]](implicit G: Sync[G]): ActionF[G, Page, Props]
}

final case class RendererF[F[_], Page, -Props](render: RouterCtlF[F, Page] => Props => VdomElement)
                                              (implicit val sync: Sync[F]) extends ActionF[F, Page, Props] {
  override def toString = s"Renderer($render)"
  @inline def apply(ctl: RouterCtlF[F, Page]): Props => VdomElement =
    render(ctl)

  override def map[A](g: Page => A): RendererF[F, A, Props] =
    RendererF(rc => render(rc contramap g))

  override def withEffect[G[_]](implicit G: Sync[G]): RendererF[G, Page, Props] =
    G.subst[F, ({ type L[E[_]] = RendererF[E, Page, Props] })#L](this)(
      RendererF(rc => render(rc.withEffect(sync))))
}

sealed trait Redirect[Page] extends ActionF[Nothing, Page, Any] {
  override def map[A](f: Page => A): Redirect[A]
  override final def withEffect[G[_]](implicit G: Sync[G]): this.type = this
}

final case class RedirectToPage[Page](page: Page, via: SetRouteVia) extends Redirect[Page] {
  override def map[A](f: Page => A): RedirectToPage[A] =
    RedirectToPage(f(page), via)
}

final case class RedirectToPath[Page](path: Path, via: SetRouteVia) extends Redirect[Page] {
  override def map[A](f: Page => A): RedirectToPath[A] =
    RedirectToPath(path, via)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy