Skip to content

Commit f21e5cf

Browse files
committed
API: Use by-name arguments for when and whenNot.
- Note: Scala 2 does not support by-name varargs, so in Scala 2 these methods are now limited to at most one argument - This required an alternative implementation vs #169.
1 parent 6026a5c commit f21e5cf

File tree

7 files changed

+161
-57
lines changed

7 files changed

+161
-57
lines changed

.scalafmt.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ runner.dialect = "scala213"
66
# - Maybe make a separate config for these files, that has two lines before method names, see https://scalameta.org/scalafmt/docs/configuration.html#fileoverride
77
# - Does this exclusion actually work? IntelliJ seems to ignore it
88
project.excludePaths = [
9+
"glob:**/src/*/scala-3/**",
910
"glob:**/src/main/scala/com/raquo/laminar/defs/**",
1011
"glob:**/project/VersionHelper.scala",
1112
]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.raquo.laminar.api
2+
3+
trait LaminarPlatformSpecific { this: LaminarAliases =>
4+
5+
/** Returns a Modifier that applies another Modifier if `condition` is true
6+
*
7+
* Note:
8+
* - The inner Modifier is evaluated only if `condition` is `true`.
9+
* - Scala 3 version of `when` supports passing multiple modifiers.
10+
*/
11+
def when[El <: Element](condition: Boolean)(mod: => Modifier[El]): Modifier[El] = {
12+
if (condition) {
13+
mod // implicitly converted to a single modifier
14+
} else {
15+
Modifier.empty
16+
}
17+
}
18+
19+
/** Returns a Modifier that applies another Modifier if `condition` is true.
20+
*
21+
* Note:
22+
* - The inner Modifier is evaluated only if `condition` is `false`.
23+
* - Scala 3 version of `when` supports passing multiple modifiers.
24+
*/
25+
@inline def whenNot[El <: Element](condition: Boolean)(mod: => Modifier[El]): Modifier[El] = when(!condition)(mod)
26+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.raquo.laminar.api
2+
3+
trait LaminarPlatformSpecific { this: LaminarAliases =>
4+
5+
/** Returns a Modifier that applies one or more Modifiers if `condition` is `true`.
6+
* Note: The inner Modifier-s are evaluated only if the condition is `true`.
7+
*/
8+
def when[El <: Element](condition: Boolean)(mods: => Modifier[El]*): Modifier[El] = {
9+
if (condition) {
10+
mods // implicitly converted to a single modifier
11+
} else {
12+
Modifier.empty
13+
}
14+
}
15+
16+
/** Returns a Modifier that applies one or more modifiers if `condition` is `true`.
17+
* Note: The inner Modifier-s are evaluated only if the condition is `false`.
18+
*/
19+
@inline def whenNot[El <: Element](condition: Boolean)(mods: => Modifier[El]*): Modifier[El] = when(!condition)(mods)
20+
}

src/main/scala/com/raquo/laminar/api/Laminar.scala

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.raquo.laminar.api
22

33
import com.raquo.airstream.web.DomEventStream
4-
import com.raquo.laminar.{DomApi, nodes}
4+
import com.raquo.laminar.{nodes, DomApi}
55
import com.raquo.laminar.defs.attrs.{AriaAttrs, HtmlAttrs, SvgAttrs}
66
import com.raquo.laminar.defs.complex.{ComplexHtmlKeys, ComplexSvgKeys}
77
import com.raquo.laminar.defs.eventProps.{DocumentEventProps, GlobalEventProps, WindowEventProps}
@@ -19,7 +19,8 @@ import org.scalajs.dom
1919
// @TODO[Performance] Check if order of traits matters for quicker access (given trait linearization). Not sure how it's encoded in JS.
2020

2121
trait Laminar
22-
extends HtmlTags
22+
extends LaminarPlatformSpecific
23+
with HtmlTags
2324
with HtmlAttrs
2425
with HtmlProps
2526
with GlobalEventProps
@@ -251,20 +252,6 @@ with Implicits {
251252

252253
//
253254

254-
/** Modifier that applies one or more modifiers if `condition` is true */
255-
def when[El <: Element](condition: Boolean)(mods: Modifier[El]*): Modifier[El] = {
256-
if (condition) {
257-
mods // implicitly converted to a single modifier
258-
} else {
259-
emptyMod
260-
}
261-
}
262-
263-
/** Modifier that applies one or more modifiers if `condition` is true */
264-
@inline def whenNot[El <: Element](condition: Boolean)(mods: Modifier[El]*): Modifier[El] = when(!condition)(mods)
265-
266-
//
267-
268255
/** Creates controlled input block.
269256
* See [[https://laminar.dev/documentation#controlled-inputs Controlled Inputs docs]]
270257
*/
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.raquo.laminar.tests.basic
2+
3+
import com.raquo.laminar.api.L._
4+
5+
import com.raquo.laminar.utils.UnitSpec
6+
7+
class ModSpecScala2 extends UnitSpec {
8+
9+
it("when keyword") {
10+
11+
var evaluatedUsed = false
12+
var evaluatedUnused = false
13+
14+
val el = div(
15+
when(true) {
16+
evaluatedUsed = true
17+
title("foo")
18+
},
19+
when(false) {
20+
evaluatedUnused = true
21+
title("bar")
22+
},
23+
when(true)(
24+
height.px(100)
25+
),
26+
when(true) {
27+
List(minAttr("10"), maxAttr("20"))
28+
},
29+
when(true)(div("hello")),
30+
when(true) {
31+
onMountInsert(_ =>
32+
"world"
33+
)
34+
},
35+
when(true) {
36+
text <-- Val("text")
37+
}
38+
)
39+
40+
mount(el)
41+
42+
expectNode(div.of(
43+
title is "foo",
44+
height is "100px",
45+
minAttr is "10",
46+
maxAttr is "20",
47+
div.of("hello"),
48+
"world",
49+
"text"
50+
))
51+
52+
assertEquals(evaluatedUsed, true)
53+
assertEquals(evaluatedUnused, false)
54+
}
55+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.raquo.laminar.tests.basic
2+
3+
import com.raquo.laminar.api.L.{*, given}
4+
import com.raquo.laminar.utils.UnitSpec
5+
6+
class ModSpecScala3 extends UnitSpec {
7+
8+
it("when keyword") {
9+
10+
var evaluatedUsed = false
11+
var evaluatedUnused = false
12+
13+
val el = div(
14+
when(true) {
15+
evaluatedUsed = true
16+
title("foo")
17+
},
18+
when(false) {
19+
evaluatedUnused = true
20+
title("bar")
21+
},
22+
when(true)(
23+
height.px(100),
24+
width.px(200)
25+
),
26+
when(true) {
27+
List(minAttr("10"), maxAttr("20"))
28+
},
29+
when(true)(div("hello")),
30+
when(true) {
31+
onMountInsert(_ =>
32+
"world"
33+
)
34+
},
35+
when(true) {
36+
text <-- Val("text")
37+
}
38+
)
39+
40+
mount(el)
41+
42+
expectNode(div.of(
43+
title is "foo",
44+
height is "100px",
45+
width is "200px",
46+
minAttr is "10",
47+
maxAttr is "20",
48+
div.of("hello"),
49+
"world",
50+
"text"
51+
))
52+
53+
assertEquals(evaluatedUsed, true)
54+
assertEquals(evaluatedUnused, false)
55+
}
56+
}

src/test/scala/com/raquo/laminar/tests/basic/ModSpec.scala

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,6 @@ import scala.scalajs.js
77

88
class ModSpec extends UnitSpec {
99

10-
it("when keyword") {
11-
12-
val el = div(
13-
when(true) {
14-
title("foo")
15-
},
16-
when(false) {
17-
title("bar")
18-
},
19-
when(true)(
20-
height.px(100),
21-
width.px(200)
22-
),
23-
when(true) {
24-
List(minAttr("10"), maxAttr("20"))
25-
},
26-
when(true)(div("hello")),
27-
when(true) {
28-
onMountInsert(_ =>
29-
"world"
30-
)
31-
},
32-
when(true) {
33-
text <-- Val("text")
34-
}
35-
)
36-
37-
mount(el)
38-
39-
expectNode(div.of(
40-
title is "foo",
41-
height is "100px",
42-
width is "200px",
43-
minAttr is "10",
44-
maxAttr is "20",
45-
div.of("hello"),
46-
"world",
47-
"text"
48-
))
49-
}
50-
5110
it("nodeSeq type inference") {
5211

5312
val nodes = nodeSeq("text", span("element"))

0 commit comments

Comments
 (0)