CustomScrollbar.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import React, { Component } from 'react';
  2. import isNil from 'lodash/isNil';
  3. import classNames from 'classnames';
  4. import Scrollbars from 'react-custom-scrollbars';
  5. interface Props {
  6. className?: string;
  7. autoHide?: boolean;
  8. autoHideTimeout?: number;
  9. autoHideDuration?: number;
  10. autoHeightMax?: string;
  11. hideTracksWhenNotNeeded?: boolean;
  12. renderTrackHorizontal?: React.FunctionComponent<any>;
  13. renderTrackVertical?: React.FunctionComponent<any>;
  14. scrollTop?: number;
  15. setScrollTop: (event: any) => void;
  16. autoHeightMin?: number | string;
  17. updateAfterMountMs?: number;
  18. }
  19. /**
  20. * Wraps component into <Scrollbars> component from `react-custom-scrollbars`
  21. */
  22. export class CustomScrollbar extends Component<Props> {
  23. static defaultProps: Partial<Props> = {
  24. autoHide: false,
  25. autoHideTimeout: 200,
  26. autoHideDuration: 200,
  27. setScrollTop: () => {},
  28. hideTracksWhenNotNeeded: false,
  29. autoHeightMin: '0',
  30. autoHeightMax: '100%',
  31. };
  32. private ref: React.RefObject<Scrollbars>;
  33. constructor(props: Props) {
  34. super(props);
  35. this.ref = React.createRef<Scrollbars>();
  36. }
  37. updateScroll() {
  38. const ref = this.ref.current;
  39. if (ref && !isNil(this.props.scrollTop)) {
  40. ref.scrollTop(this.props.scrollTop);
  41. }
  42. }
  43. componentDidMount() {
  44. this.updateScroll();
  45. // this logic is to make scrollbar visible when content is added body after mount
  46. if (this.props.updateAfterMountMs) {
  47. setTimeout(() => this.updateAfterMount(), this.props.updateAfterMountMs);
  48. }
  49. }
  50. updateAfterMount() {
  51. if (this.ref && this.ref.current) {
  52. const scrollbar = this.ref.current as any;
  53. if (scrollbar.update) {
  54. scrollbar.update();
  55. }
  56. }
  57. }
  58. componentDidUpdate() {
  59. this.updateScroll();
  60. }
  61. render() {
  62. const {
  63. className,
  64. children,
  65. autoHeightMax,
  66. autoHeightMin,
  67. setScrollTop,
  68. autoHide,
  69. autoHideTimeout,
  70. hideTracksWhenNotNeeded,
  71. renderTrackHorizontal,
  72. renderTrackVertical,
  73. } = this.props;
  74. return (
  75. <Scrollbars
  76. ref={this.ref}
  77. className={classNames('custom-scrollbar', className)}
  78. onScroll={setScrollTop}
  79. autoHeight={true}
  80. autoHide={autoHide}
  81. autoHideTimeout={autoHideTimeout}
  82. hideTracksWhenNotNeeded={hideTracksWhenNotNeeded}
  83. // These autoHeightMin & autoHeightMax options affect firefox and chrome differently.
  84. // Before these where set to inhert but that caused problems with cut of legends in firefox
  85. autoHeightMax={autoHeightMax}
  86. autoHeightMin={autoHeightMin}
  87. renderTrackHorizontal={renderTrackHorizontal || (props => <div {...props} className="track-horizontal" />)}
  88. renderTrackVertical={renderTrackVertical || (props => <div {...props} className="track-vertical" />)}
  89. renderThumbHorizontal={props => <div {...props} className="thumb-horizontal" />}
  90. renderThumbVertical={props => <div {...props} className="thumb-vertical" />}
  91. renderView={props => <div {...props} className="view" />}
  92. >
  93. {children}
  94. </Scrollbars>
  95. );
  96. }
  97. }
  98. export default CustomScrollbar;