# All files / components/Table TableWrap.js

0% Statements 0/59
0% Branches 0/18
0% Functions 0/12
0% Lines 0/32

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102

     import React from 'react';
    import PropTypes from 'prop-types';
    import _ from 'lodash';
    import TableWrapShadow from './styles/TableWrapShadow';

    // FIXME: profiling suggests this component is inefficient with rendering.

    class TableWrap extends React.Component {
      static propTypes = {
        children: PropTypes.node.isRequired,
        /**
         * A component to render as the wrapping component.
         * Passed a prop, 'shadow'=['left'|'right'|'both'], to indicate
         * the scroll position and what side of the wrapper should be shadowed.
         */
        Styles: PropTypes.func.isRequired,
      };

      static defaultProps = {
        Styles: TableWrapShadow,
      };

      state = {
        shadow: null,
      };

      componentDidMount() {
        this.updateAndSubscribeWrapShadowChanges();
      }

      componentDidUpdate() {
        this.updateAndSubscribeWrapShadowChanges();
      }

      updateAndSubscribeWrapShadowChanges = () => {
        this.setWrapShadow(this.computeWrapShadow());

        this._wrap.addEventListener(
          'scroll',
          _.debounce(
            () => {
              this.setWrapShadow(this.computeWrapShadow());
            },
            300,
            { leading: true },
          ),
        );

        window.addEventListener(
          'resize',
          _.debounce(
            () => {
              this.setWrapShadow(this.computeWrapShadow());
            },
            300,
            { leading: true },
          ),
        );
      };

      setWrapShadow = shadow => {
        if (this.state.shadow === shadow) {
          return;
        }

        this.setState({ shadow });
      };

      computeWrapShadow = () => {
        const wrap = this._wrap;

        if (!wrap) {
          return null;
        }

        const left = wrap.scrollLeft > 0;
        const right = wrap.scrollWidth !== wrap.clientWidth + wrap.scrollLeft;

        if (left && right) {
          return 'both';
        } else if (left) {
          return 'left';
        } else if (right) {
          return 'right';
        }

        return null;
      };

      render() {
        const { children, Styles } = this.props;

        return (
          <Styles innerRef={el => (this._wrap = el)} shadow={this.state.shadow}>
            {children}
          </Styles>
        );
      }
    }

    export default TableWrap;