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

com.raquo.laminar.receivers.ChildTextReceiver.scala Maven / Gradle / Ivy

The newest version!
package com.raquo.laminar.receivers

import com.raquo.airstream.core.{Observable, Source}
import com.raquo.laminar.inserters.{ChildInserter, ChildTextInserter, DynamicInserter}
import com.raquo.laminar.modifiers.{RenderableNode, RenderableText}
import com.raquo.laminar.nodes.TextNode

import scala.scalajs.js

object ChildTextReceiver {

  /** Usage example: text("hello") <-- signalOfBoolean */
  def apply(text: String): LockedChildTextReceiver = {
    new LockedChildTextReceiver(text)
  }

  /** Usage example: text(textLikeThing) <-- signalOfBoolean */
  def apply[TextLike](text: TextLike)(implicit renderable: RenderableText[TextLike]): LockedChildTextReceiver = {
    // #TODO[Perf] is there a better way to handle RenderableText.textNodeRenderable?
    //  (see comment about it in the `<--` method)
    new LockedChildTextReceiver(renderable.asString(text))
  }

  def <--(textSource: Source[String]): DynamicInserter = {
    ChildTextInserter(textSource.toObservable, RenderableText.stringRenderable)
  }

  def <--[TextLike](textSource: Source[TextLike])(implicit renderable: RenderableText[TextLike]): DynamicInserter = {
    if (renderable == RenderableText.textNodeRenderable) {
      // #Note: Special case: since we already have TextNode-s, using them in ChildTextInserter would be
      //  inefficient, so we redirect this case to ChildInserter (child <-- textSource) instead.
      // #TODO[Perf] Test performance vs regular child.text, see if we need to improve this.
      // This .asInstanceOf is safe because `textNodeRenderable` only applies if `TextLike` is `TextNode`.
      val nodes = textSource.toObservable.asInstanceOf[Observable[TextNode]]
      ChildInserter(nodes, RenderableNode.nodeRenderable, initialHooks = js.undefined)
    } else {
      ChildTextInserter(textSource.toObservable, renderable)
    }
  }

  // #TODO[Scala] For some reason I am unable to put the above <-- method inside RichTextReceiver
  //  - Scala 2 compiler explodes with "Error while emitting ChildrenReceiverSpec.scala"
  //  - Scala 3 stops compiling some basic usage patterns of `child.text <--`

  // implicit class RichTextReceiver(val self: ChildTextReceiver.type) extends AnyVal {
  //
  //   def <--(textSource: Source[TextNode]): Inserter = {
  //     ChildTextInserter(textSource.toObservable, RenderableText.textNodeRenderable)
  //   }
  //
  //   def <--[TextLike](textSource: Source[TextLike])(implicit renderable: RenderableText[TextLike]): Inserter = {
  //     if (renderable == RenderableText.textNodeRenderable) {
  //       // Special case: since we already have TextNode-s, using them in ChildTextInserter would be
  //       // inefficient, so we redirect this case to ChildInserter (child <-- textSource) instead.
  //       // #TODO[Perf] Test performance vs regular child.text, see if we need to improve this.
  //       // #Note: this .asInstanceOf is safe because `RenderableText.textNodeRenderable`
  //       //  will only apply is `TextLike` type is `TextNode`.
  //       val nodes = textSource.toObservable.asInstanceOf[Observable[TextNode]]
  //       ChildInserter(nodes, RenderableNode.nodeRenderable)
  //     } else {
  //       ChildTextInserter(textSource.toObservable, renderable)
  //     }
  //   }
  // }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy