All files / app/components ExplodeOnChange.tsx

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                              3x           3x 3x           8x           8x                           8x 8x     8x                            
import React from 'react';
import { style } from 'app/styles';
 
export interface ExplodeOnChangeProps {
  value: any;
  children: string | JSX.Element | JSX.Element[];
  initialExplosion?: boolean;
  scale?: number;
  style?: object | string;
}
 
interface ExplodeOnChangeState {
  isExploding: boolean;
}
 
const outerStyle = {
  display: 'inline-block',
  transition: 'all 1s ease',
};
 
// note 2.5 = way too in your face
const DEFAULT_SCALE = 1.8;
const HANG_TIME = 900;
 
export class ExplodeOnChange extends React.Component<
  ExplodeOnChangeProps,
  ExplodeOnChangeState
> {
  readonly state: ExplodeOnChangeState = {
    isExploding: false,
  };
 
  componentDidMount() {
    // let rendering settle or it looks glitchy
    Iif (this.props.initialExplosion) {
      setTimeout(() => {
        this.explode();
      }, 100);
    }
  }
 
  componentDidUpdate(newProps) {
    if (newProps.value !== this.props.value) {
      this.explode();
    }
  }
 
  render() {
    const { scale = DEFAULT_SCALE } = this.props;
    const addStyle = this.state.isExploding
      ? { transform: `scale(${scale}, ${scale})` }
      : null;
    return (
      <div style={style(outerStyle, this.props.style, addStyle)}>
        {this.props.children}
      </div>
    );
  }
 
  private explode() {
    this.setState({ isExploding: true });
    setTimeout(() => {
      this.setState({ isExploding: false });
    }, HANG_TIME);
  }
}