# HG changeset patch # User Tomas Zeman # Date 1609106073 -3600 # Node ID fe846f058e413f1f998d33ddf28207da42a8366c # Parent f30a3e4658368010a979b8eefca6bdd5956d9a3e pure-extras: example, publish(M2)Local/compileAll. diff -r f30a3e465836 -r fe846f058e41 build.sc --- a/build.sc Sat Dec 26 21:46:29 2020 +0100 +++ b/build.sc Sun Dec 27 22:54:33 2020 +0100 @@ -8,6 +8,7 @@ * ./mill mill.scalalib.GenIdea/idea * */ +import ammonite.ops import mill._ import mill.api.Loose import mill.define.{Command, Input, Sources, Target} @@ -28,8 +29,24 @@ object D { val scalatags211 = ivy"com.lihaoyi::scalatags::0.6.8" val scalatags = ivy"com.lihaoyi::scalatags::${V.scalatags}" + val scalatex = ivy"org.openmole::scalatex-api:0.4.6" + val oslib = ivy"com.lihaoyi::os-lib::0.7.1" } +val compilerOptions = Seq( + "-deprecation", // Emit warning and location for usages of deprecated APIs. + "-encoding", "utf-8", // Specify character encoding used by source files. + "-explaintypes", // Explain type errors in more detail. + "-feature", // Emit warning and location for usages of features that should be imported explicitly. + "-language:higherKinds", // Allow higher-kinded types + "-language:implicitConversions", // Allow definition of implicit functions called views + "-language:reflectiveCalls", + "-language:postfixOps", + "-unchecked", // Enable additional warnings where generated code depends on assumptions. + "-Xcheckinit", // Wrap field accessors to throw an exception on uninitialized access. + "-target:jvm-1.8" + ) + trait Common extends CrossSbtModule with PublishModule { def pomSettings: T[PomSettings] = PomSettings( @@ -46,19 +63,7 @@ override def artifactName = "purecss" - override def scalacOptions = T{Seq( - "-deprecation", // Emit warning and location for usages of deprecated APIs. - "-encoding", "utf-8", // Specify character encoding used by source files. - "-explaintypes", // Explain type errors in more detail. - "-feature", // Emit warning and location for usages of features that should be imported explicitly. - "-language:higherKinds", // Allow higher-kinded types - "-language:implicitConversions", // Allow definition of implicit functions called views - "-language:reflectiveCalls", - "-language:postfixOps", - "-unchecked", // Enable additional warnings where generated code depends on assumptions. - "-Xcheckinit", // Wrap field accessors to throw an exception on uninitialized access. - "-target:jvm-1.8" - )} + override def scalacOptions = T{compilerOptions} def hgId: Input[String] = T.input { os.proc("hg", "id", "-i").call().out.text.trim @@ -106,6 +111,35 @@ V.scala213 -> V.scalaJs ) +object extras extends Module { + + val name = "pure-extras" + + class JvmModule(val crossScalaVersion: String) extends Common { + override def artifactName = name + } + + class JsModule(val crossScalaVersion: String, crossJSVersion: String) + extends ScalaJSModule with Common { + + override def scalaJSVersion: Target[String] = crossJSVersion + + override def millSourcePath = super.millSourcePath / os.up + + override def artifactName = name + } + + object jvm extends Cross[JvmModule](V.scala211, V.scala212, V.scala213) + object js extends Cross[JsModule]( + V.scala211 -> V.scalaJs06, + V.scala212 -> V.scalaJs06, + V.scala212 -> V.scalaJs, + V.scala213 -> V.scalaJs06, + V.scala213 -> V.scalaJs + ) + +} + def compileAll(): Command[Unit] = T.command{ jvm(V.scala213).compile() js(V.scala213, V.scalaJs).compile() @@ -115,6 +149,14 @@ js(V.scala212, V.scalaJs06).compile() jvm(V.scala211).compile() js(V.scala211, V.scalaJs06).compile() + extras.jvm(V.scala213).compile() + extras.js(V.scala213, V.scalaJs).compile() + extras.js(V.scala213, V.scalaJs06).compile() + extras.jvm(V.scala212).compile() + extras.js(V.scala212, V.scalaJs).compile() + extras.js(V.scala212, V.scalaJs06).compile() + extras.jvm(V.scala211).compile() + extras.js(V.scala211, V.scalaJs06).compile() () } @@ -127,6 +169,14 @@ js(V.scala212, V.scalaJs06).publishLocal()() jvm(V.scala211).publishLocal()() js(V.scala211, V.scalaJs06).publishLocal()() + extras.jvm(V.scala213).publishLocal()() + extras.js(V.scala213, V.scalaJs).publishLocal()() + extras.js(V.scala213, V.scalaJs06).publishLocal()() + extras.jvm(V.scala212).publishLocal()() + extras.js(V.scala212, V.scalaJs).publishLocal()() + extras.js(V.scala212, V.scalaJs06).publishLocal()() + extras.jvm(V.scala211).publishLocal()() + extras.js(V.scala211, V.scalaJs06).publishLocal()() } def publishM2Local(p: os.Path): Command[Unit] = T.command{ @@ -138,28 +188,77 @@ js(V.scala212, V.scalaJs06).publishM2Local(p.toString)() jvm(V.scala211).publishM2Local(p.toString)() js(V.scala211, V.scalaJs06).publishM2Local(p.toString)() + extras.jvm(V.scala213).publishM2Local(p.toString)() + extras.js(V.scala213, V.scalaJs).publishM2Local(p.toString)() + extras.js(V.scala213, V.scalaJs06).publishM2Local(p.toString)() + extras.jvm(V.scala212).publishM2Local(p.toString)() + extras.js(V.scala212, V.scalaJs).publishM2Local(p.toString)() + extras.js(V.scala212, V.scalaJs06).publishM2Local(p.toString)() + extras.jvm(V.scala211).publishM2Local(p.toString)() + extras.js(V.scala211, V.scalaJs06).publishM2Local(p.toString)() () } -object extras extends Module { +object example extends ScalaModule { + override def scalaVersion: T[String] = V.scala213 + + override def scalacOptions = T{compilerOptions} + + override def moduleDeps = Seq(jvm(V.scala213), extras.jvm(V.scala213)) + + override def ivyDeps = Agg(D.scalatex, D.oslib) - class JvmModule(val crossScalaVersion: String) extends Common - class JsModule(val crossScalaVersion: String, crossJSVersion: String) - extends ScalaJSModule with Common { + override def generatedSources: Target[Seq[PathRef]] = T{ + val dir = T.ctx().dest + val src = sources() map(_.path) + val ids = src flatMap(ops.ls! _ filter(_.ext == "scalatex") map { p => + val id = p.last replaceAllLiterally (".scalatex", "") + os.write(dir / s"$id.scala", + s""" + | package example + | import scalatags.Text.all._ + | import scalatex._ + | import purecss.Extras + | import purecss.text.PureCss._ + | object `$id` { + | val id = "$id" + | val content = twf("${p.toString}") + | } + | + |/* + |${os.read(p)} + |*/ + """.stripMargin) + id + }) - override def scalaJSVersion: Target[String] = crossJSVersion + os.write(dir / "initializer.scala", + s""" + | package example + | trait ContentInitializer { + | Seq(${ids mkString("`", "`, `", "`")}) + | } + """.stripMargin) - override def millSourcePath = super.millSourcePath / os.up + os.write(dir / "main.scala", + s""" + | package example + | import os.Path + | object A extends ExampleApp with App { + | override def export: Path = Path("${exportDir().path}") + | } + """.stripMargin) + + Seq(PathRef(dir)) } - object jvm extends Cross[JvmModule](V.scala211, V.scala212, V.scala213) - object js extends Cross[JsModule]( - V.scala211 -> V.scalaJs06, - V.scala212 -> V.scalaJs06, - V.scala212 -> V.scalaJs, - V.scala213 -> V.scalaJs06, - V.scala213 -> V.scalaJs - ) + override def mainClass: T[Option[String]] = Some("example.A") + + def exportDir = T{ + val dir = T.ctx().dest + PathRef(dir) + } } + // vim: et ts=2 sw=2 syn=scala diff -r f30a3e465836 -r fe846f058e41 example/src/example/ExampleApp.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/src/example/ExampleApp.scala Sun Dec 27 22:54:33 2020 +0100 @@ -0,0 +1,44 @@ +/* + * Copyright 2020 Tomas Zeman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package example + +import os.Path +import purecss.Extras +import scalatags.Text.all._ +import scalatags.Text.tags2 + +trait ExampleApp extends ContentInitializer { + + def export: Path + + os.write.over(export / s"${`extras`.id}.html", + "" + html(head( + meta(charset:="utf-8"), + meta(name:="viewport", content:="width=device-width, initial-scale=1.0"), + tags2.title(s"Example of ${`extras`.id} | PureCSS"), + link(href:="https://unpkg.com/purecss@2.0.3/build/pure-min.css", + rel:="stylesheet", tpe:="text/css"), + tags2.style(Extras.styleSheetText) + ), body( + `extras`.content + )) + ) + + println( + s"""Please open your browser at + |file:///$export + |""".stripMargin) +} diff -r f30a3e465836 -r fe846f058e41 example/src/extras.scalatex --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/src/extras.scalatex Sun Dec 27 22:54:33 2020 +0100 @@ -0,0 +1,289 @@ +@val img200 = src:="http://placehold.it/200x200" +@val img250 = img(src:="http://placehold.it/250x250") +@val sasquatch = img(src:="http://dribbble.s3.amazonaws.com/users/4467/screenshots/661196/sasquatch-troop-full.jpg") + +@div + @h1 + Pure Extras + @h2 + CSS styles for images, thumbnails, badges, contextual menus and alerts. + Depends on Pure CSS. + @p + Pure-Scala 1:1 reimplementation of + @a(href:="http://github.com/tilomitra/cssextras", "pure-extras"). + + @h2 + Images + @p + Styling of three different types are available for images, eliptical, + rounded, bordered. To use them, just add one of these classes to the + @code(raw("<img>")) tag. + + @div(pure.g) + @div(pure.u_1_3) + @img(Extras.pure_img_elliptical, width:="200", height:="150", + src:="http://dribbble.s3.amazonaws.com/users/9418/screenshots/928345/suhio_shoot.png") + @div(pure.u_1_3) + @img(Extras.pure_img_rounded, width:="200", height:="150", + src:="http://dribbble.s3.amazonaws.com/users/9418/screenshots/928345/suhio_shoot.png") + @div(pure.u_1_3) + @img(Extras.pure_img_bordered, width:="200", height:="150", + src:="http://dribbble.s3.amazonaws.com/users/9418/screenshots/928345/suhio_shoot.png") + + @p + When using class @code("Extras.pure_img_elliptical"), if the width and + height of the image are equal, it will appear as a circle. Otherwise, it + will appear as an ellipse. + @img(Extras.pure_img_elliptical, width:="200", height:="200", img200) + + @h2 + Thumbnails + @p + Add the class @code("Extras.pure_thumbnails") to the container + @code(raw("<ul>")). Then add one of the classes, + @code("Extras.pure_thumb_elliptical"), @code("Extras.pure_thumb_rounded"), + or @code("Extras.pure_thumb_bordered"), to the @code(raw("<a>")). + + @ul(Extras.pure_thumbnails, pure.g) + @li(pure.u_1_4) + @a(Extras.pure_thumb, Extras.pure_thumb_elliptical, href:="#") + @img250 + @li(pure.u_1_4) + @a(Extras.pure_thumb, Extras.pure_thumb_rounded, href:="#") + @img250 + @li(pure.u_1_4) + @a(Extras.pure_thumb, Extras.pure_thumb_bordered, href:="#") + @img250 + @li(pure.u_1_4) + @a(Extras.pure_thumb, Extras.pure_thumb_bordered, href:="#") + @img250 + @div(Extras.caption_) + @h3(Extras.caption_head) + Rocket – game concept + @p + This is a great shot from Jozef Mak from Dribbble. + + @p + Adding a @code("div(Extras.caption_)") allows you to customize the + thumbnail with additional content. + + @p + If you have YUI grids on the page, add @code("pure_u_*") for multi-column + thumbnails that scale to fit the columns. + + @ul(Extras.pure_thumbnails, pure.g) + @li(pure.u_1_4) + @a(Extras.pure_thumb, Extras.pure_thumb_elliptical, href:="#") + @sasquatch + @li(pure.u_1_4) + @a(Extras.pure_thumb, Extras.pure_thumb_rounded, href:="#") + @sasquatch + @li(pure.u_1_4) + @a(Extras.pure_thumb, href:="#") + @sasquatch + @li(pure.u_1_4) + @a(Extras.pure_thumb, Extras.pure_thumb_bordered, href:="#") + @sasquatch + @div(Extras.caption_) + @h3(Extras.caption_head) + Thumbnail label + @p + Curabitur et sapien ac diam pharetra lacinia quis ac tortor. + Suspendisse dictum fermentum dui at mollis. Nunc pulvinar blandit + diam in vehicula. + + @h2 + Badges + @p + To create a badge, use a @code("span") tag, and add one of the badge + classes as shown below. + + @span(Extras.pure_badge) + A badge + @span(Extras.pure_badge_success) + Success badge + @span(Extras.pure_badge_warning) + Warning badge + @span(Extras.pure_badge_error) + Badges can have a bunch of content + @span(Extras.pure_badge_info) + Info badge + @span(Extras.pure_badge_inverse) + or not much at all. + + @h2 + Alerts + @p + Create alerts by adding a class to it's @code("div"). + + @h3 + Default Alert + @p + The default alert can be set by adding the @code("Extras.pure_alert") class name. + @div(Extras.pure_alert) + @label + Welcome back, Tilo. + + @h3 + Error Alert + @p + Alerts in red have the connotation of something going wrong. The error + alert can be set by appending the @code("Extras.pure_alert_error") class name + in addition to the @code("Extras.pure_alert"). + @div(Extras.pure_alert, Extras.pure_alert_error) + @label(strong("Breaking News")) + 'Most' of Atlanic City Underwater. Atlantic City Boardwalk Destroyed by Sandy. + + @h3 + Warning Alert + @p + If you want to send a warning notification, use the warning alert. It can + be set by appending the @code("Extras.pure_alert_warning") class name in + addition to the @code("Extras.pure_alert"). + @div(Extras.pure_alert, Extras.pure_alert_warning) + @label(strong("Update")) + Looks like you like the Green Bay Packers so we added the team to your Sports App! + + @h3 + Success Alert + @p + Mission successful? Use the Success Alert! It can be set by appending the + @code("Extras.pure_alert_success") in addition to the + @code("Extras.pure_alert"). + @div(Extras.pure_alert, Extras.pure_alert_success) + @label(strong("New Badge Unlocked!")) + You unlocked the "Paradise" badge! + + @h2 + Contextual Modals + + @div(pure.g) + @div(pure.u_1_2) + @h3 + Bottom Arrow + @div(Extras.pure_popover, Extras.pure_popover_bottom) + @div + @p + You have no new notifications. + @p + Receive notifications when you comment or discuss content with + friends on Yahoo! + @p + @a(pure.button, Extras.pure_button_block, href:="#") + Learn More + @div(Extras.pure_arrow_border) + @div(Extras.pure_arrow) + @div(pure.u_1_2) + @h3 + Left Arrow + @div(Extras.pure_popover, Extras.pure_popover_left) + @div + @p + You have no new notifications. + @p + Receive notifications when you comment or discuss content with + friends on Yahoo! + @p + @a(pure.button, Extras.pure_button_block, href:="#") + Learn More + @div(Extras.pure_arrow_border) + @div(Extras.pure_arrow) + + @div(pure.g) + @div(pure.u_1_2) + @h3 + Top Arrow + @div(Extras.pure_popover, Extras.pure_popover_top) + @div + @p + You have no new notifications. + @p + Receive notifications when you comment or discuss content with + friends on Yahoo! + @p + @a(pure.button, Extras.pure_button_block, href:="#") + Learn More + @div(Extras.pure_arrow_border) + @div(Extras.pure_arrow) + @div(pure.u_1_2) + @h3 + Right Arrow + @div(Extras.pure_popover, Extras.pure_popover_right) + @div + @p + You have no new notifications. + @p + Receive notifications when you comment or discuss content with + friends on Yahoo! + @p + @a(pure.button, Extras.pure_button_block, href:="#") + Learn More + @div(Extras.pure_arrow_border) + @div(Extras.pure_arrow) + + @h2 + Contextual Modals with Grids + @p + You can use grids within these contextual menus for interesting effects. + @div(pure.g) + @div(pure.u_1) + @h4 + You have mail. + @div(Extras.pure_popover, Extras.pure_popover_bottom, width:="70%") + @div(pure.g) + @div(pure.u_1_5) + @strong + Yahoo! Mail + @div(pure.u_3_5) + You have 3 new messages. + @div(pure.u_1_5, cls:="text-right") + @a(pure.button, Extras.pure_button_small, href:="#") + Read + @div(Extras.pure_arrow_border) + @div(Extras.pure_arrow) + + @h2 + Buttons + @h3 + Button Types + @p + @a(pure.button) + A regular button + @a(pure.button, Extras.pure_button_selected) + Selected + @p + @a(pure.button, Extras.pure_button_secondary) + Secondary + @a(pure.button, Extras.pure_button_error) + Error + @a(pure.button, Extras.pure_button_success) + Success + @a(pure.button, Extras.pure_button_warning) + Warning + @p + @a(pure.button, Extras.pure_button_block) + Block + + @h3 + Button Sizes + @p + Large buttons have twice the padding of regular buttons. Apply the + @code("Extras.pure_button_large"). + @a(pure.button, Extras.pure_button_large) + Big click target + @a(pure.button, Extras.pure_button_success, Extras.pure_button_large) + Big Success + + @p + Small buttons have half the padding of regular buttons. Apply the + @code("Extras.pure_button_small"). + @a(pure.button, Extras.pure_button_small) + Smaller target + @a(pure.button, Extras.pure_button_secondary, Extras.pure_button_small) + Smaller Secondary Button + @a(pure.button, Extras.pure_button_warning, Extras.pure_button_small) + Smaller Warning Button + @a(pure.button, Extras.pure_button_error, Extras.pure_button_small) + Smaller Error Button + +// vim: et ts=2 sw=2 syn=scala diff -r f30a3e465836 -r fe846f058e41 extras/shared/src/main/scala/purecss/Extras.scala --- a/extras/shared/src/main/scala/purecss/Extras.scala Sat Dec 26 21:46:29 2020 +0100 +++ b/extras/shared/src/main/scala/purecss/Extras.scala Sun Dec 27 22:54:33 2020 +0100 @@ -23,7 +23,7 @@ /* * https://github.com/tilomitra/cssextras/blob/master/css/pure-extras.css */ -object Extras extends CascadingStyleSheet { +trait Extras extends CascadingStyleSheet { initStyleSheet() /* Images. */ @@ -96,6 +96,10 @@ border:="1px solid rgba(0, 0, 0, 0.2)" ) + val pure_thumb_elliptical: Cls = cls(img(borderRadius:="50%")) + + val pure_thumb_rounded: Cls = cls(img(borderRadius:=3)) + /* Badges/Pills */ private val badge_common = immutable.Seq[StyleSheetFrag]( padding:="0.35em 0.9em 0.35em", @@ -151,7 +155,7 @@ val left_ : Cls = cls() private val arrow_common = immutable.Seq[StyleSheetFrag]( borderStyle:="solid", - borderWidth:=10, + borderWidth:="10px", height:=0, width:=0, position.absolute @@ -171,61 +175,61 @@ // box-padding: border-box; // -webkit-background-clip: padding-box; // -moz-background-clip: padding; - backgroundClip.`padding-box`, - bottom_( - pure_arrow_border( - borderColor:="#bfc0c8 transparent transparent transparent", - bottom:="-20px", - left:="50%" - ), - pure_arrow( - borderColor:="#f0f1f3 transparent transparent transparent", - bottom:="-19px", - left:="50%" - ) + backgroundClip.`padding-box` + ) + val pure_popover_bottom: Cls = cls( + pure_arrow_border( + borderColor:="#bfc0c8 transparent transparent transparent", + bottom:="-20px", + left:="50%" + ), + pure_arrow( + borderColor:="#f0f1f3 transparent transparent transparent", + bottom:="-19px", + left:="50%" + ) + ) + val pure_popover_top: Cls = cls( + pure_arrow_border( + borderColor:="transparent transparent #bfc0c8 transparent", + top:="-21px", + left:="50%" ), - top_( - pure_arrow_border( - borderColor:="transparent transparent #bfc0c8 transparent", - top:="-21px", - left:="50%" - ), - pure_arrow( - borderColor:="transparent transparent #f0f1f3 transparent", - top:="-20px", - left:="50%" - ) + pure_arrow( + borderColor:="transparent transparent #f0f1f3 transparent", + top:="-20px", + left:="50%" + ) + ) + val pure_popover_right: Cls = cls( + pure_arrow_border( + borderColor:="transparent transparent transparent #bfc0c8", + top:="45%", + right:="-21px" ), - right_( - pure_arrow_border( - borderColor:="transparent transparent transparent #bfc0c8", - top:="45%", - right:="-21px" - ), - pure_arrow( - borderColor:="transparent transparent transparent #f0f1f3", - top:="45%", - right:="-20px" - ) + pure_arrow( + borderColor:="transparent transparent transparent #f0f1f3", + top:="45%", + right:="-20px" + ) + ) + val pure_popover_left: Cls = cls( + pure_arrow_border( + borderColor:="transparent #bfc0c8 transparent transparent", + top:="45%", + left:="-21px" ), - left_( - pure_arrow_border( - borderColor:="transparent #bfc0c8 transparent transparent", - top:="45%", - left:="-21px" - ), - pure_arrow( - borderColor:="transparent #f0f1f3 transparent transparent", - top:="45%", - left:="-20px" - ) + pure_arrow( + borderColor:="transparent #f0f1f3 transparent transparent", + top:="45%", + left:="-20px" ) ) /* BUTTON IMPROVEMENTS */ val pure_button_block: Cls = cls(display.block) val pure_button_small: Cls = cls(padding:=".6em 2em .65em", fontSize:="70%") - val pure_button_large: Cls = cls(padding:=".8em 5em .9em", fontSize:="70%") + val pure_button_large: Cls = cls(padding:=".8em 5em .9em", fontSize:="110%") val pure_button_selected: Cls = cls(backgroundColor:="#345fcb", color:="#fff") val pure_button_secondary: Cls = cls(background:="rgb(161, 195, 238)", color:="rgb(26, 88, 122)") @@ -236,3 +240,5 @@ cls(background:="rgb(255, 163, 0)", color.white) } + +object Extras extends Extras \ No newline at end of file