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

com.raquo.laminar.nodes.Slot.scala Maven / Gradle / Ivy

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

import com.raquo.airstream.core.AirstreamError
import com.raquo.laminar.inserters.{Hookable, Inserter, InserterHooks}
import org.scalajs.dom

/** A [[Slot]] represents a special child component of web components.
  *
  * Many web components reserve a `slot` attribute for some of their children, with a particular meaning.
  *
  * In order to have compile-time fixed slots for your elements, you can define a variable with their name, and it will
  * allow you to attach child in a simple manner.
  */
class Slot(val name: String) {

  protected val addSlotAttributeHook = new InserterHooks(
    _onWillInsertNode = { (parent, child) =>
      child.ref match {
        case el: dom.Element =>
          el.setAttribute("slot", name)
        case text: dom.Text =>
          AirstreamError.sendUnhandledError(new Exception(
            s"Error: You tried to insert a raw text node `${text.textContent}` into the `${name}` slot of <${parent.ref.tagName.toLowerCase}>.\n" +
              " - Cause: This is not possible: named slots only accept elements. Your node was inserted into the default slot instead.\n" +
              " - Suggestion: Wrap your text node into `span()`"
          ))
        case _ =>
          () // Do nothing with comment nodes
      }
    }
  )

  def apply[I <: Inserter](children: (I with Hookable[I])*): Seq[I] = {
    children.map { inserter =>
      inserter.withHooks(addSlotAttributeHook)
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy