Skip to content

Commit

Permalink
[google-maps-input] Handle presence + focus state
Browse files Browse the repository at this point in the history
  • Loading branch information
rexxars committed Oct 6, 2020
1 parent 43cc141 commit 1c25dd1
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 18 deletions.
67 changes: 53 additions & 14 deletions packages/@sanity/google-maps-input/src/input/GeopointInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import React from 'react'
import config from 'config:@sanity/google-maps-input'
import Button from 'part:@sanity/components/buttons/default'
import Dialog from 'part:@sanity/components/dialogs/default'
import Fieldset from 'part:@sanity/components/fieldsets/default'
import FormField from 'part:@sanity/components/formfields/default'
import {PatchEvent, set, setIfMissing, unset} from 'part:@sanity/form-builder/patch-event'
import ButtonGrid from 'part:@sanity/components/buttons/button-grid'
import EditIcon from 'part:@sanity/base/edit-icon'
import TrashIcon from 'part:@sanity/base/trash-icon'
import {GoogleMapsLoadProxy} from '../loader/GoogleMapsLoadProxy'
import {Geopoint, GeopointSchemaType} from '../types'
import styles from './GeopointInput.css'
import {GeopointSelect} from './GeopointSelect'
import styles from './GeopointInput.css'

const getStaticImageUrl = value => {
const loc = `${value.lat},${value.lng}`
Expand All @@ -32,11 +32,19 @@ const getStaticImageUrl = value => {

interface InputProps {
markers: unknown[]
level?: number
value?: Geopoint
type: GeopointSchemaType
readOnly?: boolean
onFocus: (path: unknown[]) => void
onBlur: () => void
onChange: (patchEvent: unknown) => void
}

interface Focusable {
focus: () => void
}

interface InputState {
modalOpen: boolean
}
Expand All @@ -46,6 +54,8 @@ class GeopointInput extends React.PureComponent<InputProps, InputState> {
markers: []
}

editButton: Focusable | undefined

constructor(props) {
super(props)

Expand All @@ -54,8 +64,28 @@ class GeopointInput extends React.PureComponent<InputProps, InputState> {
}
}

setEditButton = (el: Focusable) => {
this.editButton = el
}

focus() {
if (this.editButton) {
this.editButton.focus()
}
}

handleToggleModal = () => {
this.setState(prevState => ({modalOpen: !prevState.modalOpen}))
const {onFocus, onBlur} = this.props
this.setState(
prevState => ({modalOpen: !prevState.modalOpen}),
() => {
if (this.state.modalOpen) {
onFocus([])
} else {
onBlur()
}
}
)
}

handleCloseModal = () => {
Expand All @@ -81,7 +111,8 @@ class GeopointInput extends React.PureComponent<InputProps, InputState> {
}

render() {
const {value, type, markers} = this.props
const {value, readOnly, type, markers, level, onFocus, onBlur} = this.props
const {modalOpen} = this.state

if (!config || !config.apiKey) {
return (
Expand All @@ -106,13 +137,16 @@ class GeopointInput extends React.PureComponent<InputProps, InputState> {
}

return (
<Fieldset
legend={type.title}
<FormField
markers={markers}
level={level}
label={type.title}
description={type.description}
className={styles.root}
markers={markers}
onFocus={onFocus}
onBlur={onBlur}
>
<div>
<>
{value && (
<div className={styles.map}>
<img
Expand All @@ -125,7 +159,12 @@ class GeopointInput extends React.PureComponent<InputProps, InputState> {

<div className={styles.functions}>
<ButtonGrid>
<Button inverted onClick={this.handleToggleModal} icon={value && EditIcon}>
<Button
inverted
onClick={this.handleToggleModal}
icon={value && EditIcon}
ref={this.setEditButton}
>
{value ? 'Edit' : 'Set location'}
</Button>

Expand All @@ -137,21 +176,21 @@ class GeopointInput extends React.PureComponent<InputProps, InputState> {
</ButtonGrid>
</div>

{this.state.modalOpen && (
{modalOpen && (
<Dialog
title="Place on map"
onClose={this.handleCloseModal}
onCloseClick={this.handleCloseModal}
message="Select location by dragging the marker or search for a place"
isOpen={this.state.modalOpen}
isOpen={modalOpen}
>
<div className={styles.dialogInner}>
<GoogleMapsLoadProxy>
{api => (
<GeopointSelect
api={api}
value={value}
onChange={this.handleChange}
onChange={readOnly ? undefined : this.handleChange}
defaultLocation={config.defaultLocation}
defaultZoom={config.defaultZoom}
/>
Expand All @@ -160,8 +199,8 @@ class GeopointInput extends React.PureComponent<InputProps, InputState> {
</div>
</Dialog>
)}
</div>
</Fieldset>
</>
</FormField>
)
}
}
Expand Down
15 changes: 11 additions & 4 deletions packages/@sanity/google-maps-input/src/input/GeopointSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const fallbackLatLng: LatLng = {lat: 40.7058254, lng: -74.1180863}
interface SelectProps {
api: typeof window.google.maps
value?: Geopoint
onChange: (latLng: google.maps.LatLng) => void
onChange?: (latLng: google.maps.LatLng) => void
defaultLocation?: LatLng
defaultZoom?: number
}
Expand Down Expand Up @@ -46,11 +46,13 @@ export class GeopointSelect extends React.PureComponent<SelectProps> {
}

setValue(geoPoint: google.maps.LatLng) {
this.props.onChange(geoPoint)
if (this.props.onChange) {
this.props.onChange(geoPoint)
}
}

render() {
const {api, defaultZoom, value} = this.props
const {api, defaultZoom, value, onChange} = this.props
return (
<div className={styles.wrapper}>
<GoogleMap
Expand All @@ -63,7 +65,12 @@ export class GeopointSelect extends React.PureComponent<SelectProps> {
<>
<SearchInput api={api} map={map} onChange={this.handlePlaceChanged} />
{value && (
<Marker api={api} map={map} position={value} onMove={this.handleMarkerDragEnd} />
<Marker
api={api}
map={map}
position={value}
onMove={onChange ? this.handleMarkerDragEnd : undefined}
/>
)}
</>
)}
Expand Down

0 comments on commit 1c25dd1

Please sign in to comment.