[react-select] Enforce OptionType should be an object (#38691)

* Extend object

* Keep the change

* All the `OptionType`s

* Formatting

* Two space indentation
This commit is contained in:
Nathan Bierema 2019-10-01 12:59:59 -04:00 committed by Ryan Cavanaugh
parent d45ec9519f
commit 643edf5b1c
23 changed files with 93 additions and 80 deletions

View File

@ -2,9 +2,9 @@ import * as React from 'react';
import Select, { Props as SelectProps } from './Select';
import { handleInputChange } from './utils';
import manageState from './stateManager';
import { OptionsType, InputActionMeta } from './types';
import { OptionsType, InputActionMeta, OptionTypeBase } from './types';
export interface AsyncProps<OptionType> {
export interface AsyncProps<OptionType extends OptionTypeBase> {
/* The default set of options to show before the user starts searching. When
set to `true`, the results for loadOptions('') will be autoloaded.
Default: false. */
@ -18,11 +18,11 @@ export interface AsyncProps<OptionType> {
cacheOptions?: any;
}
export type Props<OptionType> = SelectProps<OptionType> & AsyncProps<OptionType>;
export type Props<OptionType extends OptionTypeBase> = SelectProps<OptionType> & AsyncProps<OptionType>;
export const defaultProps: Props<any>;
export interface State<OptionType> {
export interface State<OptionType extends OptionTypeBase> {
defaultOptions?: OptionsType<OptionType>;
inputValue: string;
isLoading: boolean;
@ -31,7 +31,7 @@ export interface State<OptionType> {
passEmptyOptions: boolean;
}
export class Async<OptionType> extends React.Component<Props<OptionType>, State<OptionType>> {
export class Async<OptionType extends OptionTypeBase> extends React.Component<Props<OptionType>, State<OptionType>> {
static defaultProps: Props<any>;
select: React.Ref<any>;
lastRequest: {};

View File

@ -1,14 +1,14 @@
import { Component, Ref as ElementRef } from 'react';
import { Props as AsyncProps, State as AsyncState } from './Async';
import { Props as CreatableProps, State as CreatableState } from './Creatable';
import { OptionsType, ValueType, ActionMeta, InputActionMeta } from './types';
import { OptionsType, ValueType, ActionMeta, InputActionMeta, OptionTypeBase } from './types';
import { cleanValue } from './utils';
export type Props<OptionType> = AsyncProps<OptionType> & CreatableProps<OptionType>;
export type Props<OptionType extends OptionTypeBase> = AsyncProps<OptionType> & CreatableProps<OptionType>;
export type State<OptionType> = AsyncState<OptionType> & CreatableState<OptionType>;
export type State<OptionType extends OptionTypeBase> = AsyncState<OptionType> & CreatableState<OptionType>;
export class AsyncCreatable<OptionType> extends Component<Props<OptionType>, State<OptionType>> {
export class AsyncCreatable<OptionType extends OptionTypeBase> extends Component<Props<OptionType>, State<OptionType>> {
static defaultProps: Props<any>;
select: ElementRef<any>;
lastRequest: {};

View File

@ -1,10 +1,10 @@
import * as React from 'react';
import Select, { Props as SelectProps } from './Select';
import { OptionsType, ValueType, ActionMeta } from './types';
import { OptionsType, ValueType, ActionMeta, OptionTypeBase } from './types';
import { cleanValue } from './utils';
import manageState from './stateManager';
export interface CreatableProps<OptionType> {
export interface CreatableProps<OptionType extends OptionTypeBase> {
/* Allow options to be created while the `isLoading` prop is true. Useful to
prevent the "create new ..." option being displayed while async results are
still being loaded. */
@ -26,16 +26,16 @@ export interface CreatableProps<OptionType> {
createOptionPosition?: 'first' | 'last';
}
export type Props<OptionType> = SelectProps<OptionType> & CreatableProps<OptionType>;
export type Props<OptionType extends OptionTypeBase> = SelectProps<OptionType> & CreatableProps<OptionType>;
export const defaultProps: Props<any>;
export interface State<OptionType> {
export interface State<OptionType extends OptionTypeBase> {
newOption: OptionType | undefined;
options: OptionsType<OptionType>;
}
export class Creatable<OptionType> extends React.Component<Props<OptionType>, State<OptionType>> {
export class Creatable<OptionType extends OptionTypeBase> extends React.Component<Props<OptionType>, State<OptionType>> {
static defaultProps: Props<any>;
select: React.Ref<any>;

View File

@ -38,13 +38,14 @@ import {
OptionsType,
ValueType,
GroupedOptionsType,
OptionTypeBase,
} from './types';
export type MouseOrTouchEvent =
| React.MouseEvent<HTMLElement>
| React.TouchEvent<HTMLElement>;
export type FormatOptionLabelContext = 'menu' | 'value';
export interface FormatOptionLabelMeta<OptionType> {
export interface FormatOptionLabelMeta<OptionType extends OptionTypeBase> {
context: FormatOptionLabelContext;
inputValue: string;
selectValue: ValueType<OptionType>;
@ -52,7 +53,7 @@ export interface FormatOptionLabelMeta<OptionType> {
export type SelectComponentsProps = { [key in string]: any };
export interface Props<OptionType = { label: string; value: string }> extends SelectComponentsProps {
export interface Props<OptionType extends OptionTypeBase = { label: string; value: string }> extends SelectComponentsProps {
/* Aria label (for assistive tech) */
'aria-label'?: string;
/* HTML ID of an element that should be used as the label (for assistive tech) */
@ -210,12 +211,12 @@ export interface Props<OptionType = { label: string; value: string }> extends Se
export const defaultProps: Props<any>;
export interface MenuOptions<OptionType> {
export interface MenuOptions<OptionType extends OptionTypeBase> {
render: OptionType[];
focusable: OptionType[];
}
export interface State<OptionType> {
export interface State<OptionType extends OptionTypeBase> {
ariaLiveSelection: string;
ariaLiveContext: string;
inputIsHidden: boolean;
@ -229,7 +230,7 @@ export interface State<OptionType> {
export type ElRef = React.Ref<any>;
export default class Select<OptionType> extends React.Component<Props<OptionType>, State<OptionType>> {
export default class Select<OptionType extends OptionTypeBase> extends React.Component<Props<OptionType>, State<OptionType>> {
static defaultProps: Props<any>;
// Misc. Instance Properties

View File

@ -1,12 +1,13 @@
import { ComponentType } from 'react';
import { MultiValueProps } from '../components/MultiValue';
import { Collapse, fn } from './transitions';
import { OptionTypeBase } from '../types';
export type AnimatedMultiValueProps<OptionType> = {
export type AnimatedMultiValueProps<OptionType extends OptionTypeBase> = {
in: boolean,
onExited: fn,
} & MultiValueProps<OptionType>;
export function AnimatedMultiValue<OptionType>(WrappedComponent: ComponentType<MultiValueProps<OptionType>>): ComponentType<AnimatedMultiValueProps<OptionType>>;
export function AnimatedMultiValue<OptionType extends OptionTypeBase>(WrappedComponent: ComponentType<MultiValueProps<OptionType>>): ComponentType<AnimatedMultiValueProps<OptionType>>;
export default AnimatedMultiValue;

View File

@ -1,9 +1,10 @@
import { ComponentType } from 'react';
import { PlaceholderProps } from '../components/Placeholder';
import { Fade, collapseDuration } from './transitions';
import { OptionTypeBase } from '../types';
export type AnimatedPlaceholderProps<OptionType> = PlaceholderProps<OptionType>;
export type AnimatedPlaceholderProps<OptionType extends OptionTypeBase> = PlaceholderProps<OptionType>;
export function AnimatedPlaceholder<OptionType>(WrappedComponent: ComponentType<PlaceholderProps<OptionType>>): ComponentType<AnimatedPlaceholderProps<OptionType>>;
export function AnimatedPlaceholder<OptionType extends OptionTypeBase>(WrappedComponent: ComponentType<PlaceholderProps<OptionType>>): ComponentType<AnimatedPlaceholderProps<OptionType>>;
export default AnimatedPlaceholder;

View File

@ -1,9 +1,10 @@
import { ComponentType } from 'react';
import { SingleValueProps } from '../components/SingleValue';
import { Fade } from './transitions';
import { OptionTypeBase } from '../types';
export type AnimatedSingleValueProps<OptionType> = SingleValueProps<OptionType>;
export type AnimatedSingleValueProps<OptionType extends OptionTypeBase> = SingleValueProps<OptionType>;
export function AnimatedSingleValue<OptionType>(WrappedComponent: ComponentType<SingleValueProps<OptionType>>): ComponentType<AnimatedSingleValueProps<OptionType>>;
export function AnimatedSingleValue<OptionType extends OptionTypeBase>(WrappedComponent: ComponentType<SingleValueProps<OptionType>>): ComponentType<AnimatedSingleValueProps<OptionType>>;
export default AnimatedSingleValue;

View File

@ -1,9 +1,10 @@
import { ComponentType } from 'react';
import { TransitionGroup } from 'react-transition-group';
import { ValueContainerProps } from '../components/containers';
import { OptionTypeBase } from '../types';
export type AnimatedValueContainerProps<OptionType> = ValueContainerProps<OptionType>;
export type AnimatedValueContainerProps<OptionType extends OptionTypeBase> = ValueContainerProps<OptionType>;
export function AnimatedValueContainer<OptionType>(WrappedComponent: ComponentType<ValueContainerProps<OptionType>>): ComponentType<AnimatedValueContainerProps<OptionType>>;
export function AnimatedValueContainer<OptionType extends OptionTypeBase>(WrappedComponent: ComponentType<ValueContainerProps<OptionType>>): ComponentType<AnimatedValueContainerProps<OptionType>>;
export default AnimatedValueContainer;

View File

@ -5,8 +5,9 @@ import { default as AnimatedMultiValue, AnimatedMultiValueProps } from './MultiV
import { default as AnimatedPlaceholder, AnimatedPlaceholderProps } from './Placeholder';
import { default as AnimatedSingleValue, AnimatedSingleValueProps } from './SingleValue';
import { default as AnimatedValueContainer, AnimatedValueContainerProps } from './ValueContainer';
import { OptionTypeBase } from '../types';
export function makeAnimated<OptionType>(externalComponents?: SelectComponentsConfig<OptionType>): SelectComponents<OptionType>;
export function makeAnimated<OptionType extends OptionTypeBase>(externalComponents?: SelectComponentsConfig<OptionType>): SelectComponents<OptionType>;
export const Input: ComponentType<AnimatedInputProps>;
export const MultiValue: ComponentType<AnimatedMultiValueProps<any>>;

View File

@ -1,14 +1,14 @@
import { ReactNode } from 'react';
import { GroupType } from './types';
import { GroupType, OptionTypeBase } from './types';
export type formatGroupLabel<OptionType = any> = (group: GroupType<OptionType>) => ReactNode;
export type formatGroupLabel<OptionType extends OptionTypeBase = any> = (group: GroupType<OptionType>) => ReactNode;
export function formatGroupLabel(group: GroupType<any>): ReactNode;
export type getOptionLabel<OptionType = any> = (option: OptionType) => string;
export type getOptionLabel<OptionType extends OptionTypeBase = any> = (option: OptionType) => string;
export function getOptionLabel(option: any): string;
export type getOptionValue<OptionType = any> = (option: OptionType) => string;
export type getOptionValue<OptionType extends OptionTypeBase = any> = (option: OptionType) => string;
export function getOptionValue(option: any): string;
export type isOptionDisabled<OptionType = any> = (option: OptionType) => boolean;
export type isOptionDisabled<OptionType extends OptionTypeBase = any> = (option: OptionType) => boolean;
export function isOptionDisabled(option: any): boolean;

View File

@ -1,7 +1,7 @@
import { ComponentType, ReactNode, Ref as ElementRef } from 'react';
import { borderRadius, colors, spacing } from '../theme';
import { CommonProps, PropsWithStyles } from '../types';
import { CommonProps, OptionTypeBase, PropsWithStyles } from '../types';
interface State {
/** Whether the select is disabled. */
@ -10,7 +10,7 @@ interface State {
isFocused: boolean;
}
export type ControlProps<OptionType> = CommonProps<OptionType> &
export type ControlProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> &
PropsWithStyles &
State & {
/** Children to render. */

View File

@ -1,7 +1,7 @@
import { ReactNode, ComponentType } from 'react';
import { spacing } from '../theme';
import { CommonProps } from '../types';
import { CommonProps, OptionTypeBase } from '../types';
interface ComponentProps {
/** The children to be rendered. */
@ -11,7 +11,7 @@ interface ComponentProps {
/** Label to be displayed in the heading component. */
label: ReactNode;
}
export type GroupProps<OptionType> = CommonProps<OptionType> & ComponentProps;
export type GroupProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & ComponentProps;
export function groupCSS(): React.CSSProperties;

View File

@ -21,6 +21,7 @@ import {
MenuPlacement,
MenuPosition,
CommonProps,
OptionTypeBase,
} from '../types';
// ==============================
@ -45,7 +46,7 @@ export function getMenuPlacement(args: PlacementArgs): MenuState;
// Menu Component
// ------------------------------
export type MenuProps<OptionType> = CommonProps<OptionType> & {
export type MenuProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & {
/** The children to be rendered. */
children: ReactElement,
/** Callback to update the portal after possible flip. */
@ -66,7 +67,7 @@ export type MenuProps<OptionType> = CommonProps<OptionType> & {
export function menuCSS(state: MenuState): React.CSSProperties;
export class Menu<OptionType> extends Component<MenuProps<OptionType>, MenuState> {
export class Menu<OptionType extends OptionTypeBase> extends Component<MenuProps<OptionType>, MenuState> {
static contextTypes: {
getPortalPlacement: (state: MenuState) => void,
};
@ -93,7 +94,7 @@ export interface MenuListProps {
/** Inner ref to DOM Node */
innerRef: InnerRef;
}
export type MenuListComponentProps<OptionType> = CommonProps<OptionType> &
export type MenuListComponentProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> &
MenuListProps &
MenuListState;
export function menuListCSS(state: MenuState): React.CSSProperties;
@ -106,7 +107,7 @@ export const MenuList: ComponentType<MenuListComponentProps<any>>;
export function noOptionsMessageCSS(): React.CSSProperties;
export function loadingMessageCSS(): React.CSSProperties;
export type NoticeProps<OptionType> = CommonProps<OptionType> & {
export type NoticeProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & {
/** The children to be rendered. */
children: ReactNode,
/** Props to be passed on to the wrapper. */
@ -127,7 +128,7 @@ export const LoadingMessage: ComponentType<NoticeProps<any>>;
// Menu Portal
// ==============================
export type MenuPortalProps<OptionType> = CommonProps<OptionType> & {
export type MenuPortalProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & {
appendTo: HTMLElement,
children: ReactNode, // ideally Menu<MenuProps>
controlElement: HTMLElement,
@ -145,7 +146,7 @@ interface PortalStyleArgs {
export function menuPortalCSS(args: PortalStyleArgs): React.CSSProperties;
export class MenuPortal<OptionType> extends Component<MenuPortalProps<OptionType>, MenuPortalState> {
export class MenuPortal<OptionType extends OptionTypeBase> extends Component<MenuPortalProps<OptionType>, MenuPortalState> {
static childContextTypes: {
getPortalPlacement: (state: MenuState) => void,
};

View File

@ -1,9 +1,9 @@
import { ComponentType, Component, ReactNode } from 'react';
import { borderRadius, colors, spacing } from '../theme';
import { CommonProps } from '../types';
import { CommonProps, OptionTypeBase } from '../types';
export type MultiValueProps<OptionType> = CommonProps<OptionType> &{
export type MultiValueProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> &{
children: ReactNode,
components: any,
cropWithEllipsis: boolean,
@ -22,7 +22,7 @@ export function multiValueCSS(): React.CSSProperties;
export function multiValueLabelCSS(props: MultiValueProps<any>): React.CSSProperties;
export function multiValueRemoveCSS(props: MultiValueProps<any>): React.CSSProperties;
export interface MultiValueGenericProps<OptionType> {
export interface MultiValueGenericProps<OptionType extends OptionTypeBase> {
children: ReactNode;
data: OptionType;
innerProps: { className?: string };
@ -32,7 +32,7 @@ export const MultiValueGeneric: ComponentType<MultiValueGenericProps<any>>;
export const MultiValueContainer: typeof MultiValueGeneric;
export const MultiValueLabel: typeof MultiValueGeneric;
export type MultiValueRemoveProps<OptionType> = CommonProps<OptionType> & {
export type MultiValueRemoveProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & {
children: ReactNode,
innerProps: {
className: string,
@ -42,13 +42,13 @@ export type MultiValueRemoveProps<OptionType> = CommonProps<OptionType> & {
},
selectProps: any,
};
export class MultiValueRemove<OptionType> extends Component<MultiValueRemoveProps<OptionType>> {
export class MultiValueRemove<OptionType extends OptionTypeBase> extends Component<MultiValueRemoveProps<OptionType>> {
static defaultProps: {
children: ReactNode,
};
}
export class MultiValue<OptionType> extends Component<MultiValueProps<OptionType>> {
export class MultiValue<OptionType extends OptionTypeBase> extends Component<MultiValueProps<OptionType>> {
static defaultProps: {
cropWithEllipsis: boolean,
};

View File

@ -1,7 +1,7 @@
import { ComponentType, ReactNode, MouseEventHandler } from 'react';
import { colors, spacing } from '../theme';
import { CommonProps, PropsWithStyles, InnerRef } from '../types';
import { CommonProps, PropsWithStyles, InnerRef, OptionTypeBase } from '../types';
interface State {
/** Whether the option is disabled. */
@ -19,7 +19,7 @@ interface InnerProps {
onMouseOver: MouseEventHandler<HTMLDivElement>;
tabIndex: number;
}
export type OptionProps<OptionType> = PropsWithStyles &
export type OptionProps<OptionType extends OptionTypeBase> = PropsWithStyles &
CommonProps<OptionType> &
State & {
/** The children to be rendered. */

View File

@ -1,9 +1,9 @@
import { ComponentType, ReactNode } from 'react';
import { colors, spacing } from '../theme';
import { CommonProps } from '../types';
import { CommonProps, OptionTypeBase } from '../types';
export type PlaceholderProps<OptionType> = CommonProps<OptionType> & {
export type PlaceholderProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & {
/** The children to be rendered. */
children: ReactNode,
/** props passed to the wrapping element for the group. */

View File

@ -1,12 +1,12 @@
import { ComponentType, ReactNode } from 'react';
import { colors, spacing } from '../theme';
import { CommonProps } from '../types';
import { CommonProps, OptionTypeBase } from '../types';
interface State {
/** Whether this is disabled */
isDisabled: boolean;
}
interface ValueProps<OptionType> {
interface ValueProps<OptionType extends OptionTypeBase> {
/** The children to be rendered. */
children: ReactNode;
/* The data of the selected option rendered in the Single Value componentn */
@ -14,7 +14,7 @@ interface ValueProps<OptionType> {
/** Props passed to the wrapping element for the group. */
innerProps: any;
}
export type SingleValueProps<OptionType> = CommonProps<OptionType> & ValueProps<OptionType> & State;
export type SingleValueProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & ValueProps<OptionType> & State;
export function css(props: SingleValueProps<any>): React.CSSProperties;

View File

@ -1,6 +1,6 @@
import { Component, ReactNode, ComponentType } from 'react';
import { spacing } from '../theme';
import { CommonProps, KeyboardEventHandler } from '../types';
import { CommonProps, KeyboardEventHandler, OptionTypeBase } from '../types';
// ==============================
// Root Container
@ -13,7 +13,7 @@ export interface ContainerState {
isRtl: boolean;
}
export type ContainerProps<OptionType> = CommonProps<OptionType> &
export type ContainerProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> &
ContainerState & {
/** The children to be rendered. */
children: ReactNode,
@ -27,7 +27,7 @@ export const SelectContainer: ComponentType<ContainerProps<any>>;
// Value Container
// ==============================
export type ValueContainerProps<OptionType> = CommonProps<OptionType> & {
export type ValueContainerProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & {
/** Set when the value container should hold multiple values */
isMulti: boolean,
/** Whether the value container currently holds a value. */
@ -47,7 +47,7 @@ export interface IndicatorsState {
isRtl: boolean;
}
export type IndicatorContainerProps<OptionType> = CommonProps<OptionType> &
export type IndicatorContainerProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> &
IndicatorsState & {
/** The children to be rendered. */
children: ReactNode,

View File

@ -43,15 +43,16 @@ import MultiValue, {
import Option, { OptionProps } from './Option';
import Placeholder, { PlaceholderProps } from './Placeholder';
import SingleValue, { SingleValueProps } from './SingleValue';
import { OptionTypeBase } from '../types';
export type PlaceholderOrValue<OptionType> =
export type PlaceholderOrValue<OptionType extends OptionTypeBase> =
| Element<ComponentType<PlaceholderProps<OptionType>>>
| Element<ComponentType<SingleValueProps<OptionType>>>
| Array<Element<ComponentType<MultiValueProps<OptionType>>>>;
export type IndicatorComponentType<OptionType> = ComponentType<IndicatorProps<OptionType>>;
export type IndicatorComponentType<OptionType extends OptionTypeBase> = ComponentType<IndicatorProps<OptionType>>;
export interface SelectComponents<OptionType> {
export interface SelectComponents<OptionType extends OptionTypeBase> {
ClearIndicator: IndicatorComponentType<OptionType> | null;
Control: ComponentType<ControlProps<OptionType>>;
DropdownIndicator: IndicatorComponentType<OptionType> | null;
@ -79,12 +80,12 @@ export interface SelectComponents<OptionType> {
ValueContainer: ComponentType<ValueContainerProps<OptionType>>;
}
export type SelectComponentsConfig<OptionType> = Partial<SelectComponents<OptionType>>;
export type SelectComponentsConfig<OptionType extends OptionTypeBase> = Partial<SelectComponents<OptionType>>;
export const components: Required<SelectComponents<any>>;
export interface Props<OptionType> {
export interface Props<OptionType extends OptionTypeBase> {
components: SelectComponentsConfig<OptionType>;
}
export function defaultComponents<OptionType>(props: Props<OptionType>): SelectComponents<OptionType>;
export function defaultComponents<OptionType extends OptionTypeBase>(props: Props<OptionType>): SelectComponents<OptionType>;

View File

@ -1,7 +1,7 @@
import { ComponentType, ReactElement as ElementType } from 'react';
import { colors, spacing } from '../theme';
import { CommonProps } from '../types';
import { CommonProps, OptionTypeBase } from '../types';
// ==============================
// Dropdown & Clear Icons
@ -14,7 +14,7 @@ export function DownChevron(props: any): any; // TODO svg type
// Dropdown & Clear Buttons
// ==============================
export type IndicatorProps<OptionType> = CommonProps<OptionType> & {
export type IndicatorProps<OptionType extends OptionTypeBase> = CommonProps<OptionType> & {
/** The children to be rendered inside the indicator. */
children: ElementType,
/** Props that will be passed on to the children. */
@ -52,7 +52,7 @@ export function loadingIndicatorCSS(state: {
size: number,
}): React.CSSProperties;
export type LoadingIconProps<OptionType> = {
export type LoadingIconProps<OptionType extends OptionTypeBase> = {
/** Props that will be passed on to the children. */
innerProps: any,
/** The focused state of the select. */

View File

@ -1,15 +1,15 @@
import { Component, ComponentType, Ref as ElementRef } from 'react';
import SelectBase, { Props as SelectProps } from './Select';
import { ActionMeta, InputActionMeta, ValueType } from './types';
import { ActionMeta, InputActionMeta, OptionTypeBase, ValueType } from './types';
export interface DefaultProps<OptionType> {
export interface DefaultProps<OptionType extends OptionTypeBase> {
defaultInputValue: string;
defaultMenuIsOpen: boolean;
defaultValue: ValueType<OptionType>;
}
export interface Props<OptionType> {
export interface Props<OptionType extends OptionTypeBase> {
defaultInputValue?: string;
defaultMenuIsOpen?: boolean;
defaultValue?: ValueType<OptionType>;
@ -29,7 +29,7 @@ type StateProps<T extends SelectProps<any>> = Pick<T, Exclude<keyof T,
| 'onMenuOpen'
>>;
interface State<OptionType> {
interface State<OptionType extends OptionTypeBase> {
inputValue: string;
menuIsOpen: boolean;
value: ValueType<OptionType>;
@ -38,7 +38,7 @@ interface State<OptionType> {
type GetOptionType<T> = T extends SelectBase<infer OT> ? OT : never;
export class StateManager<
OptionType = { label: string; value: string },
OptionType extends OptionTypeBase = { label: string; value: string },
T extends SelectBase<OptionType> = SelectBase<OptionType>
> extends Component<StateProps<SelectProps<OptionType>> & Props<OptionType> & SelectProps<OptionType>, State<OptionType>> {
static defaultProps: DefaultProps<any>;

View File

@ -1,16 +1,20 @@
import * as React from 'react';
import { Props as SelectProps } from './Select';
export type OptionsType<OptionType> = ReadonlyArray<OptionType>;
export interface OptionTypeBase {
[key: string]: any;
}
export interface GroupType<OptionType> {
export type OptionsType<OptionType extends OptionTypeBase> = ReadonlyArray<OptionType>;
export interface GroupType<OptionType extends OptionTypeBase> {
options: OptionsType<OptionType>;
[key: string]: any;
}
export type GroupedOptionsType<UnionOptionType> = ReadonlyArray<GroupType<UnionOptionType>>;
export type GroupedOptionsType<OptionType extends OptionTypeBase> = ReadonlyArray<GroupType<OptionType>>;
export type ValueType<OptionType> = OptionType | OptionsType<OptionType> | null | undefined;
export type ValueType<OptionType extends OptionTypeBase> = OptionType | OptionsType<OptionType> | null | undefined;
export type FocusEventHandler = (event: React.FocusEvent<HTMLElement>) => void;
export type MouseEventHandler = (event: React.MouseEvent<HTMLElement>) => void;
@ -34,7 +38,7 @@ export interface PropsWithStyles {
export type ClassNameList = string[];
export type ClassNamesState = { [key: string]: boolean } | undefined;
export interface CommonProps<OptionType> {
export interface CommonProps<OptionType extends OptionTypeBase> {
clearValue: () => void;
className?: string;
cx: (a: string | null, b: ClassNamesState | undefined, c: string | undefined) => string | void;

View File

@ -3,6 +3,7 @@ import {
ClassNamesState,
InputActionMeta,
OptionsType,
OptionTypeBase,
ValueType,
} from './types';
@ -28,7 +29,7 @@ export function classNames(
// Clean Value
// ==============================
export function cleanValue<OptionType>(value: ValueType<OptionType>): OptionsType<OptionType>;
export function cleanValue<OptionType extends OptionTypeBase>(value: ValueType<OptionType>): OptionsType<OptionType>;
// ==============================
// Handle Input Change