@@ -8,7 +8,7 @@ import com.raquo.laminar.api.L
88import scala .collection .mutable
99import scala .collection .mutable .ListBuffer
1010import scala .scalajs .js
11- import scala .scalajs .js .timers .SetTimeoutHandle
11+ import scala .scalajs .js .timers .{ SetTimeoutHandle , setTimeout }
1212
1313case class Transition (signal : Signal [TransitionStatus ]):
1414 lazy val $isActive : Signal [Boolean ] = signal.map(_.isActive)
@@ -19,55 +19,129 @@ case class Transition(signal: Signal[TransitionStatus]):
1919 lazy val width : Mod [HtmlElement ] =
2020 Transitions .width($isActive)
2121
22+ def width (speed : Double ): Mod [HtmlElement ] =
23+ Transitions .width($isActive, speed)
24+
2225 lazy val height : Mod [HtmlElement ] =
2326 Transitions .height($isActive)
2427
28+ def height (speed : Double ): Mod [HtmlElement ] =
29+ Transitions .height($isActive, speed)
30+
2531 lazy val blur : Mod [HtmlElement ] =
2632 Transitions .blur($isActive)
2733
34+ def blur (closedBlur : Double ): Mod [HtmlElement ] =
35+ Transitions .blur($isActive, closedBlur)
36+
37+ lazy val scale : Mod [HtmlElement ] =
38+ Transitions .scale($isActive)
39+
40+ def scale (closedScale : Double , speed : Double = 1 ): Mod [HtmlElement ] =
41+ Transitions .scale($isActive, closedScale, speed)
42+
43+ def offset (closedX : Double = 0 , closedY : Double = 0 ): Mod [HtmlElement ] =
44+ Transitions .offset($isActive, closedX, closedY)
45+
2846object Transitions :
2947 def opacity ($visible : Signal [Boolean ]): Mod [HtmlElement ] =
3048 L .opacity <-- $visible.map(if _ then 1.0 else 0 ).spring
3149
32- def height ($open : Signal [Boolean ]): Mod [HtmlElement ] =
50+ enum Status :
51+ case Inserting , Active , Removing
52+
53+ def height ($open : Signal [Boolean ], speed : Double = 1 ): Mod [HtmlElement ] =
3354 val scrollHeightVar = Var (0.0 )
55+
56+ val $scrollHeight = $open.distinct
57+ .flatMap {
58+ if _ then scrollHeightVar.signal
59+ else Val (0.0 )
60+ }
61+ .spring(_.withSpeed(speed))
62+ .px
63+
64+ val signalVar = Var ($scrollHeight)
65+ var setTimeoutHandle : SetTimeoutHandle = null
66+
3467 Seq (
3568 overflowY.hidden,
3669 onMountBind { ctx =>
37- ResizeObserver --> { _ =>
70+ EventStream .periodic( 10 ) --> { _ =>
3871 scrollHeightVar.set(ctx.thisNode.ref.scrollHeight.toDouble)
3972 }
4073 },
41- onMountBind { (el : MountContext [HtmlElement ]) =>
42- L .maxHeight <-- $open.flatMap {
43- if _ then scrollHeightVar.signal
44- else Val (0.0 )
45- }.spring.px
46- }
74+ onMountBind { ctx =>
75+ $open.distinct --> { open =>
76+ if setTimeoutHandle != null then js.timers.clearTimeout(setTimeoutHandle)
77+ if open then
78+ signalVar.set($scrollHeight)
79+ setTimeoutHandle = setTimeout(700 ) {
80+ signalVar.set(Val (" none" ))
81+ }
82+ else signalVar.set($scrollHeight)
83+ }
84+ },
85+ $scrollHeight --> { _ => () },
86+ maxHeight <-- signalVar.signal.flatten
4787 )
4888
49- def width ($open : Signal [Boolean ]): Mod [HtmlElement ] =
89+ def width ($open : Signal [Boolean ], speed : Double = 1 ): Mod [HtmlElement ] =
5090 val scrollWidthVar = Var (0.0 )
91+
92+ val $scrollWidth = $open.distinct
93+ .flatMap {
94+ if _ then scrollWidthVar.signal
95+ else Val (0.0 )
96+ }
97+ .spring(_.withSpeed(speed))
98+ .px
99+
100+ val signalVar = Var ($scrollWidth)
101+ var setTimeoutHandle : SetTimeoutHandle = null
102+
51103 Seq (
52- overflowX .hidden,
104+ overflowY .hidden,
53105 onMountBind { ctx =>
54- ResizeObserver --> { _ =>
106+ EventStream .periodic( 10 ) --> { _ =>
55107 scrollWidthVar.set(ctx.thisNode.ref.scrollWidth.toDouble)
56108 }
57109 },
58- onMountBind { (ctx : MountContext [HtmlElement ]) =>
59- L .maxWidth <-- $open.flatMap {
60- if _ then scrollWidthVar.signal
61- else Val (0.0 )
62- }.spring.px
63- }
110+ onMountBind { ctx =>
111+ $open.distinct --> { open =>
112+ if setTimeoutHandle != null then js.timers.clearTimeout(setTimeoutHandle)
113+ if open then
114+ signalVar.set($scrollWidth)
115+ setTimeoutHandle = setTimeout(700 ) {
116+ signalVar.set(Val (" none" ))
117+ }
118+ else signalVar.set($scrollWidth)
119+ }
120+ },
121+ $scrollWidth --> { _ => () },
122+ maxWidth <-- signalVar.signal.flatten
64123 )
65124
66- def blur ($open : Signal [Boolean ]): Mod [HtmlElement ] =
67- styleProp(" filter" ) <-- $open.map(if _ then 0.0 else 5.0 ).spring.map { blur =>
125+ def scale ($open : Signal [Boolean ], closedScale : Double = 0.0 , speed : Double = 1 ): Mod [HtmlElement ] =
126+ List (
127+ styleProp(" transform" ) <-- $open.map(if _ then 1.0 else closedScale).spring(_.withSpeed(speed)).map { scale =>
128+ s " scale( $scale) "
129+ },
130+ transformOrigin(" top left" )
131+ )
132+
133+ def blur ($open : Signal [Boolean ], closedBlur : Double = 5.0 ): Mod [HtmlElement ] =
134+ styleProp(" filter" ) <-- $open.map(if _ then 0.0 else closedBlur).spring(_.withSpeed(0.8 )).map { blur =>
68135 s " blur( ${blur}px) "
69136 }
70137
138+ def offset ($open : Signal [Boolean ], closedX : Double = 0.0 , closedY : Double = 0.0 ): Mod [HtmlElement ] =
139+ List (
140+ position.relative,
141+ top <-- $open.map(if _ then 0.0 else closedY).spring.px,
142+ left <-- $open.map(if _ then 0.0 else closedX).spring.px
143+ )
144+
71145 def transitionList [A , Key , Output ](
72146 $items : Signal [Seq [A ]]
73147 )(getKey : A => Key )(project : (Key , A , Signal [A ], Transition ) => Output ): Signal [Seq [Output ]] =
0 commit comments