From a0f3e374423913a1f33c0c8bcb7a2bf6d9b35a2e Mon Sep 17 00:00:00 2001 From: Mark Eibes Date: Fri, 25 Dec 2020 15:54:45 +0100 Subject: [PATCH] Refactor Hooks --- src/Yoga/Block/Atom/Popover/Story.purs | 1 + src/Yoga/Block/Atom/Segmented/View.purs | 6 +- .../Atom/Segmented/View/ActiveIndicator.purs | 111 +++++++++++------- src/{Hooks => Yoga/Block/Hook}/Key.js | 0 src/{Hooks => Yoga/Block/Hook}/Key.purs | 2 +- src/{Hooks => Yoga/Block/Hook}/Scroll.purs | 10 +- .../Block/Hook}/UseKeyDown.purs | 8 +- src/{Hooks => Yoga/Block/Hook}/UseKeyUp.purs | 8 +- src/{Hooks => Yoga/Block/Hook}/UseResize.purs | 12 +- 9 files changed, 96 insertions(+), 62 deletions(-) rename src/{Hooks => Yoga/Block/Hook}/Key.js (100%) rename src/{Hooks => Yoga/Block/Hook}/Key.purs (95%) rename src/{Hooks => Yoga/Block/Hook}/Scroll.purs (85%) rename src/{Hooks => Yoga/Block/Hook}/UseKeyDown.purs (87%) rename src/{Hooks => Yoga/Block/Hook}/UseKeyUp.purs (87%) rename src/{Hooks => Yoga/Block/Hook}/UseResize.purs (88%) diff --git a/src/Yoga/Block/Atom/Popover/Story.purs b/src/Yoga/Block/Atom/Popover/Story.purs index 49b66fa..146e2df 100644 --- a/src/Yoga/Block/Atom/Popover/Story.purs +++ b/src/Yoga/Block/Atom/Popover/Story.purs @@ -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) diff --git a/src/Yoga/Block/Atom/Segmented/View.purs b/src/Yoga/Block/Atom/Segmented/View.purs index cb0d62a..2e57088 100644 --- a/src/Yoga/Block/Atom/Segmented/View.purs +++ b/src/Yoga/Block/Atom/Segmented/View.purs @@ -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) diff --git a/src/Yoga/Block/Atom/Segmented/View/ActiveIndicator.purs b/src/Yoga/Block/Atom/Segmented/View/ActiveIndicator.purs index 90ff1e7..e44c36b 100644 --- a/src/Yoga/Block/Atom/Segmented/View/ActiveIndicator.purs +++ b/src/Yoga/Block/Atom/Segmented/View/ActiveIndicator.purs @@ -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 diff --git a/src/Hooks/Key.js b/src/Yoga/Block/Hook/Key.js similarity index 100% rename from src/Hooks/Key.js rename to src/Yoga/Block/Hook/Key.js diff --git a/src/Hooks/Key.purs b/src/Yoga/Block/Hook/Key.purs similarity index 95% rename from src/Hooks/Key.purs rename to src/Yoga/Block/Hook/Key.purs index 2cf9183..be92789 100644 --- a/src/Hooks/Key.purs +++ b/src/Yoga/Block/Hook/Key.purs @@ -1,4 +1,4 @@ -module Hooks.Key where +module Yoga.Block.Hook.Key where import Data.Maybe (Maybe(..)) import Web.Event.Event (Event) diff --git a/src/Hooks/Scroll.purs b/src/Yoga/Block/Hook/Scroll.purs similarity index 85% rename from src/Hooks/Scroll.purs rename to src/Yoga/Block/Hook/Scroll.purs index 5ba42f2..3cdd448 100644 --- a/src/Hooks/Scroll.purs +++ b/src/Yoga/Block/Hook/Scroll.purs @@ -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 = diff --git a/src/Hooks/UseKeyDown.purs b/src/Yoga/Block/Hook/UseKeyDown.purs similarity index 87% rename from src/Hooks/UseKeyDown.purs rename to src/Yoga/Block/Hook/UseKeyDown.purs index 5de3559..abb690f 100644 --- a/src/Hooks/UseKeyDown.purs +++ b/src/Yoga/Block/Hook/UseKeyDown.purs @@ -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 diff --git a/src/Hooks/UseKeyUp.purs b/src/Yoga/Block/Hook/UseKeyUp.purs similarity index 87% rename from src/Hooks/UseKeyUp.purs rename to src/Yoga/Block/Hook/UseKeyUp.purs index bffabb6..cf94a8b 100644 --- a/src/Hooks/UseKeyUp.purs +++ b/src/Yoga/Block/Hook/UseKeyUp.purs @@ -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 diff --git a/src/Hooks/UseResize.purs b/src/Yoga/Block/Hook/UseResize.purs similarity index 88% rename from src/Hooks/UseResize.purs rename to src/Yoga/Block/Hook/UseResize.purs index 06421fe..fc42e71 100644 --- a/src/Hooks/UseResize.purs +++ b/src/Yoga/Block/Hook/UseResize.purs @@ -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)