react-haskell-2.0.1: Haskell React bindings

Copyright(C) 2014-15 Joel Burget
LicenseMIT
MaintainerJoel Burget <joelburget@gmail.com>
Stabilityexperimental
Portabilitynon-portable
Safe HaskellNone
LanguageHaskell2010

React

Contents

Description

Usage:

This tutorial assumes only a basic understanding of React, the DOM, and browser events. I recomment at least skimming the official React tutorial.

Let's start with a basic example:

page_ :: ReactNode Void
page_ =
    let cls = smartClass
            { name = "page"

            -- initially the input is empty
            , initialState = ""

            -- always transition to the input's new value
            , transition = (_, value) -> (value, Nothing)

            , renderFn = _ str -> div_ [ class_ "container" ] $ do
                input_ [ value_ str, onChange (Just . value . target) ]
            }
    in classLeaf cls ()

main :: IO ()
main = do
    Just doc <- currentDocument
    Just elem <- documentGetElementById doc ("elem" :: JSString)
    render page_ elem

In this example we defined a React class with Text state, but taking only () as a prop. It's possible to use anything for props and state -- numbers, JSON, even React classes.

In the example the input always contains the state from the class, and the state is updated on every input change event -- effectively, every keystroke.

Synopsis

Classes

data ReactClass props state insig exsig ctx Source

A ReactClass is a standalone component of a user interface which contains the state necessary to render itself. Classes are a tool for scoping.

Use createClass to construct.

  • props: The type of props passed in.
  • state: The type of state this class maintains.
  • insig: The type of signals this class handles (see classTransition)
  • exsig: The type of signals this class emits (see classTransition)
  • ctx: This is only used for React's mythical context feature -- If you know what that is, see childContext for usage.

data ClassConfig props state insig exsig ctx Source

Constructors

ClassConfig 

Fields

renderFn :: props -> state -> ReactNode insig
 
initialState :: state
 
name :: JSString
 
transition :: (state, insig) -> (state, Maybe exsig)
 
startupSignals :: [insig]
 
childContext :: Maybe (HashMap Text ctx)
 

type ClassCtx a = (ToJSRef a, PropTypable a) Source

A type that can be used in a child context.

React manages context (unlike props and state, which are managed entirely within Haskell), so anything used in child context must be convertable to a JSRef and must be describable by a PropType.

smartClass :: ClassConfig props state insig exsig JSString Source

Defaults for a stateful ("controller") class.

dumbClass :: ClassConfig props () sig sig JSString Source

Defaults for a stateless ("layout") class.

Rendering

render :: ReactNode Void -> Element -> IO () Source

Render a top-level component.

Note that the rendered component can't possibly emit signals.

debugRender :: Show sig => ReactNode sig -> Element -> IO () Source

Unlike render, debugRender can render components that emit signals, as long as they can be shown.

React Nodes

Events

data EventProperties e Source

Low level properties common to all events

Instances

Native Events

Synthetic Events

Local

class GeneralizeSignal sigloc siggen where Source

Implement when a local signal can be generalized to a higher level one. Used by locally

Methods

generalizeSignal :: sigloc -> siggen Source

locally :: GeneralizeSignal sigloc siggen => ReactNode sigloc -> ReactNode siggen Source

locally exists to make it simple to embed classes with local concerns. An example will be helpful:

We have some page which can respond to many different events.

data Transition
    = UserTyping JSString
    | Toggle
    ...

globalPage_ :: [AttrOrHandler Transition] -> ReactNode Transition

And we want to be able to embed some components that don't care about all that. inputBox_ can only output JSString and pageHeader_ can't send any signals at all.

inputBox_ :: ReactNode JSString
pageHeader_ :: ReactNode Void

With locally we can easily embed them in globalPage_:

instance GeneralizeSignal JSString Transition where
    generalizeSignal = UserTyping

-- (globalPage_)
renderFn = props state -> div_ [ class_ "global-page" ] $ do
    locally pageHeader_
    ...
    locally inputBox_
    ...

data AttrOrHandler signal Source

Attributes

newtype NoProps Source

When importing a foreign class you must specify the props it takes. In the common case where it takes no props, only handles layout, it's convenient to specify the type of props as NoProps.

Example:

pageLayout_ :: ReactNode () -> ReactNode () pageLayout_ = importParentClass pageLayout noProps

Constructors

NoProps () 

noProps :: NoProps Source

Used when importing a foreign class taking no props. See above example.

mkStaticAttr :: ToJSON a => Text -> a -> AttrOrHandler sig Source

Creating Elements

Class creation

classParent :: ClassCtx ctx => ClassConfig props state insig exsig ctx -> ReactNode insig -> props -> ReactNode exsig Source

classLeaf :: ClassCtx ctx => ClassConfig props state insig exsig ctx -> props -> ReactNode exsig Source

JS Interop

exportClassLeaf :: ClassCtx ctx => ClassConfig props state insig exsig ctx -> ExportedClass Source

importLeafClass :: ToJSRef props => ImportedClass props sig -> props -> ReactNode sig Source

importParentClass :: ToJSRef props => ImportedClass props sig -> props -> ReactNode sig -> ReactNode sig Source

data ExportedNode sig Source

Instances

type ExportedClass = JSRef ExportedClass_ Source

JS Interop

type ImportedClass props sig = JSRef (ImportedClass_ props sig) Source

PropTypes

class PropTypable a Source

Describe the PropType of a type

Examples:

propType (_ :: JSString) = PropString IsRequired

propType (_ :: Bool) = PropBool IsRequired

Minimal complete definition

propType