feat(14): controls generated from fragment
with their own ids and htmx requests to submit the vote
This commit is contained in:
parent
560ce6896a
commit
69a464a767
|
@ -522,6 +522,10 @@ video {
|
||||||
--tw-backdrop-sepia: ;
|
--tw-backdrop-sepia: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.static {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
|
||||||
.fixed {
|
.fixed {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,21 @@
|
||||||
id="controls"
|
id="controls"
|
||||||
class="bg-center bg-no-repeat bg-60% bg-triangle-pattern w-[375px] h-[375px] relative"
|
class="bg-center bg-no-repeat bg-60% bg-triangle-pattern w-[375px] h-[375px] relative"
|
||||||
>
|
>
|
||||||
|
<!-- This control will be repeated 3 times, with different htmx requests -->
|
||||||
<div
|
<div
|
||||||
|
th:each="choiceBadgeData : ${choiceBadges}"
|
||||||
|
id="paper-control"
|
||||||
|
th:id="${choiceBadgeData.c.name} + '-control'"
|
||||||
|
hx-get="/select/paper"
|
||||||
|
th:hx-get="'/select/' + ${choiceBadgeData.c.name}"
|
||||||
|
hx-target="#controls"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
>
|
||||||
|
<!-- This badge is fragment to be repeated in other pages as well -->
|
||||||
|
<div
|
||||||
|
th:fragment="choiceBadge (choiceBadgeData)"
|
||||||
id="paper"
|
id="paper"
|
||||||
|
th:id="${choiceBadgeData.c.name}"
|
||||||
class="top-[var(--top-offset)] left-[var(--left-offset)] w-[var(--diameter)] h-[var(--diameter)] bg-gradient-to-b rounded-full -translate-x-[var(--translation)] -translate-y-[var(--translation)] from-[var(--bg-bright)] to-[var(--bg-dark)]"
|
class="top-[var(--top-offset)] left-[var(--left-offset)] w-[var(--diameter)] h-[var(--diameter)] bg-gradient-to-b rounded-full -translate-x-[var(--translation)] -translate-y-[var(--translation)] from-[var(--bg-bright)] to-[var(--bg-dark)]"
|
||||||
style="
|
style="
|
||||||
--diameter: 8rem;
|
--diameter: 8rem;
|
||||||
|
@ -73,20 +86,25 @@
|
||||||
--translation: 50%;
|
--translation: 50%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
"
|
"
|
||||||
hx-get="/select/paper"
|
th:style="| --diameter: ${choiceBadgeData.c.diameter};
|
||||||
hx-target="#controls"
|
--bg-dark: ${choiceBadgeData.c.bgDark};
|
||||||
hx-swap="outerHTML"
|
--bg-bright: ${choiceBadgeData.c.bgBright};
|
||||||
|
${choiceBadgeData.p.toStyle}; |"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="absolute top-1/2 left-1/2 w-3/4 h-3/4 bg-gradient-to-b from-gray-300 to-gray-100 rounded-full -translate-x-1/2 -translate-y-1/2"
|
class="absolute top-1/2 left-1/2 w-3/4 h-3/4 bg-gradient-to-b from-gray-300 to-gray-100 rounded-full -translate-x-1/2 -translate-y-1/2"
|
||||||
></div>
|
></div>
|
||||||
<img
|
<img
|
||||||
src="../public/images/icon-paper.svg"
|
src="../public/images/icon-paper.svg"
|
||||||
|
th:src="${choiceBadgeData.c.iconPath}"
|
||||||
class="absolute top-1/2 left-1/2 w-1/3 -translate-x-1/2 -translate-y-1/2"
|
class="absolute top-1/2 left-1/2 w-1/3 -translate-x-1/2 -translate-y-1/2"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- This controls is only for static preview -->
|
||||||
<div
|
<div
|
||||||
|
th:remove="all"
|
||||||
id="scissors"
|
id="scissors"
|
||||||
class="top-[var(--top-offset)] left-[var(--left-offset)] w-[var(--diameter)] h-[var(--diameter)] bg-gradient-to-b rounded-full -translate-x-[var(--translation)] -translate-y-[var(--translation)] from-[var(--bg-bright)] to-[var(--bg-dark)]"
|
class="top-[var(--top-offset)] left-[var(--left-offset)] w-[var(--diameter)] h-[var(--diameter)] bg-gradient-to-b rounded-full -translate-x-[var(--translation)] -translate-y-[var(--translation)] from-[var(--bg-bright)] to-[var(--bg-dark)]"
|
||||||
style="
|
style="
|
||||||
|
@ -108,7 +126,9 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- This controls is only for static preview -->
|
||||||
<div
|
<div
|
||||||
|
th:remove="all"
|
||||||
id="rock"
|
id="rock"
|
||||||
class="top-[var(--top-offset)] left-[var(--left-offset)] w-[var(--diameter)] h-[var(--diameter)] bg-gradient-to-b rounded-full -translate-x-[var(--translation)] -translate-y-[var(--translation)] from-[var(--bg-bright)] to-[var(--bg-dark)]"
|
class="top-[var(--top-offset)] left-[var(--left-offset)] w-[var(--diameter)] h-[var(--diameter)] bg-gradient-to-b rounded-full -translate-x-[var(--translation)] -translate-y-[var(--translation)] from-[var(--bg-bright)] to-[var(--bg-dark)]"
|
||||||
style="
|
style="
|
||||||
|
|
|
@ -47,10 +47,10 @@ object Main {
|
||||||
@cask.get("/")
|
@cask.get("/")
|
||||||
def index(req: cask.Request) = {
|
def index(req: cask.Request) = {
|
||||||
val context = new Context()
|
val context = new Context()
|
||||||
println(s"getting request for ${req.remainingPathSegments}")
|
val choices = Models.choiceSelectionItems.asJava
|
||||||
context.setVariable(
|
context.setVariable(
|
||||||
"myVar",
|
"choiceBadges",
|
||||||
"Hello, from Scala world!"
|
choices
|
||||||
)
|
)
|
||||||
val result = templateEngine.process("index", context)
|
val result = templateEngine.process("index", context)
|
||||||
cask.Response(
|
cask.Response(
|
||||||
|
|
|
@ -6,14 +6,14 @@ object Models {
|
||||||
sealed trait Positioning
|
sealed trait Positioning
|
||||||
object Positioning {
|
object Positioning {
|
||||||
case object Relative extends Positioning {
|
case object Relative extends Positioning {
|
||||||
override def toString(): String = " position: absolute; "
|
def toStyle(): String = " position: absolute; "
|
||||||
}
|
}
|
||||||
final case class Absolute(
|
final case class Absolute(
|
||||||
topOffset: String,
|
topOffset: String,
|
||||||
leftOffset: String,
|
leftOffset: String,
|
||||||
translation: String = "50%"
|
translation: String = "50%"
|
||||||
) extends Positioning {
|
) extends Positioning {
|
||||||
override def toString(): String =
|
def toStyle(): String =
|
||||||
s"""
|
s"""
|
||||||
--top-offset: $topOffset;
|
--top-offset: $topOffset;
|
||||||
--left-offset: $leftOffset;
|
--left-offset: $leftOffset;
|
||||||
|
@ -27,6 +27,8 @@ position: absolute;
|
||||||
def diameter: String
|
def diameter: String
|
||||||
def bgDark: String
|
def bgDark: String
|
||||||
def bgBright: String
|
def bgBright: String
|
||||||
|
def name: String
|
||||||
|
def iconPath: String
|
||||||
}
|
}
|
||||||
object Choice {
|
object Choice {
|
||||||
val scissorsDark = "hsl(39, 89%, 49%)"
|
val scissorsDark = "hsl(39, 89%, 49%)"
|
||||||
|
@ -40,39 +42,44 @@ position: absolute;
|
||||||
diameter: String,
|
diameter: String,
|
||||||
bgDark: String = paperDark,
|
bgDark: String = paperDark,
|
||||||
bgBright: String = paperBright
|
bgBright: String = paperBright
|
||||||
) extends Choice
|
) extends Choice {
|
||||||
|
def name: String = "paper"
|
||||||
|
def iconPath: String = "public/images/icon-paper.svg"
|
||||||
|
}
|
||||||
case class Scissors(
|
case class Scissors(
|
||||||
diameter: String,
|
diameter: String,
|
||||||
bgDark: String = scissorsDark,
|
bgDark: String = scissorsDark,
|
||||||
bgBright: String = scissorsBright
|
bgBright: String = scissorsBright
|
||||||
) extends Choice
|
) extends Choice {
|
||||||
|
def name: String = "scissors"
|
||||||
|
def iconPath: String = "public/images/icon-scissors.svg"
|
||||||
|
}
|
||||||
case class Rock(
|
case class Rock(
|
||||||
diameter: String,
|
diameter: String,
|
||||||
bgDark: String = rockDark,
|
bgDark: String = rockDark,
|
||||||
bgBright: String = rockBright
|
bgBright: String = rockBright
|
||||||
) extends Choice
|
) extends Choice {
|
||||||
|
def name: String = "rock"
|
||||||
|
def iconPath: String = "public/images/icon-rock.svg"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** this will be Data Transfer Object, because Thymeleaf wants var and i want
|
||||||
* this will be Data Transfer Object, because Thymeleaf wants var and Bean Object Notation
|
* vals and enums
|
||||||
* and i want vals and enums
|
|
||||||
*/
|
*/
|
||||||
final class ChoiceBadge(
|
final case class ChoiceBadge(
|
||||||
var diameter: String = "",
|
var c: Choice,
|
||||||
var bgDark: String = "",
|
var p: Positioning
|
||||||
var bgBright: String = "",
|
)
|
||||||
var positioningStyle: String = "",
|
|
||||||
) {
|
|
||||||
def this(c: Choice, p: Positioning) = {
|
|
||||||
this(c.diameter, c.bgDark, c.bgBright, p.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val choiceSelectionItems = {
|
val choiceSelectionItems = {
|
||||||
List(
|
List(
|
||||||
ChoiceBadge(Choice.Paper("8rem"), Positioning.Absolute("6rem", "6rem")),
|
ChoiceBadge(Choice.Paper("8rem"), Positioning.Absolute("6rem", "6rem")),
|
||||||
ChoiceBadge(Choice.Scissors("8rem"), Positioning.Absolute("6rem", "17rem")),
|
ChoiceBadge(
|
||||||
ChoiceBadge(Choice.Rock("8rem"), Positioning.Absolute("15rem", "11.5rem")),
|
Choice.Scissors("8rem"),
|
||||||
|
Positioning.Absolute("6rem", "17rem")
|
||||||
|
),
|
||||||
|
ChoiceBadge(Choice.Rock("8rem"), Positioning.Absolute("15rem", "11.5rem"))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue