All files / app/components ZoomContainer.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 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 103 104 105 106 107 108 109 110 111 112                                              3x           3x         3x         3x           3x           3x     1x 1x   1x           4x     4x                                                   4x 24x       4x 24x               3x 1x 1x      
import React from 'react';
import { style } from 'app/styles';
 
import { HorizontalScroller } from 'app/components/HorizontalScroller';
 
export interface ICustomZoom {
  label: string;
  value: number;
}
 
export interface ZoomContainerProps {
  // The children are the menu content
  children: string | JSX.Element | JSX.Element[];
  scrollLeft?: number;
  customZooms?: ICustomZoom[];
  onZoom?: (value: number) => void;
  onMouseEnter?: (evt: object) => void;
  onMouseLeave?: (evt: object) => void;
  onScroll?: (scrollLeft: number) => void;
  // applied to the selector only
  style?: string | object;
}
 
const initialState = {
  zoom: 100,
};
 
type ZoomContainerState = Readonly<typeof initialState>;
 
const outerStyle = {
  _extends: 'fill',
  position: 'relative',
};
 
const scrollContainerStyle = {
  height: '100%',
  // width: is computed based on state.zoom
};
 
const zoomSelectorStyle = {
  position: 'absolute',
  right: 18,
  background: 'transparent',
};
 
const availableZooms = [100, 200, 300, 500, 800, 1300];
 
export class ZoomContainer extends React.Component<
  ZoomContainerProps,
  ZoomContainerState
> {
  readonly state: ZoomContainerState = initialState;
 
  componentDidUpdate(prevProps, prevState) {
    Eif (prevState.zoom !== this.state.zoom && this.props.onZoom) {
      this.props.onZoom(this.state.zoom);
    }
    Iif (prevProps.customZooms !== this.props.customZooms) {
      this.setState({ zoom: initialState.zoom });
    }
  }
 
  render() {
    const zoomStyle = {
      width: `${this.state.zoom || 100}%`,
    };
    return (
      <div
        style={style(outerStyle)}
        onMouseEnter={this.props.onMouseEnter}
        onMouseLeave={this.props.onMouseLeave}
      >
        <HorizontalScroller
          onScroll={this.props.onScroll}
          scrollLeft={this.props.scrollLeft}
        >
          <div style={style(scrollContainerStyle, zoomStyle)}>
            {this.props.children}
          </div>
        </HorizontalScroller>
        <div style={style(zoomSelectorStyle, this.props.style)}>
          <label style={style('normalText')}>
            <select onChange={this.onZoomChange} value={this.state.zoom}>
              {this.renderZoomOptions()}
            </select>
          </label>
        </div>
      </div>
    );
  }
 
  private renderZoomOptions(): any {
    const customZooms = this.props.customZooms || [];
    const standardZooms = availableZooms.map(zoom => ({
      value: zoom,
      label: `${zoom}% zoom`,
    }));
    return customZooms.concat(standardZooms).map(({ value, label }, index) => {
      return (
        <option key={index} value={value}>
          {label}
        </option>
      );
    });
  }
 
  private onZoomChange = evt => {
    const value = parseInt(evt.target.value, 10);
    this.setState({ zoom: value });
  };
}