Created
April 28, 2016 16:57
-
-
Save kmayer/8f1ea347cf688b0bc0f866856ec9aedc to your computer and use it in GitHub Desktop.
<StickyHeadingList> react component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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