@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,136 +0,0 @@
1
- import {
2
- type DiffComponent,
3
- type ObjectDiff,
4
- type DiffProps as GenericDiffProps,
5
- DiffTooltip,
6
- getAnnotationAtPath,
7
- } from 'sanity'
8
- import {GoogleMapsLoadProxy} from '../loader/GoogleMapsLoadProxy'
9
- import {GoogleMap} from '../map/Map'
10
- import type {GeopointRadius} from '../types'
11
- import {getGeoConfig} from '../global-workaround'
12
- import {GeopointRadiusMove} from './GeopointRadiusMove'
13
- import {RootContainer} from './GeopointFieldDiff.styles'
14
-
15
- export type DiffProps = GenericDiffProps<ObjectDiff<GeopointRadius>>
16
-
17
- export const GeopointRadiusFieldDiff: DiffComponent<ObjectDiff<GeopointRadius>> = ({
18
- diff,
19
- schemaType,
20
- }: DiffProps) => {
21
- return (
22
- <RootContainer>
23
- <GoogleMapsLoadProxy config={getGeoConfig()}>
24
- {(api) => <GeopointRadiusDiff api={api} diff={diff} schemaType={schemaType} />}
25
- </GoogleMapsLoadProxy>
26
- </RootContainer>
27
- )
28
- }
29
-
30
- function GeopointRadiusDiff({api, diff}: DiffProps & {api: typeof window.google.maps}) {
31
- const {fromValue, toValue} = diff
32
- const annotation =
33
- getAnnotationAtPath(diff, ['lat']) ||
34
- getAnnotationAtPath(diff, ['lng']) ||
35
- getAnnotationAtPath(diff, ['radius']) ||
36
- getAnnotationAtPath(diff, [])
37
-
38
- const center = getCenter(diff, api)
39
- const bounds = fromValue && toValue ? getBounds(fromValue, toValue, api) : undefined
40
-
41
- return (
42
- <DiffTooltip annotations={annotation ? [annotation] : []} description={getAction(diff)}>
43
- <div>
44
- <GoogleMap
45
- api={api}
46
- location={center}
47
- mapTypeControl={false}
48
- controlSize={20}
49
- bounds={bounds}
50
- scrollWheel={false}
51
- >
52
- {(map) => <GeopointRadiusMove api={api} map={map} diff={diff} />}
53
- </GoogleMap>
54
- </div>
55
- </DiffTooltip>
56
- )
57
- }
58
-
59
- function getBounds(
60
- fromValue: google.maps.LatLngLiteral & {radius?: number},
61
- toValue: google.maps.LatLngLiteral & {radius?: number},
62
- api: typeof window.google.maps,
63
- ): google.maps.LatLngBounds {
64
- const bounds = new api.LatLngBounds().extend(fromValue).extend(toValue)
65
-
66
- // Extend bounds to include radius circles
67
- const fromRadius = fromValue.radius || 0
68
- const toRadius = toValue.radius || 0
69
- const maxRadius = Math.max(fromRadius, toRadius)
70
-
71
- if (maxRadius > 0) {
72
- // Convert radius from meters to degrees (approximate)
73
- const radiusInDegrees = maxRadius / 111000 // Rough conversion
74
- bounds.extend({
75
- lat: fromValue.lat + radiusInDegrees,
76
- lng: fromValue.lng + radiusInDegrees,
77
- })
78
- bounds.extend({
79
- lat: fromValue.lat - radiusInDegrees,
80
- lng: fromValue.lng - radiusInDegrees,
81
- })
82
- bounds.extend({
83
- lat: toValue.lat + radiusInDegrees,
84
- lng: toValue.lng + radiusInDegrees,
85
- })
86
- bounds.extend({
87
- lat: toValue.lat - radiusInDegrees,
88
- lng: toValue.lng - radiusInDegrees,
89
- })
90
- }
91
-
92
- return bounds
93
- }
94
-
95
- function getCenter(
96
- diff: DiffProps['diff'],
97
- api: typeof window.google.maps,
98
- ): google.maps.LatLngLiteral {
99
- const {fromValue, toValue} = diff
100
- if (fromValue && toValue) {
101
- return getBounds(fromValue, toValue, api).getCenter().toJSON()
102
- }
103
-
104
- if (fromValue) {
105
- return fromValue
106
- }
107
-
108
- if (toValue) {
109
- return toValue
110
- }
111
-
112
- throw new Error('Neither a from or a to value present')
113
- }
114
-
115
- function getAction(diff: ObjectDiff<GeopointRadius>) {
116
- const {fromValue, toValue} = diff
117
- if (fromValue && toValue) {
118
- const latChanged = fromValue.lat !== toValue.lat || fromValue.lng !== toValue.lng
119
- const radiusChanged = fromValue.radius !== toValue.radius
120
-
121
- if (latChanged && radiusChanged) {
122
- return 'Moved and radius changed'
123
- } else if (latChanged) {
124
- return 'Moved'
125
- } else if (radiusChanged) {
126
- return 'Radius changed'
127
- }
128
- return 'Unchanged'
129
- } else if (fromValue) {
130
- return 'Removed'
131
- } else if (toValue) {
132
- return 'Added'
133
- }
134
-
135
- return 'Unchanged'
136
- }
@@ -1,92 +0,0 @@
1
- import {useRef, useEffect} from 'react'
2
- import {useUserColor, type ObjectDiff} from 'sanity'
3
- import {Marker} from '../map/Marker'
4
- import {Arrow} from '../map/Arrow'
5
- import type {GeopointRadius} from '../types'
6
-
7
- interface GeopointRadiusMoveProps {
8
- api: typeof window.google.maps
9
- map: google.maps.Map
10
- diff: ObjectDiff<GeopointRadius>
11
- label?: string
12
- }
13
-
14
- export function GeopointRadiusMove({diff, api, map, label}: GeopointRadiusMoveProps) {
15
- const {fromValue: from, toValue: to} = diff
16
- const annotation = diff.isChanged ? diff.annotation : undefined
17
- const userColor = useUserColor(annotation ? annotation.author : null) || undefined
18
- const fromRef = useRef<google.maps.Marker>(undefined)
19
- const toRef = useRef<google.maps.Marker>(undefined)
20
- const fromCircleRef = useRef<google.maps.Circle>(undefined)
21
- const toCircleRef = useRef<google.maps.Circle>(undefined)
22
-
23
- // Create circles for radius visualization
24
- useEffect(() => {
25
- const color = userColor?.background || '#4285F4'
26
-
27
- if (from && from.radius) {
28
- fromCircleRef.current = new api.Circle({
29
- map,
30
- center: {lat: from.lat, lng: from.lng},
31
- radius: from.radius,
32
- fillColor: color,
33
- fillOpacity: 0.1,
34
- strokeColor: color,
35
- strokeOpacity: 0.3,
36
- strokeWeight: 1,
37
- zIndex: 0,
38
- })
39
- }
40
-
41
- if (to && to.radius) {
42
- toCircleRef.current = new api.Circle({
43
- map,
44
- center: {lat: to.lat, lng: to.lng},
45
- radius: to.radius,
46
- fillColor: color,
47
- fillOpacity: 0.2,
48
- strokeColor: color,
49
- strokeOpacity: 0.8,
50
- strokeWeight: 2,
51
- zIndex: 2,
52
- })
53
- }
54
-
55
- return () => {
56
- if (fromCircleRef.current) {
57
- fromCircleRef.current.setMap(null)
58
- }
59
- if (toCircleRef.current) {
60
- toCircleRef.current.setMap(null)
61
- }
62
- }
63
- }, [api, map, from, to, userColor])
64
-
65
- return (
66
- <>
67
- {from && (
68
- <Marker
69
- api={api}
70
- map={map}
71
- position={from}
72
- zIndex={0}
73
- opacity={0.55}
74
- markerRef={fromRef}
75
- color={userColor}
76
- />
77
- )}
78
- {from && to && <Arrow api={api} map={map} from={from} to={to} zIndex={1} color={userColor} />}
79
- {to && (
80
- <Marker
81
- api={api}
82
- map={map}
83
- position={to}
84
- zIndex={2}
85
- markerRef={toRef}
86
- label={label}
87
- color={userColor}
88
- />
89
- )}
90
- </>
91
- )
92
- }
@@ -1,26 +0,0 @@
1
- import {DiffComponentResolver} from 'sanity'
2
- import {GeopointFieldDiff} from './GeopointFieldDiff'
3
- import {GeopointArrayDiff} from './GeopointArrayDiff'
4
- import {GeopointRadiusFieldDiff} from './GeopointRadiusFieldDiff'
5
-
6
- const diffResolver: DiffComponentResolver = function diffResolver({schemaType}) {
7
- if (schemaType.name === 'geopoint') {
8
- return GeopointFieldDiff
9
- }
10
-
11
- if (schemaType.name === 'geopointRadius') {
12
- return GeopointRadiusFieldDiff
13
- }
14
-
15
- if (
16
- schemaType.jsonType === 'array' &&
17
- schemaType.of.length === 1 &&
18
- schemaType.of[0].name === 'geopoint'
19
- ) {
20
- return GeopointArrayDiff
21
- }
22
-
23
- return undefined
24
- }
25
-
26
- export default diffResolver
@@ -1,11 +0,0 @@
1
- import type {GoogleMapsInputConfig} from './types'
2
-
3
- let config: GoogleMapsInputConfig
4
-
5
- export function getGeoConfig(): GoogleMapsInputConfig {
6
- return config as GoogleMapsInputConfig
7
- }
8
-
9
- export function setGeoConfig(newConfig: GoogleMapsInputConfig): void {
10
- config = newConfig
11
- }
package/src/index.ts DELETED
@@ -1,20 +0,0 @@
1
- export {GeopointInput, type GeopointInputProps} from './input/GeopointInput'
2
- export {GeopointRadiusInput, type GeopointRadiusInputProps} from './input/GeopointRadiusInput'
3
-
4
- export {GeopointArrayDiff, type DiffProps as GeopointArrayDiffProps} from './diff/GeopointArrayDiff'
5
- export {GeopointFieldDiff, type DiffProps as GeopointFieldDiffProps} from './diff/GeopointFieldDiff'
6
- export {
7
- GeopointRadiusFieldDiff,
8
- type DiffProps as GeopointRadiusFieldDiffProps,
9
- } from './diff/GeopointRadiusFieldDiff'
10
-
11
- export type {
12
- LatLng,
13
- GeopointSchemaType,
14
- Geopoint,
15
- GeopointRadius,
16
- GeopointRadiusSchemaType,
17
- GoogleMapsInputConfig,
18
- } from './types'
19
-
20
- export {googleMapsInput} from './plugin'
@@ -1,11 +0,0 @@
1
- import {styled} from 'styled-components'
2
-
3
- export const PreviewImage = styled.img`
4
- width: 100%;
5
- height: auto;
6
- vertical-align: top;
7
- `
8
-
9
- export const DialogInnerContainer = styled.div`
10
- height: 40rem;
11
- `
@@ -1,179 +0,0 @@
1
- import {useCallback, useEffect, useId, useRef, useState} from 'react'
2
- import {Box, Button, Dialog, Grid, Stack} from '@sanity/ui'
3
- import {EditIcon, TrashIcon} from '@sanity/icons'
4
- import {ObjectInputProps, set, setIfMissing, unset, ChangeIndicator, Path} from 'sanity'
5
- import {GoogleMapsLoadProxy} from '../loader/GoogleMapsLoadProxy'
6
- import type {Geopoint, GeopointSchemaType, GoogleMapsInputConfig, LatLng} from '../types'
7
- import {getGeoConfig} from '../global-workaround'
8
- import {DialogInnerContainer, PreviewImage} from './GeopointInput.styles'
9
- import {GeopointSelect} from './GeopointSelect'
10
-
11
- const EMPTY_PATH: Path = []
12
-
13
- const getStaticImageUrl = (value: LatLng, apiKey: string) => {
14
- const loc = `${value.lat},${value.lng}`
15
- const qs = new URLSearchParams({
16
- key: apiKey,
17
- center: loc,
18
- markers: loc,
19
- zoom: '13',
20
- scale: '2',
21
- size: '640x300',
22
- })
23
-
24
- return `https://maps.googleapis.com/maps/api/staticmap?${qs.toString()}`
25
- }
26
-
27
- export type GeopointInputProps = ObjectInputProps<Geopoint, GeopointSchemaType> & {
28
- geoConfig: GoogleMapsInputConfig
29
- }
30
-
31
- export function GeopointInput(props: GeopointInputProps) {
32
- const {
33
- changed,
34
- elementProps,
35
- focused,
36
- geoConfig: config,
37
- onChange,
38
- onPathFocus,
39
- path,
40
- readOnly,
41
- schemaType,
42
- value,
43
- } = props
44
-
45
- const {
46
- id,
47
- ref: inputRef,
48
- onBlur: handleBlur,
49
- onFocus: handleFocus,
50
- 'aria-describedby': ariaDescribedBy,
51
- } = elementProps
52
-
53
- const schemaTypeName = schemaType.name
54
- const dialogId = useId()
55
- const dialogRef = useRef<HTMLDivElement | null>(null)
56
- const handleFocusButton = useCallback(() => inputRef?.current?.focus(), [inputRef])
57
- const [modalOpen, setModalOpen] = useState(false)
58
-
59
- const handleCloseModal = useCallback(() => {
60
- if (dialogRef.current) dialogRef.current.blur()
61
- setModalOpen(false)
62
- handleFocusButton()
63
- }, [setModalOpen, handleFocusButton])
64
-
65
- const handleToggleModal = useCallback(
66
- () => setModalOpen((currentState) => !currentState),
67
- [setModalOpen],
68
- )
69
-
70
- const handleChange = useCallback(
71
- (latLng: google.maps.LatLng) => {
72
- onChange([
73
- setIfMissing({_type: schemaTypeName}),
74
- set(latLng.lat(), ['lat']),
75
- set(latLng.lng(), ['lng']),
76
- ])
77
- },
78
- [schemaTypeName, onChange],
79
- )
80
-
81
- const handleClear = useCallback(() => {
82
- onChange(unset())
83
- }, [onChange])
84
-
85
- useEffect(() => {
86
- if (modalOpen) {
87
- onPathFocus(EMPTY_PATH)
88
- }
89
- }, [modalOpen, onPathFocus])
90
-
91
- if (!config || !config.apiKey) {
92
- return (
93
- <div>
94
- <p>
95
- The <a href="https://sanity.io/docs/schema-types/geopoint-type">Geopoint type</a> needs a
96
- Google Maps API key with access to:
97
- </p>
98
- <ul>
99
- <li>Google Maps JavaScript API</li>
100
- <li>Google Places API Web Service</li>
101
- <li>Google Static Maps API</li>
102
- </ul>
103
- <p>
104
- Please enter the API key with access to these services in your googleMapsInput plugin
105
- config.
106
- </p>
107
- </div>
108
- )
109
- }
110
-
111
- return (
112
- <Stack space={3}>
113
- {value && (
114
- <ChangeIndicator path={path} isChanged={changed} hasFocus={!!focused}>
115
- <PreviewImage
116
- src={getStaticImageUrl(value, config.apiKey)}
117
- alt="Map location"
118
- onClick={handleFocusButton}
119
- onDoubleClick={handleToggleModal}
120
- />
121
- </ChangeIndicator>
122
- )}
123
-
124
- <Box>
125
- <Grid columns={value ? 2 : 1} gap={3}>
126
- <Button
127
- aria-describedby={ariaDescribedBy}
128
- disabled={readOnly}
129
- icon={value && EditIcon}
130
- id={id}
131
- mode="ghost"
132
- onClick={handleToggleModal}
133
- onFocus={handleFocus}
134
- padding={3}
135
- ref={inputRef}
136
- text={value ? 'Edit' : 'Set location'}
137
- />
138
-
139
- {value && (
140
- <Button
141
- disabled={readOnly}
142
- icon={TrashIcon}
143
- mode="ghost"
144
- onClick={handleClear}
145
- padding={3}
146
- text="Remove"
147
- tone="critical"
148
- />
149
- )}
150
- </Grid>
151
- </Box>
152
-
153
- {modalOpen && (
154
- <Dialog
155
- header="Place the marker on the map"
156
- id={`${dialogId}_dialog`}
157
- onBlur={handleBlur}
158
- onClose={handleCloseModal}
159
- ref={dialogRef}
160
- width={1}
161
- >
162
- <DialogInnerContainer>
163
- <GoogleMapsLoadProxy config={getGeoConfig()}>
164
- {(api) => (
165
- <GeopointSelect
166
- api={api}
167
- value={value || undefined}
168
- onChange={readOnly ? undefined : handleChange}
169
- defaultLocation={config.defaultLocation}
170
- defaultZoom={config.defaultZoom}
171
- />
172
- )}
173
- </GoogleMapsLoadProxy>
174
- </DialogInnerContainer>
175
- </Dialog>
176
- )}
177
- </Stack>
178
- )
179
- }