reposition properly when new sticky inserted

This commit is contained in:
Shawn Erquhart 2017-03-24 14:18:33 -04:00
parent fc5d935e53
commit de900eeb39

View File

@ -1,17 +1,30 @@
import React, { Component, PropTypes } from 'react';
import classnames from 'classnames';
import { partial, without } from 'lodash';
import styles from './Sticky.css';
export class StickyContext extends Component {
static childContextTypes = { subscribeToStickyContext: PropTypes.func };
static childContextTypes = {
subscribeToStickyContext: PropTypes.func,
unsubscribeToStickyContext: PropTypes.func,
requestUpdate: PropTypes.func,
};
constructor(props) {
super(props);
this.subscriptions = [];
}
subscribeToStickyContext = (fn) => {
this.subscriptions.push(fn);
};
getChildContext() {
return { subscribeToStickyContext: (fn) => { this.subscriptions.push(fn); } };
return {
subscribeToStickyContext: this.subscribeToStickyContext,
unsubscribeToStickyContext: (fn) => { this.subscriptions = without(this.subscriptions, fn); },
requestUpdate: () => { window.setTimeout(() => { this.updateStickies.call(this, this.ref); }); },
};
}
updateStickies = (ref) => {
@ -42,24 +55,41 @@ export class StickyContainer extends Component {
this.subscriptions = [];
}
static contextTypes = { subscribeToStickyContext: PropTypes.func };
static childContextTypes = { subscribeToStickyContainer: PropTypes.func };
static contextTypes = {
subscribeToStickyContext: PropTypes.func,
unsubscribeToStickyContext: PropTypes.func,
requestUpdate: PropTypes.func,
};
static childContextTypes = {
subscribeToStickyContainer: PropTypes.func,
unsubscribeToStickyContainer: PropTypes.func,
requestUpdate: PropTypes.func,
};
getChildContext() {
return { subscribeToStickyContainer: (fn) => { this.subscriptions.push(fn); } };
return {
subscribeToStickyContainer: (fn) => { this.subscriptions.push(fn); },
unsubscribeToStickyContainer: (fn) => { this.subscriptions = without(this.subscriptions, fn); },
requestUpdate: () => { this.context.requestUpdate.call(this); },
};
}
getPosition = (contextTop) => {
const rect = this.ref.getBoundingClientRect();
const shouldStick = rect.top < contextTop;
const shouldStickAtBottom = rect.bottom - 60 < contextTop;
this.subscriptions.forEach((fn) => { fn(shouldStick, shouldStickAtBottom, rect.width) });
this.subscriptions.forEach((fn) => { fn(shouldStick, shouldStickAtBottom, rect.width); });
};
componentDidMount() {
this.context.subscribeToStickyContext(this.getPosition);
}
componentWillUnmount() {
this.context.unsubscribeToStickyContext(this.getPosition);
}
render() {
return (
<div
@ -74,7 +104,11 @@ export class StickyContainer extends Component {
}
export class Sticky extends Component {
static contextTypes = { subscribeToStickyContainer: PropTypes.func };
static contextTypes = {
subscribeToStickyContainer: PropTypes.func,
unsubscribeToStickyContainer: PropTypes.func,
requestUpdate: PropTypes.func,
};
constructor(props, context) {
super(props, context);
@ -87,6 +121,11 @@ export class Sticky extends Component {
componentDidMount() {
this.context.subscribeToStickyContainer(this.updateSticky);
this.context.requestUpdate();
}
componentWillUnmount() {
this.context.unsubscribeToStickyContainer(this.updateSticky);
}
render() {