Skip to content

Commit 36f6865

Browse files
author
Federico Zivolo
committed
feat: Added child function support
1 parent 97b1e62 commit 36f6865

File tree

6 files changed

+107
-25
lines changed

6 files changed

+107
-25
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,25 @@ function App() {
117117
}
118118
```
119119

120+
## Child function
121+
122+
Whenever you want to manipulate the `width` and `height` properties before they
123+
get passed down to the child component, you can define a function as child of ResizeAware:
124+
125+
```jsx
126+
import React from 'react';
127+
import ResizeAware from 'react-resize-aware';
128+
129+
export default makeResizeAware(function MyComponent({width, height, getRef, children})) {
130+
return (
131+
<ResizeAware style={{ position: 'relative' }}>
132+
{({ width, height }) =>
133+
<div style={{ width: width / 2, height: height / 2 }} />}
134+
</ResizeAware>
135+
);
136+
})
137+
```
138+
120139
## Decorator/enhancer
121140

122141
In case you prefer to directly decorate your component to add to it the ResizeAware

docs/react-resize-aware.js

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-resize-aware",
3-
"version": "2.6.0",
3+
"version": "2.7.0",
44
"description": "A resize aware component used to detect sizes changes on your components",
55
"main": "dist/index.js",
66
"scripts": {

src/__snapshots__/index.spec.jsx.snap

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,50 @@ exports[`allows to define custom width and height names 1`] = `
111111
<Test
112112
customHeight={10}
113113
customWidth={10}
114-
>
115-
<div
116-
customHeight={10}
117-
customWidth={10}
118-
/>
119-
</Test>
114+
/>
115+
</div>
116+
</ResizeAware>
117+
`;
118+
119+
exports[`allows to use a function as child 1`] = `
120+
<ResizeAware
121+
component="div"
122+
style={
123+
Object {
124+
"position": "relative",
125+
}
126+
}
127+
>
128+
<div
129+
style={
130+
Object {
131+
"position": "relative",
132+
}
133+
}
134+
>
135+
<object
136+
aria-hidden={true}
137+
onLoad={[Function]}
138+
style={
139+
Object {
140+
"display": "block",
141+
"height": "100%",
142+
"left": 0,
143+
"overflow": "hidden",
144+
"pointerEvents": "none",
145+
"position": "absolute",
146+
"top": 0,
147+
"width": "100%",
148+
"zIndex": -1,
149+
}
150+
}
151+
tabIndex={-1}
152+
type="text/html"
153+
/>
154+
<div
155+
height={10}
156+
width={10}
157+
/>
120158
</div>
121159
</ResizeAware>
122160
`;

src/index.js

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
// Copyright 2016, Federico Zivolo
77
//
88

9-
import { createElement, Component, Children, cloneElement } from 'react';
9+
import {
10+
createElement,
11+
Component,
12+
Children,
13+
cloneElement,
14+
isValidElement,
15+
} from 'react';
1016

1117
const style = {
1218
display: 'block',
@@ -81,12 +87,16 @@ export default class ResizeAware extends Component {
8187
const widthProp = [widthPropName || 'width'];
8288
const heightProp = [heightPropName || 'height'];
8389

90+
const sizes = {
91+
[widthProp]: width,
92+
[heightProp]: height,
93+
};
94+
8495
return createElement(
8596
component,
8697
{
8798
[hasCustomComponent ? 'getRef' : 'ref']: el => (this.container = el),
88-
[widthProp]: hasCustomComponent ? width : undefined,
89-
[heightProp]: hasCustomComponent ? height : undefined,
99+
...(hasCustomComponent && sizes),
90100
...props,
91101
},
92102
createElement('object', {
@@ -97,12 +107,15 @@ export default class ResizeAware extends Component {
97107
'aria-hidden': true,
98108
tabIndex: -1,
99109
}),
100-
Children.map(children, child =>
101-
cloneElement(
102-
child,
103-
!onlyEvent ? { [widthProp]: width, [heightProp]: height } : null
104-
)
105-
)
110+
typeof children === 'function'
111+
? children({ width, height })
112+
: Children.map(
113+
children,
114+
child =>
115+
isValidElement(child)
116+
? cloneElement(child, !onlyEvent ? sizes : null)
117+
: child
118+
)
106119
);
107120
}
108121
}

src/index.spec.jsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ it('applies aria attributes to <object> to avoid screenreader issues', () => {
6363
});
6464

6565
it('allows to define custom width and height names', () => {
66-
const Test = props => <div {...props} />;
66+
const Test = props => null;
6767
const wrapper = mount(
6868
<ResizeAware
6969
style={{ position: 'relative' }}
@@ -78,3 +78,15 @@ it('allows to define custom width and height names', () => {
7878

7979
expect(toJson(wrapper)).toMatchSnapshot();
8080
});
81+
82+
it('allows to use a function as child', () => {
83+
const wrapper = mount(
84+
<ResizeAware style={{ position: 'relative' }}>
85+
{({ width, height }) => <div width={width} height={height} />}
86+
</ResizeAware>
87+
);
88+
89+
wrapper.setState({ width: 10, height: 10 });
90+
91+
expect(toJson(wrapper)).toMatchSnapshot();
92+
});

0 commit comments

Comments
 (0)