Skip to content

Commit

Permalink
Refactor: Generalize Key types
Browse files Browse the repository at this point in the history
Various improvements that attempt to make the key types (html attrs, props, etc.) more principled, including a clear distinction between simple and composite keys, a more functional SimpleKey type instead of the previously empty Key trait, etc.

The motivation is to unify SimpleKey APIs and to provide more of them, for example to support key.maybe (#89) and multiple key setters (#146).
  • Loading branch information
raquo committed Feb 17, 2025
1 parent 698d6fe commit b6bb379
Show file tree
Hide file tree
Showing 87 changed files with 763 additions and 626 deletions.
6 changes: 3 additions & 3 deletions project/DomDefsGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object DomDefsGenerator {
format = CodeFormatting()
) {

override def settersPackagePath: String = basePackagePath + ".modifiers.KeySetter"
override def settersPackagePath: String = basePackagePath + ".modifiers.SimpleKeySetter"

override def scalaJsElementTypeParam: String = "Ref"

Expand Down Expand Up @@ -425,7 +425,7 @@ object DomDefsGenerator {
traitName = traitName,
keyKind = "StyleProp",
keyKindAlias = "StyleProp",
setterType = "StyleSetter",
setterType = "StyleSetter[_]",
setterTypeAlias = "SS",
derivedKeyKind = "DerivedStyleProp",
derivedKeyKindAlias = "DSP",
Expand Down Expand Up @@ -464,7 +464,7 @@ object DomDefsGenerator {
extendsTraits = styleTrait.extendsTraits.map(_.replace("[_]", "")),
extendsUnitTraits = styleTrait.extendsUnits,
propKind = "StyleProp",
keywordType = "StyleSetter",
keywordType = "StyleSetter[_]",
derivedKeyKind = "DerivedStyleProp",
lengthUnitsNumType = "Int",
defType = LazyVal,
Expand Down
2 changes: 1 addition & 1 deletion project/Versions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ object Versions {

// -- Test --

val ScalaDomTestUtils = "18.0.0"
val ScalaDomTestUtils = "18.1.0-SNAPSHOT"

val ScalaTest = "3.2.14"

Expand Down
20 changes: 14 additions & 6 deletions src/main/scala/com/raquo/laminar/DomApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ object DomApi {
setHtmlPropertyRaw(element, prop, domValue)
}

def unsetHtmlProperty(
def removeHtmlProperty(
element: ReactiveHtmlElement.Base,
prop: HtmlProp[_, _]
): Unit = {
Expand Down Expand Up @@ -279,25 +279,33 @@ object DomApi {
def setHtmlStyle[V](
element: ReactiveHtmlElement.Base,
styleProp: StyleProp[V],
value: V
value: V | String
): Unit = {
setRefStyle(element.ref, styleProp.name, styleProp.prefixes, cssValue(value))
setHtmlStyleRaw(element.ref, styleProp.name, styleProp.prefixes, cssValue(value))
}

def setHtmlStringStyle(
element: ReactiveHtmlElement.Base,
styleProp: StyleProp[_],
value: String
): Unit = {
setRefStyle(element.ref, styleProp.name, styleProp.prefixes, cssValue(value))
setHtmlStyleRaw(element.ref, styleProp.name, styleProp.prefixes, cssValue(value))
}

@deprecated("setHtmlAnyStyle was renamed to setHtmlStyle", "18.0.0-M1")
def setHtmlAnyStyle[V](
element: ReactiveHtmlElement.Base,
style: StyleProp[V],
value: V | String
): Unit = {
setRefStyle(element.ref, style.name, style.prefixes, cssValue(value))
setHtmlStyleRaw(element.ref, style.name, style.prefixes, cssValue(value))
}

def removeHtmlStyle[V](
element: ReactiveHtmlElement.Base,
style: StyleProp[V]
): Unit = {
setHtmlStyleRaw(element.ref, style.name, style.prefixes, styleValue = null)
}

@inline private[laminar] def cssValue(value: Any): String = {
Expand All @@ -317,7 +325,7 @@ object DomApi {
// }
}

@inline private[laminar] def setRefStyle(
@inline private[laminar] def setHtmlStyleRaw(
ref: dom.html.Element,
styleCssName: String,
prefixes: immutable.Seq[String],
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com/raquo/laminar/api/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.raquo.laminar.inserters._
import com.raquo.laminar.keys._
import com.raquo.laminar.keys.CompositeKey.CompositeValueMappers
import com.raquo.laminar.modifiers._
import com.raquo.laminar.modifiers.KeyUpdater.StyleUpdater
import com.raquo.laminar.modifiers.SimpleKeyUpdater.StyleUpdater
import com.raquo.laminar.nodes._
import org.scalajs.dom

Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/com/raquo/laminar/api/Laminar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import com.raquo.laminar.defs.styles.StyleProps
import com.raquo.laminar.defs.tags.{HtmlTags, SvgTags}
import com.raquo.laminar.inputs.InputController
import com.raquo.laminar.keys._
import com.raquo.laminar.modifiers.{EventListener, KeyUpdater}
import com.raquo.laminar.modifiers.{EventListener, SimpleKeyUpdater}
import com.raquo.laminar.nodes.{DetachedRoot, ReactiveElement, ReactiveHtmlElement, ReactiveSvgElement}
import com.raquo.laminar.receivers._
import com.raquo.laminar.tags.{HtmlTag, SvgTag}
Expand Down Expand Up @@ -257,7 +257,7 @@ with Implicits {
*/
def controlled[Ref <: dom.html.Element, Ev <: dom.Event, V](
listener: EventListener[Ev, _],
updater: KeyUpdater[ReactiveHtmlElement[Ref], HtmlProp[V, _], V]
updater: SimpleKeyUpdater[ReactiveHtmlElement[Ref], HtmlProp[V, _], V]
): Binder[ReactiveHtmlElement[Ref]] = {
InputController.controlled(listener, updater)
}
Expand All @@ -266,7 +266,7 @@ with Implicits {
* See [[https://laminar.dev/documentation#controlled-inputs Controlled Inputs docs]]
*/
def controlled[Ref <: dom.html.Element, Ev <: dom.Event, V](
updater: KeyUpdater[ReactiveHtmlElement[Ref], HtmlProp[V, _], V],
updater: SimpleKeyUpdater[ReactiveHtmlElement[Ref], HtmlProp[V, _], V],
listener: EventListener[Ev, _]
): Binder[ReactiveHtmlElement[Ref]] = {
InputController.controlled(listener, updater)
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/com/raquo/laminar/api/StyleUnitsApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package com.raquo.laminar.api

import com.raquo.laminar.api.StyleUnitsApi.StyleEncoder
import com.raquo.laminar.defs.styles.units
import com.raquo.laminar.keys.DerivedStyleBuilder
import com.raquo.laminar.keys.StyleBuilder

trait StyleUnitsApi extends DerivedStyleBuilder[String, StyleEncoder]
trait StyleUnitsApi
extends StyleBuilder[String, StyleEncoder]
with units.Color[String, StyleEncoder]
with units.Length[StyleEncoder, Int]
with units.Time[StyleEncoder]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ trait ComplexHtmlKeys {

object ComplexHtmlKeys {

type CompositeHtmlProp = CompositeKey[HtmlProp[String, String], ReactiveHtmlElement.Base]
@deprecated("CompositeHtmlProp is now the same type as CompositeHtmlAttr – use the latter instead", "18.0.0-M1")
type CompositeHtmlProp = CompositeKey[ReactiveHtmlElement.Base]

type CompositeHtmlAttr = CompositeKey[HtmlAttr[String], ReactiveHtmlElement.Base]
type CompositeHtmlAttr = CompositeKey[ReactiveHtmlElement.Base]
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ trait ComplexSvgKeys {

object ComplexSvgKeys {

type CompositeSvgAttr = CompositeKey[SvgAttr[String], ReactiveSvgElement.Base]
type CompositeSvgAttr = CompositeKey[ReactiveSvgElement.Base]
}
4 changes: 2 additions & 2 deletions src/main/scala/com/raquo/laminar/defs/styles/StyleProps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.keys.DerivedStyleProp
import com.raquo.laminar.defs.styles.{traits => s}
import com.raquo.laminar.defs.styles.{units => u}
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter

// #NOTE: GENERATED CODE
// - This file is generated at compile time from the data in Scala DOM Types
Expand All @@ -16,7 +16,7 @@ trait StyleProps {

protected type DSP[V] = DerivedStyleProp[V]

protected type SS = StyleSetter
protected type SS = StyleSetter[_]


/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.raquo.laminar.defs.styles.traits

import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter

// #NOTE: GENERATED CODE
// - This file is generated at compile time from the data in Scala DOM Types
Expand All @@ -10,10 +10,10 @@ import com.raquo.laminar.modifiers.KeySetter.StyleSetter

trait AlignContent extends FlexPosition { this: StyleProp[_] =>

lazy val spaceBetween: StyleSetter = this := "space-between"
lazy val spaceBetween: StyleSetter[_] = this := "space-between"

lazy val spaceAround: StyleSetter = this := "space-around"
lazy val spaceAround: StyleSetter[_] = this := "space-around"

lazy val spaceEvenly: StyleSetter = this := "space-evenly"
lazy val spaceEvenly: StyleSetter[_] = this := "space-evenly"

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.raquo.laminar.defs.styles.traits

import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter

// #NOTE: GENERATED CODE
// - This file is generated at compile time from the data in Scala DOM Types
Expand All @@ -10,6 +10,6 @@ import com.raquo.laminar.modifiers.KeySetter.StyleSetter

trait Auto { this: StyleProp[_] =>

lazy val auto: StyleSetter = this := "auto"
lazy val auto: StyleSetter[_] = this := "auto"

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.raquo.laminar.defs.styles.traits

import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter

// #NOTE: GENERATED CODE
// - This file is generated at compile time from the data in Scala DOM Types
Expand All @@ -11,9 +11,9 @@ import com.raquo.laminar.modifiers.KeySetter.StyleSetter
trait BackfaceVisibility { this: StyleProp[_] =>

/** The back face is visible. */
lazy val visible: StyleSetter = this := "visible"
lazy val visible: StyleSetter[_] = this := "visible"

/** The back face is not visible. */
lazy val hidden: StyleSetter = this := "hidden"
lazy val hidden: StyleSetter[_] = this := "hidden"

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.raquo.laminar.defs.styles.traits

import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter

// #NOTE: GENERATED CODE
// - This file is generated at compile time from the data in Scala DOM Types
Expand All @@ -15,7 +15,7 @@ trait BackgroundAttachment { this: StyleProp[_] =>
* a scrolling mechanism, the background doesn't move with the element.
* (This is not compatible with background-clip: text.)
*/
lazy val fixed: StyleSetter = this := "fixed"
lazy val fixed: StyleSetter[_] = this := "fixed"

/**
* The background is fixed relative to the element's contents. If the element
Expand All @@ -24,12 +24,12 @@ trait BackgroundAttachment { this: StyleProp[_] =>
* are relative to the scrollable area of the element rather than to the
* border framing them.
*/
lazy val local: StyleSetter = this := "local"
lazy val local: StyleSetter[_] = this := "local"

/**
* The background is fixed relative to the element itself and does not scroll
* with its contents. (It is effectively attached to the element's border.)
*/
lazy val scroll: StyleSetter = this := "scroll"
lazy val scroll: StyleSetter[_] = this := "scroll"

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.raquo.laminar.defs.styles.traits

import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter
import com.raquo.laminar.defs.styles.{units => u}
import com.raquo.laminar.keys.DerivedStyleProp

Expand All @@ -18,13 +18,13 @@ trait BackgroundSize extends Auto with u.Length[DerivedStyleProp, Int] { this: S
* or equal to the corresponding dimensions of the background positioning
* area.
*/
lazy val cover: StyleSetter = this := "cover"
lazy val cover: StyleSetter[_] = this := "cover"

/**
* This keyword specifies that the background image should be scaled to be
* as large as possible while ensuring both its dimensions are less than or
* equal to the corresponding dimensions of the background positioning area.
*/
lazy val contain: StyleSetter = this := "contain"
lazy val contain: StyleSetter[_] = this := "contain"

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.raquo.laminar.defs.styles.traits

import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter

// #NOTE: GENERATED CODE
// - This file is generated at compile time from the data in Scala DOM Types
Expand All @@ -11,9 +11,9 @@ import com.raquo.laminar.modifiers.KeySetter.StyleSetter
trait BorderCollapse { this: StyleProp[_] =>

/** Use separated-border table rendering model. This is the default. */
lazy val separate: StyleSetter = this := "separate"
lazy val separate: StyleSetter[_] = this := "separate"

/** Use collapsed-border table rendering model. */
lazy val collapse: StyleSetter = this := "collapse"
lazy val collapse: StyleSetter[_] = this := "collapse"

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.raquo.laminar.defs.styles.traits

import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter

// #NOTE: GENERATED CODE
// - This file is generated at compile time from the data in Scala DOM Types
Expand All @@ -10,8 +10,8 @@ import com.raquo.laminar.modifiers.KeySetter.StyleSetter

trait BoxSizing { this: StyleProp[_] =>

lazy val borderBox: StyleSetter = this := "border-box"
lazy val borderBox: StyleSetter[_] = this := "border-box"

lazy val contentBox: StyleSetter = this := "content-box"
lazy val contentBox: StyleSetter[_] = this := "content-box"

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.raquo.laminar.defs.styles.traits

import com.raquo.laminar.keys.StyleProp
import com.raquo.laminar.modifiers.KeySetter.StyleSetter
import com.raquo.laminar.modifiers.SimpleKeySetter.StyleSetter

// #NOTE: GENERATED CODE
// - This file is generated at compile time from the data in Scala DOM Types
Expand All @@ -11,12 +11,12 @@ import com.raquo.laminar.modifiers.KeySetter.StyleSetter
trait Clear extends None { this: StyleProp[_] =>

/** The element is moved down to clear past left floats. */
lazy val left: StyleSetter = this := "left"
lazy val left: StyleSetter[_] = this := "left"

/** The element is moved down to clear past right floats. */
lazy val right: StyleSetter = this := "right"
lazy val right: StyleSetter[_] = this := "right"

/** The element is moved down to clear past both left and right floats. */
lazy val both: StyleSetter = this := "both"
lazy val both: StyleSetter[_] = this := "both"

}
Loading

0 comments on commit b6bb379

Please sign in to comment.