drifterOcean19
drifterOcean19

Reputation: 392

Flow - missing type annotation

Pretty new to flow and trying to fix my code to include flow. This is my code at the moment and I've added flow type check and now getting errors so I need to annotate my code properly:

// @flow
import React, { Component } from 'react';
import { Manager, Reference, Popper } from 'react-popper';

import cx from 'classnames';
import css from './Tooltip.css';
import animationsCss from './TooltipAnimations.css';

type Props = {
  theme: string,
  eventsEnabled: boolean,
}
class Tooltip extends Component<Props> {
  static defaultProps = {
    theme: 'light',
    eventsEnabled: true
  };

  firstOrderPlacement(placement) {
    if (!placement) return null;
    return placement.split('-')[0];
  }

  arrowDirectionClass(firstOrderPlacement) {
    switch (firstOrderPlacement) {
      case 'right':
        return css.arrowLeft;
      case 'left':
        return css.arrowRight;
      case 'top':
        return css.arrowDown;
      case 'bottom':
        return css.arrowUp;
      default:
        return css.arrowUp;
    }
  }

  render() {
    const { placement, className, children, fadeIn, theme, eventsEnabled } = this.props;

    return (
      <Popper placement={placement} eventsEnabled={eventsEnabled}>
        {({ ref, style, placement }) => {
          const firstOrderPlacement = this.firstOrderPlacement(placement);
          const arrowDirectionClass = this.arrowDirectionClass(firstOrderPlacement);
          const subContainerStyle = {
            display: 'flex',
            flexDirection:
              firstOrderPlacement === 'top' || firstOrderPlacement === 'bottom' ? 'column' : 'row',
          };
          const childrenContainerClassName = cx(
            css.childrenContainer,
            css.wrapper,
            theme === "dark" ? css.dark : css.light
          );
          const content = <div className={childrenContainerClassName}>{children}</div>;
          const subContainerClassName = fadeIn ? cx(animationsCss.fadeIn, className) : className;

          return (
            <div
              ref={ref}
              className={cx(css.container, css.mobileTooltip)}
              style={style}
              data-placement={placement}
            >
              <div className={subContainerClassName} style={subContainerStyle}>
                {(firstOrderPlacement === 'left' || firstOrderPlacement === 'top') && content}
                <div>
                  <div className={cx(css.arrow, arrowDirectionClass)} />
                </div>
                {(firstOrderPlacement === 'right' || firstOrderPlacement === 'bottom') && content}
              </div>
            </div>
          );
        }}
      </Popper>
    );
  }
}

export { Manager as TooltipManager, Reference as TooltipReference, Tooltip };

I believe I need to add these to my props. Are these correct?

  placement: string,
  className?: string,
  children?: any,
  fadeIn: any,

I'm missing type annotation for these two which I'm not sure how to proceed:

  firstOrderPlacement(placement) {..}

  arrowDirectionClass(firstOrderPlacement) {..}

Any help?

Upvotes: 1

Views: 5370

Answers (2)

Marko Savic
Marko Savic

Reputation: 2394

Annotate Props like:

type Props = {
  ...
  placement: string,
  className?: string,
  children?: any,
  fadeIn: any,
  ...
}

Placement parameter is string firstOrderPlacement(placement) {..} and return value of function is null or string, so you can use maybe type for annotation:

firstOrderPlacement(placement: string): ?string => {...}

Or with union type because maybe type covers undefined.

type FirstOrder = string | null;

Result of firstOrderPlacement function is parameter of arrowDirectionClass. So type of parameter:

arrowDirectionClass(firstOrderPlacement: ?string): string => {...}

Or:

arrowDirectionClass(firstOrderPlacement: FirstOrder): string => {...}

Upvotes: 3

Lyle Underwood
Lyle Underwood

Reputation: 1304

Are these correct?

Try them and find out!

Keep in mind, though, that using any is a shortcut that basically just turns off typing. For children where you are expecting react elements you should usually just use React.node. This will work if you basically want arbitrary nested DOM-like content like react elements, arrays of elements, strings of text, etc. fadeIn looks like it's probably a string, but it's kind of hard to tell without seeing where it comes from.

I'm missing type annotation for these two which I'm not sure how to proceed:

Flow wants you to type the arguments to the functions. Something like:

firstOrderPlacement(placement: string) {

or whatever.

Upvotes: 0

Related Questions