-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | ReactJS binding using Glazier and Pipes.Fluid
--
-- ReactJS binding using Glazier and Pipes.Fluid, which is more
-- functional and composable than Elm/Flux.
@package glazier-react
@version 0.6.0.0
-- | Contains commons utilities when defining your own widget
module Glazier.React.ReactDOM
-- | Using a React Element (first arg) give React rendering control over a
-- DOM element (second arg). This should only be called for the topmost
-- component.
render :: JSVal -> JSVal -> IO ()
module Glazier.React.Model
-- | Lens to the callbacks and interactions with React
class HasPlan c pln | c -> pln
plan :: HasPlan c pln => Lens' c pln
-- | Lens to the pure model for state and rendering.
class HasModel c mdl | c -> mdl
model :: HasModel c mdl => Lens' c mdl
-- | Convert to the pure serializable model for saving and restoring
class ToOutline c o | c -> o
outline :: ToOutline c o => c -> o
-- | A record of Model and Plan
data Scene mdl pln
Scene :: mdl -> pln -> Scene mdl pln
[_model] :: Scene mdl pln -> mdl
[_plan] :: Scene mdl pln -> pln
class HasScene c mdl pln | c -> mdl pln
scene :: HasScene c mdl pln => Lens' c (Scene mdl pln)
-- | All scenes should be disposable to make it easier for cleanup of
-- callbacks.
-- | A Scene can be converted to Outline by using the Model
-- | Frame is a Mvar of Scene. React rendering callback uses this MVar for
-- rendering.
type Frame mdl pln = MVar (Scene mdl pln)
class HasFrame c mdl pln | c -> mdl pln
frame :: HasFrame c mdl pln => Lens' c (Frame mdl pln)
-- | A record of Scene and Frame.
data Gizmo mdl pln
Gizmo :: Scene mdl pln -> Frame mdl pln -> Gizmo mdl pln
[_scene] :: Gizmo mdl pln -> Scene mdl pln
[_frame] :: Gizmo mdl pln -> Frame mdl pln
-- | Undecidableinstances! But this is safe because Scene is definitely
-- smaller than Gizmo
class (HasScene c mdl pln, HasFrame c mdl pln) => HasGizmo c mdl pln | c -> mdl pln
gizmo :: HasGizmo c mdl pln => Lens' c (Gizmo mdl pln)
-- | A Gizmo can be converted to Outline by using the Model
instance GHC.Generics.Generic (Glazier.React.Model.Gizmo mdl pln)
instance GHC.Generics.Generic (Glazier.React.Model.Scene mdl pln)
instance Glazier.React.Model.HasScene (Glazier.React.Model.Scene mdl pln) mdl pln
instance (Control.Disposable.Disposing pln, Control.Disposable.Disposing mdl) => Control.Disposable.Disposing (Glazier.React.Model.Scene mdl pln)
instance Glazier.React.Model.HasPlan (Glazier.React.Model.Scene mdl pln) pln
instance Glazier.React.Model.HasModel (Glazier.React.Model.Scene mdl pln) mdl
instance Glazier.React.Model.ToOutline mdl ol => Glazier.React.Model.ToOutline (Glazier.React.Model.Scene mdl pln) ol
instance Glazier.React.Model.HasFrame (Glazier.React.Model.Frame mdl pln) mdl pln
instance Control.Disposable.Disposing (Glazier.React.Model.Scene mdl pln) => Control.Disposable.Disposing (Glazier.React.Model.Gizmo mdl pln)
instance Glazier.React.Model.HasGizmo (Glazier.React.Model.Gizmo mdl pln) mdl pln
instance Glazier.React.Model.HasFrame (Glazier.React.Model.Gizmo mdl pln) mdl pln
instance Glazier.React.Model.HasScene (Glazier.React.Model.Gizmo mdl pln) mdl pln
instance Glazier.React.Model.HasPlan (Glazier.React.Model.Gizmo mdl pln) pln
instance Glazier.React.Model.HasModel (Glazier.React.Model.Gizmo mdl pln) mdl
instance Glazier.React.Model.ToOutline mdl o => Glazier.React.Model.ToOutline (Glazier.React.Model.Gizmo mdl pln) o
-- | This module based on ReactFluxPropertiesAndEvents.hs.
module Glazier.React.Event
-- | The object that dispatched the event.
-- https://developer.mozilla.org/en-US/docs/Web/API/Event/target
data DOMEventTarget
-- | The native event
-- https://developer.mozilla.org/en-US/docs/Web/API/Event
data DOMEvent
-- | Every event in React is a synthetic event, a cross-browser wrapper
-- around the native event. SyntheticEvent must only be used in
-- the first part of eventHandler.
data SyntheticEvent
-- | Using the NFData idea from ReactFluxPropertiesAndEvents.hs
-- React re-uses SyntheticEvent from a pool, which means it may no longer
-- be valid if we lazily parse it. However, we still want lazy parsing so
-- we don't parse unnecessary fields. Additionally, we don't want to
-- block during the event handling.The reason this is a problem is
-- because Javascript is single threaded, but Haskell is lazy. Therefore
-- GHCJS threads are a strange mixture of synchronous and asynchronous
-- threads, where a synchronous thread might be converted to an
-- asynchronous thread if a "black hole" is encountered. See
-- https://github.com/ghcjs/ghcjs-base/blob/master/GHCJS/Concurrent.hs
-- This safe interface requires two input functions: 1. a function to
-- reduce SyntheticEvent to a NFData. The mkEventCallback will ensure
-- that the NFData is forced which will ensure all the required fields
-- from Synthetic event has been parsed. This function must not block. 2.
-- a second function that uses the NFData. This function is allowed to
-- block. mkEventHandler results in a function that you can safely pass
-- into syncCallback1 with ContinueAsync.
eventHandler :: NFData a => (evt -> a) -> (a -> b) -> (evt -> b)
-- | a monadic version of eventHandler The monad's effects must not block!
eventHandlerM :: (Monad m, NFData a) => (evt -> m a) -> (a -> m b) -> (evt -> m b)
-- | Every SyntheticEvent can be parsed to an Event.
-- Event must only be used in the first part of
-- eventHandler.
data Event
Event :: Bool -> Bool -> DOMEventTarget -> Bool -> Int -> Bool -> DOMEvent -> DOMEventTarget -> Int -> JSString -> Event
preventDefault :: SyntheticEvent -> IO ()
isDefaultPrevented :: SyntheticEvent -> Bool
stopPropagation :: SyntheticEvent -> IO ()
isPropagationStopped :: SyntheticEvent -> Bool
-- | We can lie about this not being in IO because within the strict part
-- of eventHandlerM the SyntheticEvent is effectively immutable.
parseEvent :: SyntheticEvent -> Event
-- | Mouse and Drag/Drop events MouseEvent must only be used in the
-- first part of eventHandler.
-- https://facebook.github.io/react/docs/events.html#mouse-events
-- https://developer.mozilla.org/en-US/docs/Web/Events Event names
-- (eventType) onClick (click) onContextMenu (contextmenu) onDoubleClick
-- (dblclick) onDrag (drag) onDragEnd (dragend) onDragEnter (dragenter)
-- onDragExit (dragexit) onDragLeave (dragleave) onDragOver (dragover)
-- onDragStart (dragstart) onDrop (drop) onMouseDown (mousedown)
-- onMouseEnter (mouseenter) onMouseLeave (mouseleave) onMouseMove
-- (mousemove) onMouseOut (mouseout) onMouseOver (mouseover) onMouseUp
-- (mouseup)
data MouseEvent
MouseEvent :: Bool -> Int -> Int -> Int -> Int -> Bool -> (JSString -> Bool) -> Bool -> Int -> Int -> DOMEventTarget -> Int -> Int -> Bool -> MouseEvent
-- | We can lie about this not being in IO because within the strict part
-- of eventHandlerM the SyntheticEvent is effectively immutable.
parseMouseEvent :: SyntheticEvent -> Maybe MouseEvent
-- | Keyboard events KeyboardEvent must only be used in the first
-- part of eventHandler.
-- https://facebook.github.io/react/docs/events.html#keyboard-events
-- Event names (eventType) onKeyDown (keydown) onKeyPress (keypress)
-- onKeyUp (keyyp)
data KeyboardEvent
KeyboardEvent :: Bool -> Int -> Bool -> (JSString -> Bool) -> JSString -> Int -> JSString -> Int -> Bool -> Bool -> Bool -> Int -> KeyboardEvent
-- | We can lie about this not being in IO because within the strict part
-- of eventHandlerM the SyntheticEvent is effectively immutable.
parseKeyboardEvent :: SyntheticEvent -> Maybe KeyboardEvent
instance GHCJS.Internal.Types.IsJSVal Glazier.React.Event.DOMEventTarget
instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Event.DOMEventTarget
instance JavaScript.Extras.Cast.ToJS Glazier.React.Event.DOMEventTarget
instance JavaScript.Extras.Cast.FromJS Glazier.React.Event.DOMEventTarget
instance GHCJS.Internal.Types.IsJSVal Glazier.React.Event.DOMEvent
instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Event.DOMEvent
instance JavaScript.Extras.Cast.ToJS Glazier.React.Event.DOMEvent
instance JavaScript.Extras.Cast.FromJS Glazier.React.Event.DOMEvent
instance GHCJS.Internal.Types.IsJSVal Glazier.React.Event.SyntheticEvent
instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Event.SyntheticEvent
instance JavaScript.Extras.Cast.ToJS Glazier.React.Event.SyntheticEvent
instance JavaScript.Extras.Cast.FromJS Glazier.React.Event.SyntheticEvent
-- | HtmlT inspired monad for creating ReactElements
module Glazier.React.Element
data ReactElement
-- | Unfortunately, ReactJS did not export an easy way to check if
-- something is a ReactElement, although they do so in the internal code
-- with REACT_ELEMENT_TYPE. This function allow coercing a ReactElement
-- from a JSVal and is named unsafe as a reminder that the coersion is
-- unchecked. This function is required when receiving ReactElement from
-- javascript (eg in a callback) or to interface with foreign React
-- Elements.
unsafeCoerceElement :: JSVal -> ReactElement
-- | Create a react element (with children) from a HashMap of properties
mkBranchElement :: JSVar -> [Property] -> [ReactElement] -> IO ReactElement
-- | Create a react element (with no children) from a HashMap of properties
mkLeafElement :: JSVar -> [Property] -> IO ReactElement
-- | Not an IO action because JSString is immutable
textElement :: JSString -> ReactElement
-- | React only allows a single top most element. Provide a handly function
-- to wrap a list of ReactElements inside a div if required. If
-- there is only one element in the list, then nothing is changed.
mkCombinedElements :: [ReactElement] -> IO ReactElement
instance GHCJS.Internal.Types.IsJSVal Glazier.React.Element.ReactElement
instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Element.ReactElement
instance JavaScript.Extras.Cast.ToJS Glazier.React.Element.ReactElement
-- | HtmlT inspired monad for creating ReactElements
module Glazier.React.Markup
data ReactMarkup
ElementMarkup :: ReactElement -> ReactMarkup
TextMarkup :: JSString -> ReactMarkup
BranchMarkup :: BranchParam -> ReactMarkup
LeafMarkup :: LeafParam -> ReactMarkup
-- | The parameters required to create a branch ReactElement with children
data BranchParam
BranchParam :: JSVar -> [Property] -> (DList ReactMarkup) -> BranchParam
-- | The parameters required to create a leaf ReactElement (no children)
data LeafParam
LeafParam :: JSVar -> [Property] -> LeafParam
-- | Create ReactElements from a AtomMarkup
fromMarkup :: ReactMarkup -> IO (ReactElement)
-- | Monadic generator of ReactActom. It is a CPS-style WriterT (ie a
-- StateT) to build up a function build up a computations to generate a
-- '[AtomMarkup]'. You can use runStateT with an initial state of
-- mempty.
newtype ReactMlT m a
ReactMlT :: StateT (DList ReactMarkup) m a -> ReactMlT m a
[runReactMlT] :: ReactMlT m a -> StateT (DList ReactMarkup) m a
type ReactMl = ReactMlT Identity
-- | To use an exisitng ReactElement
fromElement :: Applicative m => ReactElement -> ReactMlT m ()
-- | Convert the ReactMlt to [R.ReactElement]
toElements :: MonadIO io => ReactMlT io () -> io [ReactElement]
-- | Render the ReactMlt under a Glazier window
markedWindow :: MonadIO io => WindowT s (ReactMlT io) () -> WindowT s io [ReactElement]
-- | Fully render the ReactMlt into a [R.ReactElement]
markedElements :: MonadIO io => WindowT s (ReactMlT io) () -> s -> io [ReactElement]
-- | Fully render the ReactMlt into a R.ReactElement
markedElement :: MonadIO io => WindowT s (ReactMlT io) () -> s -> io ReactElement
-- | For text content
txt :: Applicative m => JSString -> ReactMlT m ()
-- | For the contentless elements: eg br_
lf :: Applicative m => JSVar -> [Property] -> ReactMlT m ()
-- | For the contentful elements: eg div_
bh :: Functor m => JSVar -> [Property] -> ReactMlT m a -> ReactMlT m a
instance Control.Monad.Morph.MFunctor Glazier.React.Markup.ReactMlT
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Glazier.React.Markup.ReactMlT m)
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Glazier.React.Markup.ReactMlT m)
instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Glazier.React.Markup.ReactMlT m)
instance GHC.Base.MonadPlus m => GHC.Base.Alternative (Glazier.React.Markup.ReactMlT m)
instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Glazier.React.Markup.ReactMlT m)
instance GHC.Base.Functor m => GHC.Base.Functor (Glazier.React.Markup.ReactMlT m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Glazier.React.Markup.ReactMlT m)
instance GHC.Base.Monad m => GHC.Base.Monad (Glazier.React.Markup.ReactMlT m)
instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Data.DList.DList Glazier.React.Markup.ReactMarkup) (Glazier.React.Markup.ReactMlT m)
instance (Data.Semigroup.Semigroup a, GHC.Base.Monad m) => Data.Semigroup.Semigroup (Glazier.React.Markup.ReactMlT m a)
instance (GHC.Base.Monoid a, GHC.Base.Monad m) => GHC.Base.Monoid (Glazier.React.Markup.ReactMlT m a)
module Glazier.React.Component
-- | A newtype wrapper to give a noop disposable instance to React
-- components This allows generic deriving of model Adaptors.
data ReactComponent
mkComponent :: IO ReactComponent
instance Control.Disposable.Disposing Glazier.React.Component.ReactComponent
instance GHCJS.Internal.Types.IsJSVal Glazier.React.Component.ReactComponent
instance GHCJS.Marshal.Internal.PToJSVal Glazier.React.Component.ReactComponent
instance JavaScript.Extras.Cast.ToJS Glazier.React.Component.ReactComponent
module Glazier.React.Maker
-- | DSL for IO effects required during making widget models and callbacks
-- Maker remembers the action type to allow mapAction for
-- changing the action type by parent widgets. The model type does not
-- need to be changed, so it is hidden in the GADT existential.
data Maker act nxt
[MkHandler] :: (JSVal -> MaybeT IO [act]) -> (Callback (JSVal -> IO ()) -> nxt) -> Maker act nxt
[MkEmptyFrame] :: (Frame mdl pln -> nxt) -> Maker act nxt
[MkRenderer] :: Frame mdl pln -> (JSVal -> WindowT (Scene mdl pln) ReactMl ()) -> (Callback (JSVal -> IO JSVal) -> nxt) -> Maker act nxt
[PutFrame] :: Frame mdl pln -> Scene mdl pln -> nxt -> Maker act nxt
[GetComponent] :: (ReactComponent -> nxt) -> Maker act nxt
[MkKey] :: (JSString -> nxt) -> Maker act nxt
mkKey :: forall m_anSQ act_anCA. MonadFree (Maker act_anCA) m_anSQ => m_anSQ JSString
getComponent :: forall m_anSN act_anCA. MonadFree (Maker act_anCA) m_anSN => m_anSN ReactComponent
putFrame :: forall (mdl_XnCY :: Type) (pln_XnD0 :: Type) m_anSJ act_anCA. MonadFree (Maker act_anCA) m_anSJ => Frame mdl_XnCY pln_XnD0 -> Scene mdl_XnCY pln_XnD0 -> m_anSJ ()
mkRenderer :: forall (mdl_XnCU :: Type) (pln_XnCW :: Type) m_anSE act_anCA. MonadFree (Maker act_anCA) m_anSE => Frame mdl_XnCU pln_XnCW -> (JSVal -> WindowT (Scene mdl_XnCU pln_XnCW) ReactMl ()) -> m_anSE (Callback (JSVal -> IO JSVal))
mkEmptyFrame :: forall (mdl_XnCQ :: Type) (pln_XnCS :: Type) m_anSB act_anCA. MonadFree (Maker act_anCA) m_anSB => m_anSB (Frame mdl_XnCQ pln_XnCS)
mkHandler :: forall m_anSx act_anCA. MonadFree (Maker act_anCA) m_anSx => (JSVal -> MaybeT IO [act_anCA]) -> m_anSx (Callback (JSVal -> IO ()))
-- | Allows changing the action type of Maker
withAction :: (act -> act') -> Maker act a -> Maker act' a
hoistWithAction :: (act -> act') -> F (Maker act) a -> F (Maker act') a
instance GHC.Base.Functor (Glazier.React.Maker.Maker act)
module Glazier.React.Widget
type SceneOf w = Scene (ModelOf w) (PlanOf w)
type FrameOf w = Frame (ModelOf w) (PlanOf w)
type GizmoOf w = Gizmo (ModelOf w) (PlanOf w)
type WindowOf w = WindowT (SceneOf w) (ReactMlT Identity) ()
type GadgetOf w = GadgetT (ActionOf w) (GizmoOf w) Identity (DList (CommandOf w))
-- | tag used to choose Schema that contains Gizmos
data WithGizmo
-- | tag used to choose Schema that contains Outlines
data WithOutline
-- | You can't use type family as a type variable for a data type. The
-- workaround is to use a tag to choose between different type family
-- functions. ModelType takes a tag to choose between Gizmo or Outline.
-- This enables creating a data type that can specialize to
-- using the tag.
-- | Record of functions for a widget. Contains everything you need to make
-- the model, render, and run the event processing. This is a GADT to
-- enforce the Disposing and ToOutline constraints at the time of
-- creating the Widget record.
data Widget c a o m p
[Widget] :: (Disposing m, Disposing p, ToOutline m o) => (o -> F (Maker a) m) -> (Frame m p -> F (Maker a) p) -> WindowT (Scene m p) (ReactMlT Identity) () -> GadgetT a (Gizmo m p) Identity (DList c) -> Widget c a o m p
-- | This typeclass is convenient as it carries the 'Disposing Model' and
-- 'Disposing Plan' constraints and allows treating 'Widget c a m p' as a
-- type w
class (Disposing (ModelOf w), Disposing (PlanOf w), ToOutline (ModelOf w) (OutlineOf w)) => IsWidget w
-- | Make a Model from an Outline
mkModel :: IsWidget w => w -> OutlineOf w -> F (Maker (ActionOf w)) (ModelOf w)
-- | Given an empty frame, make the Plan that uses the frame for rendering
mkPlan :: IsWidget w => w -> Frame (ModelOf w) (PlanOf w) -> F (Maker (ActionOf w)) (PlanOf w)
-- | Rendering function that uses the Scene of Model and Plan
window :: IsWidget w => w -> WindowT (Scene (ModelOf w) (PlanOf w)) (ReactMlT Identity) ()
-- | Update function that processes Action to update the Frame and Scene
gadget :: IsWidget w => w -> GadgetT (ActionOf w) (Gizmo (ModelOf w) (PlanOf w)) Identity (DList (CommandOf w))
-- | Make the required Frame and Plan for a Model
mkGizmo :: IsWidget w => w -> ModelOf w -> F (Maker (ActionOf w)) (Gizmo (ModelOf w) (PlanOf w))
-- | Make the required Frame and Plan from an Outline
mkGizmo' :: IsWidget w => w -> OutlineOf w -> F (Maker (ActionOf w)) (Gizmo (ModelOf w) (PlanOf w))
instance (Control.Disposable.Disposing m, Control.Disposable.Disposing p, Glazier.React.Model.ToOutline m o) => Glazier.React.Widget.IsWidget (Glazier.React.Widget.Widget c a o m p)
module Glazier.React.Maker.Run
-- | This is called synchronously by React to render the DOM. This must not
-- block!
onRender :: MVar s -> (JSVal -> WindowT s (ReactMlT IO) ()) -> JSVal -> IO JSVal
mkActionCallback :: Output act -> (JSVal -> MaybeT IO [act]) -> IO (Callback (JSVal -> IO ()))
run :: MVar Int -> ReactComponent -> Output act -> Maker act (IO a) -> IO a
-- | Common functions used by command interpreters
module Glazier.React.Command.Run
componentSetState :: HasGizmo giz mdl pln => giz -> [Property] -> JSVal -> IO ()
module Glazier.React.Command
-- | Just change the state to something different so the React
-- pureComponent will call render() renderCmd :: Monad m => (sm ->
-- [JE.Property] -> J.JSVal -> cmd) -> G.GadgetT act sm m cmd
-- The resulting command should be interpreted using
-- componentSetState
basicRenderCmd :: MonadState sm m => Lens' sm Int -> Getter sm JSVal -> (sm -> [Property] -> JSVal -> cmd) -> m cmd