Skip to content

Commit 5a60663

Browse files
authored
support react 16 (#11)
Introduce a breaking change due to the fact that React 16 internals don't work the exact same way than before. For that reason, we now expose "mapDomNodeToProps" property that takes the target node as input and binds the output object properties to the transported component's properties.
1 parent 0b57ed4 commit 5a60663

File tree

7 files changed

+6461
-92
lines changed

7 files changed

+6461
-92
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
language: node_js
22
node_js:
3-
- "4.2"
3+
- "8"

README.md

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ You can also use a selector instead of an id.
7575
```
7676

7777
## Additional features
78+
79+
### Reset styling
80+
7881
The `shouldReset` prop can be used to remove any classes and styles from the DOM node we are rendering to:
7982

8083
```js
@@ -86,31 +89,50 @@ The `shouldReset` prop can be used to remove any classes and styles from the DOM
8689
</ElementPortal>
8790
```
8891

92+
### View property
93+
8994
`ElementPortal` also accepts an optional `view` prop that takes a component, to be rendered inside the portal:
9095

9196
```js
9297
<ElementPortal id="header" view={CoolHeaderComponent} />
9398
```
9499

95-
One advantage of using the `view` prop to specify a component is that any `data-` attributes from the DOM node the portal is rendering to will be passed along to our component as a `data` prop.
96-
For example, if the DOM node we are rendering to looks like this:
100+
One advantage of using the `view` prop is the ability to derive properties from the original DOM node and pass them to the the component.
101+
102+
Let's say our original DOM element already contains some useful data:
97103

98104
```html
99-
<div id="header" data-user-id="26742" data-name="Joe">
100-
...
105+
<div id="header" data-user-id="26742">
106+
Joe
101107
</div>
102108
```
103109

104-
Then our `CoolHeaderComponent` from the example above would receive the following `data` prop:
110+
And we would like to render the following component:
105111

106112
```js
107-
{
108-
'user-id': '26742',
109-
name: 'Joe'
110-
}
113+
const CoolGreeting = ({ userId, name }) => (
114+
<div>Welcome <a href={`/profile/${userId}`}>{name}!</a></div>
115+
)
116+
```
117+
118+
By using the `mapDomNodeToProps` prop, you can easily pass this data like so:
119+
120+
```js
121+
import dataAttributes from 'data-attributes';
122+
123+
const mapDomNodeToProps = (node) => ({
124+
name: node.textContent,
125+
...dataAttributes(node)
126+
});
127+
128+
ReactDOM.render(
129+
<ElementPortal id="header" mapDomNodeToProps={mapDomNodeToProps} />,
130+
document.getElementById('app')
131+
);
111132
```
112133

113134
## Usage as Higher Order Component
135+
114136
`ElementPortal` can also be used as a [HOC](https://facebook.github.io/react/docs/higher-order-components.html):
115137

116138
```js
@@ -140,4 +162,5 @@ const MyComposedComponent = compose(
140162
```
141163

142164
## Passing context to your ElementPortal
165+
143166
Context from your main tree is passed down automatically to your `ElementPortal`. For example, if you use Redux, the `store` context will not get lost, and using `connect` will behave as expected in the children of your `ElementPortal`.

0 commit comments

Comments
 (0)