import { c, classy, ComboboxProps as BaseProps, m, PopoverProps, SelectProps, } from '@onfido/castor'; import { Input, OptionList, OptionListEvent, Popover, } from '@onfido/castor-react'; import React, { ForwardedRef, SyntheticEvent, useCallback, useMemo, useRef, useState, } from 'react'; import { MaybeIcon } from '../../internal'; import { textContent, withRef } from '../../utils'; import { OptionListInit } from '../option-list/options-list-init'; export interface ComboboxProps extends BaseProps, SelectProps, PopoverProps, Omit { icon?: JSX.Element; /** Option to show when search yields no results. */ empty?: string; selectedIcon?: JSX.Element; } /** * `Combobox` by default uses two `Icon` that require `Icons` (SVG sprite) to be * included in your app. * * https://github.com/onfido/castor-icons#use-with-plain-code * * You may also provide any other SVG element via the `icon` and `selectedIcon` * props, but using Castor iconography is recommended. */ export const Combobox = withRef(function Combobox( { id: initialId, align = 'start', children, className, defaultValue, disabled, empty = 'No matching options', icon, name, onBlur, onChange, onClick, onKeyUp, position = 'bottom', required, selectedIcon, value, ...restProps }: ComboboxProps, ref: ForwardedRef ) { const inputRef = useRef(null); const selectRef = useRef(null); const optionsRef = useRef(null); const [input, setInput] = useState(''); const [search, setSearch] = useState(); const [placeholder, setPlaceholder] = useState(); const [selected, setSelected] = useState({}); const [open, setOpen] = useState(false); const preventBlur = useRef(false); // Generate unique id only if `initialId` is not provided const id = useMemo( () => initialId || `castor_combobox_${++idCount}`, [initialId] ); const propagateOnChange = useCallback(() => { // propagate `onChange` manually because void 0) } > {!selected.value ||