UNPKG

@dr.pogodin/react-utils

Version:

Collection of generic ReactJS components and utils

58 lines (47 loc) 1.46 kB
// The stuff common between different dropdown implementations. import type { Theme } from '@dr.pogodin/react-themes'; type ThemeKeyT = 'active' | 'arrow' | 'container' | 'dropdown' | 'hiddenOption' | 'label' | 'option' | 'select' // TODO: This is currently only valid for (native) <Dropdown>, // other kinds of selectors should be evaluated, and aligned with this // feature, if appropriate. | 'invalid' // TODO: This is only valid for <CustomDropdown>, thus we need to re-factor it // into a separate theme spec for that component. | 'upward'; export type ValueT = number | string; export type OptionT<NameT> = { name?: NameT | null; value: ValueT; }; export type OptionsT<NameT> = Readonly<Array<OptionT<NameT> | ValueT>>; export type PropsT< NameT, OnChangeT = React.ChangeEventHandler<HTMLSelectElement>, > = { filter?: (item: OptionT<NameT> | ValueT) => boolean; label?: React.ReactNode; onChange?: OnChangeT; options: Readonly<OptionsT<NameT>>; testId?: string; theme: Theme<ThemeKeyT>; value?: ValueT; }; function isValue<T>(x: OptionT<T> | ValueT): x is ValueT { const type = typeof x; return type === 'number' || type === 'string'; } /** Returns option value and name as a tuple. */ export function optionValueName<NameT>( option: OptionT<NameT> | ValueT, ): [ValueT, NameT | ValueT] { return isValue(option) ? [option, option] : [option.value, option.name ?? option.value]; }