Skip to content

Instantly share code, notes, and snippets.

@kmayer
Created April 28, 2016 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmayer/8f1ea347cf688b0bc0f866856ec9aedc to your computer and use it in GitHub Desktop.
Save kmayer/8f1ea347cf688b0bc0f866856ec9aedc to your computer and use it in GitHub Desktop.
<StickyHeadingList> react component
var _css = require("./sticky_heading_list.scss");
// import from https://github.com/polarblau/stickySectionHeaders
// requires jQuery as a global
(function($){
/* A little helper to calculate the sum of different
* CSS properties
*
* EXAMPLE:
* $('#my-div').cssSum('paddingLeft', 'paddingRight');
*/
$.fn.cssSum = function() {
var $self = $(this), sum = 0;
$(arguments).each(function(i, e) {
sum += parseInt($self.css(e) || 0, 10);
});
return sum;
};
})(jQuery);
/* example use:
<StickyHeadingList>
<section class="sticky-section">
<header>Sticky-ish header</header>
<div>content</div>
<div>content</div>
...
</section>
<section class="sticky-section">
<header>Next sticky-ish header</header>
<div>more content</div>
<div>more content</div>
...
</section>
</StickyHeadingList>
The section and header elements are *required*
*/
var StickyHeadingList = React.createClass({
propType: {
children: React.PropTypes.element.isRequired
},
handleScroll: function(_event) {
var $el = $(this.refs.stickyList);
$el.find('section.sticky-section').each(function() {
var $this = $(this),
top = $this.position().top,
height = $this.outerHeight(),
$head = $this.find('header'),
headHeight = $head.outerHeight();
if (top < 0) {
$this.addClass('sticky').css('paddingTop', headHeight);
$head.css({
'top' : (height + top < headHeight) ? (headHeight - (top + height)) * -1 : '',
'width': $this.outerWidth() - $head.cssSum('paddingLeft', 'paddingRight')
});
} else {
$this.removeClass('sticky').css('paddingTop', '');
}
});
},
render: function() {
return (
<div className="sticky-heading-list">
<article ref="stickyList" className="sticky-list-wrapper" onScroll={this.handleScroll}>
{this.props.children}
</article>
</div>
);
}
});
module.exports = StickyHeadingList;
// The main container will vertically fill its container
.sticky-heading-list {
height: 100%;
overflow: hidden;
position: relative;
// The main list
& article.sticky-list-wrapper {
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
// Section headers when "sticky"
& section.sticky-section.sticky header {
position: absolute;
top: 0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment