Skip to content

Commit

Permalink
add loading spinner
Browse files Browse the repository at this point in the history
the spinner is shown as the user types (and requests are being made) and
is hidden when a request comes back with results, as well as when an
error occurs.

to hide it on error required wrapping the user-supplied error callback
in our own function.

the color can be changed using the --loading-color variable.
  • Loading branch information
mxlje committed May 25, 2021
1 parent 2061865 commit cbeed30
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
3 changes: 2 additions & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
<div class="logo"></div>

<ge-autocomplete
apiKey='ge-2550bcc43e8dd92e'
apiKey='ge-9ccf84885004f273'
size='4'
lang='en'
boundary.country='de'
__host='api.dev.geocode.earth'
></ge-autocomplete>
<pre id="result"></pre>
</div>
Expand Down
13 changes: 12 additions & 1 deletion src/autocomplete/autocomplete.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
rgba(0, 0, 0, 0) 0px 0px 0px 0px,
rgba(0, 0, 0, 0.05) 0px 1px 2px 0px;

--loading-color: var(--gray-500);

--results-bg: #fff;
--results-z-index: 10;
--results-shadow:
Expand Down Expand Up @@ -75,7 +77,7 @@
display: block;
width: 100%;
border: 1px solid var(--input-border-color);
padding: 13px 12px;
padding: 13px 55px 13px 12px; /* 12 + 31 + 12 = 55, loading spinner is 31 wide */;
border-radius: var(--border-radius);
appearance: none;
-webkit-appearance: none;
Expand All @@ -84,6 +86,15 @@
box-shadow: var(--input-shadow);
}

.loading {
position: absolute;
right: 12px;
top: 7px;
width: 31px;
height: 31px;
stroke: var(--loading-color);
}

.results {
font-size: 16px;
position: absolute;
Expand Down
17 changes: 15 additions & 2 deletions src/autocomplete/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createAutocomplete } from '@geocodeearth/core-js'
import debounce from 'lodash.debounce'
import css from './autocomplete.css'
import strings from '../strings'
import { LocationMarker } from '../icons'
import { LocationMarker, Loading } from '../icons'

const emptyResults = {
text: '',
Expand All @@ -20,10 +20,11 @@ export default ({
debounce: debounceWait = 300,
onSelect: userOnSelectItem,
onChange: userOnChange,
onError = () => {},
onError: userOnError,
environment = window
}) => {
const [results, setResults] = useState(emptyResults)
const [isLoading, setIsLoading] = useState(false)
const inputRef = useRef()

// Geocode Earth Autocomplete Client
Expand All @@ -40,6 +41,7 @@ export default ({
return
}

setIsLoading(false)
setResults({ text, features })
})
.catch(onError)
Expand All @@ -53,6 +55,7 @@ export default ({
const onInputValueChange = ({ type, inputValue }) => {
const term = inputValue.trim()
if (term === '') {
setIsLoading(false)
setResults(emptyResults)
}

Expand All @@ -65,6 +68,7 @@ export default ({
// which also fires this callback. this prevents an additional request after the user has already
// selected an item.
if (type === useCombobox.stateChangeTypes.InputChange && term.length > 0) {
setIsLoading(true)
debouncedSearch(term)
}
}
Expand All @@ -76,6 +80,14 @@ export default ({
}
}

// call user-supplied error callback
const onError = (error) => {
setIsLoading(false) // hide loading indicator as this normally happens after a successful request
if (typeof userOnError === 'function') {
userOnError(error)
}
}

// turns an autocomplete result (feature) into a string
const itemToString = ({ properties: { label } }) => label

Expand Down Expand Up @@ -112,6 +124,7 @@ export default ({

<div {...getComboboxProps()} >
<input {...getInputProps({ref: inputRef})} spellCheck={false} placeholder={placeholder} className='input' />
{isLoading && <Loading className={'loading'} />}
</div>

<ol {...getMenuProps()} className={showResults ? 'results' : 'results-empty'}>
Expand Down
45 changes: 45 additions & 0 deletions src/icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,48 @@ export const LocationMarker = ({className}) =>
<path fillRule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clipRule="evenodd" />
</svg>

/**
* SVG Loaders (github.com/SamHerbert/SVG-Loaders)
* Copyright (c) 2014 Sam Herbert
*
* @license MIT
*/

// this is the `puff` loader
export const Loading = ({ className }) =>
<svg width="44" height="44" viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" className={className}>
<g fill="none" fillRule="evenodd" strokeWidth="2">
<circle cx="22" cy="22" r="1">
<animate attributeName="r"
begin="0s" dur="1.4s"
values="1; 20"
calcMode="spline"
keyTimes="0; 1"
keySplines="0.165, 0.84, 0.44, 1"
repeatCount="indefinite" />
<animate attributeName="stroke-opacity"
begin="0s" dur="1.4s"
values="1; 0"
calcMode="spline"
keyTimes="0; 1"
keySplines="0.3, 0.61, 0.355, 1"
repeatCount="indefinite" />
</circle>
<circle cx="22" cy="22" r="1">
<animate attributeName="r"
begin="-0.7s" dur="1.4s"
values="1; 20"
calcMode="spline"
keyTimes="0; 1"
keySplines="0.165, 0.84, 0.44, 1"
repeatCount="indefinite" />
<animate attributeName="stroke-opacity"
begin="-0.7s" dur="1.4s"
values="1; 0"
calcMode="spline"
keyTimes="0; 1"
keySplines="0.3, 0.61, 0.355, 1"
repeatCount="indefinite" />
</circle>
</g>
</svg>

0 comments on commit cbeed30

Please sign in to comment.