Skip to content

Commit

Permalink
API: Stop using $ in variable names, and update docs and examples. F…
Browse files Browse the repository at this point in the history
…ixes #127
  • Loading branch information
raquo committed Jan 4, 2023
1 parent 9ebcfc4 commit ff98ade
Show file tree
Hide file tree
Showing 45 changed files with 201 additions and 200 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Laminar

[![Build Status](https://circleci.com/gh/raquo/Laminar.svg?style=svg)](https://circleci.com/gh/raquo/Laminar)
[![Join the chat at https://gitter.im/Laminar_/Lobby](https://badges.gitter.im/Laminar_/Lobby.svg)](https://gitter.im/Laminar_/Lobby)
[![Chat on https://discord.gg/JTrUxhq7sj](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/JTrUxhq7sj)
![Maven Central](https://img.shields.io/maven-central/v/com.raquo/laminar_sjs1_3.svg)

Laminar is a small library that lets you build web application interfaces, keeping UI state in sync with the underlying application state. Its simple yet expressive patterns build on a rock solid foundation of [Airstream](https://github.com/raquo/Airstream) observables and the [Scala.js](https://www.scala-js.org/) platform.

Laminar is also a friendly community of passionate people from across the world who help each other learn new skills and achieve their goals. Check out all the learning materials we've put out, and chat us up on gitter if you hit a snag!

"com.raquo" %%% "laminar" % "0.14.2" // Requires Scala.js >= 1.7.1
"com.raquo" %%% "laminar" % "<version>" // Requires Scala.js 1.9.0

Look up the latest version of Laminar [here](https://laminar.dev/blog/), or in git tags above ("v" prefix is _not_ part of the version number).



Expand Down Expand Up @@ -46,3 +48,4 @@ Nikita Gazarov – [@raquo](https://twitter.com/raquo)

Laminar is provided under the [MIT license](https://github.com/raquo/laminar/blob/master/LICENSE.md).

Comments in the `defs` directory pertaining to individual DOM element tags, attributes, properties and event properties, as well as CSS properties and their special values / keywords, are taken or derived from content created by Mozilla Contributors and are licensed under Creative Commons Attribution-ShareAlike license (CC-BY-SA), v2.5.
2 changes: 1 addition & 1 deletion project/DomDefsGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object DomDefsGenerator {
def cachedGenerate(): Unit = {
cache.triggerIfCacheKeyUpdated(
metaProject.BuildInfo.scalaDomTypesVersion,
forceOnEverySnapshot = true
forceOnEverySnapshot = false
)(_ => generate())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ValueController[A, B](
}

// Force-override the `defaultValue` prop.
// If updater.$value is Signal, its initial value will in turn override this,
// If updater.values is Signal, its initial value will in turn override this,
// but if it's a stream, this will remain the effective initial value.
setValue(initialValue, force = true) // this also sets prevValue

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/com/raquo/laminar/keys/AriaAttr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ class AriaAttr[V](
optionToSetter(value.map(v => this := v))
}

def <--($value: Source[V]): AriaAttrUpdater[V] = {
def <--(values: Source[V]): AriaAttrUpdater[V] = {
new KeyUpdater[Element, AriaAttr[V], V](
this,
$value.toObservable,
values.toObservable,
(el, v, _) => DomApi.setAriaAttribute(el, this, v)
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/com/raquo/laminar/keys/CompositeKey.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ class CompositeKey[K <: Key, -El <: ReactiveElement.Base](
new LockedCompositeKey(this, items.toList)
}

def <--[V]($items: Source[V])(implicit valueMapper: CompositeValueMapper[V]): KeyUpdater[El, this.type, V] = {
def <--[V](items: Source[V])(implicit valueMapper: CompositeValueMapper[V]): KeyUpdater[El, this.type, V] = {
new KeyUpdater[El, this.type, V](
key = this,
values = $items.toObservable,
values = items.toObservable,
update = (element, nextRawItems, thisBinder) => {
val currentNormalizedItems = element.compositeValueItems(this, reason = thisBinder)
val nextNormalizedItems = valueMapper.toNormalizedList(nextRawItems, separator)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/com/raquo/laminar/keys/DerivedStyleProp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ class DerivedStyleProp[InputV](
optionToSetter(value.map(v => this := v))
}

def <--($value: Source[InputV]): DerivedStyleUpdater[InputV] = {
def <--(values: Source[InputV]): DerivedStyleUpdater[InputV] = {
new KeyUpdater[ReactiveHtmlElement.Base, StyleProp[_], InputV](
key,
$value.toObservable,
values.toObservable,
(el, v, _) => DomApi.setHtmlStringStyle(el, key, encode(v))
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/com/raquo/laminar/keys/HtmlAttr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ class HtmlAttr[V](
new KeySetter[HtmlAttr[V], V, HtmlElement](this, value, DomApi.setHtmlAttribute)
}

def <--($value: Source[V]): HtmlAttrUpdater[V] = {
def <--(values: Source[V]): HtmlAttrUpdater[V] = {
new KeyUpdater[HtmlElement, HtmlAttr[V], V](
this,
$value.toObservable,
values.toObservable,
(el, v, _) => DomApi.setHtmlAttribute(el, this, v)
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/com/raquo/laminar/keys/HtmlProp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class HtmlProp[V, DomV](
optionToSetter(value.map(v => this := v))
}

def <--($value: Source[V]): PropUpdater[V, DomV] = {
def <--(values: Source[V]): PropUpdater[V, DomV] = {
val update = if (name == "value") {
(element: HtmlElement, nextValue: V, reason: Modifier.Any) =>
// Checking against current DOM value prevents cursor position reset in Safari
Expand All @@ -48,7 +48,7 @@ class HtmlProp[V, DomV](
}
new KeyUpdater[HtmlElement, HtmlProp[V, DomV], V](
this,
$value.toObservable,
values.toObservable,
update
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class LockedCompositeKey[K <: Key, -El <: ReactiveElement.Base](
key.:=(items: _*)
}

/** If \$include emits true, value(s) will be added, if false, they will be removed. */
def <--($include: Source[Boolean]): KeyUpdater[El, CompositeKey[K, El], List[String]] = {
key <-- $include.toObservable.map(include => if (include) items else Nil)
/** If the `include` observable emits true, value(s) will be added, if false, they will be removed. */
def <--(include: Source[Boolean]): KeyUpdater[El, CompositeKey[K, El], List[String]] = {
key <-- include.toObservable.map(include => if (include) items else Nil)
}
}
4 changes: 2 additions & 2 deletions src/main/scala/com/raquo/laminar/keys/StyleProp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ class StyleProp[V](
optionToSetter(value.map(v => this := v))
}

def <--[A]($value: Source[A])(implicit ev: A => V | String): StyleUpdater[V] = {
def <--[A](values: Source[A])(implicit ev: A => V | String): StyleUpdater[V] = {
new KeyUpdater[ReactiveHtmlElement.Base, StyleProp[V], V | String](
this,
$value.asInstanceOf[Source[V | String]].toObservable,
values.asInstanceOf[Source[V | String]].toObservable,
(el, v, _) => DomApi.setHtmlAnyStyle(el, this, v)
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/com/raquo/laminar/keys/SvgAttr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ class SvgAttr[V](
optionToSetter(value.map(v => this := v))
}

def <--($value: Source[V]): SvgAttrUpdater[V] = {
def <--(values: Source[V]): SvgAttrUpdater[V] = {
new KeyUpdater[SvgElement, SvgAttr[V], V](
this,
$value.toObservable,
values.toObservable,
(el, v, _) => DomApi.setSvgAttribute(el, this, v)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import scala.scalajs.js
object ChildInserter {

def apply[El <: ReactiveElement.Base] (
$child: Observable[ChildNode.Base]
childSource: Observable[ChildNode.Base]
): Inserter[El] = {
new Inserter[El](
preferStrictMode = true,
Expand All @@ -19,7 +19,7 @@ object ChildInserter {

var maybeLastSeenChild: js.UndefOr[ChildNode.Base] = js.undefined

$child.foreach { newChildNode =>
childSource.foreach { newChildNode =>
var remainingOldExtraNodeCount = ctx.extraNodeCount

maybeLastSeenChild
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import scala.scalajs.js
object ChildTextInserter {

def apply[A, El <: ReactiveElement.Base] (
$text: Observable[A],
textSource: Observable[A],
renderable: Renderable[A]
): Inserter[El] = {
new Inserter[El](
preferStrictMode = false,
insertFn = (ctx, owner) => {
var maybeLastSeenChild: js.UndefOr[TextNode] = js.undefined
$text.foreach { newValue =>
textSource.foreach { newValue =>
maybeLastSeenChild.fold {
// First event: inserting the child for the first time: replace sentinel comment node with new TextNode
val newTextNode = renderable.asTextNode(newValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ object ChildrenCommandInserter {
type ChildrenCommand = CollectionCommand[Child]

def apply[El <: ReactiveElement.Base] (
$command: EventStream[ChildrenCommand]
commands: EventStream[ChildrenCommand]
): Inserter[El] = {
new Inserter[El](
preferStrictMode = true,
insertFn = (ctx, owner) => {
$command.foreach { command =>
commands.foreach { command =>
val nodeCountDiff = updateList(
command,
parentNode = ctx.parentNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ object ChildrenInserter {
type Children = immutable.Seq[Child]

def apply[El <: ReactiveElement.Base](
$children: Observable[Children]
childrenSource: Observable[Children]
): Inserter[El] = {
new Inserter[El](
preferStrictMode = true,
Expand All @@ -27,7 +27,7 @@ object ChildrenInserter {

var maybeLastSeenChildren: js.UndefOr[Children] = ctx.extraNodes

$children.foreach { newChildren =>
childrenSource.foreach { newChildren =>
if (!maybeLastSeenChildren.exists(_ eq newChildren)) { // #Note: auto-distinction
// println(s">> ${$children}.foreach with newChildren = ${newChildren.map(_.ref).map(DomApi.debugNodeOuterHtml)}")
maybeLastSeenChildren = newChildren
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import com.raquo.laminar.nodes.{CommentNode, ReactiveElement}

object ChildOptionReceiver {

def <--($maybeChildNode: Source[Option[Child]]): Inserter[ReactiveElement.Base] = {
def <--(maybeChildSource: Source[Option[Child]]): Inserter[ReactiveElement.Base] = {
val emptyNode = new CommentNode("")
ChildInserter($maybeChildNode.toObservable.map(_.getOrElse(emptyNode)))
ChildInserter(maybeChildSource.toObservable.map(_.getOrElse(emptyNode)))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ object ChildReceiver {

val text: ChildTextReceiver.type = ChildTextReceiver

def <--($node: Source[Child]): Inserter[ReactiveElement.Base] = {
ChildInserter($node.toObservable)
def <--(childSource: Source[Child]): Inserter[ReactiveElement.Base] = {
ChildInserter(childSource.toObservable)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.raquo.laminar.nodes.ReactiveElement

object ChildTextReceiver {

def <--[T]($node: Source[T])(implicit renderable: Renderable[T]): Inserter[ReactiveElement.Base] = {
ChildTextInserter($node.toObservable, renderable)
def <--[T](textSource: Source[T])(implicit renderable: Renderable[T]): Inserter[ReactiveElement.Base] = {
ChildTextInserter(textSource.toObservable, renderable)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.raquo.laminar.nodes.ReactiveElement

object ChildrenCommandReceiver {

def <--($command: EventSource[ChildrenCommand]): Inserter[ReactiveElement.Base] = {
ChildrenCommandInserter[ReactiveElement.Base]($command.toObservable)
def <--(commands: EventSource[ChildrenCommand]): Inserter[ReactiveElement.Base] = {
ChildrenCommandInserter[ReactiveElement.Base](commands.toObservable)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object ChildrenReceiver {
// but if needed, I might be able to implement a version that works with
// arrays and mutable Seq-s too.
// Let me know if you have a compelling use case for this.
def <--($children: Source[Children]): Inserter[ReactiveElement.Base] = {
ChildrenInserter($children.toObservable)
def <--(childrenSource: Source[Children]): Inserter[ReactiveElement.Base] = {
ChildrenInserter(childrenSource.toObservable)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.raquo.laminar.nodes.ReactiveHtmlElement

object FocusReceiver {

@inline def <--($isFocused: EventSource[Boolean]): Binder[ReactiveHtmlElement.Base] = {
FocusBinder($isFocused.toObservable)
@inline def <--(isFocused: EventSource[Boolean]): Binder[ReactiveHtmlElement.Base] = {
FocusBinder(isFocused.toObservable)
}
}
4 changes: 2 additions & 2 deletions src/test/scala/com/raquo/laminar/ChildReceiverSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ class ChildReceiverSpec extends UnitSpec {
): Unit = {

val childBus = new EventBus[ChildNode[dom.Element]]
val $child = makeObservable(childBus.events)
val childSource = makeObservable(childBus.events)

mount(div("Hello, ", child <-- $child))
mount(div("Hello, ", child <-- childSource))
expectNode(div.of("Hello, ", sentinel, expectedInitialChild))

withClue("First event:") {
Expand Down
Loading

0 comments on commit ff98ade

Please sign in to comment.