You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
1.8 KiB

  1. import ColumnHeader from './column_header';
  2. import PureRenderMixin from 'react-addons-pure-render-mixin';
  3. const easingOutQuint = (x, t, b, c, d) => c*((t=t/d-1)*t*t*t*t + 1) + b;
  4. const scrollTop = (node) => {
  5. const startTime = Date.now();
  6. const offset = node.scrollTop;
  7. const targetY = -offset;
  8. const duration = 1000;
  9. let interrupt = false;
  10. const step = () => {
  11. const elapsed = Date.now() - startTime;
  12. const percentage = elapsed / duration;
  13. if (percentage > 1 || interrupt) {
  14. return;
  15. }
  16. node.scrollTop = easingOutQuint(0, elapsed, offset, targetY, duration);
  17. requestAnimationFrame(step);
  18. };
  19. step();
  20. return () => {
  21. interrupt = true;
  22. };
  23. };
  24. const Column = React.createClass({
  25. propTypes: {
  26. heading: React.PropTypes.string,
  27. icon: React.PropTypes.string,
  28. children: React.PropTypes.node,
  29. active: React.PropTypes.bool,
  30. hideHeadingOnMobile: React.PropTypes.bool
  31. },
  32. mixins: [PureRenderMixin],
  33. handleHeaderClick () {
  34. const scrollable = ReactDOM.findDOMNode(this).querySelector('.scrollable');
  35. if (!scrollable) {
  36. return;
  37. }
  38. this._interruptScrollAnimation = scrollTop(scrollable);
  39. },
  40. handleWheel () {
  41. if (typeof this._interruptScrollAnimation !== 'undefined') {
  42. this._interruptScrollAnimation();
  43. }
  44. },
  45. render () {
  46. const { heading, icon, children, active, hideHeadingOnMobile } = this.props;
  47. let header = '';
  48. if (heading) {
  49. header = <ColumnHeader icon={icon} active={active} type={heading} onClick={this.handleHeaderClick} hideOnMobile={hideHeadingOnMobile} />;
  50. }
  51. return (
  52. <div role='section' aria-label={heading} className='column' onWheel={this.handleWheel}>
  53. {header}
  54. {children}
  55. </div>
  56. );
  57. }
  58. });
  59. export default Column;