diff --git a/bower.json b/bower.json index b1677d4..73374eb 100644 --- a/bower.json +++ b/bower.json @@ -19,7 +19,9 @@ "dependencies": { "purescript-eff": "^3.0.0", "purescript-prelude": "^3.0.0", - "purescript-unsafe-coerce": "^3.0.0" + "purescript-unsafe-coerce": "^3.0.0", + "purescript-maybe": "^3.0.0", + "purescript-nullable": "^3.0.0" }, "devDependencies": { "purescript-console": "^3.0.0", diff --git a/src/React.js b/src/React.js index 8ce9422..451f8dd 100644 --- a/src/React.js +++ b/src/React.js @@ -40,6 +40,30 @@ function getChildren(this_) { } exports.getChildren = getChildren; +function readRefImpl (this_) { + return function(name) { + return function() { + var refs = this_.refs || {}; + return refs[name]; + } + } +} +exports.readRefImpl = readRefImpl; + +function writeRef(this_) { + return function(name) { + return function(node) { + return function() { + var refs = this_.refs || {}; + refs[name] = node; + this_.refs = refs; + return {}; + } + } + } +} +exports.writeRef = writeRef; + function writeState(this_) { return function(state){ return function(){ diff --git a/src/React.purs b/src/React.purs index b547c36..6f64161 100644 --- a/src/React.purs +++ b/src/React.purs @@ -19,6 +19,7 @@ module React , ReactRefs , Refs + , Ref , Render , GetInitialState @@ -43,6 +44,8 @@ module React , getProps , getRefs + , readRef + , writeRef , getChildren , readState @@ -73,6 +76,8 @@ module React import Prelude import Control.Monad.Eff (kind Effect, Eff) +import Data.Maybe (Maybe) +import Data.Nullable (Nullable, toMaybe) import Control.Monad.Eff.Uncurried (EffFn2, runEffFn2) import Unsafe.Coerce (unsafeCoerce) @@ -302,6 +307,30 @@ foreign import getRefs :: forall props state access eff. ReactThis props state -> Eff (refs :: ReactRefs (read :: Read | access) | eff) Refs +-- | Ref type. You can store `Ref` types on `Refs` object (which in +-- | corresponds to `this.refs`). Use `ReactDOM.refToNode` if you want to +-- store a `DOM.Node.Types.Node` +foreign import data Ref :: Type + +foreign import readRefImpl :: forall props state access eff. + ReactThis props state -> + String -> + Eff (refs :: ReactRefs (read :: Read | access) | eff) (Nullable Ref) + +-- | Read named ref from `Refs`. +readRef :: forall props state access eff. + ReactThis props state -> + String -> + Eff (refs :: ReactRefs (read :: Read | access) | eff) (Maybe Ref) +readRef this name = toMaybe <$> readRefImpl this name + +-- | Write a `Ref` to `Refs` +foreign import writeRef :: forall props state access eff. + ReactThis props state -> + String -> + Nullable Ref -> + Eff (refs :: ReactRefs (write :: Write | access) | eff) Unit + -- | Read the component children property. foreign import getChildren :: forall props state eff. ReactThis props state -> diff --git a/src/React/DOM/Props.purs b/src/React/DOM/Props.purs index 82408f1..ed2659f 100644 --- a/src/React/DOM/Props.purs +++ b/src/React/DOM/Props.purs @@ -1,6 +1,10 @@ module React.DOM.Props where -import React (Event, EventHandlerContext, KeyboardEvent, MouseEvent, handle) +import Control.Monad.Eff (Eff) +import Control.Monad.Eff.Unsafe (unsafePerformEff) +import Data.Nullable (Nullable) +import Prelude (Unit, (<<<)) +import React (Event, EventHandlerContext, KeyboardEvent, MouseEvent, ReactRefs, Ref, Write, handle) foreign import data Props :: Type @@ -297,6 +301,19 @@ radioGroup = unsafeMkProps "radioGroup" readOnly :: Boolean -> Props readOnly = unsafeMkProps "readOnly" +ref :: String -> Props +ref = unsafeMkProps "ref" + +-- | You can use `writeRef` to store a reference on `Refs`. +-- | ``` purescrript +-- | div [ withRef (writeRef this "inputElement") ] [...] +-- | ``` +withRef + :: forall access eff + . (Nullable Ref -> Eff (refs :: ReactRefs (write :: Write | access) | eff) Unit) + -> Props +withRef cb = unsafeMkProps "ref" (unsafePerformEff <<< cb) + rel :: String -> Props rel = unsafeMkProps "rel"