diff --git a/src/index.js b/src/index.js index bf28673..b70e29e 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,7 @@ export default class Headroom extends Component { children: PropTypes.any.isRequired, disableInlineStyles: PropTypes.bool, disable: PropTypes.bool, + pin: PropTypes.bool, upTolerance: PropTypes.number, downTolerance: PropTypes.number, onPin: PropTypes.func, @@ -30,6 +31,7 @@ export default class Headroom extends Component { parent: () => window, disableInlineStyles: false, disable: false, + pin: false, upTolerance: 5, downTolerance: 0, onPin: noop, @@ -149,6 +151,10 @@ export default class Headroom extends Component { ) } } + + if (prevProps.pin !== this.props.pin) { + this.handleScroll() + } } componentWillUnmount() { @@ -343,6 +349,7 @@ export default class Headroom extends Component { delete divProps.onUnfix delete divProps.disableInlineStyles delete divProps.disable + delete divProps.pin delete divProps.parent delete divProps.children delete divProps.upTolerance diff --git a/src/shouldUpdate.js b/src/shouldUpdate.js index ada7a21..cea80b3 100644 --- a/src/shouldUpdate.js +++ b/src/shouldUpdate.js @@ -14,6 +14,13 @@ export default function ( scrollDirection, distanceScrolled, } + // We're pinned + } else if (props.pin) { + return { + action: state.state !== 'pinned' ? 'pin' : 'none', + scrollDirection, + distanceScrolled, + } // We're at the top and not fixed yet. } else if (currentScrollY <= props.pinStart && state.state !== 'unfixed') { return { diff --git a/test/calc.js b/test/calc.js index 1f96c16..f44e09e 100644 --- a/test/calc.js +++ b/test/calc.js @@ -9,6 +9,7 @@ describe('shouldUpdate', () => { propDefaults = { disableInlineStyles: false, disable: false, + pin: false, upTolerance: 0, downTolerance: 0, offset: 0, @@ -217,4 +218,24 @@ describe('shouldUpdate', () => { const result = shouldUpdate(100, 110, propDefaults, state) expect(result.action).to.equal('unpin-snap') }) + + it("should return an action of 'pin' if props.pin is set and not pinned, yet", () => { + const state = { + height: 100, + state: 'something', + } + + const result = shouldUpdate(100, 110, { ...propDefaults, pin: true }, state) + expect(result.action).to.equal('pin') + }) + + it("should return an action of 'none' if props.pin is set and already pinned", () => { + const state = { + height: 100, + state: 'pinned', + } + + const result = shouldUpdate(100, 110, { ...propDefaults, pin: true }, state) + expect(result.action).to.equal('none') + }) }) diff --git a/www/pages/index.md b/www/pages/index.md index 26e80e2..869b15e 100644 --- a/www/pages/index.md +++ b/www/pages/index.md @@ -72,6 +72,7 @@ Another option is to use CSS. The component has a `headroom` class as well as a * `onUnfix` — callback called when header position is no longer fixed * `upTolerance` — scroll tolerance in px when scrolling up before component is pinned * `downTolerance` — scroll tolerance in px when scrolling down before component is pinned +* `pin` — pins the header so that it is always visible * `disable` — disable pinning and unpinning * `wrapperStyle` — pass styles for the wrapper div (this maintains the components vertical space at the top of the page). * `parent` — provide a custom 'parent' element for scroll events. `parent` should be a function which resolves to the desired element.