diff --git a/src/React.purs b/src/React.purs index 22f6c4a..4c823b6 100644 --- a/src/React.purs +++ b/src/React.purs @@ -32,7 +32,6 @@ module React , pureComponentWithDerivedState , statelessComponent , ReactClass - , ReactRef , getProps , getState , setState @@ -68,11 +67,11 @@ module React import Prelude -import Data.Nullable (Nullable) import Effect (Effect) import Effect.Exception (Error) import Effect.Uncurried (EffectFn1) import Prim.Row as Row +import React.Ref as Ref import Type.Row (type (+)) import Unsafe.Coerce (unsafeCoerce) @@ -252,10 +251,6 @@ foreign import data ReactClass :: Type -> Type foreign import fragment :: ReactClass { children :: Children } --- | Type for React refs. This type is opaque, but you can use `Data.Foreign` --- | and `DOM` to validate the underlying representation. -foreign import data ReactRef :: Type - -- | Read the component props. foreign import getProps :: forall props state. ReactThis props state -> @@ -340,7 +335,7 @@ class ReactPropFields (required :: # Type) (given :: # Type) type ReservedReactPropFields r = ( key :: String - , ref :: SyntheticEventHandler (Nullable ReactRef) + , ref :: Ref.RefHandler Ref.ReactInstance | r ) diff --git a/src/React/DOM/Props.purs b/src/React/DOM/Props.purs index e3b2b50..34d90e4 100644 --- a/src/React/DOM/Props.purs +++ b/src/React/DOM/Props.purs @@ -2,10 +2,9 @@ module React.DOM.Props where import Prelude -import Data.Nullable (Nullable) import Effect (Effect) import Effect.Uncurried (mkEffectFn1) -import React (ReactRef) +import React.Ref as Ref import React.SyntheticEvent ( SyntheticEvent , SyntheticAnimationEvent @@ -894,8 +893,8 @@ onScrollCapture f = unsafeMkProps "onScrollCapture" (mkEffectFn1 f) onWheelCapture :: (SyntheticWheelEvent -> Effect Unit) -> Props onWheelCapture f = unsafeMkProps "onWheelCapture" (mkEffectFn1 f) -ref :: (Nullable ReactRef -> Effect Unit) -> Props -ref f = unsafeMkProps "ref" (mkEffectFn1 f) +ref :: Ref.RefHandler Ref.NativeNode -> Props +ref = unsafeMkProps "ref" suppressContentEditableWarning :: Boolean -> Props suppressContentEditableWarning = unsafeMkProps "suppressContentEditableWarning" diff --git a/src/React/Ref.js b/src/React/Ref.js new file mode 100644 index 0000000..a08fe02 --- /dev/null +++ b/src/React/Ref.js @@ -0,0 +1,13 @@ +"use strict"; + +var React = require("react"); + +exports.createRef = React.createRef; + +exports.liftCallbackRef = function(ref) { + return { current: ref }; +} + +exports.getCurrentRef_ = function(ref) { + return ref.current; +} diff --git a/src/React/Ref.purs b/src/React/Ref.purs new file mode 100644 index 0000000..8d05a16 --- /dev/null +++ b/src/React/Ref.purs @@ -0,0 +1,57 @@ +module React.Ref + ( Ref + , RefHandler + , ReactInstance + , NativeNode + , fromRef + , fromEffect + , getCurrentRef + , createNodeRef + , createInstanceRef + ) where + +import Prelude +import Effect (Effect) +import Data.Maybe (Maybe) +import Data.Nullable (Nullable) +import Data.Nullable as Nullable +import Effect.Uncurried (EffectFn1, runEffectFn1, mkEffectFn1) +import Unsafe.Coerce (unsafeCoerce) + +--- | An instance of a React class. +foreign import data ReactInstance :: Type + +--- | A platform-specific native layout node. On the web this will be a DOM +--- | element (see `Web.HTML.HTMLElement`). +foreign import data NativeNode :: Type + +foreign import data Ref :: Type -> Type + +foreign import data RefHandler :: Type -> Type + + +foreign import createRef :: forall a. Effect (Ref a) + +foreign import liftCallbackRef :: forall a. Ref a -> Ref a + + +createNodeRef :: Effect (Ref NativeNode) +createNodeRef = createRef + + +createInstanceRef :: Effect (Ref ReactInstance) +createInstanceRef = createRef + + +fromRef :: forall a. Ref a -> RefHandler a +fromRef = unsafeCoerce + + +fromEffect :: forall a. (Ref a -> Effect Unit) -> RefHandler a +fromEffect f = unsafeCoerce $ mkEffectFn1 (f <<< liftCallbackRef) + + +foreign import getCurrentRef_ :: forall a. EffectFn1 (Ref a) (Nullable a) + +getCurrentRef :: forall a. Ref a -> Effect (Maybe a) +getCurrentRef ref = Nullable.toMaybe <$> runEffectFn1 getCurrentRef_ ref