@contentful/field-editor-location 1.1.10 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"field-editor-location.cjs.production.min.js","sources":["../src/types.ts","../src/LocationSearchInput.tsx","../src/LocationSelector.tsx","../src/GoogleMapView.tsx","../src/LocationEditor.tsx","../src/index.tsx"],"sourcesContent":["export { Coords } from 'google-map-react';\n\nexport type LocationValue = { lat: number; lon: number };\nexport type NullableLocationValue = LocationValue | null | undefined;\n\nexport enum ViewType {\n Address = 'Address',\n Coordinates = 'Coordinates',\n}\n\nexport type GeocodeApiResponse = null | Array<{\n formatted_address: string;\n geometry: {\n location: {\n lat: () => number;\n lng: () => number;\n };\n };\n}>;\n","import React from 'react';\nimport { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\nimport { Button, Card } from '@contentful/f36-components';\nimport { Coords, GeocodeApiResponse } from './types';\n\nimport { Spinner, ValidationMessage, TextInput } from '@contentful/f36-components';\n\nconst styles = {\n root: css({\n width: '100%',\n }),\n input: css({\n position: 'relative',\n width: '100%',\n }),\n spinner: css({\n position: 'absolute',\n right: 10,\n top: 10,\n zIndex: 99,\n }),\n validationMessage: css({\n marginTop: tokens.spacingS,\n }),\n suggestion: css({\n position: 'absolute',\n transform: 'translateY(100%)',\n bottom: 0,\n left: 0,\n zIndex: 1,\n }),\n};\n\ntype LocationSearchInputProps = {\n disabled: boolean;\n value?: Coords;\n onSearchAddress: (term: string) => Promise<GeocodeApiResponse>;\n onGetAddressFromLocation: (coors: Coords | undefined, value: string) => Promise<string>;\n onChangeLocation: (location?: Coords) => void;\n};\n\nexport function LocationSearchInput(props: LocationSearchInputProps) {\n const [isSearching, setIsSearching] = React.useState<boolean>(false);\n const [address, setAddress] = React.useState<string>('');\n const [hasError, setHasError] = React.useState<boolean>(false);\n const [suggestion, setSuggestion] =\n React.useState<null | {\n address: string;\n location: { lat: number; lng: number };\n }>(null);\n\n React.useEffect(() => {\n setIsSearching(true);\n props.onGetAddressFromLocation(props.value, address).then((address) => {\n setAddress(address);\n setIsSearching(false);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies\n }, [props.value, props.disabled]);\n\n return (\n <div className={styles.root}>\n <div className={styles.input}>\n <TextInput\n testId=\"location-editor-search\"\n isInvalid={hasError}\n placeholder=\"Start typing to find location\"\n value={address}\n onChange={(e) => {\n setAddress(e.target.value);\n setHasError(false);\n setSuggestion(null);\n\n if (e.target.value === '') {\n props.onChangeLocation(undefined);\n return;\n }\n\n setIsSearching(true);\n props.onSearchAddress(e.target.value).then((value) => {\n setIsSearching(false);\n if (value === null) {\n setHasError(false);\n } else if (value.length === 0) {\n setHasError(true);\n } else {\n setHasError(false);\n setSuggestion({\n address: value[0].formatted_address,\n location: {\n lat: Number(value[0].geometry.location.lat().toString().slice(0, 8)),\n lng: Number(value[0].geometry.location.lng().toString().slice(0, 8)),\n },\n });\n }\n });\n }}\n isDisabled={props.disabled}\n />\n {isSearching && <Spinner className={styles.spinner} />}\n {suggestion && (\n <Card padding=\"none\" className={styles.suggestion}>\n <Button\n variant=\"transparent\"\n testId=\"location-editor-suggestion\"\n onClick={() => {\n setAddress(suggestion.address);\n props.onChangeLocation(suggestion.location);\n setSuggestion(null);\n }}>\n {suggestion.address}\n </Button>\n </Card>\n )}\n {hasError && (\n <ValidationMessage\n testId=\"location-editor-not-found\"\n className={styles.validationMessage}>\n No results found for <strong>{address}</strong>. Please make sure that address is\n spelled correctly.\n </ValidationMessage>\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\nimport { LocationSearchInput } from './LocationSearchInput';\n\nimport { Coords, ViewType, GeocodeApiResponse } from './types';\n\nimport { TextLink, TextInput, Radio, Flex } from '@contentful/f36-components';\n\ninterface LocationSelectorProps {\n disabled: boolean;\n value: Coords | undefined;\n view: ViewType;\n onChangeView: (view: ViewType) => void;\n onChangeLocation: (value?: Coords) => void;\n onSearchAddress: (value: string) => Promise<GeocodeApiResponse>;\n onGetAddressFromLocation: (location: Coords | undefined, address: string) => Promise<string>;\n}\n\nconst styles = {\n root: css({\n display: 'flex',\n flexDirection: 'row',\n marginTop: tokens.spacingS,\n alignItems: 'flex-end',\n }),\n main: css({\n flexGrow: 1,\n }),\n secondary: css({\n minWidth: '70px',\n textAlign: 'right',\n }),\n inputsRow: css({\n display: 'flex',\n marginTop: tokens.spacingS,\n fontSize: tokens.fontSizeM,\n color: tokens.gray900,\n fontFamily: tokens.fontStackPrimary,\n alignItems: 'center',\n }),\n splitter: css({\n width: tokens.spacingL,\n }),\n clearBtn: css({\n marginBottom: tokens.spacingS,\n }),\n};\n\nexport function LocationSelector(props: LocationSelectorProps) {\n return (\n <div className={styles.root}>\n <div className={styles.main}>\n <Flex flexDirection=\"row\">\n <Radio\n className={css({ flexBasis: '100%' })}\n id={ViewType.Address}\n testId=\"location-editor-address-radio\"\n isDisabled={props.disabled}\n value={ViewType.Address}\n isChecked={props.view === ViewType.Address}\n onChange={() => {\n props.onChangeView(ViewType.Address);\n }}>\n Address\n </Radio>\n <Radio\n className={css({ flexBasis: '100%' })}\n id={ViewType.Coordinates}\n testId=\"location-editor-coordinates-radio\"\n isDisabled={props.disabled}\n value={ViewType.Coordinates}\n isChecked={props.view === ViewType.Coordinates}\n onChange={() => {\n props.onChangeView(ViewType.Coordinates);\n }}>\n Coordinates\n </Radio>\n </Flex>\n {props.view === ViewType.Address && (\n <div className={styles.inputsRow}>\n <LocationSearchInput\n onSearchAddress={props.onSearchAddress}\n onGetAddressFromLocation={props.onGetAddressFromLocation}\n disabled={props.disabled}\n value={props.value}\n onChangeLocation={props.onChangeLocation}\n />\n </div>\n )}\n {props.view === ViewType.Coordinates && (\n <div className={styles.inputsRow}>\n <label htmlFor=\"latitude\">Latitude</label>\n <div className={styles.splitter} />\n <TextInput\n id=\"latitude\"\n testId=\"location-editor-latitude\"\n placeholder=\"Between -90 and 90\"\n isDisabled={props.disabled}\n value={props.value ? String(props.value.lat) : ''}\n onChange={(e) => {\n props.onChangeLocation({\n lng: props.value && props.value.lng !== undefined ? props.value.lng : 0,\n lat: Number(e.target.value) || 0,\n });\n }}\n type=\"number\"\n max=\"90\"\n min=\"-90\"\n step=\"0.1\"\n />\n <div className={styles.splitter} />\n <label htmlFor=\"longitude\">Longitude</label>\n <div className={styles.splitter} />\n <TextInput\n id=\"longitude\"\n testId=\"location-editor-longitude\"\n placeholder=\"Between -180 and 180\"\n isDisabled={props.disabled}\n value={props.value ? String(props.value.lng) : ''}\n onChange={(e) => {\n props.onChangeLocation({\n lat: props.value && props.value.lat !== undefined ? props.value.lat : 0,\n lng: Number(e.target.value) || 0,\n });\n }}\n type=\"number\"\n max=\"180\"\n min=\"-180\"\n step=\"0.1\"\n />\n </div>\n )}\n </div>\n <div className={styles.secondary}>\n <TextLink\n as=\"button\"\n isDisabled={props.disabled}\n testId=\"location-editor-clear\"\n className={styles.clearBtn}\n onClick={() => {\n props.onChangeLocation(undefined);\n }}>\n Clear\n </TextLink>\n </div>\n </div>\n );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport React from 'react';\nimport { css } from 'emotion';\nimport GoogleMapReact from 'google-map-react';\nimport { Coords } from './types';\n\nconst styles = {\n root: css({\n height: '300px',\n width: '100%',\n }),\n};\n\nconst BerlinLocation = {\n lat: 52.5018,\n lng: 13.41115439,\n};\n\ntype GoogleMapViewProps = {\n disabled: boolean;\n location: Coords | undefined;\n onGoogleApiLoaded: ({ maps }: { maps: any }) => void;\n onChangeLocation: (location: Coords) => void;\n googleMapsKey?: string;\n};\n\ntype GoogleMapsViewState = {\n marker: any;\n maps: any;\n};\n\nexport class GoogleMapView extends React.Component<GoogleMapViewProps, GoogleMapsViewState> {\n constructor(props: GoogleMapViewProps) {\n super(props);\n this.state = {\n marker: undefined,\n maps: undefined,\n };\n }\n\n componentDidUpdate() {\n if (this.state.marker && this.state.maps) {\n if (this.props.location) {\n const latLng = new this.state.maps.LatLng(this.props.location.lat, this.props.location.lng);\n this.state.marker.setPosition(latLng);\n this.state.marker.setVisible(true);\n } else {\n this.state.marker.setVisible(false);\n }\n this.state.marker.setDraggable(!this.props.disabled);\n this.state.marker.setCursor(this.props.disabled ? 'not-allowed' : 'auto');\n }\n }\n\n onGoogleApiLoaded = (event: { maps: any; map: any }) => {\n const { maps, map } = event;\n const marker = new maps.Marker({\n map,\n position: map.getCenter(),\n cursor: this.props.disabled ? 'not-allowed' : 'auto',\n draggable: !this.props.disabled,\n visible: Boolean(this.props.location),\n });\n\n maps.event.addListener(map, 'click', (event: any) => {\n if (this.props.disabled || !this.state.marker || !this.state.maps) {\n return;\n }\n this.state.marker.setPosition(event.latLng);\n this.state.marker.setVisible(true);\n this.props.onChangeLocation({\n lat: event.latLng.lat(),\n lng: event.latLng.lng(),\n });\n });\n\n maps.event.addListener(marker, 'dragend', (event: any) => {\n this.props.onChangeLocation({\n lat: event.latLng.lat(),\n lng: event.latLng.lng(),\n });\n });\n this.setState({ marker, maps }, () => {\n this.props.onGoogleApiLoaded({ maps });\n });\n };\n\n render() {\n return (\n <div className={styles.root}>\n <GoogleMapReact\n draggable={!this.props.disabled}\n bootstrapURLKeys={\n this.props.googleMapsKey ? { key: this.props.googleMapsKey } : undefined\n }\n defaultCenter={BerlinLocation}\n center={this.props.location}\n options={{\n scrollwheel: false,\n mapTypeId: 'roadmap',\n }}\n defaultZoom={6}\n yesIWantToUseGoogleMapApiInternals\n onGoogleApiLoaded={this.onGoogleApiLoaded}\n />\n </div>\n );\n }\n}\n","import * as React from 'react';\nimport isNumber from 'lodash/isNumber';\nimport throttle from 'lodash/throttle';\nimport { FieldAPI, FieldConnector, ParametersAPI } from '@contentful/field-editor-shared';\nimport deepEqual from 'deep-equal';\nimport {\n LocationValue,\n ViewType,\n NullableLocationValue,\n Coords,\n GeocodeApiResponse,\n} from './types';\nimport { LocationSelector } from './LocationSelector';\nimport { GoogleMapView } from './GoogleMapView';\n\nexport interface LocationEditorConnectedProps {\n /**\n * is the field disabled initially\n */\n isInitiallyDisabled: boolean;\n\n /**\n * sdk.field\n */\n field: FieldAPI;\n\n /**\n * sdk.parameters\n */\n parameters?: ParametersAPI & {\n instance: {\n googleMapsKey?: string;\n };\n };\n}\n\ntype LocationEditorProps = {\n disabled: boolean;\n value: NullableLocationValue;\n setValue: (value: NullableLocationValue) => void;\n googleMapsKey?: string;\n selectedView: ViewType;\n setSelectedView: (view: ViewType) => void;\n};\n\nfunction toLocationValue(coords?: Coords): NullableLocationValue {\n if (coords && isNumber(coords.lat) && isNumber(coords.lng)) {\n return { lat: coords.lat, lon: coords.lng };\n } else {\n return null;\n }\n}\n\nexport class LocationEditor extends React.Component<\n LocationEditorProps,\n {\n localValue?: Coords;\n mapsObject: any; // eslint-disable-line -- TODO: describe this disable @typescript-eslint/no-explicit-any\n }\n> {\n constructor(props: LocationEditorProps) {\n super(props);\n\n this.state = {\n localValue: props.value\n ? {\n lng: props.value.lon,\n lat: props.value.lat,\n }\n : undefined,\n mapsObject: null,\n };\n }\n\n // @ts-expect-error\n onSearchAddress: (value: string) => Promise<GeocodeApiResponse> = throttle((value) => {\n if (!this.state.mapsObject) {\n return Promise.resolve(null);\n }\n const { mapsObject } = this.state;\n if (!value) {\n return Promise.resolve(null);\n }\n return new Promise((resolve) => {\n const geocoder = new mapsObject.Geocoder();\n geocoder.geocode({ address: value }, resolve, () => {\n resolve(null);\n });\n });\n }, 300);\n\n onGetAddressFromLocation = (location: Coords | undefined, value: string): Promise<string> => {\n if (!this.state.mapsObject || !location) {\n return Promise.resolve('');\n }\n const { mapsObject } = this.state;\n return new Promise((resolve) => {\n const geocoder = new mapsObject.Geocoder();\n geocoder.geocode(\n { location },\n (result: GeocodeApiResponse) => {\n if (result && result.length > 0) {\n const addresses = result.map((item) => item.formatted_address);\n resolve(addresses.find((item) => item === value) || addresses[0]);\n } else {\n resolve('');\n }\n },\n () => {\n resolve('');\n }\n );\n });\n };\n\n render() {\n const { mapsObject, localValue } = this.state;\n\n return (\n <div data-test-id=\"location-editor\">\n <GoogleMapView\n disabled={this.props.disabled || mapsObject === null}\n googleMapsKey={this.props.googleMapsKey}\n location={localValue}\n onGoogleApiLoaded={({ maps }) => {\n this.setState({ mapsObject: maps });\n }}\n onChangeLocation={(coords) => {\n this.setState({ localValue: coords });\n this.props.setValue(toLocationValue(coords));\n }}\n />\n <LocationSelector\n disabled={this.props.disabled || mapsObject === null}\n value={localValue}\n view={this.props.selectedView}\n onChangeView={(view) => {\n this.props.setSelectedView(view);\n }}\n onChangeLocation={(coords) => {\n this.setState({ localValue: coords });\n this.props.setValue(toLocationValue(coords));\n }}\n onSearchAddress={this.onSearchAddress}\n onGetAddressFromLocation={this.onGetAddressFromLocation}\n />\n </div>\n );\n }\n}\n\nexport function LocationEditorConnected(props: LocationEditorConnectedProps) {\n const { field } = props;\n const googleMapsKey = props.parameters ? props.parameters.instance.googleMapsKey : undefined;\n const [selectedView, setSelectedView] = React.useState<ViewType>(ViewType.Address);\n\n return (\n <FieldConnector<LocationValue>\n isEqualValues={(value1, value2) => {\n return deepEqual(value1, value2);\n }}\n field={field}\n isInitiallyDisabled={props.isInitiallyDisabled}>\n {({ value, disabled, setValue, externalReset }) => {\n return (\n <LocationEditor\n // on external change reset component completely and init with initial value again\n key={`location-editor-${externalReset}`}\n value={value}\n disabled={disabled}\n setValue={setValue}\n googleMapsKey={googleMapsKey}\n selectedView={selectedView}\n setSelectedView={setSelectedView}\n />\n );\n }}\n </FieldConnector>\n );\n}\n\nLocationEditorConnected.defaultProps = {\n isInitiallyDisabled: true,\n};\n","import { LocationEditorConnected } from './LocationEditor';\n\nexport const LocationEditor = LocationEditorConnected;\n"],"names":["ViewType","styles","root","css","width","input","position","spinner","right","top","zIndex","validationMessage","marginTop","tokens","spacingS","suggestion","transform","bottom","left","LocationSearchInput","props","React","useState","isSearching","setIsSearching","address","setAddress","hasError","setHasError","setSuggestion","useEffect","onGetAddressFromLocation","value","then","disabled","className","TextInput","testId","isInvalid","placeholder","onChange","e","target","onSearchAddress","length","formatted_address","location","lat","Number","geometry","toString","slice","lng","onChangeLocation","undefined","isDisabled","Spinner","Card","padding","Button","variant","onClick","ValidationMessage","display","flexDirection","alignItems","main","flexGrow","secondary","minWidth","textAlign","inputsRow","fontSize","fontSizeM","color","gray900","fontFamily","fontStackPrimary","splitter","spacingL","clearBtn","marginBottom","LocationSelector","Flex","Radio","flexBasis","id","Address","isChecked","view","onChangeView","Coordinates","htmlFor","String","type","max","min","step","TextLink","as","height","BerlinLocation","GoogleMapView","onGoogleApiLoaded","event","maps","map","marker","Marker","getCenter","cursor","_this","draggable","visible","Boolean","addListener","state","setPosition","latLng","setVisible","setState","componentDidUpdate","this","LatLng","setDraggable","setCursor","render","GoogleMapReact","bootstrapURLKeys","googleMapsKey","key","defaultCenter","center","options","scrollwheel","mapTypeId","defaultZoom","yesIWantToUseGoogleMapApiInternals","Component","toLocationValue","coords","isNumber","lon","LocationEditor","throttle","mapsObject","Promise","resolve","Geocoder","geocode","result","addresses","item","find","localValue","_this2","setValue","selectedView","setSelectedView","LocationEditorConnected","field","parameters","instance","FieldConnector","isEqualValues","value1","value2","deepEqual","isInitiallyDisabled","externalReset","defaultProps"],"mappings":"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"}
1
+ {"version":3,"file":"field-editor-location.cjs.production.min.js","sources":["../src/GoogleMapView.tsx","../src/types.ts","../src/LocationSearchInput.tsx","../src/LocationSelector.tsx","../src/LocationEditor.tsx","../src/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport React from 'react';\n\nimport { css } from 'emotion';\nimport GoogleMapReact from 'google-map-react';\n\nimport { Coords } from './types';\n\nconst styles = {\n root: css({\n height: '300px',\n width: '100%',\n }),\n};\n\nconst BerlinLocation = {\n lat: 52.5018,\n lng: 13.41115439,\n};\n\ntype GoogleMapViewProps = {\n disabled: boolean;\n location: Coords | undefined;\n onGoogleApiLoaded: ({ maps }: { maps: any }) => void;\n onChangeLocation: (location: Coords) => void;\n googleMapsKey?: string;\n};\n\ntype GoogleMapsViewState = {\n marker: any;\n maps: any;\n};\n\nexport class GoogleMapView extends React.Component<GoogleMapViewProps, GoogleMapsViewState> {\n constructor(props: GoogleMapViewProps) {\n super(props);\n this.state = {\n marker: undefined,\n maps: undefined,\n };\n }\n\n componentDidUpdate() {\n if (this.state.marker && this.state.maps) {\n if (this.props.location) {\n const latLng = new this.state.maps.LatLng(this.props.location.lat, this.props.location.lng);\n this.state.marker.setPosition(latLng);\n this.state.marker.setVisible(true);\n } else {\n this.state.marker.setVisible(false);\n }\n this.state.marker.setDraggable(!this.props.disabled);\n this.state.marker.setCursor(this.props.disabled ? 'not-allowed' : 'auto');\n }\n }\n\n onGoogleApiLoaded = (event: { maps: any; map: any }) => {\n const { maps, map } = event;\n const marker = new maps.Marker({\n map,\n position: map.getCenter(),\n cursor: this.props.disabled ? 'not-allowed' : 'auto',\n draggable: !this.props.disabled,\n visible: Boolean(this.props.location),\n });\n\n maps.event.addListener(map, 'click', (event: any) => {\n if (this.props.disabled || !this.state.marker || !this.state.maps) {\n return;\n }\n this.state.marker.setPosition(event.latLng);\n this.state.marker.setVisible(true);\n this.props.onChangeLocation({\n lat: event.latLng.lat(),\n lng: event.latLng.lng(),\n });\n });\n\n maps.event.addListener(marker, 'dragend', (event: any) => {\n this.props.onChangeLocation({\n lat: event.latLng.lat(),\n lng: event.latLng.lng(),\n });\n });\n this.setState({ marker, maps }, () => {\n this.props.onGoogleApiLoaded({ maps });\n });\n };\n\n render() {\n return (\n <div className={styles.root}>\n <GoogleMapReact\n draggable={!this.props.disabled}\n bootstrapURLKeys={\n this.props.googleMapsKey ? { key: this.props.googleMapsKey } : undefined\n }\n defaultCenter={BerlinLocation}\n center={this.props.location}\n options={{\n scrollwheel: false,\n mapTypeId: 'roadmap',\n }}\n defaultZoom={6}\n yesIWantToUseGoogleMapApiInternals\n onGoogleApiLoaded={this.onGoogleApiLoaded}\n />\n </div>\n );\n }\n}\n","export interface Coords {\n lat: number;\n lng: number;\n}\n\nexport type LocationValue = { lat: number; lon: number };\nexport type NullableLocationValue = LocationValue | null | undefined;\n\nexport enum ViewType {\n Address = 'Address',\n Coordinates = 'Coordinates',\n}\n\nexport type GeocodeApiResponse = null | Array<{\n formatted_address: string;\n geometry: {\n location: {\n lat: () => number;\n lng: () => number;\n };\n };\n}>;\n","import React from 'react';\n\nimport { Button, Card, Spinner, ValidationMessage, TextInput } from '@contentful/f36-components';\nimport tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nimport { Coords, GeocodeApiResponse } from './types';\n\nconst styles = {\n root: css({\n width: '100%',\n }),\n input: css({\n position: 'relative',\n width: '100%',\n }),\n spinner: css({\n position: 'absolute',\n right: 10,\n top: 10,\n zIndex: 99,\n }),\n validationMessage: css({\n marginTop: tokens.spacingS,\n }),\n suggestion: css({\n position: 'absolute',\n transform: 'translateY(100%)',\n bottom: 0,\n left: 0,\n zIndex: 1,\n }),\n};\n\ntype LocationSearchInputProps = {\n disabled: boolean;\n value?: Coords;\n onSearchAddress: (term: string) => Promise<GeocodeApiResponse>;\n onGetAddressFromLocation: (coors: Coords | undefined, value: string) => Promise<string>;\n onChangeLocation: (location?: Coords) => void;\n};\n\nexport function LocationSearchInput(props: LocationSearchInputProps) {\n const [isSearching, setIsSearching] = React.useState<boolean>(false);\n const [address, setAddress] = React.useState<string>('');\n const [hasError, setHasError] = React.useState<boolean>(false);\n const [suggestion, setSuggestion] = React.useState<null | {\n address: string;\n location: { lat: number; lng: number };\n }>(null);\n\n React.useEffect(() => {\n setIsSearching(true);\n props.onGetAddressFromLocation(props.value, address).then((address) => {\n setAddress(address);\n setIsSearching(false);\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies\n }, [props.value, props.disabled]);\n\n return (\n <div className={styles.root}>\n <div className={styles.input}>\n <TextInput\n testId=\"location-editor-search\"\n isInvalid={hasError}\n placeholder=\"Start typing to find location\"\n value={address}\n onChange={(e) => {\n setAddress(e.target.value);\n setHasError(false);\n setSuggestion(null);\n\n if (e.target.value === '') {\n props.onChangeLocation(undefined);\n return;\n }\n\n setIsSearching(true);\n props.onSearchAddress(e.target.value).then((value) => {\n setIsSearching(false);\n if (value === null) {\n setHasError(false);\n } else if (value.length === 0) {\n setHasError(true);\n } else {\n setHasError(false);\n setSuggestion({\n address: value[0].formatted_address,\n location: {\n lat: Number(value[0].geometry.location.lat().toString().slice(0, 8)),\n lng: Number(value[0].geometry.location.lng().toString().slice(0, 8)),\n },\n });\n }\n });\n }}\n isDisabled={props.disabled}\n />\n {isSearching && <Spinner className={styles.spinner} />}\n {suggestion && (\n <Card padding=\"none\" className={styles.suggestion}>\n <Button\n variant=\"transparent\"\n testId=\"location-editor-suggestion\"\n onClick={() => {\n setAddress(suggestion.address);\n props.onChangeLocation(suggestion.location);\n setSuggestion(null);\n }}\n >\n {suggestion.address}\n </Button>\n </Card>\n )}\n {hasError && (\n <ValidationMessage\n testId=\"location-editor-not-found\"\n className={styles.validationMessage}\n >\n No results found for <strong>{address}</strong>. Please make sure that address is\n spelled correctly.\n </ValidationMessage>\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { TextLink, TextInput, Radio, Flex } from '@contentful/f36-components';\nimport tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nimport { LocationSearchInput } from './LocationSearchInput';\nimport { Coords, ViewType, GeocodeApiResponse } from './types';\n\ninterface LocationSelectorProps {\n disabled: boolean;\n value: Coords | undefined;\n view: ViewType;\n onChangeView: (view: ViewType) => void;\n onChangeLocation: (value?: Coords) => void;\n onSearchAddress: (value: string) => Promise<GeocodeApiResponse>;\n onGetAddressFromLocation: (location: Coords | undefined, address: string) => Promise<string>;\n}\n\nconst styles = {\n root: css({\n display: 'flex',\n flexDirection: 'row',\n marginTop: tokens.spacingS,\n alignItems: 'flex-end',\n }),\n main: css({\n flexGrow: 1,\n }),\n secondary: css({\n minWidth: '70px',\n textAlign: 'right',\n }),\n inputsRow: css({\n display: 'flex',\n marginTop: tokens.spacingS,\n fontSize: tokens.fontSizeM,\n color: tokens.gray900,\n fontFamily: tokens.fontStackPrimary,\n alignItems: 'center',\n }),\n splitter: css({\n width: tokens.spacingL,\n }),\n clearBtn: css({\n marginBottom: tokens.spacingS,\n }),\n};\n\nexport function LocationSelector(props: LocationSelectorProps) {\n return (\n <div className={styles.root}>\n <div className={styles.main}>\n <Flex flexDirection=\"row\">\n <Radio\n className={css({ flexBasis: '100%' })}\n id={ViewType.Address}\n testId=\"location-editor-address-radio\"\n isDisabled={props.disabled}\n value={ViewType.Address}\n isChecked={props.view === ViewType.Address}\n onChange={() => {\n props.onChangeView(ViewType.Address);\n }}\n >\n Address\n </Radio>\n <Radio\n className={css({ flexBasis: '100%' })}\n id={ViewType.Coordinates}\n testId=\"location-editor-coordinates-radio\"\n isDisabled={props.disabled}\n value={ViewType.Coordinates}\n isChecked={props.view === ViewType.Coordinates}\n onChange={() => {\n props.onChangeView(ViewType.Coordinates);\n }}\n >\n Coordinates\n </Radio>\n </Flex>\n {props.view === ViewType.Address && (\n <div className={styles.inputsRow}>\n <LocationSearchInput\n onSearchAddress={props.onSearchAddress}\n onGetAddressFromLocation={props.onGetAddressFromLocation}\n disabled={props.disabled}\n value={props.value}\n onChangeLocation={props.onChangeLocation}\n />\n </div>\n )}\n {props.view === ViewType.Coordinates && (\n <div className={styles.inputsRow}>\n <label htmlFor=\"latitude\">Latitude</label>\n <div className={styles.splitter} />\n <TextInput\n id=\"latitude\"\n testId=\"location-editor-latitude\"\n placeholder=\"Between -90 and 90\"\n isDisabled={props.disabled}\n value={props.value ? String(props.value.lat) : ''}\n onChange={(e) => {\n props.onChangeLocation({\n lng: props.value && props.value.lng !== undefined ? props.value.lng : 0,\n lat: Number(e.target.value) || 0,\n });\n }}\n type=\"number\"\n max=\"90\"\n min=\"-90\"\n step=\"0.1\"\n />\n <div className={styles.splitter} />\n <label htmlFor=\"longitude\">Longitude</label>\n <div className={styles.splitter} />\n <TextInput\n id=\"longitude\"\n testId=\"location-editor-longitude\"\n placeholder=\"Between -180 and 180\"\n isDisabled={props.disabled}\n value={props.value ? String(props.value.lng) : ''}\n onChange={(e) => {\n props.onChangeLocation({\n lat: props.value && props.value.lat !== undefined ? props.value.lat : 0,\n lng: Number(e.target.value) || 0,\n });\n }}\n type=\"number\"\n max=\"180\"\n min=\"-180\"\n step=\"0.1\"\n />\n </div>\n )}\n </div>\n <div className={styles.secondary}>\n <TextLink\n as=\"button\"\n isDisabled={props.disabled}\n testId=\"location-editor-clear\"\n className={styles.clearBtn}\n onClick={() => {\n props.onChangeLocation(undefined);\n }}\n >\n Clear\n </TextLink>\n </div>\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { FieldAPI, FieldConnector, ParametersAPI } from '@contentful/field-editor-shared';\nimport deepEqual from 'deep-equal';\nimport isNumber from 'lodash/isNumber';\nimport throttle from 'lodash/throttle';\n\nimport { GoogleMapView } from './GoogleMapView';\nimport { LocationSelector } from './LocationSelector';\nimport {\n LocationValue,\n ViewType,\n NullableLocationValue,\n Coords,\n GeocodeApiResponse,\n} from './types';\n\nexport interface LocationEditorConnectedProps {\n /**\n * is the field disabled initially\n */\n isInitiallyDisabled: boolean;\n\n /**\n * sdk.field\n */\n field: FieldAPI;\n\n /**\n * sdk.parameters\n */\n parameters?: ParametersAPI & {\n instance: {\n googleMapsKey?: string;\n };\n };\n}\n\ntype LocationEditorProps = {\n disabled: boolean;\n value: NullableLocationValue;\n setValue: (value: NullableLocationValue) => void;\n googleMapsKey?: string;\n selectedView: ViewType;\n setSelectedView: (view: ViewType) => void;\n};\n\nfunction toLocationValue(coords?: Coords): NullableLocationValue {\n if (coords && isNumber(coords.lat) && isNumber(coords.lng)) {\n return { lat: coords.lat, lon: coords.lng };\n } else {\n return null;\n }\n}\n\nexport class LocationEditor extends React.Component<\n LocationEditorProps,\n {\n localValue?: Coords;\n mapsObject: any; // eslint-disable-line -- TODO: describe this disable @typescript-eslint/no-explicit-any\n }\n> {\n constructor(props: LocationEditorProps) {\n super(props);\n\n this.state = {\n localValue: props.value\n ? {\n lng: props.value.lon,\n lat: props.value.lat,\n }\n : undefined,\n mapsObject: null,\n };\n }\n\n // @ts-expect-error\n onSearchAddress: (value: string) => Promise<GeocodeApiResponse> = throttle((value) => {\n if (!this.state.mapsObject) {\n return Promise.resolve(null);\n }\n const { mapsObject } = this.state;\n if (!value) {\n return Promise.resolve(null);\n }\n return new Promise((resolve) => {\n const geocoder = new mapsObject.Geocoder();\n geocoder.geocode({ address: value }, resolve, () => {\n resolve(null);\n });\n });\n }, 300);\n\n onGetAddressFromLocation = (location: Coords | undefined, value: string): Promise<string> => {\n if (!this.state.mapsObject || !location) {\n return Promise.resolve('');\n }\n const { mapsObject } = this.state;\n return new Promise((resolve) => {\n const geocoder = new mapsObject.Geocoder();\n geocoder.geocode(\n { location },\n (result: GeocodeApiResponse) => {\n if (result && result.length > 0) {\n const addresses = result.map((item) => item.formatted_address);\n resolve(addresses.find((item) => item === value) || addresses[0]);\n } else {\n resolve('');\n }\n },\n () => {\n resolve('');\n }\n );\n });\n };\n\n render() {\n const { mapsObject, localValue } = this.state;\n\n return (\n <div data-test-id=\"location-editor\">\n <GoogleMapView\n disabled={this.props.disabled || mapsObject === null}\n googleMapsKey={this.props.googleMapsKey}\n location={localValue}\n onGoogleApiLoaded={({ maps }) => {\n this.setState({ mapsObject: maps });\n }}\n onChangeLocation={(coords) => {\n this.setState({ localValue: coords });\n this.props.setValue(toLocationValue(coords));\n }}\n />\n <LocationSelector\n disabled={this.props.disabled || mapsObject === null}\n value={localValue}\n view={this.props.selectedView}\n onChangeView={(view) => {\n this.props.setSelectedView(view);\n }}\n onChangeLocation={(coords) => {\n this.setState({ localValue: coords });\n this.props.setValue(toLocationValue(coords));\n }}\n onSearchAddress={this.onSearchAddress}\n onGetAddressFromLocation={this.onGetAddressFromLocation}\n />\n </div>\n );\n }\n}\n\nexport function LocationEditorConnected(props: LocationEditorConnectedProps) {\n const { field } = props;\n const googleMapsKey = props.parameters ? props.parameters.instance.googleMapsKey : undefined;\n const [selectedView, setSelectedView] = React.useState<ViewType>(ViewType.Address);\n\n return (\n <FieldConnector<LocationValue>\n isEqualValues={(value1, value2) => {\n return deepEqual(value1, value2);\n }}\n field={field}\n isInitiallyDisabled={props.isInitiallyDisabled}\n >\n {({ value, disabled, setValue, externalReset }) => {\n return (\n <LocationEditor\n // on external change reset component completely and init with initial value again\n key={`location-editor-${externalReset}`}\n value={value}\n disabled={disabled}\n setValue={setValue}\n googleMapsKey={googleMapsKey}\n selectedView={selectedView}\n setSelectedView={setSelectedView}\n />\n );\n }}\n </FieldConnector>\n );\n}\n\nLocationEditorConnected.defaultProps = {\n isInitiallyDisabled: true,\n};\n","import { LocationEditorConnected } from './LocationEditor';\n\nexport const LocationEditor = LocationEditorConnected;\n"],"names":["ViewType","styles","root","css","height","width","BerlinLocation","lat","lng","GoogleMapView","props","onGoogleApiLoaded","event","maps","map","marker","Marker","position","getCenter","cursor","_this","disabled","draggable","visible","Boolean","location","addListener","state","setPosition","latLng","setVisible","onChangeLocation","setState","undefined","componentDidUpdate","this","LatLng","setDraggable","setCursor","render","React","className","GoogleMapReact","bootstrapURLKeys","googleMapsKey","key","defaultCenter","center","options","scrollwheel","mapTypeId","defaultZoom","yesIWantToUseGoogleMapApiInternals","Component","input","spinner","right","top","zIndex","validationMessage","marginTop","tokens","spacingS","suggestion","transform","bottom","left","LocationSearchInput","useState","isSearching","setIsSearching","address","setAddress","hasError","setHasError","setSuggestion","useEffect","onGetAddressFromLocation","value","then","TextInput","testId","isInvalid","placeholder","onChange","e","target","onSearchAddress","length","formatted_address","Number","geometry","toString","slice","isDisabled","Spinner","Card","padding","Button","variant","onClick","ValidationMessage","display","flexDirection","alignItems","main","flexGrow","secondary","minWidth","textAlign","inputsRow","fontSize","fontSizeM","color","gray900","fontFamily","fontStackPrimary","splitter","spacingL","clearBtn","marginBottom","LocationSelector","Flex","Radio","flexBasis","id","Address","isChecked","view","onChangeView","Coordinates","htmlFor","String","type","max","min","step","TextLink","as","toLocationValue","coords","isNumber","lon","LocationEditor","throttle","mapsObject","Promise","resolve","Geocoder","geocode","result","addresses","item","find","localValue","_this2","setValue","selectedView","setSelectedView","LocationEditorConnected","field","parameters","instance","FieldConnector","isEqualValues","value1","value2","deepEqual","isInitiallyDisabled","externalReset","defaultProps"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import React__default, { useState, createElement, Component } from 'react';
2
- import isNumber from 'lodash-es/isNumber';
3
- import throttle from 'lodash-es/throttle';
4
2
  import { FieldConnector } from '@contentful/field-editor-shared';
5
3
  import deepEqual from 'deep-equal';
4
+ import isNumber from 'lodash-es/isNumber';
5
+ import throttle from 'lodash-es/throttle';
6
6
  import { css } from 'emotion';
7
- import tokens from '@contentful/f36-tokens';
8
- import { TextInput, Spinner, Card, Button, ValidationMessage, Flex, Radio, TextLink } from '@contentful/f36-components';
9
7
  import GoogleMapReact from 'google-map-react';
8
+ import { TextInput, Spinner, Card, Button, ValidationMessage, Flex, Radio, TextLink } from '@contentful/f36-components';
9
+ import tokens from '@contentful/f36-tokens';
10
10
 
11
11
  function _inheritsLoose(subClass, superClass) {
12
12
  subClass.prototype = Object.create(superClass.prototype);
@@ -24,14 +24,113 @@ function _setPrototypeOf(o, p) {
24
24
  return _setPrototypeOf(o, p);
25
25
  }
26
26
 
27
- var ViewType;
27
+ var styles = {
28
+ root: /*#__PURE__*/css({
29
+ height: '300px',
30
+ width: '100%'
31
+ })
32
+ };
33
+ var BerlinLocation = {
34
+ lat: 52.5018,
35
+ lng: 13.41115439
36
+ };
37
+ var GoogleMapView = /*#__PURE__*/function (_React$Component) {
38
+ _inheritsLoose(GoogleMapView, _React$Component);
28
39
 
29
- (function (ViewType) {
30
- ViewType["Address"] = "Address";
31
- ViewType["Coordinates"] = "Coordinates";
32
- })(ViewType || (ViewType = {}));
40
+ function GoogleMapView(props) {
41
+ var _this;
33
42
 
34
- var styles = {
43
+ _this = _React$Component.call(this, props) || this;
44
+
45
+ _this.onGoogleApiLoaded = function (event) {
46
+ var maps = event.maps,
47
+ map = event.map;
48
+ var marker = new maps.Marker({
49
+ map: map,
50
+ position: map.getCenter(),
51
+ cursor: _this.props.disabled ? 'not-allowed' : 'auto',
52
+ draggable: !_this.props.disabled,
53
+ visible: Boolean(_this.props.location)
54
+ });
55
+ maps.event.addListener(map, 'click', function (event) {
56
+ if (_this.props.disabled || !_this.state.marker || !_this.state.maps) {
57
+ return;
58
+ }
59
+
60
+ _this.state.marker.setPosition(event.latLng);
61
+
62
+ _this.state.marker.setVisible(true);
63
+
64
+ _this.props.onChangeLocation({
65
+ lat: event.latLng.lat(),
66
+ lng: event.latLng.lng()
67
+ });
68
+ });
69
+ maps.event.addListener(marker, 'dragend', function (event) {
70
+ _this.props.onChangeLocation({
71
+ lat: event.latLng.lat(),
72
+ lng: event.latLng.lng()
73
+ });
74
+ });
75
+
76
+ _this.setState({
77
+ marker: marker,
78
+ maps: maps
79
+ }, function () {
80
+ _this.props.onGoogleApiLoaded({
81
+ maps: maps
82
+ });
83
+ });
84
+ };
85
+
86
+ _this.state = {
87
+ marker: undefined,
88
+ maps: undefined
89
+ };
90
+ return _this;
91
+ }
92
+
93
+ var _proto = GoogleMapView.prototype;
94
+
95
+ _proto.componentDidUpdate = function componentDidUpdate() {
96
+ if (this.state.marker && this.state.maps) {
97
+ if (this.props.location) {
98
+ var latLng = new this.state.maps.LatLng(this.props.location.lat, this.props.location.lng);
99
+ this.state.marker.setPosition(latLng);
100
+ this.state.marker.setVisible(true);
101
+ } else {
102
+ this.state.marker.setVisible(false);
103
+ }
104
+
105
+ this.state.marker.setDraggable(!this.props.disabled);
106
+ this.state.marker.setCursor(this.props.disabled ? 'not-allowed' : 'auto');
107
+ }
108
+ };
109
+
110
+ _proto.render = function render() {
111
+ return React__default.createElement("div", {
112
+ className: styles.root
113
+ }, React__default.createElement(GoogleMapReact, {
114
+ draggable: !this.props.disabled,
115
+ bootstrapURLKeys: this.props.googleMapsKey ? {
116
+ key: this.props.googleMapsKey
117
+ } : undefined,
118
+ defaultCenter: BerlinLocation,
119
+ center: this.props.location,
120
+ options: {
121
+ scrollwheel: false,
122
+ mapTypeId: 'roadmap'
123
+ },
124
+ defaultZoom: 6,
125
+ yesIWantToUseGoogleMapApiInternals: true,
126
+ onGoogleApiLoaded: this.onGoogleApiLoaded
127
+ }));
128
+ };
129
+
130
+ return GoogleMapView;
131
+ }(React__default.Component);
132
+
133
+ var styles$1 = {
35
134
  root: /*#__PURE__*/css({
36
135
  width: '100%'
37
136
  }),
@@ -81,9 +180,9 @@ function LocationSearchInput(props) {
81
180
  }); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate the dependencies
82
181
  }, [props.value, props.disabled]);
83
182
  return React__default.createElement("div", {
84
- className: styles.root
183
+ className: styles$1.root
85
184
  }, React__default.createElement("div", {
86
- className: styles.input
185
+ className: styles$1.input
87
186
  }, React__default.createElement(TextInput, {
88
187
  testId: "location-editor-search",
89
188
  isInvalid: hasError,
@@ -121,10 +220,10 @@ function LocationSearchInput(props) {
121
220
  },
122
221
  isDisabled: props.disabled
123
222
  }), isSearching && React__default.createElement(Spinner, {
124
- className: styles.spinner
223
+ className: styles$1.spinner
125
224
  }), suggestion && React__default.createElement(Card, {
126
225
  padding: "none",
127
- className: styles.suggestion
226
+ className: styles$1.suggestion
128
227
  }, React__default.createElement(Button, {
129
228
  variant: "transparent",
130
229
  testId: "location-editor-suggestion",
@@ -135,11 +234,18 @@ function LocationSearchInput(props) {
135
234
  }
136
235
  }, suggestion.address)), hasError && React__default.createElement(ValidationMessage, {
137
236
  testId: "location-editor-not-found",
138
- className: styles.validationMessage
237
+ className: styles$1.validationMessage
139
238
  }, "No results found for ", React__default.createElement("strong", null, address), ". Please make sure that address is spelled correctly.")));
140
239
  }
141
240
 
142
- var styles$1 = {
241
+ var ViewType;
242
+
243
+ (function (ViewType) {
244
+ ViewType["Address"] = "Address";
245
+ ViewType["Coordinates"] = "Coordinates";
246
+ })(ViewType || (ViewType = {}));
247
+
248
+ var styles$2 = {
143
249
  root: /*#__PURE__*/css({
144
250
  display: 'flex',
145
251
  flexDirection: 'row',
@@ -170,9 +276,9 @@ var styles$1 = {
170
276
  };
171
277
  function LocationSelector(props) {
172
278
  return React__default.createElement("div", {
173
- className: styles$1.root
279
+ className: styles$2.root
174
280
  }, React__default.createElement("div", {
175
- className: styles$1.main
281
+ className: styles$2.main
176
282
  }, React__default.createElement(Flex, {
177
283
  flexDirection: "row"
178
284
  }, React__default.createElement(Radio, {
@@ -200,7 +306,7 @@ function LocationSelector(props) {
200
306
  props.onChangeView(ViewType.Coordinates);
201
307
  }
202
308
  }, "Coordinates")), props.view === ViewType.Address && React__default.createElement("div", {
203
- className: styles$1.inputsRow
309
+ className: styles$2.inputsRow
204
310
  }, React__default.createElement(LocationSearchInput, {
205
311
  onSearchAddress: props.onSearchAddress,
206
312
  onGetAddressFromLocation: props.onGetAddressFromLocation,
@@ -208,11 +314,11 @@ function LocationSelector(props) {
208
314
  value: props.value,
209
315
  onChangeLocation: props.onChangeLocation
210
316
  })), props.view === ViewType.Coordinates && React__default.createElement("div", {
211
- className: styles$1.inputsRow
317
+ className: styles$2.inputsRow
212
318
  }, React__default.createElement("label", {
213
319
  htmlFor: "latitude"
214
320
  }, "Latitude"), React__default.createElement("div", {
215
- className: styles$1.splitter
321
+ className: styles$2.splitter
216
322
  }), React__default.createElement(TextInput, {
217
323
  id: "latitude",
218
324
  testId: "location-editor-latitude",
@@ -230,11 +336,11 @@ function LocationSelector(props) {
230
336
  min: "-90",
231
337
  step: "0.1"
232
338
  }), React__default.createElement("div", {
233
- className: styles$1.splitter
339
+ className: styles$2.splitter
234
340
  }), React__default.createElement("label", {
235
341
  htmlFor: "longitude"
236
342
  }, "Longitude"), React__default.createElement("div", {
237
- className: styles$1.splitter
343
+ className: styles$2.splitter
238
344
  }), React__default.createElement(TextInput, {
239
345
  id: "longitude",
240
346
  testId: "location-editor-longitude",
@@ -252,124 +358,18 @@ function LocationSelector(props) {
252
358
  min: "-180",
253
359
  step: "0.1"
254
360
  }))), React__default.createElement("div", {
255
- className: styles$1.secondary
361
+ className: styles$2.secondary
256
362
  }, React__default.createElement(TextLink, {
257
363
  as: "button",
258
364
  isDisabled: props.disabled,
259
365
  testId: "location-editor-clear",
260
- className: styles$1.clearBtn,
366
+ className: styles$2.clearBtn,
261
367
  onClick: function onClick() {
262
368
  props.onChangeLocation(undefined);
263
369
  }
264
370
  }, "Clear")));
265
371
  }
266
372
 
267
- var styles$2 = {
268
- root: /*#__PURE__*/css({
269
- height: '300px',
270
- width: '100%'
271
- })
272
- };
273
- var BerlinLocation = {
274
- lat: 52.5018,
275
- lng: 13.41115439
276
- };
277
- var GoogleMapView = /*#__PURE__*/function (_React$Component) {
278
- _inheritsLoose(GoogleMapView, _React$Component);
279
-
280
- function GoogleMapView(props) {
281
- var _this;
282
-
283
- _this = _React$Component.call(this, props) || this;
284
-
285
- _this.onGoogleApiLoaded = function (event) {
286
- var maps = event.maps,
287
- map = event.map;
288
- var marker = new maps.Marker({
289
- map: map,
290
- position: map.getCenter(),
291
- cursor: _this.props.disabled ? 'not-allowed' : 'auto',
292
- draggable: !_this.props.disabled,
293
- visible: Boolean(_this.props.location)
294
- });
295
- maps.event.addListener(map, 'click', function (event) {
296
- if (_this.props.disabled || !_this.state.marker || !_this.state.maps) {
297
- return;
298
- }
299
-
300
- _this.state.marker.setPosition(event.latLng);
301
-
302
- _this.state.marker.setVisible(true);
303
-
304
- _this.props.onChangeLocation({
305
- lat: event.latLng.lat(),
306
- lng: event.latLng.lng()
307
- });
308
- });
309
- maps.event.addListener(marker, 'dragend', function (event) {
310
- _this.props.onChangeLocation({
311
- lat: event.latLng.lat(),
312
- lng: event.latLng.lng()
313
- });
314
- });
315
-
316
- _this.setState({
317
- marker: marker,
318
- maps: maps
319
- }, function () {
320
- _this.props.onGoogleApiLoaded({
321
- maps: maps
322
- });
323
- });
324
- };
325
-
326
- _this.state = {
327
- marker: undefined,
328
- maps: undefined
329
- };
330
- return _this;
331
- }
332
-
333
- var _proto = GoogleMapView.prototype;
334
-
335
- _proto.componentDidUpdate = function componentDidUpdate() {
336
- if (this.state.marker && this.state.maps) {
337
- if (this.props.location) {
338
- var latLng = new this.state.maps.LatLng(this.props.location.lat, this.props.location.lng);
339
- this.state.marker.setPosition(latLng);
340
- this.state.marker.setVisible(true);
341
- } else {
342
- this.state.marker.setVisible(false);
343
- }
344
-
345
- this.state.marker.setDraggable(!this.props.disabled);
346
- this.state.marker.setCursor(this.props.disabled ? 'not-allowed' : 'auto');
347
- }
348
- };
349
-
350
- _proto.render = function render() {
351
- return React__default.createElement("div", {
352
- className: styles$2.root
353
- }, React__default.createElement(GoogleMapReact, {
354
- draggable: !this.props.disabled,
355
- bootstrapURLKeys: this.props.googleMapsKey ? {
356
- key: this.props.googleMapsKey
357
- } : undefined,
358
- defaultCenter: BerlinLocation,
359
- center: this.props.location,
360
- options: {
361
- scrollwheel: false,
362
- mapTypeId: 'roadmap'
363
- },
364
- defaultZoom: 6,
365
- yesIWantToUseGoogleMapApiInternals: true,
366
- onGoogleApiLoaded: this.onGoogleApiLoaded
367
- }));
368
- };
369
-
370
- return GoogleMapView;
371
- }(React__default.Component);
372
-
373
373
  function toLocationValue(coords) {
374
374
  if (coords && isNumber(coords.lat) && isNumber(coords.lng)) {
375
375
  return {