Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
ui-component-library / src / components / atoms / Map / GoogleMap.tsx
Size: Mime:
import React from 'react'
import { isObj, EMPTY_ARRAY } from 'exotic'
import { loadGoogle } from './deps/loadGoogle'
import { StyledGoogleMapWrapper, StyledGoogleMap } from './styled'
import { GoogleMapProps } from './typings'
import { data, wordings, qaAttributes, identifiers } from './fixture'

const IS_BROWSER = typeof window === 'object'
const IS_GOOGLE = typeof google === 'object'

class GoogleMap extends React.PureComponent<GoogleMapProps> {
  static defaultProps = {
    className: '',
    qa: qaAttributes.mapContainer,
    id: identifiers.outerWrapperID,
    latitude: data.latitude,
    longitude: data.longitude,
    typeOptions: {
      name: wordings.mapType,
    },
    markerPosition: data.markerPositions,
    styleOptions: EMPTY_ARRAY,
  }

  /**
   * only add global script callback in the browser
   * @todo abstract
   *
   * @note the reason this stopped loading is this triggers on a callback from google
   *       but when we already load google for autosuggest, the callback is never needed
   */
  componentDidMount() {
    console.debug('[GoogleMap] componentDidMount')
    this.loadGoogleAsync()
  }

  references = {
    googleMapDomDiv: React.createRef(),
    googleMap: undefined,
  }

  loadGoogleAsync = async() => {
    // load it again!!!!!!!!!!!!!!!!
    if (isObj(window.google)) {
      // we already loaded it...
      this.handleGoogleApisLoad()
      return
    }

    await loadGoogle()
    this.handleGoogleApisLoad()
  }

  get googleMapOptions() {
    const coordinates = {
      lat: this.props.latitude,
      lng: this.props.longitude,
    }
    const googleMapOptions = {
      zoom: 4,
      center: coordinates,
      // mapTypeIds: ['roadmap', 'satellite', 'hybrid', 'terrain', 'styled_map'],
      // mapTypeId: google.maps.MapTypeId.ROADMAP,
    }
    return googleMapOptions
  }

  /**
   * google essentially wants you to give it a dom element
   * then it will force render itself onto it
   */
  handleGoogleApisLoad() {
    const googleOptions = this.googleMapOptions
    const markerPosition = this.props.markerPosition

    this.references.googleMap = new google.maps.Map(
      document.getElementById(this.props.id),
      googleOptions
    )

    const processEachMarkerLocation = location => {
      return new google.maps.Marker({
        position: location,
        map: this.references.googleMap,
      })
    }

    const marker = markerPosition.map(processEachMarkerLocation)

    const styledMapType = new google.maps.StyledMapType(
      this.props.styleOptions,
      this.props.typeOptions
    )

    this.references.googleMap.mapTypes.set('styled_map', styledMapType)
    this.references.googleMap.setMapTypeId('styled_map')
    window.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED__.googleMapNode = this.references.googleMap
  }

  render() {
    const {
      qa,
      latitude,
      longitude,
      typeOptions,
      styleOptions,
      className,
      id,
    } = this.props

    // @NOTE needs a wrapping div when we use this `ref`
    return (
      <StyledGoogleMapWrapper className={className}>
        <StyledGoogleMap
          data-qa={qa}
          ref={this.refs.googleMapDivNode}
          id={id}
        />
      </StyledGoogleMapWrapper>
    )
  }
}

export { GoogleMap }
export default GoogleMap