react-flux-1.0.2: src/React/Flux/Addons/React.hs
-- | Bindings for the <https://facebook.github.io/react/docs/addons.html React addons> that make
-- sense to use from Haskell. At the moment, that is only the
-- <https://facebook.github.io/react/docs/animation.html animation> and
-- <https://facebook.github.io/react/docs/perf.html performance tools>.
module React.Flux.Addons.React (
-- * Animation
cssTransitionGroup
-- * Perf
, PerfAction(..)
, PerfPrint(..)
, perfToggleButton_
, perfA
) where
import Control.DeepSeq (NFData)
import Control.Monad (forM_)
import GHC.Generics (Generic)
import React.Flux
#ifdef __GHCJS__
import GHCJS.Types (JSVal, JSString)
#endif
-- | The <https://facebook.github.io/react/docs/animation.html ReactCSSTransitionGroup> element.
-- For example in React 0.14,
--
-- >cssTransitionGroup ["transitionName" $= "example", transitionAppear @= True, transitionAppearTimeout @= (100 :: Int)] $
-- > h1_ "Fading at initial mount"
cssTransitionGroup :: [PropertyOrHandler eventHandler] -> ReactElementM eventHandler a -> ReactElementM eventHandler a
#ifdef __GHCJS__
cssTransitionGroup props children = foreignClass js_CSSTransitionGroup props children
foreign import javascript unsafe
"React['addons']['CSSTransitionGroup']"
js_CSSTransitionGroup :: JSVal
#else
cssTransitionGroup _ x = x
#endif
--------------------------------------------------------------------------------
-- Perf
--------------------------------------------------------------------------------
data PerfStoreData = PerfStoreData { perfIsActive :: Bool }
-- | What to print after stopping performance measurement. See
-- <https://facebook.github.io/react/docs/perf.html> for documentation.
data PerfPrint = PerfPrintInclusive
| PerfPrintExclusive
| PerfPrintWasted
| PerfPrintDOM
deriving (Show, Eq, Generic)
instance NFData PerfPrint
-- | An action to start or stop performance measurement. For details, see
-- <https://facebook.github.io/react/docs/perf.html>.
data PerfAction = PerfStart
| PerfStopAndPrint [PerfPrint]
deriving (Show, Eq, Generic)
instance NFData PerfAction
instance StoreData PerfStoreData where
type StoreAction PerfStoreData = PerfAction
transform PerfStart _ = do
js_perf "start"
return $ PerfStoreData True
transform (PerfStopAndPrint toPrint) _ = do
js_perf "stop"
forM_ toPrint $ \action -> do
js_perf $ case action of
PerfPrintInclusive -> "printInclusive"
PerfPrintExclusive -> "printExclusive"
PerfPrintWasted -> "printWasted"
PerfPrintDOM -> "printDOM"
return $ PerfStoreData False
perfStore :: ReactStore PerfStoreData
perfStore = mkStore $ PerfStoreData False
-- | Convert a performance action into a store action. Use this if you are not using
-- 'perfToggleButton_'.
perfA :: PerfAction -> SomeStoreAction
perfA = SomeStoreAction perfStore
-- | The performance toggle button view
perfToggleButton :: ReactView [PerfPrint]
perfToggleButton = defineControllerView "perf toggle button" perfStore $ \sData toPrint ->
button_ [ onClick $ \_ _ ->
if perfIsActive sData
then [perfA $ PerfStopAndPrint toPrint]
else [perfA PerfStart]
] $
if perfIsActive sData then "Stop perf measurement" else "Start perf measurement"
-- | A button which when clicked toggles the performance measurement on and off. When the
-- measurement is stopped, the given measurements are printed. If you want more control over the
-- performance tools, you can use 'perfA' directly from your own event handlers.
perfToggleButton_ :: [PerfPrint] -> ReactElementM handler ()
perfToggleButton_ toPrint = view perfToggleButton toPrint mempty
#ifdef __GHCJS__
foreign import javascript unsafe
"React['addons']['Perf'][$1]()"
js_perf :: JSString -> IO ()
#else
js_perf :: String -> IO ()
js_perf _ = return ()
#endif