// @flow strict import * as React from 'react'; import classify from '../../utils/classify'; import {Dropdown} from '../Dropdown'; import type {IconType} from '../Icon'; import type {InputOnChangeParamsType} from '../Input'; import {Input} from '../Input'; import type {MenuOption, MenuProps} from '../Menu'; import {BodySmall, FormLabelSmall} from '../Text'; import css from './Combobox.module.css'; type InputClassNames = $ReadOnly<{ box?: string, iconLeft?: string, iconRight?: string, wrapper?: string, }>; type DropdownClassNames = $ReadOnly<{ wrapper?: string, box?: string, iconRight?: string, }>; type ClassNames = $ReadOnly<{ wrapper?: string, box?: string, input?: InputClassNames, dropdown?: DropdownClassNames, }>; export type ComboboxProps = { /* Combobox props */ classNames?: ClassNames, disabled?: boolean, type?: 'text' | 'tel', label?: string | React.Node, size?: 'medium' | 'small', onContainerClick?: ?(SyntheticEvent) => mixed, locked?: boolean, error?: boolean, errorText?: string, helperText?: string | React.Node, required?: boolean, readOnly?: boolean, boxRef?: (?HTMLElement) => mixed, value: {dropdown?: string, input?: string}, onChange: ({ input: string, dropdown: string, inputChange?: InputOnChangeParamsType, dropdownOption?: MenuOption, }) => mixed, /* Input props */ inputPlaceholder?: string, onInputFocus?: (e: SyntheticInputEvent) => mixed, onInputBlur?: (e: SyntheticInputEvent) => mixed, onInputKeyDown?: (e: SyntheticKeyboardEvent) => mixed, onInputContainerClick?: ?(SyntheticEvent) => mixed, inputName?: string, iconLeftName?: string, iconLeftType?: IconType, iconRightName?: string, iconRightType?: IconType, onIconRightClick?: ?(SyntheticEvent) => mixed, inputBoxRef?: (?HTMLElement) => mixed, minLength?: string, maxLength?: string, pattern?: string, min?: string, max?: string, /* Dropdown props */ menu?: MenuProps, onMenuOpen?: () => mixed, onMenuClose?: () => mixed, scrollMenuToBottom?: boolean, onDropdownFocus?: (e: SyntheticInputEvent) => mixed, onDropdownBlur?: (e: SyntheticInputEvent) => mixed, onDropdownKeyDown?: (e: SyntheticKeyboardEvent) => mixed, onDropdownContainerClick?: ?(SyntheticEvent) => mixed, dropdownName?: string, dropdownPlaceholder?: string, dropdownBoxRef?: (?HTMLElement) => mixed, ... }; export const Combobox: React$AbstractComponent = React.forwardRef( (props: ComboboxProps, ref) => { const { value, onChange, classNames, disabled, type = 'text', label, inputPlaceholder, size = 'medium', onContainerClick, onInputFocus, onInputBlur, onInputKeyDown, onInputContainerClick, inputName, locked, error, errorText, helperText, required, iconLeftName, iconLeftType, iconRightName, iconRightType, onIconRightClick, readOnly, boxRef, inputBoxRef, minLength, maxLength, pattern, min, max, menu, onMenuOpen, onMenuClose, scrollMenuToBottom, onDropdownFocus, onDropdownBlur, onDropdownKeyDown, onDropdownContainerClick, dropdownName, dropdownPlaceholder, dropdownBoxRef, } = props; const inputRef = React.useRef(); const dropdownRef = React.useRef(); const {input: inputValue, dropdown: dropdownInputText} = value; const handleInputChange = (evt, isEnter) => { onChange({ dropdown: dropdownInputText || '', input: evt.target.value, inputChange: {evt, isEnter}, }); }; const handleDropdownChange = (option) => { onChange({ dropdown: option.label || '', input: inputValue || '', dropdownOption: option, }); }; /* Handling locked functionality at Combobox level */ React.useEffect(() => { if (locked) { inputRef.current && (inputRef.current.disabled = true); dropdownRef.current && (dropdownRef.current.disabled = true); } else { inputRef.current && (inputRef.current.disabled = false); dropdownRef.current && (dropdownRef.current.disabled = false); } }, [locked]); return (
{Boolean(label) && (
{label ?? ''}   {required && *}
)}
{(Boolean(helperText) || error) && (
{error && errorText ? ( {errorText} ) : typeof helperText === 'string' ? ( {helperText} ) : ( helperText )}
)}
); }, );