Skip to content

Commit ca7e5f0

Browse files
maxmalovredonkulus
authored andcommitted
Introduce children function support (#120)
I've found that children function support allows to pass sticky state to children components in a very handy way. This approach can be used instead of introducing another wrapper component that will handle state change with `onStateChange` and pass it to children components
1 parent f3f90ba commit ca7e5f0

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

README.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import Sticky from 'react-stickynode';
6060

6161
### Handling State Change
6262

63-
You can be notified when the state of the sticky component changes by passing a callback to the `onStateChange` prop. The callback will receive an object in the format `{status: CURRENT_STATUS}`, with `CURRENT_STATUS` being an integer representing the status:
63+
You can be notified when the state of the sticky component changes by passing a callback to the `onStateChange` prop. The callback will receive an object in the format `{status: CURRENT_STATUS}`, with `CURRENT_STATUS` being an integer representing the status:
6464

6565
| Value | Name | Note|
6666
|-----|-----|-----|
@@ -83,9 +83,27 @@ const handleStateChange = (status) => {
8383
</Sticky>
8484
```
8585

86-
### Freezing
86+
Also `Sticky` supports children functions:
8787

88-
You can provide a function in the `shouldFreeze` prop which will tell the component to temporarily stop updating during prop and state changes, as well as ignore scroll and resize events. This function should return a boolean indicating whether the component should currently be frozen.
88+
```js
89+
import Sticky from 'react-stickynode';
90+
91+
<Sticky>
92+
{status => {
93+
if (status.status === Sticky.STATUS_FIXED) {
94+
return 'the component is sticky';
95+
}
96+
if (status.status === Sticky.STATUS_ORIGINAL) {
97+
return 'the component in the original position';
98+
}
99+
return 'the component is released'
100+
}}
101+
</Sticky>
102+
```
103+
104+
### Freezing
105+
106+
You can provide a function in the `shouldFreeze` prop which will tell the component to temporarily stop updating during prop and state changes, as well as ignore scroll and resize events. This function should return a boolean indicating whether the component should currently be frozen.
89107

90108
## Install & Development
91109

src/Sticky.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,12 @@ class Sticky extends Component {
380380
[this.props.releasedClass]: this.state.status === STATUS_RELEASED
381381
})
382382

383+
var children = this.props.children;
384+
383385
return (
384386
<div ref={(outer) => { this.outerElement = outer; }} className={outerClasses} style={outerStyle}>
385387
<div ref={(inner) => { this.innerElement = inner; }} className='sticky-inner-wrapper' style={innerStyle}>
386-
{this.props.children}
388+
{typeof children === 'function' ? children({ status: this.state.status }) : children}
387389
</div>
388390
</div>
389391
);

tests/unit/Sticky-test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,22 @@ describe('Sticky', function () {
171171
sinon.assert.calledWith(callback.secondCall, {status: Sticky.STATUS_ORIGINAL});
172172
});
173173

174+
it('should call the children function on state change', function () {
175+
var childrenStub = sinon.stub().returns(null);
176+
jsx.renderComponent(Sticky, { children: childrenStub });
177+
178+
sinon.assert.notCalled(childrenStub);
179+
180+
// Scroll down to 10px, and status should change to FIXED
181+
window.scrollTo(0, 10);
182+
sinon.assert.calledWith(childrenStub, {status: Sticky.STATUS_FIXED});
183+
184+
// Scroll up to 0px, and Sticky should reset
185+
window.scrollTo(0, 0);
186+
sinon.assert.calledTwice(childrenStub);
187+
sinon.assert.calledWith(childrenStub.secondCall, {status: Sticky.STATUS_ORIGINAL});
188+
});
189+
174190
it('should work as expected (long Sticky)', function () {
175191
STICKY_HEIGHT = 1200;
176192
sticky = jsx.renderComponent(Sticky);

0 commit comments

Comments
 (0)