trptk-sanity/components/CountryInput.tsx
2026-02-24 12:22:46 +01:00

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 || ''}
/>
)
}