-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
Data.scala
195 lines (165 loc) · 6.48 KB
/
Data.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package scalacss.internal
import japgolly.univeq.UnivEq
final case class ClassName(value: String)
object ClassName {
implicit def univEq: UnivEq[ClassName] = UnivEq.derive
}
/**
* A CSS attribute and its corresponding value.
*
* Example: `CssKV("margin-bottom", "12px")`
*/
final case class CssKV(key: String, value: String)
object CssKV {
implicit def univEq: UnivEq[CssKV] = UnivEq.derive
final class Lens(val get: CssKV => String, val set: (CssKV, String) => CssKV)
val key = new Lens(_.key , (a, b) => CssKV(b, a.value))
val value = new Lens(_.value, (a, b) => CssKV(a.key, b))
}
/** Defines the range of unicode characters the font face supports. */
case class UnicodeRange(from: Int, to: Int) {
override def toString = "U+%x-%x".format(from, to)
}
object UnicodeRange {
implicit def univEq: UnivEq[UnicodeRange] = UnivEq.derive
}
/**
* Text to include in generated class names.
*
* [[mutable.Register.NameGen]]s can choose to include it in the output class names, or ignore it.
*/
final case class ClassNameHint(value: String)
/**
* Animation keyframes.
*
* @param name Name of animation.
* @param frames Frame definitions.
*/
final case class Keyframes(name: KeyframeAnimationName, frames: Seq[(KeyframeSelector, StyleA)])
/**
* Font face declaration
*
* http://www.w3schools.com/cssref/css3_pr_font-face_rule.asp
*/
final case class FontFace[FF](fontFamily : FF,
src : NonEmptyVector[String],
fontStretchValue : Option[Value] = None,
fontStyleValue : Option[Value] = None,
fontWeightValue : Option[Value] = None,
unicodeRangeValue : Option[UnicodeRange] = None) {
import FontFace._
def fontStretch = new FontStretchBuilder[FF](v => copy(fontStretchValue = Some(v)))
def fontStyle = new FontStyleBuilder [FF](v => copy(fontStyleValue = Some(v)))
def fontWeight = new FontWeightBuilder [FF](v => copy(fontWeightValue = Some(v)))
def unicodeRange(from: Int, to: Int) = copy(unicodeRangeValue = Some(UnicodeRange(from, to)))
}
object FontFace {
final class FontSrcSelector(val fontFamily: Option[String]) extends AnyVal {
def src(src: String, additionalSrc: String*): FontFace[Option[String]] =
FontFace(fontFamily, NonEmptyVector(src, additionalSrc.toVector))
}
final class FontStretchBuilder[FF](private val b: Value => FontFace[FF]) extends AnyVal {
def condensed = b(Literal.condensed)
def expanded = b(Literal.expanded)
def extraCondensed = b(Literal.extraCondensed)
def extraExpanded = b(Literal.extraExpanded)
def normal = b(Literal.Typed.normal.value)
def semiCondensed = b(Literal.semiCondensed)
def semiExpanded = b(Literal.semiExpanded)
def ultraCondensed = b(Literal.ultraCondensed)
def ultraExpanded = b(Literal.ultraExpanded)
}
final class FontStyleBuilder[FF](private val b: Value => FontFace[FF]) extends AnyVal {
def italic = b(Literal.italic)
def normal = b(Literal.Typed.normal.value)
def oblique = b(Literal.oblique)
}
final class FontWeightBuilder[FF](private val b: Value => FontFace[FF]) extends AnyVal {
def _100 = b("100")
def _200 = b("200")
def _300 = b("300")
def _400 = b("400")
def _500 = b("500")
def _600 = b("600")
def _700 = b("700")
def _800 = b("800")
def _900 = b("900")
def bold = b(Literal.bold)
def bolder = b(Literal.bolder)
def lighter = b(Literal.lighter)
def normal = b(Literal.Typed.normal.value)
}
}
sealed abstract class LengthUnit(val value: String)
object LengthUnit {
case object cm extends LengthUnit("cm")
case object ch extends LengthUnit("ch")
case object em extends LengthUnit("em")
case object ex extends LengthUnit("ex")
case object in extends LengthUnit("in")
case object mm extends LengthUnit("mm")
case object pc extends LengthUnit("pc")
case object pt extends LengthUnit("pt")
case object px extends LengthUnit("px")
case object rem extends LengthUnit("rem")
case object vh extends LengthUnit("vh")
case object vmin extends LengthUnit("vmin")
case object vmax extends LengthUnit("vmax")
case object vw extends LengthUnit("vw")
implicit def univEq: UnivEq[LengthUnit] = UnivEq.derive
}
final case class Length[@specialized(scala.Int, scala.Double) N](n: N, u: LengthUnit) {
def value = {
val s = n.toString
if (s == "0") "0" else s + u.value
}
def *(m: N)(implicit N: Numeric[N]): Length[N] =
copy(n = N.times(this.n, m))
def /(m: Double)(implicit N: Numeric[N]): Length[Double] =
copy(n = N.toDouble(n) / m)
def unary_-(implicit N: Numeric[N]): Length[N] =
copy(n = N.negate(this.n))
}
object Length {
implicit def univEq[N: UnivEq]: UnivEq[Length[N]] = UnivEq.derive
}
final case class Percentage[@specialized(scala.Int, scala.Double) N](n: N) {
def value: Value = n.toString + "%"
}
object Percentage {
implicit def univEq[N: UnivEq]: UnivEq[Percentage[N]] = UnivEq.derive
implicit def univEqX: UnivEq[Percentage[_]] = UnivEq.force // TODO This isn't actually true...
}
sealed abstract class ResolutionUnit(val value: String)
object ResolutionUnit {
/** Dots per inch */
case object dpi extends ResolutionUnit("dpi")
/** Dots per centimeter */
case object dpcm extends ResolutionUnit("dpcm")
/** Dots per pixel */
case object dppx extends ResolutionUnit("dppx")
implicit def univEq: UnivEq[ResolutionUnit] = UnivEq.derive
}
final case class Resolution[@specialized(scala.Int, scala.Double) N](n: N, u: ResolutionUnit) {
def value = n.toString + u.value
def *(m: N)(implicit N: Numeric[N]): Resolution[N] =
copy(n = N.times(this.n, m))
def /(m: Double)(implicit N: Numeric[N]): Resolution[Double] =
copy(n = N.toDouble(n) / m, u)
def unary_-(implicit N: Numeric[N]): Resolution[N] =
copy(n = N.negate(this.n), u)
}
final case class Ratio(x: Int, y: Int) {
def value = s"$x/$y"
}
object Ratio {
implicit def univEq: UnivEq[Ratio] = UnivEq.derive
/** Traditional TV format in the 20th century. */
def tvTraditional = Ratio(4, 3)
/** Modern, 'widescreen', TV format. 16:9 */
def tvWidescreen = Ratio(16, 9)
/** The most common movie format since the 1960s. 1.85:1 */
def movieTraditional = Ratio(91, 50)
/** The 'widescreen', anamorphic, movie format. 2.39:1 */
def movieWidescreen = Ratio(239, 100)
}