mirror of
https://github.com/rowtype-yoga/ry-blocks.git
synced 2024-09-19 09:17:27 +03:00
Refactor Hooks
This commit is contained in:
parent
55a6f6fc66
commit
a0f3e37442
@ -103,6 +103,7 @@ popover = do
|
||||
, stiffness: 200.0
|
||||
, damping: 20.0
|
||||
, mass: 0.7
|
||||
, delay: 0.3
|
||||
}
|
||||
}
|
||||
{ placement: Placement Placement.Bottom (Just Placement.Start)
|
||||
|
@ -10,13 +10,13 @@ import Data.TwoOrMore as TwoOrMore
|
||||
import Effect.Aff (delay)
|
||||
import Effect.Unsafe (unsafePerformEffect)
|
||||
import Foreign.Object as Object
|
||||
import Hooks.Key as Key
|
||||
import Hooks.UseResize (useResize)
|
||||
import Yoga.Block.Hook.Key as Key
|
||||
import Yoga.Block.Hook.UseResize (useResize)
|
||||
import Yoga.Block.Hook.UseKeyDown (useKeyDown)
|
||||
import Math as Math
|
||||
import React.Basic.DOM (css)
|
||||
import React.Basic.DOM as R
|
||||
import React.Basic.Emotion as E
|
||||
import React.Basic.Extra.Hooks.UseKeyDown (useKeyDown)
|
||||
import React.Basic.Hooks (reactComponent)
|
||||
import React.Basic.Hooks as React
|
||||
import React.Basic.Hooks.Aff (useAff)
|
||||
|
@ -9,7 +9,7 @@ import Effect.Unsafe (unsafePerformEffect)
|
||||
import Foreign.Object as Object
|
||||
import Framer.Motion (VariantLabel)
|
||||
import Framer.Motion as Motion
|
||||
import Hooks.Scroll (useScrollPosition)
|
||||
import Yoga.Block.Hook.Scroll (useScrollPosition)
|
||||
import Literals.Undefined (undefined)
|
||||
import MotionValue (useMotionValue)
|
||||
import MotionValue as MotionValue
|
||||
@ -21,12 +21,12 @@ import React.Basic.Hooks as React
|
||||
import Unsafe.Coerce (unsafeCoerce)
|
||||
import Yoga.Block.Atom.Segmented.Style as Style
|
||||
|
||||
type Props =
|
||||
{ activeItemRefs ∷ TwoOrMore (Ref (Nullable Node))
|
||||
, activeItemIndex ∷ Int
|
||||
, updateActiveIndex ∷ Int -> Effect Unit
|
||||
, windowWidth ∷ Number
|
||||
}
|
||||
type Props
|
||||
= { activeItemRefs ∷ TwoOrMore (Ref (Nullable Node))
|
||||
, activeItemIndex ∷ Int
|
||||
, updateActiveIndex ∷ Int -> Effect Unit
|
||||
, windowWidth ∷ Number
|
||||
}
|
||||
|
||||
component ∷ ReactComponent Props
|
||||
component =
|
||||
@ -42,14 +42,16 @@ component =
|
||||
_ <-
|
||||
runMaybeT do
|
||||
rawStyles <- traverse getStyle props.activeItemRefs
|
||||
let styles = rawStyles <#> \s -> s { left = s.left + scrollX }
|
||||
let
|
||||
styles = rawStyles <#> \s -> s { left = s.left + scrollX }
|
||||
unless (maybeAnimationVariants == Just styles) do
|
||||
setVariants (Just styles) # lift
|
||||
mempty
|
||||
useLayoutEffect maybeDragX do
|
||||
case maybeDragX, maybeAnimationVariants of
|
||||
Just x, Just animationVariants -> do
|
||||
let { left, width } = handleDrag { activeItemIndex: props.activeItemIndex, animationVariants, x }
|
||||
let
|
||||
{ left, width } = handleDrag { activeItemIndex: props.activeItemIndex, animationVariants, x }
|
||||
activeLeft # MotionValue.set left
|
||||
activeWidth # MotionValue.set width
|
||||
_, _ -> mempty
|
||||
@ -88,9 +90,12 @@ component =
|
||||
when (isJust maybeDragX) $ setDragX (Just pi.point.x)
|
||||
, onDragEnd:
|
||||
Motion.onDragEnd \_ pi -> do
|
||||
let x = maybeDragX # fromMaybe' \_ -> unsafeCrashWith "no x should not happen"
|
||||
let newIdx = findOverlapping props.activeItemIndex animationVariants x
|
||||
let v = animationVariants TwoOrMore.!! newIdx # fromMaybe' \_ -> unsafeCrashWith "omg"
|
||||
let
|
||||
x = maybeDragX # fromMaybe' \_ -> unsafeCrashWith "no x should not happen"
|
||||
let
|
||||
newIdx = findOverlapping props.activeItemIndex animationVariants x
|
||||
let
|
||||
v = animationVariants TwoOrMore.!! newIdx # fromMaybe' \_ -> unsafeCrashWith "omg"
|
||||
setDragX Nothing
|
||||
activeLeft # MotionValue.set v.left
|
||||
activeWidth # MotionValue.set v.width
|
||||
@ -118,18 +123,23 @@ getStyle itemRef = do
|
||||
indexToVariant ∷ Int -> VariantLabel
|
||||
indexToVariant = show >>> unsafeCoerce
|
||||
|
||||
type BBox =
|
||||
{ top ∷ Number, left ∷ Number, width ∷ Number, height ∷ Number }
|
||||
type BBox
|
||||
= { top ∷ Number, left ∷ Number, width ∷ Number, height ∷ Number }
|
||||
|
||||
findOverlapping ∷ Int -> TwoOrMore BBox -> Number -> Int
|
||||
findOverlapping activeIndex styles x =
|
||||
fromMaybe activeIndex do
|
||||
curr <- styles TwoOrMore.!! activeIndex
|
||||
let fst = TwoOrMore.head styles
|
||||
let lst = TwoOrMore.last styles
|
||||
let inside e = (e.left < x) && (e.left + e.width) >= x
|
||||
let tooFarLeft = MZ.guard (x <= fst.left + fst.width) $> 0
|
||||
let tooFarRight = MZ.guard (x >= lst.left) $> TwoOrMore.length styles - 1
|
||||
let
|
||||
fst = TwoOrMore.head styles
|
||||
let
|
||||
lst = TwoOrMore.last styles
|
||||
let
|
||||
inside e = (e.left < x) && (e.left + e.width) >= x
|
||||
let
|
||||
tooFarLeft = MZ.guard (x <= fst.left + fst.width) $> 0
|
||||
let
|
||||
tooFarRight = MZ.guard (x >= lst.left) $> TwoOrMore.length styles - 1
|
||||
TwoOrMore.findIndex inside styles <|> tooFarLeft <|> tooFarRight
|
||||
|
||||
handleDrag ∷
|
||||
@ -139,11 +149,16 @@ handleDrag ∷
|
||||
} ->
|
||||
{ left ∷ Number, width ∷ Number }
|
||||
handleDrag { x, activeItemIndex, animationVariants } = do
|
||||
let idx = findOverlapping activeItemIndex animationVariants x
|
||||
let av = animationVariants
|
||||
let firstVariant = av # TwoOrMore.head
|
||||
let lastVariant = av # TwoOrMore.last
|
||||
let baseVariant = av TwoOrMore.!! idx # fromMaybe' \_ -> unsafeCrashWith "shit"
|
||||
let
|
||||
idx = findOverlapping activeItemIndex animationVariants x
|
||||
let
|
||||
av = animationVariants
|
||||
let
|
||||
firstVariant = av # TwoOrMore.head
|
||||
let
|
||||
lastVariant = av # TwoOrMore.last
|
||||
let
|
||||
baseVariant = av TwoOrMore.!! idx # fromMaybe' \_ -> unsafeCrashWith "shit"
|
||||
let
|
||||
closestVariant =
|
||||
if x >= (baseVariant.left + (baseVariant.width / 2.0)) then
|
||||
@ -157,25 +172,41 @@ handleDrag { x, activeItemIndex, animationVariants } = do
|
||||
else
|
||||
closestVariant /\ baseVariant
|
||||
-- Total
|
||||
let rangeStart = smaller.left + (smaller.width / 2.0)
|
||||
let rangeEnd = greater.left + (greater.width / 2.0)
|
||||
let range = rangeEnd - rangeStart
|
||||
let ratio = ((x - rangeStart) / range)
|
||||
let interpolatedWidth = (greater.width * ratio) + smaller.width * (1.0 - ratio)
|
||||
let
|
||||
rangeStart = smaller.left + (smaller.width / 2.0)
|
||||
let
|
||||
rangeEnd = greater.left + (greater.width / 2.0)
|
||||
let
|
||||
range = rangeEnd - rangeStart
|
||||
let
|
||||
ratio = ((x - rangeStart) / range)
|
||||
let
|
||||
interpolatedWidth = (greater.width * ratio) + smaller.width * (1.0 - ratio)
|
||||
-- Right
|
||||
let rangeStartRight = smaller.left + smaller.width
|
||||
let rangeEndRight = greater.left + greater.width
|
||||
let rangeRight = rangeEndRight - rangeStartRight
|
||||
let ratioRight = ((x + (interpolatedWidth / 2.0) - rangeStartRight) / rangeRight)
|
||||
let
|
||||
rangeStartRight = smaller.left + smaller.width
|
||||
let
|
||||
rangeEndRight = greater.left + greater.width
|
||||
let
|
||||
rangeRight = rangeEndRight - rangeStartRight
|
||||
let
|
||||
ratioRight = ((x + (interpolatedWidth / 2.0) - rangeStartRight) / rangeRight)
|
||||
-- Left
|
||||
let rangeStartLeft = smaller.left
|
||||
let rangeEndLeft = greater.left
|
||||
let rangeLeft = rangeEndLeft - rangeStartLeft
|
||||
let ratioLeft = (((x - (interpolatedWidth / 2.0)) - rangeStartLeft) / rangeLeft)
|
||||
let
|
||||
rangeStartLeft = smaller.left
|
||||
let
|
||||
rangeEndLeft = greater.left
|
||||
let
|
||||
rangeLeft = rangeEndLeft - rangeStartLeft
|
||||
let
|
||||
ratioLeft = (((x - (interpolatedWidth / 2.0)) - rangeStartLeft) / rangeLeft)
|
||||
-- Individual
|
||||
let left = rangeStartLeft + (ratioLeft * rangeLeft)
|
||||
let right = rangeStartRight + (ratioRight * rangeRight)
|
||||
let width = right - left
|
||||
let
|
||||
left = rangeStartLeft + (ratioLeft * rangeLeft)
|
||||
let
|
||||
right = rangeStartRight + (ratioRight * rangeRight)
|
||||
let
|
||||
width = right - left
|
||||
if x < firstVariant.left then
|
||||
{ left: firstVariant.left, width: firstVariant.width }
|
||||
else
|
||||
|
@ -1,4 +1,4 @@
|
||||
module Hooks.Key where
|
||||
module Yoga.Block.Hook.Key where
|
||||
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Web.Event.Event (Event)
|
@ -1,4 +1,4 @@
|
||||
module Hooks.Scroll where
|
||||
module Yoga.Block.Hook.Scroll where
|
||||
|
||||
import Prelude
|
||||
import Data.Newtype (class Newtype)
|
||||
@ -20,12 +20,12 @@ registerListener listener = do
|
||||
addEventListener eventType listener false target
|
||||
pure $ removeEventListener eventType listener false target
|
||||
|
||||
newtype UseScrollPosition hooks = UseScrollPosition (UseLayoutEffect Unit (UseState ScrollPosition hooks))
|
||||
|
||||
newtype UseScrollPosition hooks
|
||||
= UseScrollPosition (UseLayoutEffect Unit (UseState ScrollPosition hooks))
|
||||
derive instance ntUseScrollPosition ∷ Newtype (UseScrollPosition hooks) _
|
||||
|
||||
type ScrollPosition =
|
||||
{ scrollX ∷ Number, scrollY ∷ Number }
|
||||
type ScrollPosition
|
||||
= { scrollX ∷ Number, scrollY ∷ Number }
|
||||
|
||||
useScrollPosition ∷ Hook UseScrollPosition ScrollPosition
|
||||
useScrollPosition =
|
@ -1,19 +1,19 @@
|
||||
module React.Basic.Extra.Hooks.UseKeyDown where
|
||||
module Yoga.Block.Hook.UseKeyDown where
|
||||
|
||||
import Prelude
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Newtype (class Newtype)
|
||||
import Effect (Effect)
|
||||
import Hooks.Key (KeyCode, getKeyCode, intToKeyCode)
|
||||
import Yoga.Block.Hook.Key (KeyCode, getKeyCode, intToKeyCode)
|
||||
import React.Basic.Hooks (Hook, UseEffect, coerceHook, useEffectAlways)
|
||||
import Web.Event.Event (EventType(..))
|
||||
import Web.Event.EventTarget (addEventListener, eventListener, removeEventListener)
|
||||
import Web.HTML (window)
|
||||
import Web.HTML.Window as Win
|
||||
|
||||
newtype UseKeyDown hooks = UseKeyDown
|
||||
newtype UseKeyDown hooks
|
||||
= UseKeyDown
|
||||
(UseEffect Unit hooks)
|
||||
|
||||
derive instance ntUseKeyDown ∷ Newtype (UseKeyDown hooks) _
|
||||
|
||||
useKeyDown ∷ (KeyCode -> Effect Unit) -> Hook UseKeyDown Unit
|
@ -1,19 +1,19 @@
|
||||
module React.Basic.Extra.Hooks.UseKeyUp where
|
||||
module Yoga.Block.Hook.UseKeyUp where
|
||||
|
||||
import Prelude
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Newtype (class Newtype)
|
||||
import Effect (Effect)
|
||||
import Hooks.Key (KeyCode, getKeyCode, intToKeyCode)
|
||||
import Yoga.Block.Hook.Key (KeyCode, getKeyCode, intToKeyCode)
|
||||
import React.Basic.Hooks (Hook, UseEffect, coerceHook, useEffect)
|
||||
import Web.Event.Event (EventType(..))
|
||||
import Web.Event.EventTarget (addEventListener, eventListener, removeEventListener)
|
||||
import Web.HTML (window)
|
||||
import Web.HTML.Window as Win
|
||||
|
||||
newtype UseKeyUp hooks = UseKeyUp
|
||||
newtype UseKeyUp hooks
|
||||
= UseKeyUp
|
||||
(UseEffect Unit hooks)
|
||||
|
||||
derive instance ntUseKeyUp ∷ Newtype (UseKeyUp hooks) _
|
||||
|
||||
useKeyUp ∷ (KeyCode -> Effect Unit) -> Hook UseKeyUp Unit
|
@ -1,4 +1,4 @@
|
||||
module Hooks.UseResize where
|
||||
module Yoga.Block.Hook.UseResize where
|
||||
|
||||
import Prelude
|
||||
import Data.Int (toNumber)
|
||||
@ -20,15 +20,16 @@ registerListener listener = do
|
||||
addEventListener eventType listener false target
|
||||
pure $ removeEventListener eventType listener false target
|
||||
|
||||
newtype UseResize hooks = UseResize (UseLayoutEffect Unit (UseState { width ∷ Number, height ∷ Number } hooks))
|
||||
|
||||
newtype UseResize hooks
|
||||
= UseResize (UseLayoutEffect Unit (UseState { width ∷ Number, height ∷ Number } hooks))
|
||||
derive instance ntUseResize ∷ Newtype (UseResize hooks) _
|
||||
|
||||
useResize ∷ Hook UseResize { width ∷ Number, height ∷ Number }
|
||||
useResize =
|
||||
coerceHook React.do
|
||||
size /\ updateSize <- useState { width: 0.0, height: 0.0 }
|
||||
let setSize = updateSize <<< const
|
||||
let
|
||||
setSize = updateSize <<< const
|
||||
useLayoutEffect unit do
|
||||
setSizeFromWindow setSize
|
||||
listener <- makeListener setSize
|
||||
@ -51,7 +52,8 @@ useResize' ∷ Effect Unit -> Hook UseResize { width ∷ Number, height ∷ Numb
|
||||
useResize' eff =
|
||||
coerceHook React.do
|
||||
size /\ updateSize <- useState { width: 0.0, height: 0.0 }
|
||||
let setSize = updateSize <<< const
|
||||
let
|
||||
setSize = updateSize <<< const
|
||||
useLayoutEffect unit do
|
||||
setSizeFromWindow setSize
|
||||
listener <- makeListener (setSize >=> const eff)
|
Loading…
Reference in New Issue
Block a user