@sanity/google-maps-input 4.2.1 → 5.0.1

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.
Files changed (39) hide show
  1. package/LICENSE +1 -1
  2. package/assets/google-maps-input.png +0 -0
  3. package/assets/google-maps-radius-input.png +0 -0
  4. package/dist/index.d.ts +54 -84
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +736 -652
  7. package/dist/index.js.map +1 -1
  8. package/package.json +36 -80
  9. package/dist/index.cjs +0 -1014
  10. package/dist/index.cjs.map +0 -1
  11. package/dist/index.d.cts +0 -85
  12. package/sanity.json +0 -8
  13. package/src/diff/GeopointArrayDiff.tsx +0 -86
  14. package/src/diff/GeopointFieldDiff.styles.tsx +0 -20
  15. package/src/diff/GeopointFieldDiff.tsx +0 -97
  16. package/src/diff/GeopointMove.tsx +0 -48
  17. package/src/diff/GeopointRadiusFieldDiff.tsx +0 -136
  18. package/src/diff/GeopointRadiusMove.tsx +0 -92
  19. package/src/diff/resolver.ts +0 -26
  20. package/src/global-workaround.ts +0 -11
  21. package/src/index.ts +0 -20
  22. package/src/input/GeopointInput.styles.tsx +0 -11
  23. package/src/input/GeopointInput.tsx +0 -179
  24. package/src/input/GeopointRadiusInput.tsx +0 -258
  25. package/src/input/GeopointRadiusSelect.tsx +0 -193
  26. package/src/input/GeopointSelect.tsx +0 -79
  27. package/src/loader/GoogleMapsLoadProxy.tsx +0 -62
  28. package/src/loader/LoadError.tsx +0 -43
  29. package/src/loader/loadGoogleMapsApi.ts +0 -77
  30. package/src/map/Arrow.tsx +0 -76
  31. package/src/map/Map.styles.tsx +0 -10
  32. package/src/map/Map.tsx +0 -125
  33. package/src/map/Marker.tsx +0 -130
  34. package/src/map/SearchInput.styles.tsx +0 -8
  35. package/src/map/SearchInput.tsx +0 -56
  36. package/src/map/util.ts +0 -14
  37. package/src/plugin.tsx +0 -92
  38. package/src/types.ts +0 -46
  39. package/v2-incompatible.js +0 -10
