All files / ts/components/navigation footer.tsx

100% Statements 39/39
100% Branches 15/15
100% Functions 8/8
100% Lines 36/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 8032x 32x 32x 32x 32x                   32x 32x 8x 8x     32x 3x 2x 2x       32x 1x 1x     32x 11x 11x 22x 11x 11x     11x                   32x 13x 13x   13x                 8x 2x     32x 10x   10x 4x   6x     32x   32x  
import * as classNames from 'classnames';
import * as React from 'react';
import { HTMLProps, PureComponent } from 'react';
import * as ReactDOM from 'react-dom';
import store from '../../store';
import { ComponentProps } from '../../types';
 
export interface FooterProps extends ComponentProps, HTMLProps<HTMLElement> {
  /**
   * Fix the footer to the bottom of the window when there is not enough content to push it down.
   */
  sticky?: boolean;
}
 
export class Footer extends PureComponent<FooterProps, {}> {
  public componentDidMount() {
    this.notifyAppRoot(this.props);
    this.toggleResizeListeners(this.props);
  }
 
  public componentWillUpdate(nextProps: FooterProps) {
    if (Boolean(this.props.sticky) !== Boolean(nextProps.sticky)) {
      this.notifyAppRoot(nextProps);
      this.toggleResizeListeners(nextProps);
    }
  }
 
  public componentWillUnmount() {
    window.removeEventListener('resize', this.updateAppRoot);
    this.notifyAppRoot({ sticky: false });
  }
 
  public render() {
    const {
      sticky,
      component: Component = 'div',
      children,
      ...remainingProps
    } = this.props;
 
    return (
      <Component
        {...remainingProps}
        className={classNames('footer', sticky && 'sticky')}
      >
        {children}
      </Component>
    );
  }
 
  private notifyAppRoot(props: FooterProps) {
    const { sticky } = props;
    const element = ReactDOM.findDOMNode(this);
 
    store.setState({
      hasStickyFooter: Boolean(sticky),
      footerHeight:
        element && element instanceof HTMLElement
          ? element.getBoundingClientRect().height
          : undefined,
    });
  }
 
  private updateAppRoot = () => {
    this.notifyAppRoot(this.props);
  };
 
  private toggleResizeListeners(props: FooterProps) {
    const { sticky } = props;
 
    if (sticky) {
      window.addEventListener('resize', this.updateAppRoot);
    } else {
      window.removeEventListener('resize', this.updateAppRoot);
    }
  }
}
 
export default Footer;