column.jsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import PropTypes from 'prop-types';
  2. import { PureComponent } from 'react';
  3. import { supportsPassiveEvents } from 'detect-passive-events';
  4. import { scrollTop } from '../scroll';
  5. const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
  6. export default class Column extends PureComponent {
  7. static propTypes = {
  8. children: PropTypes.node,
  9. label: PropTypes.string,
  10. bindToDocument: PropTypes.bool,
  11. };
  12. scrollTop () {
  13. let scrollable = null;
  14. if (this.props.bindToDocument) {
  15. scrollable = document.scrollingElement;
  16. } else {
  17. scrollable = this.node.querySelector('.scrollable');
  18. }
  19. if (!scrollable) {
  20. return;
  21. }
  22. this._interruptScrollAnimation = scrollTop(scrollable);
  23. }
  24. handleWheel = () => {
  25. if (typeof this._interruptScrollAnimation !== 'function') {
  26. return;
  27. }
  28. this._interruptScrollAnimation();
  29. };
  30. setRef = c => {
  31. this.node = c;
  32. };
  33. componentDidMount () {
  34. if (this.props.bindToDocument) {
  35. document.addEventListener('wheel', this.handleWheel, listenerOptions);
  36. } else {
  37. this.node.addEventListener('wheel', this.handleWheel, listenerOptions);
  38. }
  39. }
  40. componentWillUnmount () {
  41. if (this.props.bindToDocument) {
  42. document.removeEventListener('wheel', this.handleWheel, listenerOptions);
  43. } else {
  44. this.node.removeEventListener('wheel', this.handleWheel, listenerOptions);
  45. }
  46. }
  47. render () {
  48. const { label, children } = this.props;
  49. return (
  50. <div role='region' aria-label={label} className='column' ref={this.setRef}>
  51. {children}
  52. </div>
  53. );
  54. }
  55. }