aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala')
-rw-r--r--src/main/scala/reading/Media.scala12
-rw-r--r--src/main/scala/reading/component/Index.scala24
-rw-r--r--src/main/scala/reading/component/index/BookDetail.scala3
-rw-r--r--src/main/scala/reading/component/index/Books.scala1
-rw-r--r--src/main/scala/reading/component/index/Filters.scala41
-rw-r--r--src/main/scala/reading/component/index/FiltersMenu.scala72
-rw-r--r--src/main/scala/reading/component/index/Header.scala76
-rw-r--r--src/main/scala/reading/component/index/Menu.scala104
-rw-r--r--src/main/scala/reading/component/index/style/BookDetail.scala12
-rw-r--r--src/main/scala/reading/component/index/style/Books.scala11
-rw-r--r--src/main/scala/reading/component/index/style/Count.scala20
-rw-r--r--src/main/scala/reading/component/index/style/Filters.scala34
-rw-r--r--src/main/scala/reading/component/index/style/FiltersMenu.scala28
-rw-r--r--src/main/scala/reading/component/index/style/Header.scala80
-rw-r--r--src/main/scala/reading/component/index/style/Menu.scala97
-rw-r--r--src/main/scala/reading/component/style/Color.scala53
-rw-r--r--src/main/scala/reading/component/style/Global.scala24
-rw-r--r--src/main/scala/reading/component/style/Index.scala16
-rw-r--r--src/main/scala/reading/component/widget/Popup.scala4
-rw-r--r--src/main/scala/reading/component/widget/style/Popup.scala38
20 files changed, 507 insertions, 243 deletions
diff --git a/src/main/scala/reading/Media.scala b/src/main/scala/reading/Media.scala
new file mode 100644
index 0000000..b9294e2
--- /dev/null
+++ b/src/main/scala/reading/Media.scala
@@ -0,0 +1,12 @@
+package reading
+
+import scalacss.Defaults._
+import scalacss.internal.DslBase.ToStyle
+
+object Media extends StyleSheet.Inline {
+ import dsl._
+
+ def desktop(st: ToStyle*): ToStyle = media.minWidth(1000.px)(st: _*)
+
+ def mobile(st: ToStyle*): ToStyle = media.maxWidth(1000.px)(st: _*)
+}
diff --git a/src/main/scala/reading/component/Index.scala b/src/main/scala/reading/component/Index.scala
index 8c2fdd6..57f5b4b 100644
--- a/src/main/scala/reading/component/Index.scala
+++ b/src/main/scala/reading/component/Index.scala
@@ -9,9 +9,8 @@ import scalacss.ScalatagsCss._
import reading.Books
import reading.component.style.{ Index => IndexStyle }
-import reading.component.index.{ FiltersMenu, Filters, Books => BooksComponent }
+import reading.component.index.{ Menu, Header, Books => BooksComponent }
import reading.models.{ Book, Filter }
-import reading.utils.RxTag
object Index {
def apply(initialFilters: Seq[Filter]): HtmlTag = {
@@ -20,25 +19,16 @@ object Index {
if (filters().isEmpty) Books() else Book.filter(Books(), filters())
}
val count: Rx[Int] = Rx(books().length)
+ val showFiltersMenu: Var[Boolean] = Var(false)
div(
IndexStyle.render,
-
- div(
- IndexStyle.header,
- RxTag { implicit context =>
- span(s"Conseils de lecture, ${count()} livre${if (count() > 1) "s" else ""}")
- }
- ),
-
+ IndexStyle.page,
+ Menu(books, filters, showFiltersMenu),
div(
- IndexStyle.page,
- FiltersMenu(books, filters),
- div(
- IndexStyle.main,
- Filters(filters),
- BooksComponent(books)
- )
+ IndexStyle.main,
+ Header(filters, showFiltersMenu, count),
+ BooksComponent(books)
)
)
}
diff --git a/src/main/scala/reading/component/index/BookDetail.scala b/src/main/scala/reading/component/index/BookDetail.scala
index 6a9d83a..80280ac 100644
--- a/src/main/scala/reading/component/index/BookDetail.scala
+++ b/src/main/scala/reading/component/index/BookDetail.scala
@@ -15,7 +15,8 @@ object BookDetail {
img(
BookStyle.cover,
- src := s"cover/${book.title}.jpg"
+ src := s"cover/${book.title}.jpg",
+ alt := book.title
),
div(
diff --git a/src/main/scala/reading/component/index/Books.scala b/src/main/scala/reading/component/index/Books.scala
index 5d7c92e..b75a5b0 100644
--- a/src/main/scala/reading/component/index/Books.scala
+++ b/src/main/scala/reading/component/index/Books.scala
@@ -30,6 +30,7 @@ object Books {
img(
BooksStyle.cover,
src := s"cover/${book.title}.jpg",
+ alt := book.title,
RxAttr(onclick, Rx(() => focus() = Some(book)))
)
)
diff --git a/src/main/scala/reading/component/index/Filters.scala b/src/main/scala/reading/component/index/Filters.scala
deleted file mode 100644
index 569bd86..0000000
--- a/src/main/scala/reading/component/index/Filters.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-package reading.component.index
-
-import rx._
-import Ctx.Owner.Unsafe._
-
-import scalatags.JsDom.all._
-import scalacss.Defaults._
-import scalacss.ScalatagsCss._
-
-import reading.component.index.style.{ Filters => FiltersStyle }
-import reading.component.widget.Cross
-import reading.component.style.Col
-import reading.models.Filter
-import reading.Route
-import reading.utils.{ RxTag, RxAttr }
-
-object Filters {
- def apply(filters: Var[Seq[Filter]]): Frag =
- RxTag { implicit context =>
- if (filters().isEmpty)
- span("")
- else
- div(
- FiltersStyle.render,
- FiltersStyle.filters,
-
- filters().sortBy(_.name).map { filter =>
- div(
- FiltersStyle.filter,
- RxAttr(onclick, Rx(() => {
- val newFilters = Filter.remove(filters(), filter)
- filters() = newFilters
- Route.push(Route.Books(newFilters))
- })),
- span(FiltersStyle.name, filter.name.capitalize),
- Cross(15.px, Col.black)
- )
- }
- )
- }
-}
diff --git a/src/main/scala/reading/component/index/FiltersMenu.scala b/src/main/scala/reading/component/index/FiltersMenu.scala
deleted file mode 100644
index f3f9ca2..0000000
--- a/src/main/scala/reading/component/index/FiltersMenu.scala
+++ /dev/null
@@ -1,72 +0,0 @@
-package reading.component.index
-
-import rx._
-import Ctx.Owner.Unsafe._
-
-import scalatags.JsDom.all._
-import scalacss.Defaults._
-import scalacss.ScalatagsCss._
-
-import reading.component.index.style.{ FiltersMenu => FiltersMenuStyle }
-import reading.models._
-import reading.utils.{ RxTag, RxAttr }
-import reading.Route
-
-object FiltersMenu {
- def apply(books: Rx[Seq[Book]], filters: Var[Seq[Filter]]): Frag =
- RxTag { implicit context =>
- div(
- FiltersMenuStyle.render,
- FiltersMenuStyle.groups,
- filters().find(_.kind == FilterKind.Grade) match {
- case None =>
- group(books, filters, "Classe", Grade.values.map(Filter.apply(_)))
- case Some(grade) =>
- group(books, filters, "Programme", Program.values.map(Filter.apply(_)))
- },
- group(books, filters, "Theme", Theme.values.map(Filter.apply(_))),
- group(books, filters, "Genre", Genre.values.map(Filter.apply(_))),
- group(books, filters, "Niveau", Level.values.map(Filter.apply(_))),
- group(books, filters, "Période", Period.values.map(Filter.apply(_)))
- )
- }
-
- def group(
- books: Rx[Seq[Book]],
- filters: Var[Seq[Filter]],
- name: String,
- groupFilters: Seq[Filter]
- )(
- implicit
- context: Ctx.Data
- ): Frag = {
- val filtersWithCount = Rx {
- groupFilters
- .filter(filter => !Filter.contains(filters(), filter))
- .map(filter => (filter, Book.filter(books(), Seq(filter)).length))
- .filter(_._2 > 0)
- }
-
- if (filtersWithCount().isEmpty)
- span("")
- else
- div(
- FiltersMenuStyle.group,
- div(FiltersMenuStyle.groupTitle, name),
- div(
- filtersWithCount().map {
- case (filter, count) =>
- button(
- FiltersMenuStyle.filter,
- RxAttr(onclick, Rx(() => {
- val newFilters = filter +: filters()
- filters() = newFilters
- Route.push(Route.Books(newFilters))
- })),
- span(s"${filter.name.capitalize} ($count)")
- )
- }
- )
- )
- }
-}
diff --git a/src/main/scala/reading/component/index/Header.scala b/src/main/scala/reading/component/index/Header.scala
new file mode 100644
index 0000000..7e29b4c
--- /dev/null
+++ b/src/main/scala/reading/component/index/Header.scala
@@ -0,0 +1,76 @@
+package reading.component.index
+
+import org.scalajs.dom
+
+import rx._
+import Ctx.Owner.Unsafe._
+
+import scalatags.JsDom.all._
+import scalacss.Defaults._
+import scalacss.ScalatagsCss._
+
+import reading.component.index.style.{ Header => HeaderStyle }
+import reading.component.widget.Cross
+import reading.component.style.{ Color => C }
+import reading.models.Filter
+import reading.Route
+import reading.utils.{ RxTag, RxAttr }
+
+object Header {
+ def apply(filters: Var[Seq[Filter]], showFiltersMenu: Var[Boolean], booksCount: Rx[Int]): Frag = {
+ val filtersCount: Rx[Int] = Rx(filters().length)
+
+ div(
+ HeaderStyle.render,
+ HeaderStyle.header,
+
+ RxTag { implicit context =>
+ div(
+ div(
+ HeaderStyle.showFiltersMenu,
+ RxAttr(onclick, Rx(() => {
+ showFiltersMenu() = true
+ dom.document.body.style.overflowY = "hidden"
+ })),
+ "Filtrer",
+ if (filtersCount() > 0) span(HeaderStyle.filtersCount, filtersCount()) else span("")
+ ),
+
+ if (filters().isEmpty)
+ span("")
+ else
+ div(
+ HeaderStyle.filters,
+
+ div(
+ HeaderStyle.clear,
+ RxAttr(onclick, Rx(() => updateFilters(filters, Nil))),
+ "Effacer les filtres"
+ ),
+
+ filters().sortBy(_.name).map { filter =>
+ div(
+ HeaderStyle.filter,
+ RxAttr(onclick, Rx(() => updateFilters(filters, Filter.remove(filters(), filter)))),
+ span(HeaderStyle.name, filter.name.capitalize),
+ Cross(15.px, C.black.value)
+ )
+ }
+ )
+ )
+ },
+
+ RxTag { implicit context =>
+ div(
+ HeaderStyle.booksCount,
+ span(s"${booksCount()} livre${if (booksCount() > 1) "s" else ""}")
+ )
+ }
+ )
+ }
+
+ private def updateFilters(filters: Var[Seq[Filter]], newFilters: Seq[Filter]): Unit = {
+ filters() = newFilters
+ Route.push(Route.Books(newFilters))
+ }
+}
diff --git a/src/main/scala/reading/component/index/Menu.scala b/src/main/scala/reading/component/index/Menu.scala
new file mode 100644
index 0000000..5ffbd25
--- /dev/null
+++ b/src/main/scala/reading/component/index/Menu.scala
@@ -0,0 +1,104 @@
+package reading.component.index
+
+import org.scalajs.dom
+
+import rx._
+import Ctx.Owner.Unsafe._
+
+import scalatags.JsDom.all._
+import scalacss.Defaults._
+import scalacss.ScalatagsCss._
+
+import reading.component.index.style.{ Menu => MenuStyle }
+import reading.models._
+import reading.utils.{ RxTag, RxAttr }
+import reading.Route
+
+object Menu {
+ def apply(books: Rx[Seq[Book]], filters: Var[Seq[Filter]], showFiltersMenu: Var[Boolean]): Frag =
+ RxTag { implicit context =>
+ div(
+ MenuStyle.render,
+ if (showFiltersMenu()) MenuStyle.show else "",
+ MenuStyle.menu,
+
+ header(showFiltersMenu, filters().length),
+
+ filters().find(_.kind == FilterKind.Grade) match {
+ case None => group(books, filters, "Classe", Grade.values.map(Filter.apply(_)))
+ case Some(grade) => group(books, filters, grade.name, Program.values.map(Filter.apply(_)), Some(grade))
+ },
+ group(books, filters, "Theme", Theme.values.map(Filter.apply(_))),
+ group(books, filters, "Genre", Genre.values.map(Filter.apply(_))),
+ group(books, filters, "Niveau", Level.values.map(Filter.apply(_))),
+ group(books, filters, "Période", Period.values.map(Filter.apply(_)))
+ )
+ }
+
+ def header(showFiltersMenu: Var[Boolean], count: Int): HtmlTag =
+ div(
+ MenuStyle.header,
+ span(
+ MenuStyle.close,
+ RxAttr(onclick, Rx(() => {
+ showFiltersMenu() = false
+ dom.document.body.style.overflowY = "scroll"
+ }))
+ ),
+ "Filtrer",
+ if (count > 0) span(MenuStyle.count, count) else span("")
+ )
+
+ def group(
+ books: Rx[Seq[Book]],
+ filters: Var[Seq[Filter]],
+ name: String,
+ groupFilters: Seq[Filter],
+ parentFilter: Option[Filter] = None
+ )(
+ implicit
+ context: Ctx.Data
+ ): Frag = {
+ val filtersWithCount = Rx {
+ groupFilters
+ .map(filter => (filter, Book.filter(books(), Seq(filter)).length))
+ .filter(_._2 > 0)
+ }
+
+ if (filtersWithCount().isEmpty)
+ span("")
+ else
+ div(
+ MenuStyle.filterGroup,
+ div(
+ MenuStyle.filterTitle,
+ parentFilter.map(filter =>
+ RxAttr(onclick, Rx(() => updateFilters(filters, Filter.remove(filters(), filter))))).getOrElse(""),
+ if (parentFilter.isDefined) MenuStyle.activeFilter else "",
+ name
+ ),
+ div(
+ filtersWithCount().map {
+ case (filter, count) => {
+ val isActive = Filter.contains(filters(), filter)
+
+ button(
+ MenuStyle.filter,
+ if (isActive) MenuStyle.activeFilter else "",
+ RxAttr(onclick, Rx(() => updateFilters(
+ filters,
+ if (isActive) Filter.remove(filters(), filter) else filter +: filters()
+ ))),
+ span(s"${filter.name.capitalize} ($count)")
+ )
+ }
+ }
+ )
+ )
+ }
+
+ private def updateFilters(filters: Var[Seq[Filter]], newFilters: Seq[Filter]): Unit = {
+ filters() = newFilters
+ Route.push(Route.Books(newFilters))
+ }
+}
diff --git a/src/main/scala/reading/component/index/style/BookDetail.scala b/src/main/scala/reading/component/index/style/BookDetail.scala
index e54c964..6e79113 100644
--- a/src/main/scala/reading/component/index/style/BookDetail.scala
+++ b/src/main/scala/reading/component/index/style/BookDetail.scala
@@ -2,7 +2,8 @@ package reading.component.index.style
import scalacss.Defaults._
-import reading.component.style.Col
+import reading.Media
+import reading.component.style.{ Color => C }
object BookDetail extends StyleSheet.Inline {
import dsl._
@@ -12,7 +13,7 @@ object BookDetail extends StyleSheet.Inline {
fontSize(18.px),
fontWeight.bold,
marginBottom(20.px),
- color(Col.congoBrown)
+ color(C.congoBrown.value)
)
val author = style(
@@ -20,12 +21,15 @@ object BookDetail extends StyleSheet.Inline {
)
val detail = style(
- display.flex
+ display.flex,
+ flexWrap.wrap,
+ justifyContent.center
)
val cover = style(
height(300.px),
- marginRight(30.px)
+ marginRight(30.px),
+ Media.mobile(marginBottom(30.px))
)
val item = style(
diff --git a/src/main/scala/reading/component/index/style/Books.scala b/src/main/scala/reading/component/index/style/Books.scala
index 34a7a83..79aea1a 100644
--- a/src/main/scala/reading/component/index/style/Books.scala
+++ b/src/main/scala/reading/component/index/style/Books.scala
@@ -2,22 +2,27 @@ package reading.component.index.style
import scalacss.Defaults._
+import reading.Media
+
object Books extends StyleSheet.Inline {
import dsl._
val books = style(
display.flex,
- flexWrap.wrap
+ flexWrap.wrap,
+ justifyContent.center
)
val book = style(
- width(250.px),
+ Media.desktop(width(250.px)),
+ Media.mobile(width(150.px)),
paddingBottom(60.px),
textAlign.center
)
val cover = style(
- height(250.px),
+ Media.desktop(height(250.px)),
+ Media.mobile(height(150.px)),
cursor.pointer
)
}
diff --git a/src/main/scala/reading/component/index/style/Count.scala b/src/main/scala/reading/component/index/style/Count.scala
new file mode 100644
index 0000000..cc1eb80
--- /dev/null
+++ b/src/main/scala/reading/component/index/style/Count.scala
@@ -0,0 +1,20 @@
+package reading.component.index.style
+
+import scalacss.Defaults._
+
+import reading.component.style.{ Color => C }
+
+object Count extends StyleSheet.Inline {
+ import dsl._
+
+ val count = style(
+ display.flex,
+ alignItems.center,
+ justifyContent.center,
+ backgroundColor(C.stiletto.value),
+ width(25.px),
+ height(25.px),
+ borderRadius(50.%%),
+ marginLeft(20.px)
+ )
+}
diff --git a/src/main/scala/reading/component/index/style/Filters.scala b/src/main/scala/reading/component/index/style/Filters.scala
deleted file mode 100644
index c324965..0000000
--- a/src/main/scala/reading/component/index/style/Filters.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-package reading.component.index.style
-
-import scalacss.Defaults._
-
-import reading.component.style.Col
-
-object Filters extends StyleSheet.Inline {
- import dsl._
-
- val filters = style(
- marginBottom(50.px),
- display.flex
- )
-
- val filter = style(
- display.flex,
- alignItems.center,
- padding(15.px),
- marginRight(20.px),
- borderRadius(2.px),
- &.hover(cursor.pointer),
- border(1.px, solid, Col.alto),
- fontSize(18.px)
- )
-
- val name = style(
- marginRight(10.px)
- )
-
- val cross = style(
- width(15.px),
- height(15.px)
- )
-}
diff --git a/src/main/scala/reading/component/index/style/FiltersMenu.scala b/src/main/scala/reading/component/index/style/FiltersMenu.scala
deleted file mode 100644
index 3fcc363..0000000
--- a/src/main/scala/reading/component/index/style/FiltersMenu.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-package reading.component.index.style
-
-import scalacss.Defaults._
-
-import reading.component.style.Col
-
-object FiltersMenu extends StyleSheet.Inline {
- import dsl._
-
- val groups = style(
- width(280.px)
- )
-
- val group = style(
- marginBottom(30.px)
- )
-
- val groupTitle = style(
- color(Col.congoBrown),
- fontWeight.bold,
- textTransform.uppercase,
- padding(10.px, 30.px, 15.px)
- )
-
- val filter = style(
- padding(10.px, 30.px)
- )
-}
diff --git a/src/main/scala/reading/component/index/style/Header.scala b/src/main/scala/reading/component/index/style/Header.scala
new file mode 100644
index 0000000..643dd8e
--- /dev/null
+++ b/src/main/scala/reading/component/index/style/Header.scala
@@ -0,0 +1,80 @@
+package reading.component.index.style
+
+import scalacss.Defaults._
+
+import reading.Media
+import reading.component.style.{ Color => C }
+
+object Header extends StyleSheet.Inline {
+ import dsl._
+
+ val header = style(
+ Media.desktop(margin(40.px)),
+ Media.mobile(margin(30.px))
+ )
+
+ val showFiltersMenu = style(
+ Media.desktop(display.none),
+ Media.mobile(
+ display.flex,
+ justifyContent.center,
+ alignItems.center,
+ width(100.%%),
+ backgroundColor(C.englishWalnut.value),
+ color(C.white.value),
+ border(1.px, solid, C.congoBrown.value),
+ borderRadius(4.px),
+ marginBottom(20.px),
+ padding(10.px, 0.px),
+ cursor.pointer
+ )
+ )
+
+ val filtersCount = style(
+ Count.count
+ )
+
+ val filters = style(
+ display.flex,
+ marginBottom(30.px),
+ Media.mobile(display.none)
+ )
+
+ private val box = style(
+ display.flex,
+ alignItems.center,
+ padding(15.px),
+ marginRight(20.px),
+ borderRadius(2.px),
+ border(1.px, solid, C.gray.lighten(80).value),
+ fontSize(18.px),
+ &.hover(cursor.pointer)
+ )
+
+ val clear = style(
+ box,
+ backgroundColor(C.mickado.value),
+ color(C.white.value),
+ &.hover(backgroundColor(C.mickado.lighten(20).value))
+ )
+
+ val filter = style(
+ box,
+ &.hover(borderColor(C.gray.lighten(50).value))
+ )
+
+ val name = style(
+ marginRight(10.px)
+ )
+
+ val cross = style(
+ width(15.px),
+ height(15.px)
+ )
+
+ val booksCount = style(
+ fontSize(20.px),
+ color(C.gray.value),
+ Media.mobile(textAlign.center)
+ )
+}
diff --git a/src/main/scala/reading/component/index/style/Menu.scala b/src/main/scala/reading/component/index/style/Menu.scala
new file mode 100644
index 0000000..38620e8
--- /dev/null
+++ b/src/main/scala/reading/component/index/style/Menu.scala
@@ -0,0 +1,97 @@
+package reading.component.index.style
+
+import scalacss.Defaults._
+
+import reading.Media
+import reading.component.style.{ Color => C }
+
+object Menu extends StyleSheet.Inline {
+ import dsl._
+
+ val menu = style(
+ Media.mobile(display.none),
+ backgroundColor(C.englishWalnut.value),
+ color(C.white.value),
+ width(280.px),
+ height(100.%%),
+ boxShadow := "4px 0px 6px -1px rgba(0, 0, 0, 0.2)"
+ )
+
+ val header = style(
+ display.flex,
+ alignItems.center,
+ justifyContent.center,
+ position.relative,
+ height(60.px),
+ backgroundColor(C.englishWalnut.darken(20).value),
+ color(C.white.value),
+ textTransform.uppercase,
+ fontWeight.bold,
+ letterSpacing(1.px),
+ marginBottom(20.px),
+ Media.mobile(boxShadow := "0px 3px 5px -1px rgba(0, 0, 0, 0.2)")
+ )
+
+ val close = style(
+ Media.desktop(display.none),
+ Media.mobile(
+ position.absolute,
+ top(0.px),
+ left(0.px),
+ width(100.%%),
+ height(100.%%),
+ cursor.pointer
+ )
+ )
+
+ val count = style(
+ Count.count
+ )
+
+ val show = style(
+ Media.mobile(
+ display.block,
+ position.fixed,
+ top(0.px),
+ left(0.px),
+ width(100.%%),
+ height(100.%%),
+ zIndex(1),
+ overflowY.scroll,
+ backgroundColor(C.white.value),
+ color(C.black.value)
+ )
+ )
+
+ val filterGroup = style()
+
+ private val filterCommon = style(
+ display.flex,
+ alignItems.center,
+ width(100.%%),
+ padding(5.px, 30.px),
+ textAlign.left
+ )
+
+ val filterTitle = style(
+ filterCommon,
+ minHeight(50.px),
+ fontWeight.bold,
+ textTransform.uppercase,
+ letterSpacing(1.px),
+ marginBottom(10.px)
+ )
+
+ val filter = style(
+ filterCommon,
+ marginLeft(10.px),
+ minHeight(40.px),
+ color.inherit,
+ &.lastChild(marginBottom(30.px))
+ )
+
+ val activeFilter = style(
+ color(C.stiletto.value),
+ cursor.pointer
+ )
+}
diff --git a/src/main/scala/reading/component/style/Color.scala b/src/main/scala/reading/component/style/Color.scala
index 85498de..1f44eb5 100644
--- a/src/main/scala/reading/component/style/Color.scala
+++ b/src/main/scala/reading/component/style/Color.scala
@@ -1,16 +1,47 @@
package reading.component.style
-import scalacss.Defaults._
+import scala.util.Try
+
+import scalacss.internal.{ ValueT, Color => ScalaCssColor }
+
+case class Color(red: Int, green: Int, blue: Int, alpha: Double = 1.0) {
+ val value: ValueT[ValueT.Color] = ScalaCssColor.rgba(red, green, blue, alpha)
+
+ def lighten(n: Int): Color =
+ Color(
+ red = Color.bound(red + n),
+ green = Color.bound(green + n),
+ blue = Color.bound(blue + n),
+ alpha = alpha
+ )
+
+ def darken(n: Int): Color =
+ Color(
+ red = Color.bound(red - n),
+ green = Color.bound(green - n),
+ blue = Color.bound(blue - n),
+ alpha = alpha
+ )
+}
// http://chir.ag/projects/name-that-color
-object Col extends StyleSheet.Inline {
- import dsl._
-
- val black = c"#000000"
- val white = c"#FFFFFF"
- val gray = c"#7E7E7E"
- val alto = c"#D4D1D1"
- val eastBay = c"#505080"
- val congoBrown = c"#57363E"
- val stiletto = c"#9C3336"
+object Color {
+ val black = Color.fromHex("#000000")
+ val mickado = Color.fromHex("#2D2510")
+ val white = Color.fromHex("#FFFFFF")
+ val gray = Color.fromHex("#808080")
+ val eastBay = Color.fromHex("#505080")
+ val congoBrown = Color.fromHex("#57363E")
+ val stiletto = Color.fromHex("#9C3336")
+ val englishWalnut = Color.fromHex("#3F2626")
+
+ def fromHex(hex: String, alpha: Double = 1.0) =
+ Color(
+ red = Try(Integer.parseInt(hex.slice(1, 3), 16)).getOrElse(0),
+ green = Try(Integer.parseInt(hex.slice(3, 5), 16)).getOrElse(0),
+ blue = Try(Integer.parseInt(hex.slice(5, 7), 16)).getOrElse(0),
+ alpha = alpha
+ )
+
+ def bound(n: Int): Int = Math.max(0, Math.min(255, n))
}
diff --git a/src/main/scala/reading/component/style/Global.scala b/src/main/scala/reading/component/style/Global.scala
index 861b78a..db7ef34 100644
--- a/src/main/scala/reading/component/style/Global.scala
+++ b/src/main/scala/reading/component/style/Global.scala
@@ -2,27 +2,43 @@ package reading.component.style
import scalacss.Defaults._
+import reading.component.style.{ Color => C }
+
object Global extends StyleSheet.Standalone {
import dsl._
- "html" -
+ "html" - (
boxSizing.borderBox
+ )
+
+ "body" - (
+ position.absolute,
+ top(0.px),
+ right(0.px),
+ bottom(0.px),
+ left(0.px)
+ )
+
+ "body > *" - (
+ minHeight(100.%%)
+ )
"a" - (
- color(Col.eastBay),
+ color(C.eastBay.value),
&.hover(
textDecoration := "underline"
)
)
- "*, *:before, *:after" -
+ "*, *:before, *:after" - (
boxSizing.inherit
+ )
"button" - (
cursor.pointer,
display.flex,
backgroundColor(initial),
- color(Col.black),
+ color(C.black.value),
border.none
)
}
diff --git a/src/main/scala/reading/component/style/Index.scala b/src/main/scala/reading/component/style/Index.scala
index 8f31683..9f1d261 100644
--- a/src/main/scala/reading/component/style/Index.scala
+++ b/src/main/scala/reading/component/style/Index.scala
@@ -5,22 +5,12 @@ import scalacss.Defaults._
object Index extends StyleSheet.Inline {
import dsl._
- val header = style(
- fontSize(40.px),
- color(Col.congoBrown),
- textAlign.center,
- margin(10.px, auto, 30.px),
- padding(20.px),
- &.hover(
- textDecoration := "none"
- )
- )
-
val page = style(
- display.flex
+ display.flex,
+ minHeight(inherit)
)
val main = style(
- marginLeft(20.px)
+ width(100.%%)
)
}
diff --git a/src/main/scala/reading/component/widget/Popup.scala b/src/main/scala/reading/component/widget/Popup.scala
index 67e6a4c..f47bc1c 100644
--- a/src/main/scala/reading/component/widget/Popup.scala
+++ b/src/main/scala/reading/component/widget/Popup.scala
@@ -10,7 +10,7 @@ import scalacss.Defaults._
import scalacss.ScalatagsCss._
import reading.component.widget.style.{ Popup => PopupStyle }
-import reading.component.style.Col
+import reading.component.style.{ Color => C }
import reading.utils.{ RxAttr }
object Popup {
@@ -32,7 +32,7 @@ object Popup {
button(
PopupStyle.cross,
RxAttr(onclick, Rx(() => close(onClose))),
- Cross(20.px, Col.stiletto)
+ Cross(20.px, C.stiletto.value)
)
)
)
diff --git a/src/main/scala/reading/component/widget/style/Popup.scala b/src/main/scala/reading/component/widget/style/Popup.scala
index 422e3bd..ea67d9e 100644
--- a/src/main/scala/reading/component/widget/style/Popup.scala
+++ b/src/main/scala/reading/component/widget/style/Popup.scala
@@ -2,7 +2,8 @@ package reading.component.widget.style
import scalacss.Defaults._
-import reading.component.style.Col
+import reading.Media
+import reading.component.style.{ Color => C }
object Popup extends StyleSheet.Inline {
import dsl._
@@ -21,22 +22,33 @@ object Popup extends StyleSheet.Inline {
)
val curtain = style(
- width(100.%%),
- height(100.%%),
- position.absolute,
- top(0.px),
- left(0.px),
- backgroundColor(Col.black),
- opacity(0.5),
- cursor.pointer
+ Media.desktop(
+ width(100.%%),
+ height(100.%%),
+ position.absolute,
+ top(0.px),
+ left(0.px),
+ backgroundColor(C.black.value),
+ opacity(0.5),
+ cursor.pointer
+ ),
+ Media.mobile(
+ display.none
+ )
)
val content = style(
position.relative,
- width(50.%%),
- backgroundColor(Col.white),
- padding(30.px),
- borderRadius(5.px)
+ backgroundColor(C.white.value),
+ Media.desktop(
+ width(50.%%),
+ borderRadius(5.px)
+ ),
+ Media.mobile(
+ width(100.%%),
+ height(100.%%)
+ ),
+ padding(30.px)
)
val cross = style(