Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

105 rader
2.7 KiB

  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import SmoothScrollbar from 'smooth-scrollbar';
  4. export default class Scrollbar extends React.Component {
  5. static propTypes = {
  6. damping: PropTypes.number,
  7. thumbMinSize: PropTypes.number,
  8. syncCallbacks: PropTypes.bool,
  9. renderByPixels: PropTypes.bool,
  10. alwaysShowTracks: PropTypes.bool,
  11. continuousScrolling: PropTypes.bool,
  12. wheelEventTarget: PropTypes.element,
  13. plugins: PropTypes.object,
  14. onScroll: PropTypes.func,
  15. children: PropTypes.node,
  16. };
  17. static childContextTypes = {
  18. getScrollbar: PropTypes.func,
  19. };
  20. constructor(props) {
  21. super(props);
  22. this.callbacks = [];
  23. }
  24. getChildContext() {
  25. return {
  26. getScrollbar: (cb) => {
  27. if (typeof cb !== 'function') return;
  28. if (this.scrollbar) setTimeout(() => cb(this.scrollbar));
  29. else this.callbacks.push(cb);
  30. }
  31. };
  32. }
  33. componentDidMount() {
  34. this.scrollbar = SmoothScrollbar.init(this.$container, this.props);
  35. this.callbacks.forEach((cb) => {
  36. requestAnimationFrame(() => cb(this.scrollbar));
  37. });
  38. this.scrollbar.addListener(this.handleScroll.bind(this));
  39. }
  40. componentWillUnmount() {
  41. if (this.scrollbar) {
  42. this.scrollbar.destroy();
  43. }
  44. }
  45. componentWillReceiveProps(nextProps) {
  46. Object.keys(nextProps).forEach((key) => {
  47. if (!key in this.scrollbar.options) {
  48. return;
  49. }
  50. if (key === 'plugins') {
  51. Object.keys(nextProps.plugins).forEach((pluginName) => {
  52. this.scrollbar.updatePluginOptions(pluginName, nextProps.plugins[pluginName]);
  53. });
  54. } else {
  55. this.scrollbar.options[key] = nextProps[key];
  56. }
  57. });
  58. }
  59. componentDidUpdate() {
  60. this.scrollbar && this.scrollbar.update();
  61. }
  62. handleScroll(status) {
  63. if (this.props.onScroll) {
  64. this.props.onScroll(status, this.scrollbar);
  65. }
  66. }
  67. render() {
  68. const {
  69. damping,
  70. thumbMinSize,
  71. syncCallbacks,
  72. renderByPixels,
  73. alwaysShowTracks,
  74. continuousScrolling,
  75. wheelEventTarget,
  76. plugins,
  77. onScroll,
  78. children,
  79. ...others,
  80. } = this.props;
  81. return (
  82. <section data-scrollbar ref={element => this.$container = element} {...others}>
  83. <div>{children}</div>
  84. </section>
  85. );
  86. }
  87. }