git.iko.soy/rowtype-yoga/psfp
on master help sign in
Draggable Springs
a1f9c3bMark Eibes
components/src/React/Basic/Hooks/Spring/Stories.purs+17−12
@@ -5,12 +5,13 @@ import Data.Tuple.Nested ((/\))
5import Debug.Trace (spy)
5import Debug.Trace (spy)
6import Effect (Effect)
6import Effect (Effect)
7import Effect.Unsafe (unsafePerformEffect)
7import Effect.Unsafe (unsafePerformEffect)
8+import JSS (jssClasses)
8import Justifill (justifill)
9import Justifill (justifill)
9import React.Basic.DOM (css)
10import React.Basic.DOM (css)
10import React.Basic.DOM as R
11import React.Basic.DOM as R
11import React.Basic.Events (handler_)
12import React.Basic.Events (handler_)
12import React.Basic.Helpers (jsx)
13import React.Basic.Helpers (jsx)
13−import React.Basic.Hooks (component, element, fragment, useLayoutEffect, useState)
14+import React.Basic.Hooks (ReactComponent, component, element, fragment, useLayoutEffect, useState)
14import React.Basic.Hooks as React
15import React.Basic.Hooks as React
15import React.Basic.Hooks.Spring (animated, animatedDiv, useSpring, useSpringImpl)
16import React.Basic.Hooks.Spring (animated, animatedDiv, useSpring, useSpringImpl)
16import React.Basic.Hooks.UseGesture (useDrag, withDragProps)
17import React.Basic.Hooks.UseGesture (useDrag, withDragProps)
@@ -20,6 +21,7 @@ import Web.DOM.DOMTokenList (toggle)
20import Yoga.Box.Component as Box
21import Yoga.Box.Component as Box
21import Yoga.Spec.Helpers (withDarkTheme)
22import Yoga.Spec.Helpers (withDarkTheme)
22import Yoga.Stack.Component as Stack
23import Yoga.Stack.Component as Stack
24+import Yoga.Theme.Styles (makeStylesJSS)
23
25
24stories ∷ Effect Storybook
26stories ∷ Effect Storybook
25stories = do
27stories = do
@@ -29,37 +31,40 @@ stories = do
29 add "The Drag" (withDarkTheme mkDragAnimated)
31 add "The Drag" (withDarkTheme mkDragAnimated)
30 [ {} ]
32 [ {} ]
31
33
34+mkAnimated ∷ Effect (ReactComponent {})
32mkAnimated = do
35mkAnimated = do
33 box <- Box.makeComponent
36 box <- Box.makeComponent
34 component "Animated Example" \{} -> React.do
37 component "Animated Example" \{} -> React.do
35 toggled /\ modifyToggled <- useState false
38 toggled /\ modifyToggled <- useState false
36− springStyles /\ set <- useSpring $ const { marginTop: "80px", transform: "scale3d(" <> if toggled then "0.9, 0.9, 1.0" else "1.0, 2.0, 1.0" <> ")" }
39+ springStyles /\ set <- useSpring $ const { marginTop: "80px", marginBottom: "80px", opacity: 0.7, transform: "scale3d(" <> if toggled then "0.9, 0.9, 1.0" else "1.0, 2.0, 1.0" <> ")" }
37 useLayoutEffect toggled do
40 useLayoutEffect toggled do
38− set { marginTop: "80px", transform: "scale3d(" <> if toggled then "0.9, 0.9, 1.0" else "1.0, 2.0, 1.0" <> ")" }
41+ set { marginTop: "80px", marginBottom: "30px", opacity: if toggled then 0.7 else 0.9, transform: "scale3d(" <> if toggled then "0.9, 0.9, 1.0" else "1.0, 2.0, 1.0" <> ")" }
39 pure mempty
42 pure mempty
40 pure
43 pure
41 $ fragment
44 $ fragment
42− [ R.button { children: [ R.text "Toggle" ], onClick: handler_ (modifyToggled not) }
43− , animatedDiv
45+ [ animatedDiv
44− { style: css (spy "toni" springStyles)
46+ { style: css springStyles
45− , children: [ jsx box {} [ R.text "HIIIIIIIIIIIIOOOO" ] ]
47+ , children: [ jsx box {} [ R.text "Click the button" ] ]
46 }
48 }
49+ , R.button { children: [ R.text "Toggle" ], onClick: handler_ (modifyToggled not) }
47 ]
50 ]
48
51
52+mkDragAnimated ∷ Effect (ReactComponent {})
49mkDragAnimated = do
53mkDragAnimated = do
50 box <- Box.makeComponent
54 box <- Box.makeComponent
55+ useStyles <- makeStylesJSS $ jssClasses \t -> { div: { width: "200px", height: "200px", background: "hotpink" } }
51− component "Animated Example" \{} -> React.do
56+ component "Draggable Example" \{} -> React.do
52− toggled /\ modifyToggled <- useState false
53 springStyles /\ set <- useSpring $ const { x: 0.0, y: 0.0 }
57 springStyles /\ set <- useSpring $ const { x: 0.0, y: 0.0 }
58+ classes <- useStyles {}
54 mkDragProps <-
59 mkDragProps <-
55 useDrag \{ down, movement: mx /\ my } ->
60 useDrag \{ down, movement: mx /\ my } ->
56 set { x: if down then mx else 0.0, y: if down then my else 0.0 }
61 set { x: if down then mx else 0.0, y: if down then my else 0.0 }
57 pure
62 pure
58 $ fragment
63 $ fragment
59− [ R.button { children: [ R.text "Toggle" ], onClick: handler_ (modifyToggled not) }
60− , animatedDiv
64+ [ animatedDiv
61 ( { style: css springStyles
65 ( { style: css springStyles
66+ , className: classes.div
62− , children: [ jsx box {} [ R.text "HIIIIIIIIIIIIOOOO" ] ]
67+ , children: [ jsx box {} [ R.text "Drag me somewhere" ] ]
63 }
68 }
64 `withDragProps`
69 `withDragProps`
65 mkDragProps
70 mkDragProps
components/src/React/Basic/Hooks/UseGesture.purs+16−6
@@ -1,7 +1,11 @@
1module React.Basic.Hooks.UseGesture where
1module React.Basic.Hooks.UseGesture where
2
2
3import Prelude
3import Prelude
4−import Data.Tuple (Tuple)
4+import Data.Array ((!!))
5+import Data.Foldable (fold)
6+import Data.Monoid.Additive (Additive(..))
7+import Data.Newtype (ala)
8+import Data.Tuple.Nested ((/\), type (/\))
5import Effect (Effect)
9import Effect (Effect)
6import Effect.Uncurried (EffectFn1, runEffectFn1)
10import Effect.Uncurried (EffectFn1, runEffectFn1)
7import Effect.Unsafe (unsafePerformEffect)
11import Effect.Unsafe (unsafePerformEffect)
@@ -9,14 +13,15 @@ import Prim.Row (class Lacks, class Nub)
9import React.Basic.Events (EventHandler)
13import React.Basic.Events (EventHandler)
10import React.Basic.Hooks (Hook, unsafeHook)
14import React.Basic.Hooks (Hook, unsafeHook)
11import Record (disjointUnion)
15import Record (disjointUnion)
16+import Yoga.Helpers ((?||))
12
17
13foreign import data UseDrag ∷ Type -> Type -> Type
18foreign import data UseDrag ∷ Type -> Type -> Type
14
19
15type DragHandler
20type DragHandler
16− = { down ∷ Boolean, movement ∷ Tuple Number Number } -> Effect Unit
21+ = { down ∷ Boolean, movement ∷ Number /\ Number } -> Effect Unit
17
22
18type DragHandlerImpl
23type DragHandlerImpl
19− = { down ∷ Boolean, movement ∷ Tuple Number Number } -> Unit
24+ = { down ∷ Boolean, movement ∷ Array Number } -> Unit
20
25
21type DragProps
26type DragProps
22 = { onMouseDown ∷ EventHandler, onTouchStart ∷ EventHandler }
27 = { onMouseDown ∷ EventHandler, onTouchStart ∷ EventHandler }
@@ -24,10 +29,15 @@ type DragProps
24foreign import useDragImpl ∷ EffectFn1 DragHandlerImpl (Effect DragProps)
29foreign import useDragImpl ∷ EffectFn1 DragHandlerImpl (Effect DragProps)
25
30
26useDrag ∷ DragHandler -> Hook (UseDrag Unit) (Effect DragProps)
31useDrag ∷ DragHandler -> Hook (UseDrag Unit) (Effect DragProps)
27−useDrag dragHandler = unsafeHook (runEffectFn1 useDragImpl x)
32+useDrag dragHandler = unsafeHook (runEffectFn1 useDragImpl f)
28 where
33 where
29− x ∷ DragHandlerImpl
34+ f x =
30− x = unsafePerformEffect <<< dragHandler
35+ (unsafePerformEffect <<< dragHandler)
36+ { down: x.down, movement: mx /\ my
37+ }
38+ where
39+ mx = x.movement !! 0 ?|| 0.0
40+ my = x.movement !! 1 ?|| 0.0
31
41
32withDragProps ∷
42withDragProps ∷
33 ∀ attrs.
43 ∀ attrs.