-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support CSS and keyframes interpolations
- Loading branch information
Showing
6 changed files
with
201 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package slinky.styledcomponents | ||
|
||
case class InterpolatedCSS[P](parts: Seq[String], interpolations: Seq[InterpolationPart[P]]) |
26 changes: 26 additions & 0 deletions
26
src/main/scala/slinky/styledcomponents/InterpolationPart.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package slinky.styledcomponents | ||
|
||
import scala.scalajs.js | ||
import js.JSConverters._ | ||
|
||
import scala.language.implicitConversions | ||
|
||
trait InterpolationPart[+P] extends js.Object | ||
trait KeyframesInterpolationPart[P] extends InterpolationPart[P] | ||
|
||
object InterpolationPart { | ||
implicit def fromPropsFunction[P, O](fn: P => O)(implicit ev: O => InterpolationPart[P]): InterpolationPart[P] = { | ||
(((o: js.Any) => { | ||
fn(o.asInstanceOf[js.Dynamic].__.asInstanceOf[P]) | ||
}): js.Function1[js.Any, js.Any]).asInstanceOf[InterpolationPart[P]] | ||
} | ||
|
||
implicit def fromString[P](str: String): InterpolationPart[P] = str.asInstanceOf[InterpolationPart[P]] | ||
|
||
implicit def fromCSS[P](css: InterpolatedCSS[P]): InterpolationPart[P] = { | ||
StyledComponentsNamespace.css.call( | ||
null, | ||
css.parts.toJSArray +: css.interpolations: _* | ||
).asInstanceOf[InterpolationPart[P]] | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/main/scala/slinky/styledcomponents/StyledBuilder.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package slinky.styledcomponents | ||
|
||
import slinky.core.{AttrPair, ExternalComponentWithAttributes, ExternalPropsWriterProvider, TagElement} | ||
import slinky.readwrite.Writer | ||
|
||
import scala.scalajs.js | ||
import scala.scalajs.js.| | ||
import js.JSConverters._ | ||
|
||
final class StyledBuilder[P, TagType <: TagElement](private val innerObj: js.Object) extends AnyVal { | ||
def attrs(pairs: AttrPair[TagType]*): StyledBuilder[P, TagType] = { | ||
val dictionary = js.Dictionary[js.Any]() | ||
pairs.foreach(p => dictionary(p.name) = p.value) | ||
new StyledBuilder(innerObj.asInstanceOf[js.Dynamic].attrs(dictionary).asInstanceOf[js.Object]) | ||
} | ||
|
||
def apply(c: InterpolatedCSS[P]): ExternalComponentWithAttributes[TagType] { | ||
type Props = P | ||
} = { | ||
new ExternalComponentWithAttributes[TagType]()(new Writer[P] { | ||
override def write(p: P): js.Object = js.Dynamic.literal(__ = p.asInstanceOf[js.Object]) | ||
}.asInstanceOf[ExternalPropsWriterProvider]) { | ||
override type Props = P | ||
override val component: String | js.Object = { | ||
innerObj.asInstanceOf[js.Function].call( | ||
js.undefined, | ||
c.parts.toJSArray +: c.interpolations: _* | ||
).asInstanceOf[js.Object] | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,41 @@ | ||
package slinky | ||
|
||
import slinky.core.{ExternalComponentWithAttributes, ExternalPropsWriterProvider, Tag, TagElement} | ||
import slinky.readwrite.Writer | ||
import org.scalajs.dom.raw.HTMLElement | ||
import slinky.core.{Attr, AttrPair, CustomAttribute} | ||
import slinky.web.html | ||
|
||
import scala.scalajs.js | ||
import js.JSConverters._ | ||
import scala.scalajs.js.| | ||
|
||
package object styledcomponents { | ||
private def elemHandler[P, T <: TagElement](sc: StringContext, comp: js.Function, fns: Seq[P => js.Any]): StyledComponentConstructor[P] { type TagType = T } = { | ||
val jsFns = fns.map(v => ((o: js.Any) => { v(o.asInstanceOf[js.Dynamic].__.asInstanceOf[P]) }): js.Function1[js.Any, js.Any]) | ||
StyledComponents.button.call( | ||
js.undefined, | ||
sc.parts.toJSArray +: jsFns: _* | ||
).asInstanceOf[StyledComponentConstructor[P] { type TagType = T }] | ||
} | ||
|
||
implicit class StyledInterpolator(val sc: StringContext) extends AnyVal { | ||
def button[P](fns: (P => js.Any)*) = | ||
elemHandler[P, html.button.tagType](sc, StyledComponents.button, fns) | ||
def css[P](fns: InterpolationPart[P]*): InterpolatedCSS[P] = { | ||
InterpolatedCSS(sc.parts, fns) | ||
} | ||
|
||
def injectGlobal[P](fns: InterpolationPart[P]*): Unit = { | ||
StyledComponentsNamespace.injectGlobal.call( | ||
js.undefined, | ||
sc.parts.toJSArray +: fns: _* | ||
) | ||
} | ||
|
||
def keyframes[P](fns: InterpolationPart[P]*): KeyframesInterpolationPart[P] = { | ||
StyledComponentsNamespace.keyframes.call( | ||
js.undefined, | ||
sc.parts.toJSArray +: fns: _* | ||
).asInstanceOf[KeyframesInterpolationPart[P]] | ||
} | ||
} | ||
|
||
def styled[P](c: StyledComponentConstructor[P]): ExternalComponentWithAttributes[c.TagType] { type Props = P } = { | ||
new ExternalComponentWithAttributes[c.TagType]()(new Writer[P] { | ||
override def write(p: P): js.Object = js.Dynamic.literal(__ = p.asInstanceOf[js.Object]) | ||
}.asInstanceOf[ExternalPropsWriterProvider]) { | ||
override type Props = P | ||
override val component: String | js.Object = c | ||
object styled { | ||
def button[P]: StyledBuilder[P, html.button.tagType] = { | ||
new StyledBuilder[P, html.button.tagType](StyledComponents.button.asInstanceOf[js.Object]) | ||
} | ||
} | ||
|
||
object innerRef extends Attr { | ||
@inline def :=(v: org.scalajs.dom.Element => Unit) = new AttrPair[Any]("innerRef", v) | ||
@inline def :=(v: slinky.core.facade.ReactRef[org.scalajs.dom.Element]) = new AttrPair[Any]("innerRef", v) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters