Skip to content

Commit ac490ce

Browse files
committed
Optional VDOM now via Optional typeclass
1 parent 4e5d8bb commit ac490ce

File tree

8 files changed

+45
-45
lines changed

8 files changed

+45
-45
lines changed

core/src/main/scala/japgolly/scalajs/react/vdom/Implicits.scala

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import Scalatags._
66

77
abstract class LowPri {
88
@inline implicit final def _react_fragSeq [A <% Frag](xs: Seq[A]) : Frag = SeqFrag(xs)
9-
@inline implicit final def _react_fragOption[A <% Frag](xs: Option[A]): Frag = SeqFrag(xs.toSeq)
109
@inline implicit final def _react_fragArray [A <% Frag](xs: Array[A]) : Frag = SeqFrag[A](xs.toSeq)
10+
11+
// @inline implicit final def _react_fragOption[A <% Frag](xs: Option[A]): Frag = SeqFrag(xs.toSeq)
12+
// @inline implicit final def _react_fragOptional[T[_], A](t: T[A])(implicit o: Optional[T], f: A => Frag): Frag =
13+
// o.fold(t, f, ???)
1114
}
1215

1316
// If you're wondering why abstract class instead of trait, https://issues.scala-lang.org/browse/SI-4767
@@ -29,11 +32,8 @@ abstract class Implicits extends LowPri {
2932
@inline implicit final def _react_attrRef[R <: Ref]: AttrValue[R] =
3033
new GenericAttr[R](_.name)
3134

32-
@inline implicit final def _react_attrOption[A](implicit tc: AttrValue[A]): AttrValue[Option[A]] =
33-
new OptionalAttrValue[Option, A](tc, _ foreach _)
34-
35-
@inline implicit final def _react_attrJsUndef[A](implicit tc: AttrValue[A]): AttrValue[js.UndefOr[A]] =
36-
new OptionalAttrValue[js.UndefOr, A](tc, _ foreach _)
35+
@inline implicit final def _react_attrOptional[T[_], A](implicit t: Optional[T], a: AttrValue[A]): AttrValue[T[A]] =
36+
new OptionalAttrValue[T, A](t, a)
3737

3838
// Styles
3939
@inline implicit final def _react_styleString : StyleValue[String] = stringStyleX
@@ -45,20 +45,17 @@ abstract class Implicits extends LowPri {
4545
implicit final val _react_styleFloat : StyleValue[Float] = GenericStyle.stringValue
4646
implicit final val _react_styleDouble : StyleValue[Double] = GenericStyle.stringValue
4747

48-
@inline implicit final def _react_styleOption[A](implicit tc: StyleValue[A]): StyleValue[Option[A]] =
49-
new OptionalStyleValue[Option, A](tc, _ foreach _)
50-
51-
@inline implicit final def _react_styleJsUndef[A](implicit tc: StyleValue[A]): StyleValue[js.UndefOr[A]] =
52-
new OptionalStyleValue[js.UndefOr, A](tc, _ foreach _)
48+
@inline implicit final def _react_styleOptional[T[_], A](implicit t: Optional[T], a: StyleValue[A]): StyleValue[T[A]] =
49+
new OptionalStyleValue[T, A](t, a)
5350

5451
// Frag
5552
@inline implicit final def _react_fragReactNode[T <% ReactNode](v: T): Frag = new ReactNodeFrag(v)
5653

5754
// TagMod
58-
@inline implicit final def _react_nodeSeq [A <% TagMod](xs: Seq[A]) : TagMod = new SeqNode(xs)
59-
@inline implicit final def _react_nodeArray [A <% TagMod](xs: Array[A]) : TagMod = new SeqNode[A](xs.toSeq)
60-
@inline implicit final def _react_nodeOption [A <% TagMod](o: Option[A]) : TagMod = o.fold(EmptyTag)(a => a)
61-
@inline implicit final def _react_nodeJsUndef[A <% TagMod](o: js.UndefOr[A]): TagMod = o.fold(EmptyTag)(a => a)
55+
@inline implicit final def _react_nodeSeq [A <% TagMod](xs: Seq[A]) : TagMod = new SeqNode(xs)
56+
@inline implicit final def _react_nodeArray[A <% TagMod](xs: Array[A]) : TagMod = new SeqNode[A](xs.toSeq)
57+
@inline implicit final def _react_nodeOptional[T[_], A](t: T[A])(implicit o: Optional[T], f: A => TagMod): TagMod =
58+
o.fold(t, f, EmptyTag)
6259

6360
// Scalatags misc
6461
@inline implicit final def _react_styleOrdering : Ordering[Style] = Scalatags.styleOrdering
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package japgolly.scalajs.react.vdom
2+
3+
import scala.scalajs.js.UndefOr
4+
5+
trait Optional[T[_]] {
6+
def foreach[A](t: T[A])(f: A => Unit): Unit
7+
def fold[A, B](t: T[A], f: A => B, b: => B): B
8+
}
9+
10+
object Optional {
11+
implicit object OptionalOption extends Optional[Option] {
12+
@inline final override def foreach[A](t: Option[A])(f: (A) => Unit): Unit = t foreach f
13+
@inline final override def fold[A, B](t: Option[A], f: A => B, b: => B): B = t.fold(b)(f)
14+
}
15+
16+
implicit object OptionalJsUndefOr extends Optional[UndefOr] {
17+
@inline final override def foreach[A](t: UndefOr[A])(f: (A) => Unit): Unit = t foreach f
18+
@inline final override def fold[A, B](t: UndefOr[A], f: A => B, b: => B): B = t.fold(b)(f)
19+
}
20+
}

core/src/main/scala/japgolly/scalajs/react/vdom/Scalatags.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,12 @@ private[vdom] object Scalatags {
181181
override def compare(x: Attr, y: Attr): Int = x.name compareTo y.name
182182
}
183183

184-
final class OptionalAttrValue[O[_], T](tc: AttrValue[T], run: (O[T], T => Unit) => Unit) extends AttrValue[O[T]] {
185-
override def apply(b: Builder, a: Attr, v: O[T]) = run(v, tc(b, a, _))
184+
final class OptionalAttrValue[T[_], A](ot: Optional[T], v: AttrValue[A]) extends AttrValue[T[A]] {
185+
override def apply(b: Builder, s: Attr, t: T[A]) = ot.foreach(t)(v(b, s, _))
186186
}
187187

188-
final class OptionalStyleValue[O[_], T](tc: StyleValue[T], run: (O[T], T => Unit) => Unit) extends StyleValue[O[T]] {
189-
override def apply(b: Builder, a: Style, v: O[T]) = run(v, tc(b, a, _))
188+
final class OptionalStyleValue[T[_], A](ot: Optional[T], v: StyleValue[A]) extends StyleValue[T[A]] {
189+
override def apply(b: Builder, s: Style, t: T[A]) = ot.foreach(t)(v(b, s, _))
190190
}
191191

192192
@inline def makeAbstractReactTag(tag: String, void: Boolean, namespaceConfig: Namespace): ReactTag =

scalaz-7.0/src/main/scala/japgolly/scalajs/react/ScalazReact.scala

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,10 @@ import scalaz.effect.IO
99
import Scalaz.Id
1010
import Leibniz.===
1111

12-
package vdom {
13-
import Scalatags._
14-
15-
abstract class ScalazImplicits {
16-
17-
18-
}
19-
}
20-
21-
object ScalazReact extends vdom.ScalazImplicits {
12+
object ScalazReact {
2213
// Don't edit this directly. Run sync-scala70
2314

15+
2416
implicit val IoToIo: IO ~> IO = NaturalTransformation.refl[IO]
2517
implicit object IdToIo extends (Id ~> IO) {
2618
override def apply[A](a: Id[A]): IO[A] = IO(a)

scalaz-7.1/src/main/scala/japgolly/scalajs/react/ScalazReact.scala

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,12 @@ import scalaz.effect.IO
99
import Scalaz.Id
1010
import Leibniz.===
1111

12-
package vdom {
13-
import Scalatags._
12+
object ScalazReact {
1413

15-
abstract class ScalazImplicits {
16-
@inline implicit final def _react_attrMaybe[A](implicit tc: AttrValue[A]): AttrValue[Maybe[A]] =
17-
new OptionalAttrValue[Maybe, A](tc, _.cata(_, ()))
18-
19-
@inline implicit final def _react_styleMaybe[A](implicit tc: StyleValue[A]): StyleValue[Maybe[A]] =
20-
new OptionalStyleValue[Maybe, A](tc, _.cata(_, ()))
21-
22-
@inline implicit final def _react_nodeMaybe[A <% TagMod](m: Maybe[A]): TagMod = m.cata(a => a, EmptyTag)
14+
implicit object OptionalMaybe extends vdom.Optional[Maybe] {
15+
@inline final override def foreach[A](m: Maybe[A])(f: (A) => Unit): Unit = m.cata(f, ())
16+
@inline final override def fold[A, B](t: Maybe[A], f: A => B, b: => B): B = t.cata(f, b)
2317
}
24-
}
25-
26-
object ScalazReact extends vdom.ScalazImplicits {
2718

2819
implicit val IoToIo: IO ~> IO = NaturalTransformation.refl[IO]
2920
implicit object IdToIo extends (Id ~> IO) {

sync-scala70

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ f=src/main/scala/japgolly/scalajs/react/ScalazReact.scala
88
echo "$f"
99
perl -pe 's!(?<=[^A-Z_]M\[)_!+_!' < $s1/$f > $s0/$f
1010
sed -i "
11-
/Maybe/d;
11+
/OptionalMaybe/,/^ *} *$/d;
1212
/^object/a\ // Don't edit this directly. Run $(basename "$0")
1313
" $s0/$f
1414

test/src/test/scala/japgolly/scalajs/react/CoreTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ object CoreTest extends TestSuite {
148148

149149
'stringArray - {
150150
val strArr = Array("hello")
151-
test(div(Some("lol"), Some(1), None: Option[String], h1("Hello"), Array(1, 2, 3), strArr, EmptyTag),
151+
test(div("lol".some, 1.some, None: Option[String], h1("Hello"), Array(1, 2, 3), strArr, EmptyTag),
152152
"""<div>lol1<h1>Hello</h1>123hello</div>""")
153153
}
154154

test/src/test/scala/japgolly/scalajs/react/PrefixedVdomTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ object PrefixedVdomTest extends TestSuite {
148148

149149
'stringArray - {
150150
val strArr = Array("hello")
151-
test(<.div(Some("lol"), Some(1), None: Option[String], <.h1("Hello"), Array(1, 2, 3), strArr, EmptyTag),
151+
test(<.div("lol".some, 1.some, None: Option[String], <.h1("Hello"), Array(1, 2, 3), strArr, EmptyTag),
152152
"""<div>lol1<h1>Hello</h1>123hello</div>""")
153153
}
154154

0 commit comments

Comments
 (0)