54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
import React, {useCallback, useMemo, useState} from 'react'
|
|
import {Autocomplete, Card, Text} from '@sanity/ui'
|
|
import {set, unset, StringInputProps} from 'sanity'
|
|
import {countryList} from '../schemaTypes/country-list'
|
|
|
|
const options = countryList.map((c) => ({value: c.value, payload: c}))
|
|
|
|
export function CountryInput(props: StringInputProps) {
|
|
const {value, onChange, readOnly} = props
|
|
const [query, setQuery] = useState('')
|
|
|
|
const filtered = useMemo(() => {
|
|
if (!query) return options
|
|
const q = query.toLowerCase()
|
|
return options.filter((o) => o.payload.title.toLowerCase().includes(q))
|
|
}, [query])
|
|
|
|
const handleSelect = useCallback(
|
|
(val: string) => {
|
|
onChange(val ? set(val) : unset())
|
|
},
|
|
[onChange],
|
|
)
|
|
|
|
const renderOption = useCallback(
|
|
(option: (typeof options)[number]) => (
|
|
<Card as="button" padding={3}>
|
|
<Text size={1}>{option.payload.title}</Text>
|
|
</Card>
|
|
),
|
|
[],
|
|
)
|
|
|
|
const selectedTitle = useMemo(() => {
|
|
if (!value) return undefined
|
|
return countryList.find((c) => c.value === value)?.title
|
|
}, [value])
|
|
|
|
return (
|
|
<Autocomplete
|
|
id="country-input"
|
|
options={filtered}
|
|
onSelect={handleSelect}
|
|
onQueryChange={(q) => setQuery(q ?? '')}
|
|
placeholder="Search for a country…"
|
|
renderOption={renderOption}
|
|
value={value || ''}
|
|
readOnly={readOnly}
|
|
openButton
|
|
filterOption={() => true}
|
|
renderValue={() => selectedTitle || value || ''}
|
|
/>
|
|
)
|
|
}
|