Skip to content

Commit 4bf5a5a

Browse files
elliotdaviesethul
authored andcommitted
Add support for createRef API (#172)
* Get refs compiling * Tidy up * Actually include Refs files, duh * Bugfix Ref.js * Add bower.json file * HTMLElement -> NativeNode * Lift callback refs into an object * Missed reference to HTMLElement * Remove unneeded import * Comments * DOM -> Node
1 parent a2e40f9 commit 4bf5a5a

File tree

4 files changed

+75
-11
lines changed

4 files changed

+75
-11
lines changed

src/React.purs

+2-7
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ module React
3232
, pureComponentWithDerivedState
3333
, statelessComponent
3434
, ReactClass
35-
, ReactRef
3635
, getProps
3736
, getState
3837
, setState
@@ -68,11 +67,11 @@ module React
6867

6968
import Prelude
7069

71-
import Data.Nullable (Nullable)
7270
import Effect (Effect)
7371
import Effect.Exception (Error)
7472
import Effect.Uncurried (EffectFn1)
7573
import Prim.Row as Row
74+
import React.Ref as Ref
7675
import Type.Row (type (+))
7776
import Unsafe.Coerce (unsafeCoerce)
7877

@@ -252,10 +251,6 @@ foreign import data ReactClass :: Type -> Type
252251

253252
foreign import fragment :: ReactClass { children :: Children }
254253

255-
-- | Type for React refs. This type is opaque, but you can use `Data.Foreign`
256-
-- | and `DOM` to validate the underlying representation.
257-
foreign import data ReactRef :: Type
258-
259254
-- | Read the component props.
260255
foreign import getProps :: forall props state.
261256
ReactThis props state ->
@@ -340,7 +335,7 @@ class ReactPropFields (required :: # Type) (given :: # Type)
340335

341336
type ReservedReactPropFields r =
342337
( key :: String
343-
, ref :: SyntheticEventHandler (Nullable ReactRef)
338+
, ref :: Ref.RefHandler Ref.ReactInstance
344339
| r
345340
)
346341

src/React/DOM/Props.purs

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ module React.DOM.Props where
22

33
import Prelude
44

5-
import Data.Nullable (Nullable)
65
import Effect (Effect)
76
import Effect.Uncurried (mkEffectFn1)
8-
import React (ReactRef)
7+
import React.Ref as Ref
98
import React.SyntheticEvent
109
( SyntheticEvent
1110
, SyntheticAnimationEvent
@@ -894,8 +893,8 @@ onScrollCapture f = unsafeMkProps "onScrollCapture" (mkEffectFn1 f)
894893
onWheelCapture :: (SyntheticWheelEvent -> Effect Unit) -> Props
895894
onWheelCapture f = unsafeMkProps "onWheelCapture" (mkEffectFn1 f)
896895

897-
ref :: (Nullable ReactRef -> Effect Unit) -> Props
898-
ref f = unsafeMkProps "ref" (mkEffectFn1 f)
896+
ref :: Ref.RefHandler Ref.NativeNode -> Props
897+
ref = unsafeMkProps "ref"
899898

900899
suppressContentEditableWarning :: Boolean -> Props
901900
suppressContentEditableWarning = unsafeMkProps "suppressContentEditableWarning"

src/React/Ref.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"use strict";
2+
3+
var React = require("react");
4+
5+
exports.createRef = React.createRef;
6+
7+
exports.liftCallbackRef = function(ref) {
8+
return { current: ref };
9+
}
10+
11+
exports.getCurrentRef_ = function(ref) {
12+
return ref.current;
13+
}

src/React/Ref.purs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
module React.Ref
2+
( Ref
3+
, RefHandler
4+
, ReactInstance
5+
, NativeNode
6+
, fromRef
7+
, fromEffect
8+
, getCurrentRef
9+
, createNodeRef
10+
, createInstanceRef
11+
) where
12+
13+
import Prelude
14+
import Effect (Effect)
15+
import Data.Maybe (Maybe)
16+
import Data.Nullable (Nullable)
17+
import Data.Nullable as Nullable
18+
import Effect.Uncurried (EffectFn1, runEffectFn1, mkEffectFn1)
19+
import Unsafe.Coerce (unsafeCoerce)
20+
21+
--- | An instance of a React class.
22+
foreign import data ReactInstance :: Type
23+
24+
--- | A platform-specific native layout node. On the web this will be a DOM
25+
--- | element (see `Web.HTML.HTMLElement`).
26+
foreign import data NativeNode :: Type
27+
28+
foreign import data Ref :: Type -> Type
29+
30+
foreign import data RefHandler :: Type -> Type
31+
32+
33+
foreign import createRef :: forall a. Effect (Ref a)
34+
35+
foreign import liftCallbackRef :: forall a. Ref a -> Ref a
36+
37+
38+
createNodeRef :: Effect (Ref NativeNode)
39+
createNodeRef = createRef
40+
41+
42+
createInstanceRef :: Effect (Ref ReactInstance)
43+
createInstanceRef = createRef
44+
45+
46+
fromRef :: forall a. Ref a -> RefHandler a
47+
fromRef = unsafeCoerce
48+
49+
50+
fromEffect :: forall a. (Ref a -> Effect Unit) -> RefHandler a
51+
fromEffect f = unsafeCoerce $ mkEffectFn1 (f <<< liftCallbackRef)
52+
53+
54+
foreign import getCurrentRef_ :: forall a. EffectFn1 (Ref a) (Nullable a)
55+
56+
getCurrentRef :: forall a. Ref a -> Effect (Maybe a)
57+
getCurrentRef ref = Nullable.toMaybe <$> runEffectFn1 getCurrentRef_ ref

0 commit comments

Comments
 (0)