@shopify/polaris
Version:
Shopify’s product component library
82 lines (81 loc) • 2.79 kB
JavaScript
import React from 'react';
import { getRectForNode } from '@shopify/javascript-utilities/geometry';
import { withAppProvider, } from '../../utilities/with-app-provider';
class Sticky extends React.Component {
constructor() {
super(...arguments);
this.state = {
isSticky: false,
style: {},
};
this.placeHolderNode = null;
this.stickyNode = null;
this.setPlaceHolderNode = (node) => {
this.placeHolderNode = node;
};
this.setStickyNode = (node) => {
this.stickyNode = node;
};
this.handlePositioning = (stick, top = 0, left = 0, width = 0) => {
const { isSticky } = this.state;
if ((stick && !isSticky) || (!stick && isSticky)) {
this.adjustPlaceHolderNode(stick);
this.setState({ isSticky: !isSticky });
}
const style = stick
? {
position: 'fixed',
top,
left,
width,
}
: {};
this.setState({ style });
};
this.adjustPlaceHolderNode = (add) => {
if (this.placeHolderNode && this.stickyNode) {
this.placeHolderNode.style.paddingBottom = add
? `${getRectForNode(this.stickyNode).height}px`
: '0px';
}
};
}
componentDidMount() {
const { boundingElement, offset = false, disableWhenStacked = false, polaris: { stickyManager }, } = this.props;
if (!this.stickyNode || !this.placeHolderNode)
return;
stickyManager.registerStickyItem({
stickyNode: this.stickyNode,
placeHolderNode: this.placeHolderNode,
handlePositioning: this.handlePositioning,
offset,
boundingElement,
disableWhenStacked,
});
}
componentWillUnmount() {
const { stickyManager } = this.props.polaris;
if (!this.stickyNode)
return;
stickyManager.unregisterStickyItem(this.stickyNode);
}
render() {
const { style, isSticky } = this.state;
const { children } = this.props;
const childrenContent = isFunction(children)
? children(isSticky)
: children;
return (<div>
<div ref={this.setPlaceHolderNode}/>
<div ref={this.setStickyNode} style={style}>
{childrenContent}
</div>
</div>);
}
}
function isFunction(arg) {
return typeof arg === 'function';
}
// Use named export once withAppProvider is refactored away
// eslint-disable-next-line import/no-default-export
export default withAppProvider()(Sticky);