Skip to content

Commit

Permalink
New: Link reflected attrs and props when obtained via ReflectedHtmlAttr
Browse files Browse the repository at this point in the history
This is needed to give Laminar enough info to remove a prop by removing its reflected html attribute. There is no standard way to unset a built-in JS prop on html elements.

I do not like this approach in SDT very much, but this is what I could muster without refactoring lots of things.
  • Loading branch information
raquo committed Aug 15, 2024
1 parent 0244494 commit 846b78f
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,25 +79,27 @@ class PropsTraitGenerator(
line()
line()

distinctImplNames().foreach { implName =>
line(
InlineProtectedDef.codeStr,
" ",
implName,
s"($keyImplNameArgName: String)",
": ",
keyKind,
"[",
scalaValueTypeByImplName(implName),
", ",
domValueTypeByImplName(implName),
"]",
" = ",
baseImplName,
s"($keyImplNameArgName, ${transformCodecName(codecByImplName(implName))})",
)
line()
}
distinctImplNames().foreach(printImplDef)
}

protected def printImplDef(implName: String): Unit = {
line(
InlineProtectedDef.codeStr,
" ",
implName,
s"($keyImplNameArgName: String)",
": ",
keyKind,
"[",
scalaValueTypeByImplName(implName),
", ",
domValueTypeByImplName(implName),
"]",
" = ",
baseImplName,
s"($keyImplNameArgName, ${transformCodecName(codecByImplName(implName))})",
)
line()
}

}
4 changes: 4 additions & 0 deletions shared/src/main/scala/com/raquo/domtypes/common/AttrDef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ package com.raquo.domtypes.common
* @param scalaValueType - Type of values you can write to this attribute in Scala
* Note: in the DOM, the attribute's value is always `String`.
* @param codec - Codec needed to convert between `scalaValueType` and String
* @param reflectedProp - If the attribute is reflected, this is the corresponding property.
* Note that the linked prop instance will NOT have this attr
* in its `reflectedAttr` field to prevent a cyclic reference.
* @param commentLines - Scaladoc comment lines for this key
* @param docUrls - Scaladoc documentation URLs for this key
*/
Expand All @@ -28,6 +31,7 @@ case class AttrDef(
namespace: Option[String],
scalaValueType: String,
codec: String,
reflectedProp: Option[PropDef],
override val commentLines: List[String],
override val docUrls: List[String]
) extends KeyDef {
Expand Down
30 changes: 17 additions & 13 deletions shared/src/main/scala/com/raquo/domtypes/common/PropDef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ package com.raquo.domtypes.common
/**
* This type represents an HTML element property.
*
* @param scalaName - Suggested name of this prop in Scala.
* The name is chosen to
* - match Scala naming style (e.g. camelCase)
* - avoid name collisions between different types of keys
* (e.g. `title` tag vs `title` attribute)
* - avoid using up popular names for unpopular keys
* @param scalaAliases - Aliases that should be defined linking to the main `scalaName`
* @param domName - Native attribute name in the DOM.
* @param scalaValueType - Type of values you can write to this attribute in Scala
* @param domValueType - Type of values that this property holds in the DOM
* @param codec - Codec needed to convert between `scalaValueType` and `domValueType`
* @param commentLines - Scaladoc comment lines for this key
* @param docUrls - Scaladoc documentation URLs for this key
* @param scalaName - Suggested name of this prop in Scala.
* The name is chosen to
* - match Scala naming style (e.g. camelCase)
* - avoid name collisions between different types of keys
* (e.g. `title` tag vs `title` attribute)
* - avoid using up popular names for unpopular keys
* @param scalaAliases - Aliases that should be defined linking to the main `scalaName`
* @param domName - Native property name in the DOM.
* @param scalaValueType - Type of values you can write to this attribute in Scala
* @param domValueType - Type of values that this property holds in the DOM
* @param codec - Codec needed to convert between `scalaValueType` and `domValueType`
* @param reflectedAttr - If the property is reflected, this is the corresponding attr.
* Note that the linked attr instance will NOT have this prop
* in its `reflectedProp` field to prevent a cyclic reference.
* @param commentLines - Scaladoc comment lines for this key
* @param docUrls - Scaladoc documentation URLs for this key
*/
case class PropDef(
scalaName: String,
Expand All @@ -24,6 +27,7 @@ case class PropDef(
scalaValueType: String,
domValueType: String,
codec: String,
reflectedAttr: Option[AttrDef],
override val commentLines: List[String],
override val docUrls: List[String]
) extends KeyDef
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,38 @@ case class ReflectedHtmlAttrDef(
override val docUrls: List[String]
) extends KeyDef {

def toPropDef: PropDef = PropDef(
private lazy val _rawPropDef = PropDef(
scalaName = scalaName,
domName = domPropName,
scalaValueType = scalaValueType,
domValueType = domPropValueType,
codec = propCodec,
reflectedAttr = None,
commentLines = commentLines,
docUrls = docUrls
)

def toAttrDef: AttrDef = AttrDef(
private lazy val _rawAttrDef = AttrDef(
tagType = HtmlTagType,
scalaName = scalaName,
domName = domAttrName,
namespace = None,
scalaValueType = scalaValueType,
codec = attrCodec,
reflectedProp = None,
commentLines = commentLines,
docUrls = docUrls
)

lazy val toPropDef: PropDef = {
_rawPropDef.copy(
reflectedAttr = Some(_rawAttrDef)
)
}

lazy val toAttrDef: AttrDef = {
_rawAttrDef.copy(
reflectedProp = Some(_rawPropDef)
)
}
}
Loading

0 comments on commit 846b78f

Please sign in to comment.