@@ -1,77 +0,0 @@
1
- declare global {
2
- // eslint-disable-next-line
3
- interface Window {
4
- gm_authFailure: any
5
- ___sanity_googleMapsApiCallback: any
6
- }
7
- }
8
-
9
- const callbackName = '___sanity_googleMapsApiCallback'
10
- const authFailureCallbackName = 'gm_authFailure'
11
-
12
- export class AuthError extends Error {}
13
-
14
- function _loadGoogleMapsApi(config: {locale: string; apiKey: string}) {
15
- return new Promise<typeof window.google.maps>((resolve, reject) => {
16
- window[authFailureCallbackName] = () => {
17
- reject(new AuthError('Authentication error when loading Google Maps API.'))
18
- }
19
-
20
- window[callbackName] = () => {
21
- resolve(window.google.maps)
22
- }
23
-
24
- const script = document.createElement('script')
25
- script.onerror = (
26
- event: Event | string,
27
- source?: string,
28
- lineno?: number,
29
- colno?: number,
30
- error?: Error,
31
- ) => reject(new Error(coeerceError(event, error)))
32
-
33
- script.src = `https://maps.googleapis.com/maps/api/js?key=${config.apiKey}&libraries=places&callback=${callbackName}&language=${config.locale}`
34
- document.getElementsByTagName('head')[0].appendChild(script)
35
- }).finally(() => {
36
- delete window[callbackName]
37
- delete window[authFailureCallbackName]
38
- })
39
- }
40
-
41
- let memo: Promise<typeof window.google.maps> | null = null
42
- export function loadGoogleMapsApi(config: {
43
- locale: string
44
- apiKey: string
45
- }): Promise<typeof window.google.maps> {
46
- if (memo) {
47
- return memo
48
- }
49
- memo = _loadGoogleMapsApi(config)
50
- memo.catch(() => {
51
- memo = null
52
- })
53
- return memo
54
- }
55
- function coeerceError(event: Event | string, error?: Error): string {
56
- if (error) {
57
- return error.message
58
- }
59
-
60
- if (typeof event === 'string') {
61
- return event
62
- }
63
-
64
- return isErrorEvent(event) ? event.message : 'Failed to load Google Maps API'
65
- }
66
-
67
- function isErrorEvent(event: unknown): event is ErrorEvent {
68
- if (typeof event !== 'object' || event === null) {
69
- return false
70
- }
71
-
72
- if (!('message' in event)) {
73
- return false
74
- }
75
-
76
- return typeof (event as ErrorEvent).message === 'string'
77
- }
package/src/map/Arrow.tsx DELETED
@@ -1,76 +0,0 @@
1
- import {type MutableRefObject, PureComponent} from 'react'
2
- import type {LatLng} from '../types'
3
- import {latLngAreEqual} from './util'
4
-
5
- interface Props {
6
- api: typeof window.google.maps
7
- map: google.maps.Map
8
- from: LatLng
9
- to: LatLng
10
- color?: {background: string; border: string; text: string}
11
- zIndex?: number
12
- arrowRef?: MutableRefObject<google.maps.Polyline | undefined>
13
- onClick?: (event: google.maps.MapMouseEvent) => void
14
- }
15
-
16
- export class Arrow extends PureComponent<Props> {
17
- line: google.maps.Polyline | undefined
18
-
19
- eventHandlers: {
20
- click?: google.maps.MapsEventListener
21
- } = {}
22
-
23
- componentDidMount() {
24
- const {from, to, api, map, zIndex, onClick, color, arrowRef} = this.props
25
- const lineSymbol = {
26
- path: api.SymbolPath.FORWARD_OPEN_ARROW,
27
- }
28
-
29
- this.line = new api.Polyline({
30
- map,
31
- zIndex,
32
- path: [from, to],
33
- icons: [{icon: lineSymbol, offset: '50%'}],
34
- strokeOpacity: 0.55,
35
- strokeColor: color ? color.text : 'black',
36
- })
37
-
38
- if (onClick) {
39
- this.eventHandlers.click = api.event.addListener(this.line, 'click', onClick)
40
- }
41
-
42
- if (arrowRef) {
43
- arrowRef.current = this.line
44
- }
45
- }
46
-
47
- componentDidUpdate(prevProps: Props) {
48
- if (!this.line) {
49
- return
50
- }
51
-
52
- const {from, to, map} = this.props
53
- if (!latLngAreEqual(prevProps.from, from) || !latLngAreEqual(prevProps.to, to)) {
54
- this.line.setPath([from, to])
55
- }
56
-
57
- if (prevProps.map !== map) {
58
- this.line.setMap(map)
59
- }
60
- }
61
-
62
- componentWillUnmount() {
63
- if (this.line) {
64
- this.line.setMap(null)
65
- }
66
-
67
- if (this.eventHandlers.click) {
68
- this.eventHandlers.click.remove()
69
- }
70
- }
71
-
72
- // eslint-disable-next-line class-methods-use-this
73
- render(): any {
74
- return null
75
- }
76
- }
@@ -1,10 +0,0 @@
1
- import {styled} from 'styled-components'
2
-
3
- export const MapContainer = styled.div`
4
- position: absolute;
5
- top: 0;
6
- left: 0;
7
- height: 100%;
8
- width: 100%;
9
- box-sizing: border-box;
10
- `
package/src/map/Map.tsx DELETED
@@ -1,125 +0,0 @@
1
- import {createRef, PureComponent, type ReactElement} from 'react'
2
- import type {LatLng} from '../types'
3
- import {latLngAreEqual} from './util'
4
- import {MapContainer} from './Map.styles'
5
-
6
- interface MapProps {
7
- api: typeof window.google.maps
8
- location: LatLng
9
- bounds?: google.maps.LatLngBounds
10
- defaultZoom?: number
11
- mapTypeControl?: boolean
12
- scrollWheel?: boolean
13
- controlSize?: number
14
- onClick?: (event: google.maps.MapMouseEvent) => void
15
- children?: (map: google.maps.Map) => ReactElement
16
- }
17
-
18
- interface MapState {
19
- map: google.maps.Map | undefined
20
- }
21
-
22
- export class GoogleMap extends PureComponent<MapProps, MapState> {
23
- static defaultProps = {
24
- defaultZoom: 8,
25
- scrollWheel: true,
26
- }
27
-
28
- state: MapState = {map: undefined}
29
- clickHandler: google.maps.MapsEventListener | undefined
30
- mapRef = createRef<HTMLDivElement>()
31
- mapEl: HTMLDivElement | null = null
32
-
33
- componentDidMount() {
34
- this.attachClickHandler()
35
- }
36
-
37
- attachClickHandler = () => {
38
- const map = this.state.map
39
- if (!map) {
40
- return
41
- }
42
-
43
- const {api, onClick} = this.props
44
- const {event} = api
45
-
46
- if (this.clickHandler) {
47
- this.clickHandler.remove()
48
- }
49
-
50
- if (onClick) {
51
- this.clickHandler = event.addListener(map, 'click', onClick)
52
- }
53
- }
54
-
55
- componentDidUpdate(prevProps: MapProps) {
56
- const map = this.state.map
57
- if (!map) {
58
- return
59
- }
60
-
61
- const {onClick, location, bounds} = this.props
62
-
63
- if (prevProps.onClick !== onClick) {
64
- this.attachClickHandler()
65
- }
66
-
67
- if (!latLngAreEqual(prevProps.location, location)) {
68
- map.panTo(this.getCenter())
69
- }
70
-
71
- if (bounds && (!prevProps.bounds || !bounds.equals(prevProps.bounds))) {
72
- map.fitBounds(bounds)
73
- }
74
- }
75
-
76
- componentWillUnmount() {
77
- if (this.clickHandler) {
78
- this.clickHandler.remove()
79
- }
80
- }
81
-
82
- getCenter(): google.maps.LatLng {
83
- const {location, api} = this.props
84
- return new api.LatLng(location.lat, location.lng)
85
- }
86
-
87
- constructMap(el: HTMLDivElement) {
88
- const {defaultZoom, api, mapTypeControl, controlSize, bounds, scrollWheel} = this.props
89
-
90
- const map = new api.Map(el, {
91
- zoom: defaultZoom,
92
- center: this.getCenter(),
93
- scrollwheel: scrollWheel,
94
- streetViewControl: false,
95
- mapTypeControl,
96
- controlSize,
97
- })
98
-
99
- if (bounds) {
100
- map.fitBounds(bounds)
101
- }
102
-
103
- return map
104
- }
105
-
106
- setMapElement = (element: HTMLDivElement | null) => {
107
- if (element && element !== this.mapEl) {
108
- const map = this.constructMap(element)
109
- this.setState({map}, this.attachClickHandler)
110
- }
111
-
112
- this.mapEl = element
113
- }
114
-
115
- render() {
116
- const {children} = this.props
117
- const {map} = this.state
118
- return (
119
- <>
120
- <MapContainer ref={this.setMapElement} />
121
- {children && map ? children(map) : null}
122
- </>
123
- )
124
- }
125
- }
@@ -1,130 +0,0 @@
1
- import {PureComponent, type MutableRefObject} from 'react'
2
- import type {LatLng} from '../types'
3
- import {latLngAreEqual} from './util'
4
-
5
- const markerPath =
6
- 'M 3.052 3.7 C 1.56 5.293 0.626 7.612 0.663 9.793 C 0.738 14.352 2.793 16.077 6.078 22.351 C 7.263 25.111 8.497 28.032 9.672 32.871 C 9.835 33.584 9.994 34.246 10.069 34.305 C 10.143 34.362 10.301 33.697 10.465 32.983 C 11.639 28.145 12.875 25.226 14.059 22.466 C 17.344 16.192 19.398 14.466 19.474 9.908 C 19.511 7.727 18.574 5.405 17.083 3.814 C 15.379 1.994 12.809 0.649 10.069 0.593 C 7.328 0.536 4.756 1.882 3.052 3.7 Z'
7
-
8
- interface Props {
9
- api: typeof window.google.maps
10
- map: google.maps.Map
11
- onMove?: (event: google.maps.MapMouseEvent) => void
12
- onClick?: (event: google.maps.MapMouseEvent) => void
13
- position: LatLng | google.maps.LatLng
14
- zIndex?: number
15
- opacity?: number
16
- label?: string
17
- markerRef?: MutableRefObject<google.maps.Marker | undefined>
18
- color?: {background: string; border: string; text: string}
19
- }
20
-
21
- export class Marker extends PureComponent<Props> {
22
- marker: google.maps.Marker | undefined
23
-
24
- eventHandlers: {
25
- move?: google.maps.MapsEventListener
26
- click?: google.maps.MapsEventListener
27
- } = {}
28
-
29
- componentDidMount() {
30
- const {position, api, map, onMove, zIndex, opacity, label, markerRef, color} = this.props
31
- const {Marker: GMarker} = api
32
-
33
- let icon: google.maps.Symbol | undefined
34
- if (color) {
35
- icon = {
36
- path: markerPath,
37
- fillOpacity: 1,
38
- fillColor: color.background,
39
- strokeColor: color.border,
40
- strokeWeight: 2,
41
- anchor: new api.Point(10, 35),
42
- labelOrigin: new api.Point(10, 11),
43
- }
44
- }
45
-
46
- this.marker = new GMarker({
47
- draggable: Boolean(onMove),
48
- position,
49
- map,
50
- zIndex,
51
- opacity,
52
- label,
53
- icon,
54
- })
55
-
56
- if (markerRef) {
57
- markerRef.current = this.marker
58
- }
59
-
60
- this.attachMoveHandler()
61
- this.attachClickHandler()
62
- }
63
-
64
- componentDidUpdate(prevProps: Props) {
65
- if (!this.marker) {
66
- return
67
- }
68
-
69
- const {position, onMove, label, zIndex, opacity, map} = this.props
70
-
71
- if (prevProps.onMove !== onMove) {
72
- this.attachMoveHandler()
73
- }
74
-
75
- if (!latLngAreEqual(prevProps.position, position)) {
76
- this.marker.setPosition(position)
77
- }
78
-
79
- if (prevProps.label !== label) {
80
- this.marker.setLabel(label || null)
81
- }
82
-
83
- if (prevProps.zIndex !== zIndex) {
84
- this.marker.setZIndex(zIndex || null)
85
- }
86
-
87
- if (prevProps.opacity !== opacity) {
88
- this.marker.setOpacity(opacity || null)
89
- }
90
-
91
- if (prevProps.map !== map) {
92
- this.marker.setMap(map)
93
- }
94
- }
95
-
96
- componentWillUnmount() {
97
- if (this.eventHandlers.move) {
98
- this.eventHandlers.move.remove()
99
- }
100
-
101
- if (this.marker) {
102
- this.marker.setMap(null)
103
- }
104
- }
105
-
106
- attachMoveHandler() {
107
- const {api, onMove} = this.props
108
- if (this.eventHandlers.move) {
109
- this.eventHandlers.move.remove()
110
- }
111
- if (this.marker && onMove) {
112
- this.eventHandlers.move = api.event.addListener(this.marker, 'dragend', onMove)
113
- }
114
- }
115
-
116
- attachClickHandler() {
117
- const {api, onClick} = this.props
118
- if (this.eventHandlers.click) {
119
- this.eventHandlers.click.remove()
120
- }
121
- if (this.marker && onClick) {
122
- this.eventHandlers.click = api.event.addListener(this.marker, 'click', onClick)
123
- }
124
- }
125
-
126
- // eslint-disable-next-line class-methods-use-this
127
- render(): any {
128
- return null
129
- }
130
- }
@@ -1,8 +0,0 @@
1
- import {styled} from 'styled-components'
2
-
3
- export const WrapperContainer = styled.div`
4
- position: absolute;
5
- right: 10px;
6
- top: 10px;
7
- width: 220px;
8
- `
@@ -1,56 +0,0 @@
1
- import {TextInput} from '@sanity/ui'
2
- import {WrapperContainer} from './SearchInput.styles'
3
- import {createRef, PureComponent} from 'react'
4
-
5
- interface Props {
6
- api: typeof window.google.maps
7
- map: google.maps.Map
8
- onChange: (result: google.maps.places.PlaceResult) => void
9
- }
10
-
11
- export class SearchInput extends PureComponent<Props> {
12
- searchInputRef = createRef<HTMLInputElement>()
13
- autoComplete: google.maps.places.Autocomplete | undefined
14
-
15
- handleChange = () => {
16
- if (!this.autoComplete) {
17
- return
18
- }
19
-
20
- this.props.onChange(this.autoComplete.getPlace())
21
-
22
- if (this.searchInputRef.current) {
23
- this.searchInputRef.current.value = ''
24
- }
25
- }
26
-
27
- componentDidMount() {
28
- const input = this.searchInputRef.current
29
- if (!input) {
30
- return
31
- }
32
-
33
- const {api, map} = this.props
34
- const {Circle, places, event} = api
35
- const searchBounds = new Circle({center: map.getCenter(), radius: 100}).getBounds()!
36
- this.autoComplete = new places.Autocomplete(input, {
37
- bounds: searchBounds,
38
- types: [], // return all kinds of places
39
- })
40
-
41
- event.addListener(this.autoComplete, 'place_changed', this.handleChange)
42
- }
43
-
44
- render() {
45
- return (
46
- <WrapperContainer>
47
- <TextInput
48
- name="place"
49
- ref={this.searchInputRef}
50
- placeholder="Search for place or address"
51
- padding={4}
52
- />
53
- </WrapperContainer>
54
- )
55
- }
56
- }
package/src/map/util.ts DELETED
@@ -1,14 +0,0 @@
1
- import type {LatLng} from '../types'
2
-
3
- export function latLngAreEqual(
4
- latLng1: LatLng | google.maps.LatLng,
5
- latLng2: LatLng | google.maps.LatLng,
6
- ): boolean {
7
- const lat1 = typeof latLng1.lat === 'function' ? latLng1.lat() : latLng1.lat
8
- const lng1 = typeof latLng1.lng === 'function' ? latLng1.lng() : latLng1.lng
9
-
10
- const lat2 = typeof latLng2.lat === 'function' ? latLng2.lat() : latLng2.lat
11
- const lng2 = typeof latLng2.lng === 'function' ? latLng2.lng() : latLng2.lng
12
-
13
- return lat1 === lat2 && lng1 === lng2
14
- }
package/src/plugin.tsx DELETED
@@ -1,92 +0,0 @@
1
- import {definePlugin, type SchemaType} from 'sanity'
2
- import {GeopointInput, type GeopointInputProps} from './input/GeopointInput'
3
- import {GeopointRadiusInput, type GeopointRadiusInputProps} from './input/GeopointRadiusInput'
4
- import {setGeoConfig} from './global-workaround'
5
- import type {GeopointSchemaType, GeopointRadiusSchemaType, GoogleMapsInputConfig} from './types'
6
-
7
- export const googleMapsInput = definePlugin<GoogleMapsInputConfig>((config) => {
8
- setGeoConfig(config)
9
- return {
10
- name: 'google-maps-input',
11
- schema: {
12
- types: [
13
- {
14
- name: 'geopointRadius',
15
- title: 'Geopoint with Radius',
16
- type: 'object',
17
- fields: [
18
- {
19
- name: 'lat',
20
- title: 'Latitude',
21
- type: 'number',
22
- validation: (Rule: any) => Rule.required().min(-90).max(90),
23
- },
24
- {
25
- name: 'lng',
26
- title: 'Longitude',
27
- type: 'number',
28
- validation: (Rule: any) => Rule.required().min(-180).max(180),
29
- },
30
- {
31
- name: 'alt',
32
- title: 'Altitude',
33
- type: 'number',
34
- },
35
- {
36
- name: 'radius',
37
- title: 'Radius (meters)',
38
- type: 'number',
39
- validation: (Rule: any) => Rule.required().min(1).max(50000),
40
- },
41
- ],
42
- preview: {
43
- select: {
44
- lat: 'lat',
45
- lng: 'lng',
46
- radius: 'radius',
47
- },
48
- prepare({lat, lng, radius}: {lat: number; lng: number; radius: number}) {
49
- return {
50
- title: `${lat.toFixed(6)}, ${lng.toFixed(6)}`,
51
- subtitle: radius ? `Radius: ${radius}m` : 'No radius set',
52
- }
53
- },
54
- },
55
- },
56
- ],
57
- },
58
- form: {
59
- components: {
60
- input(props) {
61
- if (isGeopoint(props.schemaType)) {
62
- const castedProps = props as unknown as Omit<GeopointInputProps, 'geoConfig'>
63
- return <GeopointInput {...castedProps} geoConfig={config} />
64
- }
65
- if (isGeopointRadius(props.schemaType)) {
66
- const castedProps = props as unknown as Omit<GeopointRadiusInputProps, 'geoConfig'>
67
- return <GeopointRadiusInput {...castedProps} geoConfig={config} />
68
- }
69
- return props.renderDefault(props)
70
- },
71
- },
72
- },
73
- }
74
- })
75
-
76
- function isGeopoint(schemaType: SchemaType): schemaType is GeopointSchemaType {
77
- return isType('geopoint', schemaType)
78
- }
79
-
80
- function isGeopointRadius(schemaType: SchemaType): schemaType is GeopointRadiusSchemaType {
81
- return isType('geopointRadius', schemaType)
82
- }
83
-
84
- function isType(name: string, schema?: SchemaType): boolean {
85
- if (schema?.name === name) {
86
- return true
87
- // eslint-disable-next-line no-negated-condition
88
- } else if (!schema?.name) {
89
- return false
90
- }
91
- return isType(name, schema?.type)
92
- }
package/src/types.ts DELETED
@@ -1,46 +0,0 @@
1
- import type {DiffComponent, DiffComponentOptions, ObjectDiff} from 'sanity'
2
- import type {ObjectSchemaType} from 'sanity'
3
-
4
- export interface LatLng {
5
- lat: number
6
- lng: number
7
- }
8
-
9
- export interface Geopoint {
10
- _type: 'geopoint'
11
- _key?: string
12
- lat: number
13
- lng: number
14
- alt?: number
15
- }
16
-
17
- export interface GeopointRadius {
18
- _type: 'geopointRadius'
19
- _key?: string
20
- lat: number
21
- lng: number
22
- alt?: number
23
- radius: number
24
- }
25
-
26
- export interface GeopointSchemaType extends ObjectSchemaType {
27
- diffComponent?: DiffComponent<ObjectDiff<Geopoint>> | DiffComponentOptions<ObjectDiff<Geopoint>>
28
- }
29
-
30
- export interface GeopointRadiusSchemaType extends ObjectSchemaType {
31
- diffComponent?:
32
- | DiffComponent<ObjectDiff<GeopointRadius>>
33
- | DiffComponentOptions<ObjectDiff<GeopointRadius>>
34
- }
35
-
36
- export interface GoogleMapsInputConfig {
37
- apiKey: string
38
- defaultZoom?: number
39
- defaultLocale?: string
40
- defaultLocation?: {
41
- lat: number
42
- lng: number
43
- }
44
- defaultRadiusZoom?: number
45
- defaultRadius?: number
46
- }
@@ -1,10 +0,0 @@
1
- const {showIncompatiblePluginDialog} = require('@sanity/incompatible-plugin')
2
- const {name, version} = require('./package.json')
3
-
4
- export default showIncompatiblePluginDialog({
5
- name: name,
6
- versions: {
7
- v3: version,
8
- v2: '^2.30.0',
9
- },
10
- })