git.iko.soy/rowtype-yoga/psfp
on de44991 help sign in
66 lines 2.2 kB history raw
1module DOM.Hook where
3import Prelude
5import Data.Maybe (Maybe(..))
6import Data.Newtype (class Newtype)
7import Data.Nullable (Nullable)
8import Data.Nullable as Nullable
9import Data.Traversable (for_)
10import Data.Tuple.Nested (type (/\))
11import React.Basic (Ref)
12import React.Basic.Hooks (Hook, UseLayoutEffect, UseRef, UseState, coerceHook, readRefMaybe, useLayoutEffect, useRef, useState, (/\))
13import React.Basic.Hooks as React
14import Unsafe.Coerce (unsafeCoerce)
15import Web.DOM (Node)
16import Web.DOM.Element (clientHeight)
17import Web.HTML (window)
18import Web.HTML.HTMLDocument as Document
19import Web.HTML.HTMLElement (DOMRect, getBoundingClientRect)
20import Web.HTML.HTMLElement as HTMLElement
21import Web.HTML.Window (document)
23newtype UseBoundingBox hooks
24 = UseBoundingBox
25 ( UseLayoutEffect Unit
26 ( UseState (Maybe DOMRect)
27 (UseRef (Nullable Node) hooks)
28 )
29 )
31derive instance ntUseBoundingBox ∷ Newtype (UseBoundingBox hooks) _
33useBoundingBox ∷ Hook UseBoundingBox (Maybe DOMRect /\ Ref (Nullable Node))
34useBoundingBox =
35 coerceHook React.do
36 (nullableRef ∷ (Ref (Nullable Node))) <- useRef Nullable.null
37 bb /\ modifyBb <- useState Nothing
38 useLayoutEffect unit do
39 maybeRef <- readRefMaybe nullableRef
40 let toHTMLOrSVGElement = unsafeCoerce -- [TODO] Make a bit safer?
41 for_ (maybeRef <#> toHTMLOrSVGElement) \elem -> do
42 rect <- getBoundingClientRect elem
43 modifyBb (const $ Just rect)
44 pure (pure unit)
45 pure (bb /\ nullableRef)
48newtype UseViewportHeight hooks
49 = UseViewportHeight (UseLayoutEffect Unit (UseState (Maybe Number) hooks))
51derive instance ntUseViewportHeight ∷ Newtype (UseViewportHeight hooks) _
53useViewportHeight ∷ Hook UseViewportHeight (Maybe Number)
54useViewportHeight =
55 coerceHook React.do
56 viewportHeight /\ modifyViewportHeight <- useState Nothing
57 useLayoutEffect unit do
58 doc <- window >>= document
59 let maybeElem = Document.toNode doc # HTMLElement.fromNode
60 case maybeElem of
61 Nothing -> pure unit
62 Just elem -> do
63 ch <- clientHeight (HTMLElement.toElement elem)
64 modifyViewportHeight (const $ Just ch)
65 pure (pure unit)
66 pure viewportHeight