glazier-react-1.0.0.0: src/Glazier/React/Component/Internal.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Glazier.React.Component.Internal
( ShimComponent(..) -- constructor exported
, shimComponent
, rerenderShim
, ComponentRef(..) -- constructor exported
) where
import Control.DeepSeq
import Data.String
import qualified GHC.Generics as G
import qualified GHCJS.Marshal.Pure as J
import qualified GHCJS.Types as J
import qualified JavaScript.Extras as JE
-- | Returns a reference to the javascript *class* definition
-- of the shim wrapper around ReactPureComponent
newtype ShimComponent = ShimComponent JE.JSRep
deriving (G.Generic, Show, J.IsJSVal, J.PToJSVal, JE.ToJS, IsString, NFData)
-- | This returns the javascript class definition of ShimComponent.
-- There is ever only one shim class, so it is purely available
shimComponent :: ShimComponent
shimComponent = ShimComponent js_shimComponent
-- | Rerenders an instance of a component created using ShimComponent.
rerenderShim :: ComponentRef -> IO ()
rerenderShim = js_rerenderShim
-- | This is used store the react "ref" to a javascript instance of a react Component.
newtype ComponentRef = ComponentRef JE.JSRep
deriving (G.Generic, Show, J.IsJSVal, J.PToJSVal, JE.ToJS, IsString, NFData)
instance JE.FromJS ComponentRef where
fromJS a | js_isReactComponent a = Just $ ComponentRef $ JE.JSRep a
fromJS _ = Nothing
#ifdef __GHCJS__
foreign import javascript unsafe
"$r = hgr$shimComponent();"
js_shimComponent :: JE.JSRep
-- !!blah is javascript way of converting to bool
-- using undocumented api to check if something is react component
-- https://stackoverflow.com/questions/33199959/how-to-detect-a-react-component-vs-a-react-element
foreign import javascript unsafe
"!(!($1 && !(!($1['isReactComponent']))))"
js_isReactComponent :: J.JSVal -> Bool
foreign import javascript unsafe
"if ($1 && $1['rerender']) { $1['rerender']() };"
js_rerenderShim :: ComponentRef -> IO ()
#else
js_shimComponent :: JE.JSRep
js_shimComponent = JE.JSRep J.nullRef
js_isReactComponent :: J.JSVal -> Bool
js_isReactComponent _ = False
js_rerenderShim :: ComponentRef -> IO ()
js_rerenderShim _ = pure ()
#endif