From 7c33a958277e53aa335dcddec28ebfe6502638ca Mon Sep 17 00:00:00 2001 From: Claas Ahlrichs Date: Fri, 3 Aug 2018 01:41:18 +0200 Subject: [PATCH] added definitions for react select (v2) (#27737) * moved existing "react-select" definitions into "v1" directory * updated references to V1 of "react-select" * dts-gen --dt --name react-select --template module * added placeholders for react-select definitions and tests * fixed imports of react and react-select * updated config. files * drafted definitions for react-select * updated definitions for react-select * made Props in stateManager.d.ts and Select.d.ts optional * handle grouped options in Select.d.ts * updated definitions for react-select * resolved merge conflicts * fixed issues identified by "npm test" * updated type of "menuPortalTarget" * remove OptionType type and introduce throughout as a generic parameter * add an extra type * re-enable interface-over-type-literal lint rule * parameterize GroupedOptionsType after some consideration this should be parameterized, typically with a union type, see Grouped example which is a select of `ColourOption | FlavourOption` --- types/react-select/index.d.ts | 667 +----------------- types/react-select/lib/Async.d.ts | 47 ++ types/react-select/lib/AsyncCreatable.d.ts | 25 + types/react-select/lib/Creatable.d.ts | 49 ++ types/react-select/lib/Select.d.ts | 419 +++++++++++ .../react-select/lib/accessibility/index.d.ts | 10 + types/react-select/lib/animated/Input.d.ts | 10 + .../react-select/lib/animated/MultiValue.d.ts | 12 + .../lib/animated/Placeholder.d.ts | 9 + .../lib/animated/SingleValue.d.ts | 9 + .../lib/animated/ValueContainer.d.ts | 9 + types/react-select/lib/animated/index.d.ts | 17 + .../lib/animated/transitions.d.ts | 50 ++ types/react-select/lib/builtins.d.ts | 10 + .../react-select/lib/components/Control.d.ts | 29 + types/react-select/lib/components/Group.d.ts | 24 + types/react-select/lib/components/Input.d.ts | 23 + types/react-select/lib/components/Menu.d.ts | 158 +++++ .../lib/components/MultiValue.d.ts | 57 ++ types/react-select/lib/components/Option.d.ts | 41 ++ .../lib/components/Placeholder.d.ts | 17 + .../lib/components/SingleValue.d.ts | 23 + .../lib/components/containers.d.ts | 57 ++ types/react-select/lib/components/index.d.ts | 142 ++++ .../lib/components/indicators.d.ts | 67 ++ types/react-select/lib/diacritics.d.ts | 1 + types/react-select/lib/filters.d.ts | 16 + types/react-select/lib/stateManager.d.ts | 36 + types/react-select/lib/styles.d.ts | 99 +++ types/react-select/lib/theme.d.ts | 53 ++ types/react-select/lib/types.d.ts | 100 +++ types/react-select/lib/utils.d.ts | 121 ++++ types/react-select/test/AtlaskitDummy.ts | 11 + types/react-select/test/ChronoNodeDummy.ts | 1 + types/react-select/test/data.ts | 132 ++++ .../test/examples/AccessingInternals.tsx | 114 +++ .../test/examples/AnimatedMulti.tsx | 17 + .../test/examples/AsyncCallbacks.tsx | 42 ++ .../test/examples/AsyncCreatable.tsx | 28 + .../react-select/test/examples/AsyncMulti.tsx | 39 + .../test/examples/AsyncPromises.tsx | 34 + .../test/examples/BasicGrouped.tsx | 37 + .../react-select/test/examples/BasicMulti.tsx | 15 + .../test/examples/BasicSingle.tsx | 101 +++ .../test/examples/ControlledMenu.tsx | 42 ++ .../test/examples/CreatableAdvanced.tsx | 70 ++ .../test/examples/CreatableInputOnly.tsx | 72 ++ .../test/examples/CreatableMulti.tsx | 22 + .../test/examples/CreatableSingle.tsx | 29 + .../test/examples/CreateFilter.tsx | 85 +++ .../test/examples/CustomClearIndicator.tsx | 35 + .../test/examples/CustomControl.tsx | 32 + .../test/examples/CustomDropdownIndicator.tsx | 24 + .../test/examples/CustomFilterOptions.tsx | 34 + .../test/examples/CustomGetOptionLabel.tsx | 23 + .../test/examples/CustomGroup.tsx | 24 + .../test/examples/CustomGroupHeading.tsx | 31 + .../examples/CustomIndicatorSeparator.tsx | 27 + .../examples/CustomIndicatorsContainer.tsx | 21 + .../test/examples/CustomInput.tsx | 27 + .../test/examples/CustomIsOptionDisabled.tsx | 21 + .../test/examples/CustomLoadingIndicator.tsx | 47 ++ .../test/examples/CustomLoadingMessage.tsx | 50 ++ .../react-select/test/examples/CustomMenu.tsx | 37 + .../test/examples/CustomMenuList.tsx | 29 + .../examples/CustomMultiValueContainer.tsx | 23 + .../test/examples/CustomMultiValueLabel.tsx | 23 + .../test/examples/CustomMultiValueRemove.tsx | 25 + .../test/examples/CustomNoOptionsMessage.tsx | 31 + .../test/examples/CustomOption.tsx | 22 + .../test/examples/CustomPlaceholder.tsx | 19 + .../test/examples/CustomSelectContainer.tsx | 24 + .../test/examples/CustomSingleValue.tsx | 25 + .../test/examples/CustomValueContainer.tsx | 28 + .../test/examples/Experimental.tsx | 211 ++++++ .../react-select/test/examples/MenuPortal.tsx | 91 +++ .../test/examples/OnSelectResetsInput.tsx | 47 ++ types/react-select/test/examples/Popout.tsx | 128 ++++ .../test/examples/StyledMulti.tsx | 53 ++ .../test/examples/StyledSingle.tsx | 51 ++ types/react-select/test/styled-components.tsx | 17 + types/react-select/tsconfig.json | 97 ++- types/react-select/tslint.json | 4 +- types/react-select/v1/index.d.ts | 654 +++++++++++++++++ .../{ => v1}/lib/Option/index.d.ts | 0 .../lib/utils/defaultMenuRenderer/index.d.ts | 0 .../{ => v1}/react-select-tests.tsx | 0 types/react-select/v1/tsconfig.json | 35 + types/react-select/v1/tslint.json | 1 + types/react-virtualized-select/tsconfig.json | 9 +- 90 files changed, 4716 insertions(+), 662 deletions(-) create mode 100644 types/react-select/lib/Async.d.ts create mode 100644 types/react-select/lib/AsyncCreatable.d.ts create mode 100644 types/react-select/lib/Creatable.d.ts create mode 100644 types/react-select/lib/Select.d.ts create mode 100644 types/react-select/lib/accessibility/index.d.ts create mode 100644 types/react-select/lib/animated/Input.d.ts create mode 100644 types/react-select/lib/animated/MultiValue.d.ts create mode 100644 types/react-select/lib/animated/Placeholder.d.ts create mode 100644 types/react-select/lib/animated/SingleValue.d.ts create mode 100644 types/react-select/lib/animated/ValueContainer.d.ts create mode 100644 types/react-select/lib/animated/index.d.ts create mode 100644 types/react-select/lib/animated/transitions.d.ts create mode 100644 types/react-select/lib/builtins.d.ts create mode 100644 types/react-select/lib/components/Control.d.ts create mode 100644 types/react-select/lib/components/Group.d.ts create mode 100644 types/react-select/lib/components/Input.d.ts create mode 100644 types/react-select/lib/components/Menu.d.ts create mode 100644 types/react-select/lib/components/MultiValue.d.ts create mode 100644 types/react-select/lib/components/Option.d.ts create mode 100644 types/react-select/lib/components/Placeholder.d.ts create mode 100644 types/react-select/lib/components/SingleValue.d.ts create mode 100644 types/react-select/lib/components/containers.d.ts create mode 100644 types/react-select/lib/components/index.d.ts create mode 100644 types/react-select/lib/components/indicators.d.ts create mode 100644 types/react-select/lib/diacritics.d.ts create mode 100644 types/react-select/lib/filters.d.ts create mode 100644 types/react-select/lib/stateManager.d.ts create mode 100644 types/react-select/lib/styles.d.ts create mode 100644 types/react-select/lib/theme.d.ts create mode 100644 types/react-select/lib/types.d.ts create mode 100644 types/react-select/lib/utils.d.ts create mode 100644 types/react-select/test/AtlaskitDummy.ts create mode 100644 types/react-select/test/ChronoNodeDummy.ts create mode 100644 types/react-select/test/data.ts create mode 100644 types/react-select/test/examples/AccessingInternals.tsx create mode 100644 types/react-select/test/examples/AnimatedMulti.tsx create mode 100644 types/react-select/test/examples/AsyncCallbacks.tsx create mode 100644 types/react-select/test/examples/AsyncCreatable.tsx create mode 100644 types/react-select/test/examples/AsyncMulti.tsx create mode 100644 types/react-select/test/examples/AsyncPromises.tsx create mode 100644 types/react-select/test/examples/BasicGrouped.tsx create mode 100644 types/react-select/test/examples/BasicMulti.tsx create mode 100644 types/react-select/test/examples/BasicSingle.tsx create mode 100644 types/react-select/test/examples/ControlledMenu.tsx create mode 100644 types/react-select/test/examples/CreatableAdvanced.tsx create mode 100644 types/react-select/test/examples/CreatableInputOnly.tsx create mode 100644 types/react-select/test/examples/CreatableMulti.tsx create mode 100644 types/react-select/test/examples/CreatableSingle.tsx create mode 100644 types/react-select/test/examples/CreateFilter.tsx create mode 100644 types/react-select/test/examples/CustomClearIndicator.tsx create mode 100644 types/react-select/test/examples/CustomControl.tsx create mode 100644 types/react-select/test/examples/CustomDropdownIndicator.tsx create mode 100644 types/react-select/test/examples/CustomFilterOptions.tsx create mode 100644 types/react-select/test/examples/CustomGetOptionLabel.tsx create mode 100644 types/react-select/test/examples/CustomGroup.tsx create mode 100644 types/react-select/test/examples/CustomGroupHeading.tsx create mode 100644 types/react-select/test/examples/CustomIndicatorSeparator.tsx create mode 100644 types/react-select/test/examples/CustomIndicatorsContainer.tsx create mode 100644 types/react-select/test/examples/CustomInput.tsx create mode 100644 types/react-select/test/examples/CustomIsOptionDisabled.tsx create mode 100644 types/react-select/test/examples/CustomLoadingIndicator.tsx create mode 100644 types/react-select/test/examples/CustomLoadingMessage.tsx create mode 100644 types/react-select/test/examples/CustomMenu.tsx create mode 100644 types/react-select/test/examples/CustomMenuList.tsx create mode 100644 types/react-select/test/examples/CustomMultiValueContainer.tsx create mode 100644 types/react-select/test/examples/CustomMultiValueLabel.tsx create mode 100644 types/react-select/test/examples/CustomMultiValueRemove.tsx create mode 100644 types/react-select/test/examples/CustomNoOptionsMessage.tsx create mode 100644 types/react-select/test/examples/CustomOption.tsx create mode 100644 types/react-select/test/examples/CustomPlaceholder.tsx create mode 100644 types/react-select/test/examples/CustomSelectContainer.tsx create mode 100644 types/react-select/test/examples/CustomSingleValue.tsx create mode 100644 types/react-select/test/examples/CustomValueContainer.tsx create mode 100644 types/react-select/test/examples/Experimental.tsx create mode 100644 types/react-select/test/examples/MenuPortal.tsx create mode 100644 types/react-select/test/examples/OnSelectResetsInput.tsx create mode 100644 types/react-select/test/examples/Popout.tsx create mode 100644 types/react-select/test/examples/StyledMulti.tsx create mode 100644 types/react-select/test/examples/StyledSingle.tsx create mode 100644 types/react-select/test/styled-components.tsx create mode 100644 types/react-select/v1/index.d.ts rename types/react-select/{ => v1}/lib/Option/index.d.ts (100%) rename types/react-select/{ => v1}/lib/utils/defaultMenuRenderer/index.d.ts (100%) rename types/react-select/{ => v1}/react-select-tests.tsx (100%) create mode 100644 types/react-select/v1/tsconfig.json create mode 100644 types/react-select/v1/tslint.json diff --git a/types/react-select/index.d.ts b/types/react-select/index.d.ts index 31ff0db561..9c4728254c 100644 --- a/types/react-select/index.d.ts +++ b/types/react-select/index.d.ts @@ -1,654 +1,21 @@ -// Type definitions for react-select 1.3 -// Project: https://github.com/JedWatson/react-select -// Definitions by: ESQUIBET Hugo -// Gilad Gray -// Izaak Baker -// Tadas Dailyda -// Mark Vujevits -// Mike Deverell -// MartynasZilinskas -// Onat Yigit Mercan -// Ian Johnson -// Anton Novik -// David Schkalee -// Arthur Udalov -// Sebastian Silbermann -// Endurance Idehen -// Guillaume Chartier +// Type definitions for react-select 2.0 +// Project: https://github.com/JedWatson/react-select#readme +// Definitions by: Claas Ahlrichs +// Jon Freedman // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.6 +// TypeScript Version: 2.9 -import * as React from 'react'; +import SelectBase from './lib/Select'; +import { StateManager } from './lib/stateManager'; -export default class ReactSelectClass extends React.Component> { - focus(): void; - setValue(value: Option): void; -} -// Other components -export class Creatable extends React.Component> { } -export class Async extends React.Component> { } -export class AsyncCreatable extends React.Component> { } +export default SelectBase; +// export default StateManager; -export type OptionComponentType = React.ComponentType>; -export type ValueComponentType = React.ComponentType>; - -export type HandlerRendererResult = JSX.Element | null | false; - -// Handlers -export type FocusOptionHandler = (option: Option) => void; -export type SelectValueHandler = (option: Option) => void; -export type ArrowRendererHandler = (props: ArrowRendererProps) => HandlerRendererResult; -export type ClearRendererHandler = () => HandlerRendererResult; -export type FilterOptionHandler = (option: Option, filter: string) => boolean; -export type FilterOptionsHandler = (options: Options, filter: string, currentValues: Options) => Options; -export type InputRendererHandler = (props: { [key: string]: any }) => HandlerRendererResult; -export type MenuRendererHandler = (props: MenuRendererProps) => HandlerRendererResult; -export type OnCloseHandler = () => void; -export type OnInputChangeHandler = (inputValue: string) => string; -export type OnInputKeyDownHandler = React.KeyboardEventHandler; -export type OnMenuScrollToBottomHandler = () => void; -export type OnOpenHandler = () => void; -export type OnFocusHandler = React.FocusEventHandler; -export type OnBlurHandler = React.FocusEventHandler; -export type OptionRendererHandler = (option: Option) => HandlerRendererResult; -export type ValueRendererHandler = (option: Option, index?: number) => HandlerRendererResult; -export type OnValueClickHandler = (option: Option, event: React.MouseEvent) => void; -export type IsOptionUniqueHandler = (arg: { option: Option, options: Options, labelKey: string, valueKey: string }) => boolean; -export type IsValidNewOptionHandler = (arg: { label: string }) => boolean; -export type NewOptionCreatorHandler = (arg: { label: string, labelKey: string, valueKey: string }) => Option; -export type PromptTextCreatorHandler = (filterText: string) => string; -export type ShouldKeyDownEventCreateNewOptionHandler = (arg: { keyCode: number }) => boolean; - -export type OnChangeSingleHandler = OnChangeHandler>; -export type OnChangeMultipleHandler = OnChangeHandler>; -export type OnChangeHandler | Options> = (newValue: TOption | null) => void; -export type OnNewOptionClickHandler = (option: Option) => void; - -export type LoadOptionsHandler = LoadOptionsAsyncHandler | LoadOptionsLegacyHandler; -export type LoadOptionsAsyncHandler = (input: string) => Promise>; -export type LoadOptionsLegacyHandler = (input: string, callback: (err: any, result: AutocompleteResult) => void) => void; - -export interface AutocompleteResult { - /** The search-results to be displayed */ - options: Options; - /** - * Should be set to true, if and only if a longer query with the same prefix - * would return a subset of the results - * If set to true, more specific queries will not be sent to the server. - */ - complete: boolean; -} - -export type Options = Array>; - -export interface Option { - /** Text for rendering */ - label?: string; - /** Value for searching */ - value?: TValue; - /** - * Allow this option to be cleared - * @default true - */ - clearableValue?: boolean; - /** - * Do not allow this option to be selected - * @default false - */ - disabled?: boolean; - /** - * In the event that a custom menuRenderer is provided, Option should be able - * to accept arbitrary key-value pairs. See react-virtualized-select. - */ - [property: string]: any; -} - -export type OptionValues = string | number | boolean; - -export interface MenuRendererProps { - /** - * The currently focused option; should be visible in the menu by default. - * default {} - */ - focusedOption: Option; - - /** - * Callback to focus a new option; receives the option as a parameter. - */ - focusOption: FocusOptionHandler; - - /** - * Option labels are accessible with this string key. - */ - labelKey: string; - - /** - * Ordered array of options to render. - */ - options: Options; - - /** - * Callback to select a new option; receives the option as a parameter. - */ - selectValue: SelectValueHandler; - - /** - * Array of currently selected options. - */ - valueArray: Options; - - /** - * Callback to remove selection from option; receives the option as a parameter. - */ - removeValue: SelectValueHandler; - - /** - * function which returns a custom way to render the options in the menu - */ - optionRenderer: OptionRendererHandler; -} - -export interface OptionComponentProps { - /** - * Classname(s) to apply to the option component. - */ - className?: string; - - /** - * Currently focused option. - */ - focusOption?: Option; - - inputValue?: string; - instancePrefix?: string; - - /** - * True if this option is disabled. - */ - isDisabled?: boolean; - - /** - * True if this option is focused. - */ - isFocused?: boolean; - - /** - * True if this option is selected. - */ - isSelected?: boolean; - - /** - * Callback to be invoked when this option is focused. - */ - onFocus?: (option: Option, event: any) => void; - - /** - * Callback to be invoked when this option is selected. - */ - onSelect?: (option: Option, event: any) => void; - - /** - * Option to be rendered by this component. - */ - option: Option; - - /** - * Index of the option being rendered in the list - */ - optionIndex?: number; - - /** - * Callback to invoke when removing an option from a multi-selection. (Not necessarily the one - * being rendered) - */ - removeValue?: (value: TValue | TValue[]) => void; - - /** - * Callback to invoke to select an option. (Not necessarily the one being rendered) - */ - selectValue?: (value: TValue | TValue[]) => void; -} - -export interface ArrowRendererProps { - /** - * Arrow mouse down event handler. - */ - onMouseDown: React.MouseEventHandler; - - /** - * whether the Select is open or not. - */ - isOpen: boolean; -} - -export interface ValueComponentProps { - disabled: ReactSelectProps['disabled']; - id: string; - instancePrefix: string; - onClick: OnValueClickHandler | null; - onRemove?: SelectValueHandler; - placeholder: ReactSelectProps['placeholder']; - value: Option; - values?: Array>; -} - -export interface ReactSelectProps extends React.Props> { - /** - * text to display when `allowCreate` is true. - * @default 'Add "{label}"?' - */ - addLabelText?: string; - /** - * renders a custom drop-down arrow to be shown in the right-hand side of the select. - * @default undefined - */ - arrowRenderer?: ArrowRendererHandler | null; - /** - * blurs the input element after a selection has been made. Handy for lowering the keyboard on mobile devices. - * @default false - */ - autoBlur?: boolean; - /** - * autofocus the component on mount - * @deprecated. Use autoFocus instead - * @default false - */ - autofocus?: boolean; - /** - * autofocus the component on mount - * @default false - */ - autoFocus?: boolean; - /** - * If enabled, the input will expand as the length of its value increases - */ - autosize?: boolean; - /** - * whether pressing backspace removes the last item when there is no input value - * @default true - */ - backspaceRemoves?: boolean; - /** - * Message to use for screenreaders to press backspace to remove the current item - * {label} is replaced with the item label - * @default "Press backspace to remove..." - */ - backspaceToRemoveMessage?: string; - /** - * CSS className for the outer element - */ - className?: string; - /** - * Prefix prepended to element default className if no className is defined - */ - classNamePrefix?: string; - /** - * title for the "clear" control when `multi` is true - * @default "Clear all" - */ - clearAllText?: string; - /** - * Renders a custom clear to be shown in the right-hand side of the select when clearable true - * @default undefined - */ - clearRenderer?: ClearRendererHandler; - /** - * title for the "clear" control - * @default "Clear value" - */ - clearValueText?: string; - /** - * whether to close the menu when a value is selected - * @default true - */ - closeOnSelect?: boolean; - /** - * whether it is possible to reset value. if enabled, an X button will appear at the right side. - * @default true - */ - clearable?: boolean; - /** - * whether backspace removes an item if there is no text input - * @default true - */ - deleteRemoves?: boolean; - /** - * delimiter to use to join multiple values - * @default "," - */ - delimiter?: string; - /** - * whether the Select is disabled or not - * @default false - */ - disabled?: boolean; - /** - * whether escape clears the value when the menu is closed - * @default true - */ - escapeClearsValue?: boolean; - /** - * method to filter a single option - */ - filterOption?: FilterOptionHandler; - /** - * method to filter the options array - */ - filterOptions?: FilterOptionsHandler; - /** - * id for the underlying HTML input element - * @default undefined - */ - id?: string; - /** - * whether to strip diacritics when filtering - * @default true - */ - ignoreAccents?: boolean; - /** - * whether to perform case-insensitive filtering - * @default true - */ - ignoreCase?: boolean; - /** - * custom attributes for the Input (in the Select-control) e.g: {'data-foo': 'bar'} - * @default {} - */ - inputProps?: { [key: string]: any }; - /** - * renders a custom input - */ - inputRenderer?: InputRendererHandler; - /** - * allows for synchronization of component id's on server and client. - * @see https://github.com/JedWatson/react-select/pull/1105 - */ - instanceId?: string; - /** - * whether the Select is loading externally or not (such as options being loaded). - * if true, a loading spinner will be shown at the right side. - * @default false - */ - isLoading?: boolean; - /** - * (legacy mode) joins multiple values into a single form field with the delimiter - * @default false - */ - joinValues?: boolean; - /** - * the option property to use for the label - * @default "label" - */ - labelKey?: string; - /** - * (any, start) match the start or entire string when filtering - * @default "any" - */ - matchPos?: string; - /** - * (any, label, value) which option property to filter on - * @default "any" - */ - matchProp?: string; - /** - * buffer of px between the base of the dropdown and the viewport to shift if menu doesnt fit in viewport - * @default 0 - */ - menuBuffer?: number; - /** - * optional style to apply to the menu container - */ - menuContainerStyle?: React.CSSProperties; - /** - * renders a custom menu with options - */ - menuRenderer?: MenuRendererHandler; - /** - * optional style to apply to the menu - */ - menuStyle?: React.CSSProperties; - /** - * multi-value input - * @default false - */ - multi?: boolean; - /** - * field name, for hidden `` tag - */ - name?: string; - /** - * placeholder displayed when there are no matching search results or a falsy value to hide it - * @default "No results found" - */ - noResultsText?: string | JSX.Element; - /** - * onBlur handler: function (event) {} - */ - onBlur?: OnBlurHandler; - /** - * whether to clear input on blur or not - * @default true - */ - onBlurResetsInput?: boolean; - /** - * whether the input value should be reset when options are selected. - * Also input value will be set to empty if 'onSelectResetsInput=true' and - * Select will get new value that not equal previous value. - * @default true - */ - onSelectResetsInput?: boolean; - /** - * whether to clear input when closing the menu through the arrow - * @default true - */ - onCloseResetsInput?: boolean; - /** - * onChange handler: function (newValue) {} - */ - onChange?: OnChangeHandler; - /** - * fires when the menu is closed - */ - onClose?: OnCloseHandler; - /** - * onFocus handler: function (event) {} - */ - onFocus?: OnFocusHandler; - /** - * onInputChange handler: function (inputValue) {} - */ - onInputChange?: OnInputChangeHandler; - /** - * onInputKeyDown handler: function (keyboardEvent) {} - */ - onInputKeyDown?: OnInputKeyDownHandler; - /** - * fires when the menu is scrolled to the bottom; can be used to paginate options - */ - onMenuScrollToBottom?: OnMenuScrollToBottomHandler; - /** - * fires when the menu is opened - */ - onOpen?: OnOpenHandler; - /** - * boolean to enable opening dropdown when focused - * @default false - */ - openOnClick?: boolean; - /** - * open the options menu when the input gets focus (requires searchable = true) - * @default true - */ - openOnFocus?: boolean; - /** - * className to add to each option component - */ - optionClassName?: string; - /** - * option component to render in dropdown - */ - optionComponent?: OptionComponentType; - /** - * function which returns a custom way to render the options in the menu - */ - optionRenderer?: OptionRendererHandler; - /** - * array of Select options - * @default false - */ - options?: Options; - /** - * number of options to jump when using page up/down keys - * @default 5 - */ - pageSize?: number; - /** - * field placeholder, displayed when there's no value - * @default "Select..." - */ - placeholder?: string | JSX.Element; - /** - * whether the selected option is removed from the dropdown on multi selects - * @default true - */ - removeSelected?: boolean; - /** - * applies HTML5 required attribute when needed - * @default false - */ - required?: boolean; - /** - * value to use when you clear the control - */ - resetValue?: any; - /** - * use react-select in right-to-left direction - * @default false - */ - rtl?: boolean; - /** - * whether the viewport will shift to display the entire menu when engaged - * @default true - */ - scrollMenuIntoView?: boolean; - /** - * whether to enable searching feature or not - * @default true; - */ - searchable?: boolean; - /** - * whether to select the currently focused value when the [tab] key is pressed - */ - tabSelectsValue?: boolean; - /** - * initial field value - */ - value?: Option | Options | string | string[] | number | number[] | boolean; - /** - * the option property to use for the value - * @default "value" - */ - valueKey?: string; - /** - * function which returns a custom way to render the value selected - * @default false - */ - valueRenderer?: ValueRendererHandler; - /** - * optional style to apply to the control - */ - style?: React.CSSProperties; - - /** - * optional tab index of the control - */ - tabIndex?: string | number; - - /** - * value component to render - */ - valueComponent?: ValueComponentType; - - /** - * optional style to apply to the component wrapper - */ - wrapperStyle?: React.CSSProperties; - - /** - * onClick handler for value labels: function (value, event) {} - */ - onValueClick?: OnValueClickHandler; - - /** - * pass the value to onChange as a simple value (legacy pre 1.0 mode), defaults to false - */ - simpleValue?: boolean; -} - -export interface ReactCreatableSelectProps extends ReactSelectProps { - /** - * Searches for any matching option within the set of options. This function prevents - * duplicate options from being created. - */ - isOptionUnique?: IsOptionUniqueHandler; - - /** - * Determines if the current input text represents a valid option. - */ - isValidNewOption?: IsValidNewOptionHandler; - - /** - * factory to create new options - */ - newOptionCreator?: NewOptionCreatorHandler; - - /** - * Creates prompt/placeholder for option text. - */ - promptTextCreator?: PromptTextCreatorHandler; - - /** - * Decides if a keyDown event (eg its 'keyCode') should result in the creation of a new option. - */ - shouldKeyDownEventCreateNewOption?: ShouldKeyDownEventCreateNewOptionHandler; - - /** - * new option click handler: function (option) {} - */ - onNewOptionClick?: OnNewOptionClickHandler; - - /** - * true: Show new option at top of list - * false: Show new option at bottom of list - * @default true - */ - showNewOptionAtTop?: boolean; -} - -export interface ReactAsyncSelectProps extends ReactSelectProps { - /** - * Whether to auto-load the default async options set. - */ - autoload?: boolean; - - /** - * object to use to cache results; can be null to disable cache - */ - cache?: { [key: string]: any } | boolean; - - /** - * function to call to load options asynchronously - */ - loadOptions: LoadOptionsHandler; - - /** - * replaces the placeholder while options are loading - */ - loadingPlaceholder?: string | JSX.Element; - /** - * displayed in the drop down list when the user did not type anything yet - */ - searchPromptText?: string; -} - -export type ReactAsyncCreatableSelectProps = ReactAsyncSelectProps & ReactCreatableSelectProps; +export { SelectBase }; +export { default as Async } from './lib/Async'; +export { default as AsyncCreatable } from './lib/AsyncCreatable'; +export { default as Creatable } from './lib/Creatable'; +export { createFilter } from './lib/filters'; +export { default as makeAnimated } from './lib/animated/index'; +export { components } from './lib/components/index'; +export { mergeStyles } from './lib/styles'; diff --git a/types/react-select/lib/Async.d.ts b/types/react-select/lib/Async.d.ts new file mode 100644 index 0000000000..8acc5532b7 --- /dev/null +++ b/types/react-select/lib/Async.d.ts @@ -0,0 +1,47 @@ +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'; + +export interface AsyncProps { + /* The default set of options to show before the user starts searching. When + set to `true`, the results for loadOptions('') will be autoloaded. */ + defaultOptions: OptionsType | boolean; + /* Function that returns a promise, which is the set of options to be used + once the promise resolves. */ + loadOptions: (inputValue: string, callback: ((options: OptionsType) => void)) => Promise | void; + /* If cacheOptions is truthy, then the loaded data will be cached. The cache + will remain until `cacheOptions` changes value. */ + cacheOptions: any; +} + +export type Props = SelectProps & AsyncProps; + +export const defaultProps: Props; + +export interface State { + defaultOptions?: OptionsType; + inputValue: string; + isLoading: boolean; + loadedInputValue?: string; + loadedOptions: OptionsType; + passEmptyOptions: boolean; +} + +export class Async extends React.Component, State> { + static defaultProps: Props; + select: React.Ref; + lastRequest: {}; + mounted: boolean; + optionsCache: { [key: string]: OptionsType }; + + focus(): void; + blur(): void; + loadOptions(inputValue: string, callback: (options: OptionsType) => void): void; + handleInputChange: (newValue: string, actionMeta: InputActionMeta) => string; +} + +export function makeAsyncSelect(SelectComponent: React.ComponentType): Async; + +export default Async; diff --git a/types/react-select/lib/AsyncCreatable.d.ts b/types/react-select/lib/AsyncCreatable.d.ts new file mode 100644 index 0000000000..5fbdd8e52c --- /dev/null +++ b/types/react-select/lib/AsyncCreatable.d.ts @@ -0,0 +1,25 @@ +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 { cleanValue } from './utils'; + +type Props = AsyncProps & CreatableProps; + +type State = AsyncState & CreatableState; + +export class AsyncCreatable extends Component, State> { + static defaultProps: Props; + select: ElementRef; + lastRequest: {}; + mounted: boolean; + optionsCache: { [key: string]: OptionsType }; + + focus(): void; + blur(): void; + loadOptions(inputValue: string, callback: (options: OptionsType) => void): void; + handleInputChange: (newValue: string, actionMeta: InputActionMeta) => string; + onChange: (newValue: ValueType, actionMeta: ActionMeta) => void; +} + +export default AsyncCreatable; diff --git a/types/react-select/lib/Creatable.d.ts b/types/react-select/lib/Creatable.d.ts new file mode 100644 index 0000000000..c194441a8b --- /dev/null +++ b/types/react-select/lib/Creatable.d.ts @@ -0,0 +1,49 @@ +import * as React from 'react'; +import Select, { Props as SelectProps } from './Select'; +import { OptionsType, ValueType, ActionMeta } from './types'; +import { cleanValue } from './utils'; +import manageState from './stateManager'; + +export interface CreatableProps { + /* 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. */ + allowCreateWhileLoading?: boolean; + /* Gets the label for the "create new ..." option in the menu. Is given the + current input value. */ + formatCreateLabel?: (inputValue: string) => Node; + /* Determines whether the "create new ..." option should be displayed based on + the current input value, select value and options array. */ + isValidNewOption?: (a: string, b: ValueType, c: OptionsType) => boolean; + /* Returns the data for the new option when it is created. Used to display the + value, and is passed to `onChange`. */ + getNewOptionData?: (a: string, b: Node) => OptionType; + /* If provided, this will be called with the input value when a new option is + created, and `onChange` will **not** be called. Use this when you need more + control over what happens when new options are created. */ + onCreateOption?: (inputValue: string) => void; + /* Sets the position of the createOption element in your options list. Defaults to 'last' */ + createOptionPosition?: 'first' | 'last'; +} + +export type Props = SelectProps & CreatableProps; + +export const defaultProps: Props; + +export interface State { + newOption: OptionType | undefined; + options: OptionsType; +} + +export class Creatable extends React.Component, State> { + static defaultProps: Props; + select: React.Ref; + + onChange: (newValue: ValueType, actionMeta: ActionMeta) => void; + focus(): void; + blur(): void; +} + +export function makeCreatableSelect(SelectComponent: React.ComponentType): Creatable; + +export default Creatable; diff --git a/types/react-select/lib/Select.d.ts b/types/react-select/lib/Select.d.ts new file mode 100644 index 0000000000..0298ea0288 --- /dev/null +++ b/types/react-select/lib/Select.d.ts @@ -0,0 +1,419 @@ +import * as React from 'react'; + +import { Option } from './filters'; +import { + InstructionsContext, + ValueEventContext, +} from './accessibility/index'; + +import { + classNames, + noop, + scrollIntoView, +} from './utils'; + +import { + formatGroupLabel, + getOptionLabel, + getOptionValue, + isOptionDisabled, +} from './builtins'; + +import { + PlaceholderOrValue, + SelectComponents, + SelectComponentsConfig, +} from './components/index'; +import { StylesConfig } from './styles'; + +import { + ActionMeta, + ActionTypes, + FocusDirection, + FocusEventHandler, + GroupType, + InputActionMeta, + KeyboardEventHandler, + MenuPlacement, + MenuPosition, + OptionsType, + ValueType, + GroupedOptionsType, +} from './types'; + +export type MouseOrTouchEvent = + | React.MouseEvent + | React.TouchEvent; +export type FormatOptionLabelContext = 'menu' | 'value'; +export interface FormatOptionLabelMeta { + context: FormatOptionLabelContext; + inputValue: string; + selectValue: ValueType; +} + +export interface Props { + /* Aria label (for assistive tech) */ + 'aria-label'?: string; + /* HTML ID of an element that should be used as the label (for assistive tech) */ + 'aria-labelledby'?: string; + /* Focus the control when it is mounted */ + autoFocus?: boolean; + /* Remove the currently focused option when the user presses backspace */ + backspaceRemovesValue?: boolean; + /* Remove focus from the input when the user selects an option (handy for dismissing the keyboard on touch devices) */ + blurInputOnSelect?: boolean; + /* When the user reaches the top/bottom of the menu, prevent scroll on the scroll-parent */ + captureMenuScroll?: boolean; + /* className attribute applied to the outer component */ + className?: string; + /* classNamePrefix attribute used as a base for inner component classNames */ + classNamePrefix?: string | null; + /* Close the select menu when the user selects an option */ + closeMenuOnSelect?: boolean; + /* + If `true`, close the select menu when the user scrolls the document/body. + + If a function, takes a standard javascript `ScrollEvent` you return a boolean: + + `true` => The menu closes + + `false` => The menu stays open + + This is useful when you have a scrollable modal and want to portal the menu out, + but want to avoid graphical issues. + */ + closeMenuOnScroll?: boolean | EventListener; + /* + This complex object includes all the compositional components that are used + in `react-select`. If you wish to overwrite a component, pass in an object + with the appropriate namespace. + + If you only wish to restyle a component, we recommend using the `styles` prop + instead. For a list of the components that can be passed in, and the shape + that will be passed to them, see [the components docs](/api#components) + */ + components?: SelectComponentsConfig; + /* Whether the value of the select, e.g. SingleValue, should be displayed in the control. */ + controlShouldRenderValue?: boolean; + /* Delimiter used to join multiple values into a single HTML Input value */ + delimiter?: string; + /* Clear all values when the user presses escape AND the menu is closed */ + escapeClearsValue?: boolean; + /* Custom method to filter whether an option should be displayed in the menu */ + filterOption?: (( + option: Option, + rawInput: string + ) => boolean) | null; + /* Formats group labels in the menu as React components */ + formatGroupLabel?: typeof formatGroupLabel; + /* Formats option labels in the menu and control as React components */ + formatOptionLabel?: (a: OptionType, b: FormatOptionLabelMeta) => Node; + /* Resolves option data to a string to be displayed as the label by components */ + getOptionLabel?: typeof getOptionLabel; + /* Resolves option data to a string to compare options and specify value attributes */ + getOptionValue?: typeof getOptionValue; + /* Hide the selected option from the menu */ + hideSelectedOptions?: boolean; + /* The id to set on the SelectContainer component. */ + id?: string; + /* The value of the search input */ + inputValue?: string; + /* The id of the search input */ + inputId?: string; + /* Define an id prefix for the select components e.g. {your-id}-value */ + instanceId?: number | string; + /* Is the select value clearable */ + isClearable?: boolean; + /* Is the select disabled */ + isDisabled?: boolean; + /* Is the select in a state of loading (async) */ + isLoading?: boolean; + /* Override the built-in logic to detect whether an option is disabled */ + isOptionDisabled?: (a: OptionType, b: OptionsType) => boolean | false; + /* Override the built-in logic to detect whether an option is selected */ + isOptionSelected?: (a: OptionType, b: OptionsType) => boolean; + /* Support multiple selected options */ + isMulti?: boolean; + /* Is the select direction right-to-left */ + isRtl?: boolean; + /* Whether to enable search functionality */ + isSearchable?: boolean; + /* Async: Text to display when loading options */ + loadingMessage?: (obj: { inputValue: string }) => string | null; + /* Minimum height of the menu before flipping */ + minMenuHeight?: number; + /* Maximum height of the menu before scrolling */ + maxMenuHeight?: number; + /* Whether the menu is open */ + menuIsOpen?: boolean; + /* Default placement of the menu in relation to the control. 'auto' will flip + when there isn't enough space below the control. */ + menuPlacement?: MenuPlacement; + /* The CSS position value of the menu, when "fixed" extra layout management is required */ + menuPosition?: MenuPosition; + /* Whether the menu should use a portal, and where it should attach */ + menuPortalTarget?: HTMLElement | null; + /* Whether to block scroll events when the menu is open */ + menuShouldBlockScroll?: boolean; + /* Whether the menu should be scrolled into view when it opens */ + menuShouldScrollIntoView?: boolean; + /* Name of the HTML Input (optional - without this, no input will be rendered) */ + name?: string; + /* Text to display when there are no options */ + noOptionsMessage?: (obj: { inputValue: string }) => string | null; + /* Handle blur events on the control */ + onBlur?: FocusEventHandler; + /* Handle change events on the select */ + onChange?: (value: ValueType, action: ActionMeta) => void; + /* Handle focus events on the control */ + onFocus?: FocusEventHandler; + /* Handle change events on the input */ + onInputChange?: (newValue: string, actionMeta: InputActionMeta) => void; + /* Handle key down events on the select */ + onKeyDown?: KeyboardEventHandler; + /* Handle the menu opening */ + onMenuOpen?: () => void; + /* Handle the menu closing */ + onMenuClose?: () => void; + /* Fired when the user scrolls to the top of the menu */ + onMenuScrollToTop?: (event: React.SyntheticEvent) => void; + /* Fired when the user scrolls to the bottom of the menu */ + onMenuScrollToBottom?: (event: React.SyntheticEvent) => void; + /* Allows control of whether the menu is opened when the Select is focused */ + openMenuOnFocus?: boolean; + /* Allows control of whether the menu is opened when the Select is clicked */ + openMenuOnClick?: boolean; + /* Array of options that populate the select menu */ + options?: GroupedOptionsType | OptionsType; + /* Number of options to jump in menu when page{up|down} keys are used */ + pageSize?: number; + /* Placeholder text for the select value */ + placeholder?: string; + /* Status to relay to screen readers */ + screenReaderStatus?: (obj: { count: number }) => string; + /* Style modifier methods */ + styles?: StylesConfig; + /* Sets the tabIndex attribute on the input */ + tabIndex?: string; + /* Select the currently focused option when the user presses tab */ + tabSelectsValue?: boolean; + /* The value of the select; reflected by the selected option */ + value?: ValueType; + + defaultInputValue?: string; + defaultMenuIsOpen?: boolean; + defaultValue?: ValueType; +} + +export const defaultProps: Props; + +export interface MenuOptions { + render: OptionType[]; + focusable: OptionType[]; +} + +export interface State { + ariaLiveSelection: string; + ariaLiveContext: string; + inputIsHidden: boolean; + isFocused: boolean; + isComposing: boolean; + focusedOption: OptionType | null; + focusedValue: OptionType | null; + menuOptions: MenuOptions; + selectValue: OptionsType; +} + +export type ElRef = React.Ref; + +export default class Select extends React.Component, State> { + static defaultProps: Props; + + // Misc. Instance Properties + // ------------------------------ + + blockOptionHover: boolean; + clearFocusValueOnUpdate: boolean; + commonProps: any; // TODO + components: SelectComponents; + hasGroups: boolean; + initialTouchX: number; + initialTouchY: number; + inputIsHiddenAfterUpdate: boolean | null; + instancePrefix: string; + openAfterFocus: boolean; + scrollToFocusedOptionOnUpdate: boolean; + userIsDragging: boolean | null; + + // Refs + // ------------------------------ + + controlRef: ElRef; + getControlRef: (ref: HTMLElement) => void; + focusedOptionRef: ElRef; + getFocusedOptionRef: (ref: HTMLElement) => void; + menuListRef: ElRef; + getMenuListRef: (ref: HTMLElement) => void; + inputRef: ElRef; + getInputRef: (ref: HTMLElement) => void; + + // Lifecycle + // ------------------------------ + + cacheComponents: (components: SelectComponents) => void; + + // ============================== + // Consumer Handlers + // ============================== + + onMenuOpen(): void; + onMenuClose(): void; + onInputChange(newValue: string, actionMeta: InputActionMeta): void; + + // ============================== + // Methods + // ============================== + + focusInput(): void; + blurInput(): void; + + // aliased for consumers + focus(): void; + blur(): void; + + openMenu(focusOption: 'first' | 'last'): void; + focusValue(direction: 'previous' | 'next'): void; + + focusOption(direction: FocusDirection): void; + setValue: ( + newValue: ValueType, + action: ActionTypes, + option?: OptionType + ) => void; + selectOption: (newValue: OptionType) => void; + removeValue: (removedValue: OptionType) => void; + clearValue: () => void; + popValue: () => void; + + // ============================== + // Getters + // ============================== + + getCommonProps(): { + cx: any; + clearValue: () => void; + getStyles: (key: string, props: {}) => {}; + getValue: () => OptionType[]; + hasValue: boolean; + isMulti: boolean; + isRtl: boolean; + options: OptionsType; + selectOption: (newValue: OptionType) => void; + setValue: (newValue: ValueType, action: ActionTypes, option?: OptionType) => void; + selectProps: Readonly<{ + children?: Node; + }> & Readonly>; +}; + + getNextFocusedValue(nextSelectValue: OptionsType): OptionType; + + getNextFocusedOption(options: OptionsType): OptionType; + getOptionLabel: (data: OptionType) => string; + getOptionValue: (data: OptionType) => string; + getStyles: (key: string, props: {}) => {}; + getElementId: (element: 'group' | 'input' | 'listbox' | 'option') => string; + getActiveDescendentId: () => any; + + // ============================== + // Helpers + // ============================== + announceAriaLiveSelection: (props: { + event: string, + context: ValueEventContext, + }) => void; + announceAriaLiveContext: (props: { + event: string, + context?: InstructionsContext, + }) => void; + + hasValue(): boolean; + hasOptions(): boolean; + countOptions(): number; + isClearable(): boolean; + isOptionDisabled(option: OptionType, selectValue: OptionsType): boolean; + isOptionSelected(option: OptionType, selectValue: OptionsType): boolean; + filterOption(option: {}, inputValue: string): boolean; + formatOptionLabel(data: OptionType, context: FormatOptionLabelContext): Node; + formatGroupLabel(data: GroupType): Node; + + // ============================== + // Mouse Handlers + // ============================== + + onMenuMouseDown: (event: React.MouseEvent) => void; + onMenuMouseMove: (event: React.MouseEvent) => void; + onControlMouseDown: (event: MouseOrTouchEvent) => void; + onDropdownIndicatorMouseDown: (event: MouseOrTouchEvent) => void; + onClearIndicatorMouseDown: (event: MouseOrTouchEvent) => void; + onScroll: (event: Event) => void; + + // ============================== + // Composition Handlers + // ============================== + + startListeningComposition(): void; + stopListeningComposition(): void; + onCompositionStart: () => void; + onCompositionEnd: () => void; + + // ============================== + // Touch Handlers + // ============================== + + startListeningToTouch(): void; + stopListeningToTouch(): void; + onTouchStart: (event: TouchEvent) => void; + onTouchMove: (event: TouchEvent) => void; + onTouchEnd: (event: TouchEvent) => void; + onControlTouchEnd: (event: React.TouchEvent) => void; + onClearIndicatorTouchEnd: (event: React.TouchEvent) => void; + onDropdownIndicatorTouchEnd: (event: React.TouchEvent) => void; + + // ============================== + // Focus Handlers + // ============================== + + handleInputChange: (event: React.KeyboardEvent) => void; + onInputFocus: (event: React.FocusEvent) => void; + onInputBlur: (event: React.FocusEvent) => void; + onOptionHover: (focusedOption: OptionType) => void; + shouldHideSelectedOptions: () => boolean; + + // ============================== + // Keyboard Handlers + // ============================== + + onKeyDown: (event: React.KeyboardEvent) => void; + + // ============================== + // Menu Options + // ============================== + + buildMenuOptions(props: Props, selectValue: OptionsType): MenuOptions; + + // ============================== + // Renderers + // ============================== + constructAriaLiveMessage(): string; + + renderInput(): Node; + renderPlaceholderOrValue(): PlaceholderOrValue | null; + renderClearIndicator(): Node; + renderLoadingIndicator(): Node; + renderIndicatorSeparator(): Node; + renderDropdownIndicator(): Node; + renderMenu(): Node; + renderFormField(): Node; + + renderLiveRegion(): Node; +} diff --git a/types/react-select/lib/accessibility/index.d.ts b/types/react-select/lib/accessibility/index.d.ts new file mode 100644 index 0000000000..633aaeda72 --- /dev/null +++ b/types/react-select/lib/accessibility/index.d.ts @@ -0,0 +1,10 @@ +export interface InstructionsContext { isSearchable?: boolean; isMulti?: boolean; label?: string; } +export interface ValueEventContext { value: string; } + +export function instructionsAriaMessage(event: any, context?: InstructionsContext): string; + +export function valueEventAriaMessage(event: any, context: ValueEventContext): string; + +export function valueFocusAriaMessage({ focusedValue, getOptionLabel, selectValue }: any): string; +export function optionFocusAriaMessage({ focusedOption, getOptionLabel, options }: any): string; +export function resultsAriaMessage({ inputValue, screenReaderMessage }: any): string; diff --git a/types/react-select/lib/animated/Input.d.ts b/types/react-select/lib/animated/Input.d.ts new file mode 100644 index 0000000000..ad752a96c5 --- /dev/null +++ b/types/react-select/lib/animated/Input.d.ts @@ -0,0 +1,10 @@ +import * as React from 'react'; +import { InputProps } from '../components/Input'; +import { BaseTransition } from './transitions'; +import { PropsWithInnerRef } from '../types'; + +export type AnimatedInputProps = BaseTransition & PropsWithInnerRef & InputProps; + +export function AnimatedInput(WrappedComponent: React.ComponentType): React.ComponentType; + +export default AnimatedInput; diff --git a/types/react-select/lib/animated/MultiValue.d.ts b/types/react-select/lib/animated/MultiValue.d.ts new file mode 100644 index 0000000000..8a8f37ad16 --- /dev/null +++ b/types/react-select/lib/animated/MultiValue.d.ts @@ -0,0 +1,12 @@ +import { ComponentType } from 'react'; +import { MultiValueProps } from '../components/MultiValue'; +import { Collapse, fn } from './transitions'; + +export type AnimatedMultiValueProps = { + in: boolean, + onExited: fn, +} & MultiValueProps; + +export function AnimatedMultiValue(WrappedComponent: ComponentType>): ComponentType>; + +export default AnimatedMultiValue; diff --git a/types/react-select/lib/animated/Placeholder.d.ts b/types/react-select/lib/animated/Placeholder.d.ts new file mode 100644 index 0000000000..1dbd3ba203 --- /dev/null +++ b/types/react-select/lib/animated/Placeholder.d.ts @@ -0,0 +1,9 @@ +import { ComponentType } from 'react'; +import { PlaceholderProps } from '../components/Placeholder'; +import { Fade, collapseDuration } from './transitions'; + +export type AnimatedPlaceholderProps = PlaceholderProps; + +export function AnimatedPlaceholder(WrappedComponent: ComponentType>): ComponentType>; + +export default AnimatedPlaceholder; diff --git a/types/react-select/lib/animated/SingleValue.d.ts b/types/react-select/lib/animated/SingleValue.d.ts new file mode 100644 index 0000000000..6cd1bea908 --- /dev/null +++ b/types/react-select/lib/animated/SingleValue.d.ts @@ -0,0 +1,9 @@ +import { ComponentType } from 'react'; +import { SingleValueProps } from '../components/SingleValue'; +import { Fade } from './transitions'; + +export type AnimatedSingleValueProps = SingleValueProps; + +export function AnimatedSingleValue(WrappedComponent: ComponentType>): ComponentType>; + +export default AnimatedSingleValue; diff --git a/types/react-select/lib/animated/ValueContainer.d.ts b/types/react-select/lib/animated/ValueContainer.d.ts new file mode 100644 index 0000000000..6bd15c0c19 --- /dev/null +++ b/types/react-select/lib/animated/ValueContainer.d.ts @@ -0,0 +1,9 @@ +import { ComponentType } from 'react'; +import { TransitionGroup } from 'react-transition-group'; +import { ValueContainerProps } from '../components/containers'; + +export type AnimatedValueContainerProps = ValueContainerProps; + +export function AnimatedValueContainer(WrappedComponent: ComponentType>): ComponentType>; + +export default AnimatedValueContainer; diff --git a/types/react-select/lib/animated/index.d.ts b/types/react-select/lib/animated/index.d.ts new file mode 100644 index 0000000000..6760d55e81 --- /dev/null +++ b/types/react-select/lib/animated/index.d.ts @@ -0,0 +1,17 @@ +import { ComponentType } from 'react'; +import { SelectComponents, defaultComponents } from '../components/index'; +import { default as AnimatedInput, AnimatedInputProps } from './Input'; +import { default as AnimatedMultiValue, AnimatedMultiValueProps } from './MultiValue'; +import { default as AnimatedPlaceholder, AnimatedPlaceholderProps } from './Placeholder'; +import { default as AnimatedSingleValue, AnimatedSingleValueProps } from './SingleValue'; +import { default as AnimatedValueContainer, AnimatedValueContainerProps } from './ValueContainer'; + +export function makeAnimated(externalComponents?: SelectComponents): SelectComponents; + +export const Input: ComponentType; +export const MultiValue: ComponentType>; +export const Placeholder: ComponentType>; +export const SingleValue: ComponentType>; +export const ValueContainer: ComponentType>; + +export default makeAnimated; diff --git a/types/react-select/lib/animated/transitions.d.ts b/types/react-select/lib/animated/transitions.d.ts new file mode 100644 index 0000000000..ee2bd3c83b --- /dev/null +++ b/types/react-select/lib/animated/transitions.d.ts @@ -0,0 +1,50 @@ +import * as React from 'react'; +import { Transition } from 'react-transition-group'; + +export type fn = () => void; +export interface BaseTransition { + /** Whether we are in a transition. */ + in: boolean; + /** Function to be called once transition finishes. */ + onExited: fn; +} + +// ============================== +// Fade Transition +// ============================== + +export type FadeProps = BaseTransition & { + component: React.ComponentType, + duration: number, +}; +export const Fade: React.ComponentType; + +// ============================== +// Collapse Transition +// ============================== + +export const collapseDuration: number; + +export type TransitionState = 'exiting' | 'exited'; +export type Width = number | 'auto'; +export interface CollapseProps { children: any; in: boolean; } +export interface CollapseState { width: Width; } + +// wrap each MultiValue with a collapse transition; decreases width until +// finally removing from DOM +export class Collapse extends React.Component { + duration: number; + transition: { + exiting: any, + exited: any, + }; + + // width must be calculated; cannot transition from `undefined` to `number` + getWidth: (ref: React.Ref) => void; + + // get base styles + getStyle: (width: Width) => any; + + // get transition styles + getTransition: (state: TransitionState) => any; +} diff --git a/types/react-select/lib/builtins.d.ts b/types/react-select/lib/builtins.d.ts new file mode 100644 index 0000000000..b1e1c37cc8 --- /dev/null +++ b/types/react-select/lib/builtins.d.ts @@ -0,0 +1,10 @@ +import { ReactNode as Node } from 'react'; +import { GroupType } from './types'; + +export function formatGroupLabel(group: GroupType): Node; + +export function getOptionLabel(option: any): string; + +export function getOptionValue(option: any): string; + +export function isOptionDisabled(option: any): boolean; diff --git a/types/react-select/lib/components/Control.d.ts b/types/react-select/lib/components/Control.d.ts new file mode 100644 index 0000000000..019f75bee9 --- /dev/null +++ b/types/react-select/lib/components/Control.d.ts @@ -0,0 +1,29 @@ +import { ComponentType, ReactNode as Node, Ref as ElementRef } from 'react'; + +import { borderRadius, colors, spacing } from '../theme'; +import { CommonProps, PropsWithStyles } from '../types'; + +interface State { + /** Whether the select is disabled. */ + isDisabled: boolean; + /** Whether the select is focused. */ + isFocused: boolean; +} + +export type ControlProps = CommonProps & + PropsWithStyles & + State & { + /** Children to render. */ + children: Node, + innerRef: ElementRef, + /** The mouse down event and the innerRef to pass down to the controller element. */ + innerProps: { + onMouseDown: (event: React.MouseEvent) => void, + }, + }; + +export function css(state: State): any; // TODO css type + +declare const Control: ComponentType>; + +export default Control; diff --git a/types/react-select/lib/components/Group.d.ts b/types/react-select/lib/components/Group.d.ts new file mode 100644 index 0000000000..d37964c0b4 --- /dev/null +++ b/types/react-select/lib/components/Group.d.ts @@ -0,0 +1,24 @@ +import { ReactNode as Node, ComponentType } from 'react'; + +import { spacing } from '../theme'; +import { CommonProps } from '../types'; + +interface ComponentProps { + /** The children to be rendered. */ + children: Node; + /** Component to wrap the label, recieves headingProps. */ + Heading: ComponentType; + /** Label to be displayed in the heading component. */ + label: Node; +} +export type GroupProps = CommonProps & ComponentProps; + +export function groupCSS(): any; // TODO css type + +export const Group: ComponentType>; + +export function groupHeadingCSS(): any; // TODO css type + +export const GroupHeading: ComponentType; + +export default Group; diff --git a/types/react-select/lib/components/Input.d.ts b/types/react-select/lib/components/Input.d.ts new file mode 100644 index 0000000000..16f07491d2 --- /dev/null +++ b/types/react-select/lib/components/Input.d.ts @@ -0,0 +1,23 @@ +import { ComponentType, Ref as ElementRef } from 'react'; + +import { colors, spacing } from '../theme'; + +import { PropsWithStyles, ClassNamesState } from '../types'; + +export type InputProps = PropsWithStyles & { + cx: (a: string | null, b: ClassNamesState, c: string) => string | void, + /** Reference to the internal element */ + innerRef: (element: ElementRef) => void, + /** Set whether the input should be visible. Does not affect input size. */ + isHidden: boolean, + /** Whether the input is disabled */ + isDisabled?: boolean, + className?: string, +}; + +export function inputCSS(props: InputProps): any; // TODO css type; +export function inputStyle(isHidden: boolean): any; // TODO css type + +export const Input: ComponentType; + +export default Input; diff --git a/types/react-select/lib/components/Menu.d.ts b/types/react-select/lib/components/Menu.d.ts new file mode 100644 index 0000000000..85b5ef0fae --- /dev/null +++ b/types/react-select/lib/components/Menu.d.ts @@ -0,0 +1,158 @@ +import { + Component, + ReactElement, + Ref as ElementRef, + ReactNode as Node, + ComponentType +} from 'react'; +import { createPortal } from 'react-dom'; + +import { + animatedScrollTo, + getBoundingClientObj, + RectType, + getScrollParent, + getScrollTop, + scrollTo, +} from '../utils'; +import { borderRadius, colors, spacing } from '../theme'; +import { + InnerRef, + MenuPlacement, + MenuPosition, + CommonProps, +} from '../types'; + +// ============================== +// Menu +// ============================== + +// Get Menu Placement +// ------------------------------ + +interface MenuState { placement: 'bottom' | 'top' | null; maxHeight: number; } +interface PlacementArgs { + maxHeight: number; + menuEl: ElementRef; + minHeight: number; + placement: 'bottom' | 'top' | 'auto'; + shouldScroll: boolean; + isFixedPosition: boolean; +} + +export function getMenuPlacement(args: PlacementArgs): MenuState; + +// Menu Component +// ------------------------------ + +export type MenuProps = CommonProps & { + /** The children to be rendered. */ + children: ReactElement, + /** Callback to update the portal after possible flip. */ + getPortalPlacement: (state: MenuState) => void, + /** Props to be passed to the menu wrapper. */ + innerProps: object, + /** Set the maximum height of the menu. */ + maxMenuHeight: number, + /** Set whether the menu should be at the top, at the bottom. The auto options sets it to bottom. */ + menuPlacement: MenuPlacement, + /* The CSS position value of the menu, when "fixed" extra layout management is required */ + menuPosition: MenuPosition, + /** Set the minimum height of the menu. */ + minMenuHeight: number, + /** Set whether the page should scroll to show the menu. */ + menuShouldScrollIntoView: boolean, +}; + +export function menuCSS(state: MenuState): any; // TODO css type + +export class Menu extends Component, MenuState> { + static contextTypes: { + getPortalPlacement: (state: MenuState) => void, + }; + getPlacement: (ref: ElementRef) => void; + getState: () => MenuProps & MenuState; +} + +export default Menu; + +// ============================== +// Menu List +// ============================== + +interface MenuListState { + /** Set classname for isMulti */ + isMulti: boolean; + /* Set the max height of the Menu component */ + maxHeight: number; +} + +export interface MenuListProps { + /** The children to be rendered. */ + children: Node; + /** Inner ref to DOM Node */ + innerRef: InnerRef; +} +export type MenuListComponentProps = CommonProps & + MenuListProps & + MenuListState; +export function menuListCSS(state: MenuState): any; // TODO css type +export const MenuList: ComponentType>; + +// ============================== +// Menu Notices +// ============================== + +export function noOptionsMessageCSS(): any; // TODO css type +export function loadingMessageCSS(): any; // TODO css type + +export type NoticeProps = CommonProps & { + /** The children to be rendered. */ + children: Node, + /** Props to be passed on to the wrapper. */ + innerProps: { [key: string]: any }, +}; + +export const NoOptionsMessage: ComponentType>; +// NoOptionsMessage.defaultProps = { +// children: 'No options', +// }; + +export const LoadingMessage: ComponentType>; +// LoadingMessage.defaultProps = { +// children: 'Loading...', +// }; + +// ============================== +// Menu Portal +// ============================== + +export type MenuPortalProps = CommonProps & { + appendTo: HTMLElement, + children: Node, // ideally Menu + controlElement: HTMLElement, + menuPlacement: MenuPlacement, + menuPosition: MenuPosition, +}; +interface MenuPortalState { + placement: 'bottom' | 'top' | null; +} +interface PortalStyleArgs { + offset: number; + position: MenuPosition; + rect: RectType; +} + +export function menuPortalCSS(args: PortalStyleArgs): any; // TODO css type + +export class MenuPortal extends Component, MenuPortalState> { + static childContextTypes: { + getPortalPlacement: (state: MenuState) => void, + }; + getChildContext(): { + getPortalPlacement: (state: MenuState) => void; + }; + + // callback for occassions where the menu must "flip" + getPortalPlacement: (state: MenuState) => void; +} diff --git a/types/react-select/lib/components/MultiValue.d.ts b/types/react-select/lib/components/MultiValue.d.ts new file mode 100644 index 0000000000..495b4fc96f --- /dev/null +++ b/types/react-select/lib/components/MultiValue.d.ts @@ -0,0 +1,57 @@ +import { ComponentType, Component, ReactNode as Node } from 'react'; + +import { borderRadius, colors, spacing } from '../theme'; +import { CommonProps } from '../types'; + +export type MultiValueProps = CommonProps &{ + children: Node, + components: any, + cropWithEllipsis: boolean, + data: OptionType, + innerProps: any, + isFocused: boolean, + isDisabled: boolean, + removeProps: { + onTouchEnd: (event: any) => void, + onClick: (event: any) => void, + onMouseDown: (event: any) => void, + }, +}; + +export function multiValueCSS(): any; // TODO css type +export function multiValueLabelCSS(props: MultiValueProps): any; // TODO css type +export function multiValueRemoveCSS(props: MultiValueProps): any; // TODO css type + +export interface MultiValueGenericProps { + children: Node; + data: OptionType; + innerProps: { className?: string }; + selectProps: any; +} +export const MultiValueGeneric: ComponentType>; + +export const MultiValueContainer: typeof MultiValueGeneric; +export const MultiValueLabel: typeof MultiValueGeneric; +export type MultiValueRemoveProps = CommonProps & { + children: Node, + innerProps: { + className: string, + onTouchEnd: (event: any) => void, + onClick: (event: any) => void, + onMouseDown: (event: any) => void, + }, + selectProps: any, +}; +export class MultiValueRemove extends Component> { + static defaultProps: { + children: Node, + }; +} + +export class MultiValue extends Component> { + static defaultProps: { + cropWithEllipsis: boolean, + }; +} + +export default MultiValue; diff --git a/types/react-select/lib/components/Option.d.ts b/types/react-select/lib/components/Option.d.ts new file mode 100644 index 0000000000..743083fff8 --- /dev/null +++ b/types/react-select/lib/components/Option.d.ts @@ -0,0 +1,41 @@ +import { ComponentType, ReactNode as Node, MouseEventHandler } from 'react'; + +import { colors, spacing } from '../theme'; +import { CommonProps, PropsWithStyles, InnerRef } from '../types'; + +interface State { + /** Wether the option is disabled. */ + isDisabled: boolean; + /** Wether the option is focused. */ + isFocused: boolean; + /** Whether the option is selected. */ + isSelected: boolean; +} +interface InnerProps { + id: string; + key: string; + onClick: MouseEventHandler; + onMouseOver: MouseEventHandler; + tabIndex: number; +} +export type OptionProps = PropsWithStyles & + CommonProps & + State & { + /** The children to be rendered. */ + children: Node, + /** Inner ref to DOM Node */ + innerRef: InnerRef, + /** props passed to the wrapping element for the group. */ + innerProps: InnerProps, + /* Text to be displayed representing the option. */ + label: string, + /* Type is used by the menu to determine whether this is an option or a group. + In the case of option this is always `option`. */ + type: 'option', + }; + +export function optionCSS(state: State): any; // TODO css type + +export const Option: ComponentType>; + +export default Option; diff --git a/types/react-select/lib/components/Placeholder.d.ts b/types/react-select/lib/components/Placeholder.d.ts new file mode 100644 index 0000000000..f674f74cc2 --- /dev/null +++ b/types/react-select/lib/components/Placeholder.d.ts @@ -0,0 +1,17 @@ +import { ComponentType, ReactNode as Node } from 'react'; + +import { colors, spacing } from '../theme'; +import { CommonProps } from '../types'; + +export type PlaceholderProps = CommonProps & { + /** The children to be rendered. */ + children: Node, + /** props passed to the wrapping element for the group. */ + innerProps: { [key: string]: any }, +}; + +export function placeholderCSS(): any; // TODO css type + +export const Placeholder: ComponentType>; + +export default Placeholder; diff --git a/types/react-select/lib/components/SingleValue.d.ts b/types/react-select/lib/components/SingleValue.d.ts new file mode 100644 index 0000000000..c5f922d84c --- /dev/null +++ b/types/react-select/lib/components/SingleValue.d.ts @@ -0,0 +1,23 @@ +import { ComponentType } from 'react'; +import { colors, spacing } from '../theme'; +import { CommonProps } from '../types'; + +interface State { + /** Whether this is disabled */ + isDisabled: boolean; +} +interface ValueProps { + /** The children to be rendered. */ + children: string; + /* The data of the selected option rendered in the Single Value componentn */ + data: OptionType; + /** Props passed to the wrapping element for the group. */ + innerProps: any; +} +export type SingleValueProps = CommonProps & ValueProps & State; + +export function css(props: SingleValueProps): any; // TODO css type + +export const SingleValue: ComponentType>; + +export default SingleValue; diff --git a/types/react-select/lib/components/containers.d.ts b/types/react-select/lib/components/containers.d.ts new file mode 100644 index 0000000000..373a552062 --- /dev/null +++ b/types/react-select/lib/components/containers.d.ts @@ -0,0 +1,57 @@ +import { Component, ReactNode as Node, ComponentType } from 'react'; +import { spacing } from '../theme'; +import { CommonProps, KeyboardEventHandler } from '../types'; + +// ============================== +// Root Container +// ============================== + +export interface ContainerState { + /** Whether the select is disabled. */ + isDisabled: boolean; + /** Whether the text in the select is indented from right to left. */ + isRtl: boolean; +} + +export type ContainerProps = CommonProps & + ContainerState & { + /** The children to be rendered. */ + children: Node, + /** Inner props to be passed down to the container. */ + innerProps: { onKeyDown: KeyboardEventHandler }, + }; +export function containerCSS(state: ContainerState): any; // TODO css type; +export const SelectContainer: ComponentType>; + +// ============================== +// Value Container +// ============================== + +export type ValueContainerProps = CommonProps & { + /** Set when the value container should hold multiple values */ + isMulti: boolean, + /** Whether the value container currently holds a value. */ + hasValue: boolean, + /** The children to be rendered. */ + children: Node, +}; +export function valueContainerCSS(): any; // TODO css type; +export class ValueContainer extends Component> {} + +// ============================== +// Indicator Container +// ============================== + +export interface IndicatorsState { + /** Whether the text should be rendered right to left. */ + isRtl: boolean; +} + +export type IndicatorContainerProps = CommonProps & + IndicatorsState & { + /** The children to be rendered. */ + children: Node, + }; + +export function indicatorsContainerCSS(): any; // TODO css type; +export const IndicatorsContainer: ComponentType>; diff --git a/types/react-select/lib/components/index.d.ts b/types/react-select/lib/components/index.d.ts new file mode 100644 index 0000000000..7d493a562a --- /dev/null +++ b/types/react-select/lib/components/index.d.ts @@ -0,0 +1,142 @@ +import { + ComponentType, + ReactElement as Element, +} from 'react'; +import { + IndicatorContainerProps, + ContainerProps, + ValueContainerProps, + IndicatorsContainer, + SelectContainer, + ValueContainer, +} from './containers'; +import { + IndicatorProps, + LoadingIconProps, + ClearIndicator, + DropdownIndicator, + LoadingIndicator, + IndicatorSeparator, + DownChevron, + CrossIcon, +} from './indicators'; + +import Control, { ControlProps } from './Control'; +import Group, { GroupProps, GroupHeading } from './Group'; +import Input, { InputProps } from './Input'; +import Menu, { + MenuProps, + MenuList, + MenuListComponentProps, + MenuPortal, + MenuPortalProps, + NoticeProps, + NoOptionsMessage, + LoadingMessage, +} from './Menu'; +import MultiValue, { + MultiValueProps, + MultiValueContainer, + MultiValueLabel, + MultiValueRemove, +} from './MultiValue'; +import Option, { OptionProps } from './Option'; +import Placeholder, { PlaceholderProps } from './Placeholder'; +import SingleValue, { SingleValueProps } from './SingleValue'; + +export type PlaceholderOrValue = + | Element>> + | Element>> + | Array>>>; + +export type IndicatorComponentType = ComponentType>; + +export interface SelectComponents { + ClearIndicator: IndicatorComponentType | null; + Control: ComponentType>; + DropdownIndicator: IndicatorComponentType | null; + DownChevron: ComponentType; + CrossIcon: ComponentType; + Group: ComponentType>; + GroupHeading: ComponentType; + IndicatorsContainer: ComponentType>; + IndicatorSeparator: IndicatorComponentType | null; + Input: ComponentType; + LoadingIndicator: ComponentType> | null; + Menu: ComponentType>; + MenuList: ComponentType>; + MenuPortal: ComponentType>; + LoadingMessage: ComponentType>; + NoOptionsMessage: ComponentType>; + MultiValue: ComponentType>; + MultiValueContainer: ComponentType; + MultiValueLabel: ComponentType; + MultiValueRemove: ComponentType; + Option: ComponentType>; + Placeholder: ComponentType>; + SelectContainer: ComponentType>; + SingleValue: ComponentType>; + ValueContainer: ComponentType>; +} + +export interface SelectComponentsConfig { + ClearIndicator?: IndicatorComponentType | null; + Control?: ComponentType>; + DropdownIndicator?: IndicatorComponentType | null; + DownChevron?: ComponentType; + CrossIcon?: ComponentType; + Group?: ComponentType>; + GroupHeading?: ComponentType; + IndicatorsContainer?: ComponentType>; + IndicatorSeparator?: IndicatorComponentType | null; + Input?: ComponentType; + LoadingIndicator?: ComponentType> | null; + Menu?: ComponentType>; + MenuList?: ComponentType>; + MenuPortal?: ComponentType>; + LoadingMessage?: ComponentType>; + NoOptionsMessage?: ComponentType>; + MultiValue?: ComponentType>; + MultiValueContainer?: ComponentType; + MultiValueLabel?: ComponentType; + MultiValueRemove?: ComponentType; + Option?: ComponentType>; + Placeholder?: ComponentType>; + SelectContainer?: ComponentType>; + SingleValue?: ComponentType>; + ValueContainer?: ComponentType>; +} + +export namespace components { + const ClearIndicator: IndicatorComponentType | null; + const Control: ComponentType>; + const DropdownIndicator: IndicatorComponentType | null; + const DownChevron: ComponentType; + const CrossIcon: ComponentType; + const Group: ComponentType>; + const GroupHeading: ComponentType; + const IndicatorsContainer: ComponentType>; + const IndicatorSeparator: IndicatorComponentType | null; + const Input: ComponentType; + const LoadingIndicator: ComponentType> | null; + const Menu: ComponentType>; + const MenuList: ComponentType>; + const MenuPortal: ComponentType>; + const LoadingMessage: ComponentType>; + const NoOptionsMessage: ComponentType>; + const MultiValue: ComponentType>; + const MultiValueContainer: ComponentType; + const MultiValueLabel: ComponentType; + const MultiValueRemove: ComponentType; + const Option: ComponentType>; + const Placeholder: ComponentType>; + const SelectContainer: ComponentType>; + const SingleValue: ComponentType>; + const ValueContainer: ComponentType>; +} + +export interface Props { + components: SelectComponentsConfig; +} + +export function defaultComponents(props: Props): SelectComponentsConfig; diff --git a/types/react-select/lib/components/indicators.d.ts b/types/react-select/lib/components/indicators.d.ts new file mode 100644 index 0000000000..d27cc518da --- /dev/null +++ b/types/react-select/lib/components/indicators.d.ts @@ -0,0 +1,67 @@ +import { ComponentType, ReactElement as ElementType } from 'react'; + +import { colors, spacing } from '../theme'; +import { CommonProps } from '../types'; + +// ============================== +// Dropdown & Clear Icons +// ============================== + +export function CrossIcon(props: any): any; // TODO svg type +export function DownChevron(props: any): any; // TODO svg type + +// ============================== +// Dropdown & Clear Buttons +// ============================== + +export type IndicatorProps = CommonProps & { + /** The children to be rendered inside the indicator. */ + children: ElementType, + /** Props that will be passed on to the children. */ + innerProps: any, + /** The focused state of the select. */ + isFocused: boolean, + /** Whether the text is right to left */ + isRtl: boolean, +}; + +export type baseCSS = (props: IndicatorProps) => any; // TODO css type + +export const dropdownIndicatorCSS: baseCSS; +export const DropdownIndicator: ComponentType>; + +export const clearIndicatorCSS: baseCSS; +export const ClearIndicator: ComponentType>; + +// ============================== +// Separator +// ============================== + +export interface SeparatorState { isDisabled: boolean; } + +export function indicatorSeparatorCSS(state: SeparatorState): any; // TODO css type + +export const IndicatorSeparator: ComponentType>; + +// ============================== +// Loading +// ============================== + +export function loadingIndicatorCSS(state: { + isFocused: boolean, + size: number, +}): any; // TODO css type + +export type LoadingIconProps = { + /** Props that will be passed on to the children. */ + innerProps: any, + /** The focused state of the select. */ + isFocused: boolean, + /** Whether the text is right to left */ + isRtl: boolean, +} & CommonProps & { + /** Set size of the container. */ + size: number, +}; +export const LoadingIndicator: ComponentType>; +// TODO LoadingIndicator.defaultProps: { size: number }; diff --git a/types/react-select/lib/diacritics.d.ts b/types/react-select/lib/diacritics.d.ts new file mode 100644 index 0000000000..855a0e152a --- /dev/null +++ b/types/react-select/lib/diacritics.d.ts @@ -0,0 +1 @@ +export function stripDiacritics(str: string): string; diff --git a/types/react-select/lib/filters.d.ts b/types/react-select/lib/filters.d.ts new file mode 100644 index 0000000000..33d1a7fddf --- /dev/null +++ b/types/react-select/lib/filters.d.ts @@ -0,0 +1,16 @@ +export interface Config { + ignoreCase?: boolean; + ignoreAccents?: boolean; + stringify?: (obj: any) => string; + trim?: boolean; + matchFrom?: 'any' | 'start'; +} + +import { stripDiacritics } from './diacritics'; + +export interface Option { label: string; value: string; data: any; } + +export function createFilter(config: Config | null): ( + option: Option, + rawInput: string +) => boolean; diff --git a/types/react-select/lib/stateManager.d.ts b/types/react-select/lib/stateManager.d.ts new file mode 100644 index 0000000000..07a17f52f7 --- /dev/null +++ b/types/react-select/lib/stateManager.d.ts @@ -0,0 +1,36 @@ +import { Component, ComponentType, Ref as ElementRef } from 'react'; + +import { ActionMeta, InputActionMeta, ValueType } from './types'; + +export interface Props { + defaultInputValue?: string; + defaultMenuIsOpen?: boolean; + defaultValue?: ValueType; + inputValue?: string; + menuIsOpen?: boolean; + value?: ValueType; +} +interface State { + inputValue: string; + menuIsOpen: boolean; + value: ValueType; +} + +export class StateManager extends Component, State> { + static defaultProps: Props; + + select: ElementRef; + + focus(): void; + blur(): void; + getProp(key: string): any; + callProp(name: string, ...args: any[]): any; + onChange: (value: any, actionMeta: ActionMeta) => void; + onInputChange: (value: any, actionMeta: InputActionMeta) => void; + onMenuOpen: () => void; + onMenuClose: () => void; +} + +export function manageState(SelectComponent: ComponentType): StateManager; + +export default manageState; diff --git a/types/react-select/lib/styles.d.ts b/types/react-select/lib/styles.d.ts new file mode 100644 index 0000000000..9c5178fed1 --- /dev/null +++ b/types/react-select/lib/styles.d.ts @@ -0,0 +1,99 @@ +import { + containerCSS, + indicatorsContainerCSS, + valueContainerCSS, +} from './components/containers'; +import { css as controlCSS } from './components/Control'; +import { groupCSS, groupHeadingCSS } from './components/Group'; +import { + clearIndicatorCSS, + dropdownIndicatorCSS, + loadingIndicatorCSS, + indicatorSeparatorCSS, +} from './components/indicators'; +import { inputCSS } from './components/Input'; +import { placeholderCSS } from './components/Placeholder'; +import { optionCSS } from './components/Option'; +import { + menuCSS, + menuListCSS, + menuPortalCSS, + noOptionsMessageCSS, + loadingMessageCSS, +} from './components/Menu'; +import { css as singleValueCSS } from './components/SingleValue'; +import { + multiValueCSS, + multiValueLabelCSS, + multiValueRemoveCSS, +} from './components/MultiValue'; + +export interface Props { [key: string]: any; } + +/** + * @param base -- the component's default style + * @param state -- the component's current state e.g. `isFocused` + * @returns + */ +export type styleFn = (base: any, state: any) => any; + +export interface Styles { + clearIndicator?: styleFn; + container?: styleFn; + control?: styleFn; + dropdownIndicator?: styleFn; + group?: styleFn; + groupHeading?: styleFn; + indicatorsContainer?: styleFn; + indicatorSeparator?: styleFn; + input?: styleFn; + loadingIndicator?: styleFn; + // TODO loadingMessageCSS?: styleFn; + loadingMessage?: styleFn; + menu?: styleFn; + menuList?: styleFn; + menuPortal?: styleFn; + multiValue?: styleFn; + multiValueLabel?: styleFn; + multiValueRemove?: styleFn; + // TODO noOptionsMessageCSS?: styleFn; + noOptionsMessage?: styleFn; + option?: styleFn; + placeholder?: styleFn; + singleValue?: styleFn; + valueContainer: styleFn; +} +export interface StylesConfig { + clearIndicator?: styleFn; + container?: styleFn; + control?: styleFn; + dropdownIndicator?: styleFn; + group?: styleFn; + groupHeading?: styleFn; + indicatorsContainer?: styleFn; + indicatorSeparator?: styleFn; + input?: styleFn; + loadingIndicator?: styleFn; + // TODO loadingMessageCSS?: styleFn; + loadingMessage?: styleFn; + menu?: styleFn; + menuList?: styleFn; + menuPortal?: styleFn; + multiValue?: styleFn; + multiValueLabel?: styleFn; + multiValueRemove?: styleFn; + // TODO noOptionsMessageCSS?: styleFn; + noOptionsMessage?: styleFn; + option?: styleFn; + placeholder?: styleFn; + singleValue?: styleFn; + valueContainer?: styleFn; +} +export type GetStyles = (a: string, b: Props) => any; + +export const defaultStyles: Styles; + +// Merge Utility +// Allows consumers to extend a base Select with additional styles + +export function mergeStyles(source: any, target: any): any; diff --git a/types/react-select/lib/theme.d.ts b/types/react-select/lib/theme.d.ts new file mode 100644 index 0000000000..7282dd20ad --- /dev/null +++ b/types/react-select/lib/theme.d.ts @@ -0,0 +1,53 @@ +export const borderRadius: number; + +export const colors: { + text: string; + textLight: string; + primary: string; + primary75: string; + primary50: string; + primary25: string; + danger: string; + dangerLight: string; + + neutral0: string; + neutral1: string; + neutral2: string; + neutral3: string; + neutral4: string; + neutral5: string; + neutral10: string; + neutral20: string; + neutral30: string; + neutral40: string; + neutral50: string; + neutral60: string; + neutral70: string; + neutral80: string; + neutral90: string; + neutral100: string; + + neutral1a: string; + neutral2a: string; + neutral3a: string; + neutral4a: string; + neutral5a: string; + neutral10a: string; + neutral20a: string; + neutral30a: string; + neutral40a: string; + neutral50a: string; + neutral60a: string; + neutral70a: string; + neutral80a: string; + neutral90a: string; +}; + +export const spacing: { + /* Used to calculate consistent margin/padding on elements */ + baseUnit: number, + /* The minimum height of the control */ + controlHeight: number, + /* The amount of space between the control and menu */ + menuGutter: number, +}; diff --git a/types/react-select/lib/types.d.ts b/types/react-select/lib/types.d.ts new file mode 100644 index 0000000000..08ebfae965 --- /dev/null +++ b/types/react-select/lib/types.d.ts @@ -0,0 +1,100 @@ +import * as React from 'react'; + +export type OptionsType = OptionType[]; + +export interface GroupType { + options: OptionsType; + [key: string]: any; +} + +export type GroupedOptionsType = Array>; + +export type ValueType = OptionType | OptionsType | null | undefined; + +export type FocusEventHandler = (event: React.FocusEvent) => void; +export type MouseEventHandler = (event: React.MouseEvent) => void; +export type KeyboardEventHandler = (event: React.KeyboardEvent) => void; + +export type InnerRef = React.Ref; +export interface PropsWithInnerRef { + /** The inner reference. */ + innerRef: React.Ref; +} + +export interface PropsWithStyles { + /* + Get the styles of a particular part of the select. Pass in the name of the + property as the first argument, and the current props as the second argument. + See the `styles` object for the properties available. + */ + getStyles: (name: string, props: any) => {}; +} + +export type ClassNameList = string[]; +export type ClassNamesState = { [key: string]: boolean } | undefined; + +export interface CommonProps { + clearValue: () => void; + className?: string; + cx: (a: string | null, b: ClassNamesState | undefined, c: string | undefined) => string | void; + /* + Get the styles of a particular part of the select. Pass in the name of the + property as the first argument, and the current props as the second argument. + See the `styles` object for the properties available. + */ + getStyles: (name: string, props: any) => {}; + getValue: () => ValueType; + hasValue: boolean; + isMulti: boolean; + options: OptionsType; + selectOption: (option: OptionType) => void; + selectProps: any; + setValue: (value: ValueType, action: ActionTypes) => void; +} + +export type ActionTypes = + | 'select-option' + | 'deselect-option' + | 'remove-value' + | 'pop-value' + | 'set-value' + | 'clear' + | 'create-option'; + +export interface ActionMeta { + action: ActionTypes; +} + +export type InputActionTypes = + | 'set-value' + | 'input-change' + | 'input-blur' + | 'menu-close'; + +export interface InputActionMeta { + action: InputActionTypes; +} + +export type MenuPlacement = 'auto' | 'bottom' | 'top'; +export type MenuPosition = 'absolute' | 'fixed'; + +export type FocusDirection = + | 'up' + | 'down' + | 'pageup' + | 'pagedown' + | 'first' + | 'last'; + +export type OptionProps = PropsWithInnerRef & { + data: any, + id: number, + index: number, + isDisabled: boolean, + isFocused: boolean, + isSelected: boolean, + label: string, + onClick: MouseEventHandler, + onMouseOver: MouseEventHandler, + value: any, +}; diff --git a/types/react-select/lib/utils.d.ts b/types/react-select/lib/utils.d.ts new file mode 100644 index 0000000000..c907d59c2a --- /dev/null +++ b/types/react-select/lib/utils.d.ts @@ -0,0 +1,121 @@ +import * as React from 'react'; +import { + ClassNamesState, + InputActionMeta, + OptionsType, + ValueType, +} from './types'; + +// ============================== +// NO OP +// ============================== + +export function noop(): void; +export function emptyString(): string; + +// ============================== +// Class Name Prefixer +// ============================== + +export function classNames( + prefix?: string | null, + cssKey?: string | null, + state?: ClassNamesState, + className?: string, +): string; + +// ============================== +// Clean Value +// ============================== + +export function cleanValue(value: ValueType): OptionsType; + +// ============================== +// Handle Input Change +// ============================== + +export function handleInputChange( + inputValue: string, + actionMeta: InputActionMeta, + onInputChange?: (inputValue: string, actionMeta: InputActionMeta) => string | void +): string; + +// ============================== +// Scroll Helpers +// ============================== + +export function isDocumentElement(el: Element): boolean; + +// Normalized Scroll Top +// ------------------------------ + +export function normalizedHeight(el: Element): number; + +// Normalized scrollTo & scrollTop +// ------------------------------ + +export function getScrollTop(el: Element): number; + +export function scrollTo(el: Element, top: number): void; + +// Get Scroll Parent +// ------------------------------ + +export function getScrollParent(element: React.Ref): Element; + +// Animated Scroll To +// ------------------------------ + +export function animatedScrollTo( + element: Element, + to: number, + duration: number, + callback: (element: Element) => void +): void; + +// Scroll Into View +// ------------------------------ + +export function scrollIntoView( + menuEl: HTMLElement, + focusedEl: HTMLElement +): void; + +// ============================== +// Get bounding client object +// ============================== + +// cannot get keys using array notation with DOMRect +export function getBoundingClientObj(element: HTMLElement): { + bottom: number; + height: number; + left: number; + right: number; + top: number; + width: number; +}; +export interface RectType { + left: number; + right: number; + bottom: number; + height: number; + width: number; +} + +// ============================== +// String to Key (kebabify) +// ============================== + +export function toKey(str: string): string; + +// ============================== +// Touch Capability Detector +// ============================== + +export function isTouchCapable(): boolean; + +// ============================== +// Mobile Device Detector +// ============================== + +export function isMobileDevice(): boolean; diff --git a/types/react-select/test/AtlaskitDummy.ts b/types/react-select/test/AtlaskitDummy.ts new file mode 100644 index 0000000000..e6e75e9e32 --- /dev/null +++ b/types/react-select/test/AtlaskitDummy.ts @@ -0,0 +1,11 @@ +export const Tooltip = (props: any) => null; + +export const EmojiIcon = (props: any) => null; + +export const EditorPanelIcon = (props: any) => null; + +export const Spinner = (props: any) => null; + +export const Button = (props: any) => null; + +export const Modal = (props: any) => null; diff --git a/types/react-select/test/ChronoNodeDummy.ts b/types/react-select/test/ChronoNodeDummy.ts new file mode 100644 index 0000000000..1e4aed01b0 --- /dev/null +++ b/types/react-select/test/ChronoNodeDummy.ts @@ -0,0 +1 @@ +export function parseDate(a: any): any {} diff --git a/types/react-select/test/data.ts b/types/react-select/test/data.ts new file mode 100644 index 0000000000..a4bff0225d --- /dev/null +++ b/types/react-select/test/data.ts @@ -0,0 +1,132 @@ +import { GroupedOptionsType, GroupType } from "react-select/lib/types"; + +export interface ColourOption { + value: string; + label: string; + color: string; + disabled?: boolean; +} + +export const colourOptions: ColourOption[] = [ + { value: 'ocean', label: 'Ocean', color: '#00B8D9' }, + { value: 'blue', label: 'Blue', color: '#0052CC', disabled: true }, + { value: 'purple', label: 'Purple', color: '#5243AA' }, + { value: 'red', label: 'Red', color: '#FF5630' }, + { value: 'orange', label: 'Orange', color: '#FF8B00' }, + { value: 'yellow', label: 'Yellow', color: '#FFC400' }, + { value: 'green', label: 'Green', color: '#36B37E' }, + { value: 'forest', label: 'Forest', color: '#00875A' }, + { value: 'slate', label: 'Slate', color: '#253858' }, + { value: 'silver', label: 'Silver', color: '#666666' }, +]; + +export interface FlavourOption { + value: string; + label: string; + rating: 'safe' | 'good' | 'wild' | 'crazy'; +} + +export const flavourOptions: FlavourOption[] = [ + { value: 'vanilla', label: 'Vanilla', rating: 'safe' }, + { value: 'chocolate', label: 'Chocolate', rating: 'good' }, + { value: 'strawberry', label: 'Strawberry', rating: 'wild' }, + { value: 'salted-caramel', label: 'Salted Caramel', rating: 'crazy' }, +]; + +export interface StateOption { + value: string; + label: string; +} + +export const stateOptions: StateOption[] = [ + { value: 'AL', label: 'Alabama' }, + { value: 'AK', label: 'Alaska' }, + { value: 'AS', label: 'American Samoa' }, + { value: 'AZ', label: 'Arizona' }, + { value: 'AR', label: 'Arkansas' }, + { value: 'CA', label: 'California' }, + { value: 'CO', label: 'Colorado' }, + { value: 'CT', label: 'Connecticut' }, + { value: 'DE', label: 'Delaware' }, + { value: 'DC', label: 'District Of Columbia' }, + { value: 'FM', label: 'Federated States Of Micronesia' }, + { value: 'FL', label: 'Florida' }, + { value: 'GA', label: 'Georgia' }, + { value: 'GU', label: 'Guam' }, + { value: 'HI', label: 'Hawaii' }, + { value: 'ID', label: 'Idaho' }, + { value: 'IL', label: 'Illinois' }, + { value: 'IN', label: 'Indiana' }, + { value: 'IA', label: 'Iowa' }, + { value: 'KS', label: 'Kansas' }, + { value: 'KY', label: 'Kentucky' }, + { value: 'LA', label: 'Louisiana' }, + { value: 'ME', label: 'Maine' }, + { value: 'MH', label: 'Marshall Islands' }, + { value: 'MD', label: 'Maryland' }, + { value: 'MA', label: 'Massachusetts' }, + { value: 'MI', label: 'Michigan' }, + { value: 'MN', label: 'Minnesota' }, + { value: 'MS', label: 'Mississippi' }, + { value: 'MO', label: 'Missouri' }, + { value: 'MT', label: 'Montana' }, + { value: 'NE', label: 'Nebraska' }, + { value: 'NV', label: 'Nevada' }, + { value: 'NH', label: 'New Hampshire' }, + { value: 'NJ', label: 'New Jersey' }, + { value: 'NM', label: 'New Mexico' }, + { value: 'NY', label: 'New York' }, + { value: 'NC', label: 'North Carolina' }, + { value: 'ND', label: 'North Dakota' }, + { value: 'MP', label: 'Northern Mariana Islands' }, + { value: 'OH', label: 'Ohio' }, + { value: 'OK', label: 'Oklahoma' }, + { value: 'OR', label: 'Oregon' }, + { value: 'PW', label: 'Palau' }, + { value: 'PA', label: 'Pennsylvania' }, + { value: 'PR', label: 'Puerto Rico' }, + { value: 'RI', label: 'Rhode Island' }, + { value: 'SC', label: 'South Carolina' }, + { value: 'SD', label: 'South Dakota' }, + { value: 'TN', label: 'Tennessee' }, + { value: 'TX', label: 'Texas' }, + { value: 'UT', label: 'Utah' }, + { value: 'VT', label: 'Vermont' }, + { value: 'VI', label: 'Virgin Islands' }, + { value: 'VA', label: 'Virginia' }, + { value: 'WA', label: 'Washington' }, + { value: 'WV', label: 'West Virginia' }, + { value: 'WI', label: 'Wisconsin' }, + { value: 'WY', label: 'Wyoming' }, +]; + +export const optionLength = [ + { value: 1, label: 'general' }, + { + value: 2, + label: + 'Evil is the moment when I lack the strength to be true to the Good that compels me.', + }, + { + value: 3, + label: + // tslint:disable-next-line:max-line-length + "It is now an easy matter to spell out the ethic of a truth: 'Do all that you can to persevere in that which exceeds your perseverance. Persevere in the interruption. Seize in your being that which has seized and broken you.", + }, +]; + +// let bigOptions = []; +// for (let i = 0; i < 10000; i++) { +// bigOptions = bigOptions.concat(colourOptions); +// } + +const colourGroup: GroupType = { + label: 'Colours', + options: colourOptions +}; +const flavourGroup: GroupType = { + label: 'Flavours', + options: flavourOptions, +}; + +export const groupedOptions: GroupedOptionsType = [ colourGroup, flavourGroup ]; diff --git a/types/react-select/test/examples/AccessingInternals.tsx b/types/react-select/test/examples/AccessingInternals.tsx new file mode 100644 index 0000000000..8948bc19e7 --- /dev/null +++ b/types/react-select/test/examples/AccessingInternals.tsx @@ -0,0 +1,114 @@ +import * as React from 'react'; + +import Select from 'react-select'; +import AsyncSelect from 'react-select/lib/Async'; +import CreatableSelect from 'react-select/lib/Creatable'; +import { Note } from '../styled-components'; +import { ColourOption, colourOptions } from '../data'; + +const filterColors = (inputValue: string) => + colourOptions.filter(i => + i.label.toLowerCase().includes(inputValue.toLowerCase()) + ); + +const promiseOptions = (inputValue: string) => + new Promise(resolve => { + setTimeout(() => { + resolve(filterColors(inputValue)); + }, 1000); + }); + +export default class AccessingInterals extends React.Component { + selectRef: Select; + asyncRef: AsyncSelect; + creatableRef: CreatableSelect; + focus = () => { + console.log(this.selectRef); + this.selectRef.focus(); + } + focusCreatable = () => { + console.log(this.creatableRef); + this.creatableRef.focus(); + } + focusAsync = () => { + console.log(this.asyncRef); + this.asyncRef.focus(); + } + blurAsync = () => { + this.asyncRef.blur(); + } + blurCreatable = () => { + this.creatableRef.blur(); + } + blur = () => this.selectRef.blur(); + onSelectRef = (ref: any) => { + console.log(ref); + this.selectRef = ref; + } + render() { + return ( + +

+ Creatable Select +

+ { this.creatableRef = ref; }} + isClearable + options={colourOptions} + /> + + + + + + +

+ Async Select +

+ { this.asyncRef = ref; }} + cacheOptions + defaultOptions + loadOptions={promiseOptions} + /> + + + + + + +

Select

+ +); diff --git a/types/react-select/test/examples/BasicSingle.tsx b/types/react-select/test/examples/BasicSingle.tsx new file mode 100644 index 0000000000..69697566c2 --- /dev/null +++ b/types/react-select/test/examples/BasicSingle.tsx @@ -0,0 +1,101 @@ +import * as React from 'react'; + +import Select from 'react-select'; +import { colourOptions } from '../data'; +import { Note } from '../styled-components'; + +const Checkbox = (props: any) => ; + +interface State { + isClearable: boolean; + isDisabled: boolean; + isLoading: boolean; + isRtl: boolean; + isSearchable: boolean; +} + +export default class SingleSelect extends React.Component { + state = { + isClearable: true, + isDisabled: false, + isLoading: false, + isRtl: false, + isSearchable: true, + }; + + toggleClearable = () => + this.setState(state => ({ isClearable: !state.isClearable })) + toggleDisabled = () => + this.setState(state => ({ isDisabled: !state.isDisabled })) + toggleLoading = () => + this.setState(state => ({ isLoading: !state.isLoading })) + toggleRtl = () => this.setState(state => ({ isRtl: !state.isRtl })); + toggleSearchable = () => + this.setState(state => ({ isSearchable: !state.isSearchable })) + render() { + const { + isClearable, + isSearchable, + isDisabled, + isLoading, + isRtl, + } = this.state; + return ( + + ; + +interface State { + menuIsOpen: boolean; +} + +export default class controlledMenu extends React.Component { + state = { + menuIsOpen: false, + }; + toggleMenuIsOpen = () => + this.setState(state => ({ menuIsOpen: !state.menuIsOpen })) + render() { + const { menuIsOpen } = this.state; + return ( + + ; + +interface State { + ignoreCase: boolean; + ignoreAccents: boolean; + trim: boolean; + matchFromStart: boolean; +} + +export default class SelectCreateFilter extends React.Component { + state: State = { + ignoreCase: false, + ignoreAccents: false, + trim: false, + matchFromStart: false, + }; + toggleOption = (key: string) => () => { + this.setState((state: any) => ({ ...state, [key]: !state[key] })); + } + render() { + const { + ignoreCase, + ignoreAccents, + trim, + matchFromStart, + } = this.state; + + const filterConfig = { + ignoreCase, + ignoreAccents, + trim, + matchFrom: this.state.matchFromStart ? ('start' as 'start') : ('any' as 'any'), + }; + + return ( + + + ); +} diff --git a/types/react-select/test/examples/CustomControl.tsx b/types/react-select/test/examples/CustomControl.tsx new file mode 100644 index 0000000000..3ed018e05e --- /dev/null +++ b/types/react-select/test/examples/CustomControl.tsx @@ -0,0 +1,32 @@ +import * as React from 'react'; + +import Select, { components } from 'react-select'; +import { colourOptions } from '../data'; +const controlStyles = { + borderRadius: '1px solid black', + padding: '5px', + background: colourOptions[2].color, + color: 'white' +}; + +const ControlComponent = (props: any) => ( +
+ {

Custom Control

} + +
+); + +export default class CustomControl extends React.Component { + render() { + return ( + +); diff --git a/types/react-select/test/examples/CustomFilterOptions.tsx b/types/react-select/test/examples/CustomFilterOptions.tsx new file mode 100644 index 0000000000..62a13f2a89 --- /dev/null +++ b/types/react-select/test/examples/CustomFilterOptions.tsx @@ -0,0 +1,34 @@ +import * as React from 'react'; +import Select from 'react-select'; +import { colourOptions } from '../data'; + +interface State { + ignoreCase: boolean; + ignoreAccents: boolean; + trim: boolean; + matchFrom: boolean; +} + +const filterOptions = (candidate: any, input: string) => { + if (input) { + return candidate.value === customOptions[0].value; + } + return true; +}; + +const customOptions = [{ value: 'custom', label: 'Using a custom filter to always display this option on search' }, ...colourOptions]; + +export default class SelectCreateFilter extends React.Component { + render() { + return ( + +
+ ); + } +} diff --git a/types/react-select/test/examples/CustomGroup.tsx b/types/react-select/test/examples/CustomGroup.tsx new file mode 100644 index 0000000000..7085e2901c --- /dev/null +++ b/types/react-select/test/examples/CustomGroup.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; + +import Select, { components } from 'react-select'; +import { ColourOption, colourOptions, FlavourOption, groupedOptions } from '../data'; + +const groupStyles = { + border: `2px dotted ${colourOptions[2].color}`, + borderRadius: '5px', + background: '#f2fcff' +}; + +const Group = (props: any) => ( +
+ +
+); + +export default () => ( + + defaultValue={colourOptions[1]} + options={groupedOptions} + components={{ Group }} + /> +); diff --git a/types/react-select/test/examples/CustomGroupHeading.tsx b/types/react-select/test/examples/CustomGroupHeading.tsx new file mode 100644 index 0000000000..abf09de9ef --- /dev/null +++ b/types/react-select/test/examples/CustomGroupHeading.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; + +import Select, { components } from 'react-select'; +import { ColourOption, colourOptions, FlavourOption, groupedOptions } from '../data'; +import { EditorPanelIcon, Tooltip } from '../AtlaskitDummy'; + +const groupStyles = { + border: `2px dotted ${colourOptions[2].color}`, + color: 'white', + background: colourOptions[2].color, + padding: '5px 0px', + display: 'flex', +}; + +const GroupHeading = (props: any) => ( +
+ + + + +
+); + +export default () => ( + + defaultValue={colourOptions[1]} + options={groupedOptions} + components={{ GroupHeading }} + styles={{ groupHeading: (base: any) => ({ ...base, flex: '1 1', color: 'white', margin: 0 }) }} + /> +); diff --git a/types/react-select/test/examples/CustomIndicatorSeparator.tsx b/types/react-select/test/examples/CustomIndicatorSeparator.tsx new file mode 100644 index 0000000000..c63d4a0f0e --- /dev/null +++ b/types/react-select/test/examples/CustomIndicatorSeparator.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import Select from 'react-select'; +import { colourOptions } from '../data'; + +const indicatorSeparatorStyle = { + alignSelf: 'stretch', + backgroundColor: colourOptions[2].color, + marginBottom: 8, + marginTop: 8, + width: 1, +}; + +const IndicatorSeparator = ({ innerProps }: any) => { + return ( + + ); +}; + +export default () => ( + +); diff --git a/types/react-select/test/examples/CustomInput.tsx b/types/react-select/test/examples/CustomInput.tsx new file mode 100644 index 0000000000..e2bd0eb7d6 --- /dev/null +++ b/types/react-select/test/examples/CustomInput.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import { Tooltip } from '../AtlaskitDummy'; +import Select, { components } from 'react-select'; +import { colourOptions } from '../data'; + +const Input = (props: any) => { + if (props.isHidden) { + return ; + } + return ( +
+ + + +
+ ); +}; + +export default () => ( + option.rating !== 'safe'} + /> +
+ ); + } +} diff --git a/types/react-select/test/examples/CustomLoadingIndicator.tsx b/types/react-select/test/examples/CustomLoadingIndicator.tsx new file mode 100644 index 0000000000..627599d52a --- /dev/null +++ b/types/react-select/test/examples/CustomLoadingIndicator.tsx @@ -0,0 +1,47 @@ +import * as React from 'react'; +import { Spinner, Tooltip } from '../AtlaskitDummy'; +import AsyncSelect from 'react-select/lib/Async'; +import { colourOptions } from '../data'; + +const LoadingIndicator = (props: any) => { + return ( + + + + ); +}; + +interface State { + inputValue: string; +} + +const filterColors = (inputValue: string) => + colourOptions.filter(i => + i.label.toLowerCase().includes(inputValue.toLowerCase()) + ); + +const promiseOptions = (inputValue: string) => + new Promise(resolve => { + setTimeout(() => { + resolve(filterColors(inputValue)); + }, 1000); + }); + +export default class CustomLoadingIndicator extends React.Component { + state = { inputValue: '' }; + handleInputChange = (newValue: string) => { + const inputValue = newValue.replace(/\W/g, ''); + this.setState({ inputValue }); + return inputValue; + } + render() { + return ( + + ); + } +} diff --git a/types/react-select/test/examples/CustomLoadingMessage.tsx b/types/react-select/test/examples/CustomLoadingMessage.tsx new file mode 100644 index 0000000000..04776ebfd6 --- /dev/null +++ b/types/react-select/test/examples/CustomLoadingMessage.tsx @@ -0,0 +1,50 @@ +import * as React from 'react'; +import { Tooltip } from '../AtlaskitDummy'; +import AsyncSelect from 'react-select/lib/Async'; +import { colourOptions } from '../data'; + +const LoadingMessage = (props: any) => { + return ( + +
+ {props.children} +
+
+ ); +}; + +interface State { + inputValue: string; +} + +const filterColors = (inputValue: string) => + colourOptions.filter(i => + i.label.toLowerCase().includes(inputValue.toLowerCase()) + ); + +const promiseOptions = (inputValue: string) => + new Promise(resolve => { + setTimeout(() => { + resolve(filterColors(inputValue)); + }, 1000); + }); + +export default class CustomLoadingIndicator extends React.Component { + state = { inputValue: '' }; + handleInputChange = (newValue: string) => { + const inputValue = newValue.replace(/\W/g, ''); + this.setState({ inputValue }); + return inputValue; + } + render() { + return ( + ({ ...base, backgroundColor: colourOptions[2].color, color: 'white' }) }} + components={{ LoadingMessage }} + /> + ); + } +} diff --git a/types/react-select/test/examples/CustomMenu.tsx b/types/react-select/test/examples/CustomMenu.tsx new file mode 100644 index 0000000000..b774a7fa1e --- /dev/null +++ b/types/react-select/test/examples/CustomMenu.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; + +import Select, { components } from 'react-select'; +import { ColourOption, colourOptions, FlavourOption, groupedOptions } from '../data'; + +function getLength(options: any) { + return options.reduce((acc: any, curr: any) => { + if (curr.options) return acc + getLength(curr.options); + return acc + 1; + }, 0); +} + +const menuHeaderStyle = { + padding: '8px 12px', +}; + +const Menu = (props: any) => { + const optionsLength = getLength(props.options); + return ( + +
+ Custom Menu with {optionsLength} options +
+ + {props.children} + +
+ ); +}; + +export default () => ( + + defaultValue={colourOptions[1]} + options={groupedOptions} + components={{ Menu }} + /> +); diff --git a/types/react-select/test/examples/CustomMenuList.tsx b/types/react-select/test/examples/CustomMenuList.tsx new file mode 100644 index 0000000000..48a3cf62f7 --- /dev/null +++ b/types/react-select/test/examples/CustomMenuList.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; + +import Select, { components } from 'react-select'; +import { ColourOption, colourOptions, FlavourOption, groupedOptions } from '../data'; + +const menuHeaderStyle = { + padding: '8px 12px', + background: colourOptions[2].color, + color: 'white', +}; + +const MenuList = (props: any) => { + return ( + +
+ Custom Menu List +
+ {props.children} +
+ ); +}; + +export default () => ( + + defaultValue={colourOptions[1]} + options={groupedOptions} + components={{ MenuList }} + /> +); diff --git a/types/react-select/test/examples/CustomMultiValueContainer.tsx b/types/react-select/test/examples/CustomMultiValueContainer.tsx new file mode 100644 index 0000000000..1b556751e1 --- /dev/null +++ b/types/react-select/test/examples/CustomMultiValueContainer.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { Tooltip } from '../AtlaskitDummy'; +import Select, { components } from 'react-select'; +import { colourOptions } from '../data'; + +const MultiValueContainer = (props: any) => { + return ( + + + + ); +}; + +export default () => ( + ({ ...base, backgroundColor: colourOptions[2].color, color: 'white' }) }} + defaultValue={[colourOptions[4], colourOptions[5]]} + isMulti + options={colourOptions} + /> +); diff --git a/types/react-select/test/examples/CustomMultiValueRemove.tsx b/types/react-select/test/examples/CustomMultiValueRemove.tsx new file mode 100644 index 0000000000..81dfaf35e9 --- /dev/null +++ b/types/react-select/test/examples/CustomMultiValueRemove.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { EmojiIcon, Tooltip } from '../AtlaskitDummy'; +import Select, { components } from 'react-select'; +import { colourOptions } from '../data'; + +const MultiValueRemove = (props: any) => { + return ( + + + + + + ); +}; + +export default () => ( + ({ ...base, ...msgStyles }) }} + isSearchable + name="color" + options={[]} + /> + ); + } +} diff --git a/types/react-select/test/examples/CustomOption.tsx b/types/react-select/test/examples/CustomOption.tsx new file mode 100644 index 0000000000..aa115e78bf --- /dev/null +++ b/types/react-select/test/examples/CustomOption.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import { Tooltip } from '../AtlaskitDummy'; +import Select, { components } from 'react-select'; +import { colourOptions } from '../data'; + +const Option = (props: any) => { + return ( + + + + ); +}; + +export default () => ( + ({ ...base, fontSize: '1em', color: colourOptions[2].color, fontWeight: 400 }) }} + options={colourOptions} + /> +); diff --git a/types/react-select/test/examples/CustomSelectContainer.tsx b/types/react-select/test/examples/CustomSelectContainer.tsx new file mode 100644 index 0000000000..393b8d1dd8 --- /dev/null +++ b/types/react-select/test/examples/CustomSelectContainer.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import Select, { components } from 'react-select'; +import { Tooltip } from '../AtlaskitDummy'; +import { colourOptions } from '../data'; + +const SelectContainer = ({ children, ...props }: any) => { + return ( + + + {children} + + + ); +}; + +export default () => ( + ({ ...base, padding: 5, borderRadius: 5, background: colourOptions[2].color, color: 'white', display: 'flex' }) }} + components={{ SingleValue }} + isSearchable + name="color" + options={colourOptions} + /> + ); + } +} diff --git a/types/react-select/test/examples/CustomValueContainer.tsx b/types/react-select/test/examples/CustomValueContainer.tsx new file mode 100644 index 0000000000..31d18ef50b --- /dev/null +++ b/types/react-select/test/examples/CustomValueContainer.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import Select, { components } from 'react-select'; +import { colourOptions } from '../data'; + +const ValueContainer = ({ children, ...props }: any) => ( + + {children} + +); + +export default class CustomControl extends React.Component { + render() { + return ( + v.some(i => i.date.isSame(o.date, 'day'))} + maxMenuHeight={380} + onChange={this.props.onChange} + onInputChange={this.handleInputChange} + options={options} + value={value} + /> + ); + } +} + +export default class Experimental extends React.Component { + state = { + value: defaultOptions[0], + }; + handleChange = (value: any) => { + this.setState({ value }); + } + render() { + const { value } = this.state; + const displayValue = value && value.value ? value.value.toString() : 'null'; + return ( +
+
Value: {displayValue}
+ +
+ ); + } +} diff --git a/types/react-select/test/examples/MenuPortal.tsx b/types/react-select/test/examples/MenuPortal.tsx new file mode 100644 index 0000000000..32590acfb1 --- /dev/null +++ b/types/react-select/test/examples/MenuPortal.tsx @@ -0,0 +1,91 @@ +import * as React from 'react'; +import { Modal, Button } from '../AtlaskitDummy'; +import Select from 'react-select'; +import { H1, Note } from '../styled-components'; + +import { colourOptions } from '../data'; + +interface State { + isOpen: boolean; + isFixed: boolean; + portalPlacement: 'auto' | 'bottom' | 'top'; +} + +export default class MenuPortal extends React.Component { + state: State = { + isOpen: false, + isFixed: false, + portalPlacement: 'bottom', + }; + open = () => { + console.log('menuPortal is Open'); + this.setState({ isOpen: true }); + } + close = () => { this.setState({ isOpen: false }); }; + setPlacement = ({ currentTarget }: any) => { + const portalPlacement = currentTarget && currentTarget.value; + this.setState({ portalPlacement }); + } + toggleMode = () => { + this.setState(state => ({ isFixed: !state.isFixed })); + } + render() { + const { close, open } = this; + const { isOpen, isFixed, portalPlacement } = this.state; + return ( + + + { + isOpen ? + +

Portaled Menu Element

+ + + + + + + + + Fixed + + + + Portal + +
+ : null + } +
+ ); + } +} diff --git a/types/react-select/test/examples/OnSelectResetsInput.tsx b/types/react-select/test/examples/OnSelectResetsInput.tsx new file mode 100644 index 0000000000..af1327b1bb --- /dev/null +++ b/types/react-select/test/examples/OnSelectResetsInput.tsx @@ -0,0 +1,47 @@ +import * as React from 'react'; +import Select from 'react-select'; +import { colourOptions } from '../data'; +import { InputActionMeta } from 'react-select/lib/types'; + +export default class OnSelectResetsInput extends React.Component { + state = { + inputValue: '', + menuIsOpen: undefined + }; + onInputChange = (inputValue: string, { action }: InputActionMeta) => { + console.log(inputValue, action); + switch (action) { + case 'input-change': + this.setState({ inputValue }); + return; + case 'menu-close': + console.log(this.state.inputValue); + let menuIsOpen; + if (this.state.inputValue) { + menuIsOpen = true; + } + this.setState({ + menuIsOpen + }); + return; + default: + return; + } + } + render() { + const { inputValue, menuIsOpen } = this.state; + return ( + + + ); + } +} + +// styled components + +const Menu = (props: any) => { + const shadow = colors.neutral10a; + return ( +
+ ); +}; +const Blanket = (props: any) => ( +
+); +const Dropdown = ({ children, isOpen, target, onClose }: any) => ( +
// TODO css type + {target} + {isOpen ? {children} : null} + {isOpen ? : null} +
+); +const Svg = (p: any) => ( + +); +const DropdownIndicator = () => ( +
// TODO css type + + + +
+); +const ChevronDown = () => ( + + + +); diff --git a/types/react-select/test/examples/StyledMulti.tsx b/types/react-select/test/examples/StyledMulti.tsx new file mode 100644 index 0000000000..a4dedb4156 --- /dev/null +++ b/types/react-select/test/examples/StyledMulti.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; +import * as chroma from 'chroma-js'; + +import { colourOptions } from '../data'; +import Select from 'react-select'; + +const colourStyles = { + control: (styles: any) => ({ ...styles, backgroundColor: 'white' }), + option: (styles: any, { data, isDisabled, isFocused, isSelected }: any) => { + const color = chroma(data.color); + return { + ...styles, + backgroundColor: isDisabled + ? null + : isSelected ? data.color : isFocused ? color.alpha(0.1).css() : null, + color: isDisabled + ? '#ccc' + : isSelected + ? chroma.contrast(color, 'white') > 2 ? 'white' : 'black' + : data.color, + cursor: isDisabled ? 'not-allowed' : 'default', + }; + }, + multiValue: (styles: any, { data }: any) => { + const color = chroma(data.color); + return { + ...styles, + backgroundColor: color.alpha(0.1).css(), + }; + }, + multiValueLabel: (styles: any, { data }: any) => ({ + ...styles, + color: data.color, + }), + multiValueRemove: (styles: any, { data }: any) => ({ + ...styles, + color: data.color, + ':hover': { + backgroundColor: data.color, + color: 'white', + }, + }), +}; + +export default () => ( + +); diff --git a/types/react-select/test/styled-components.tsx b/types/react-select/test/styled-components.tsx new file mode 100644 index 0000000000..fa18465cd8 --- /dev/null +++ b/types/react-select/test/styled-components.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; + +export const Note = ({ Tag = 'div', ...props }: any) => ( + +); + +export const H1 = (props: any) =>

; +export const H2 = (props: any) =>

; diff --git a/types/react-select/tsconfig.json b/types/react-select/tsconfig.json index 7855eceaf1..8c7a1921bd 100644 --- a/types/react-select/tsconfig.json +++ b/types/react-select/tsconfig.json @@ -1,10 +1,4 @@ { - "files": [ - "index.d.ts", - "lib/Option/index.d.ts", - "lib/utils/defaultMenuRenderer/index.d.ts", - "react-select-tests.tsx" - ], "compilerOptions": { "module": "commonjs", "lib": [ @@ -12,16 +6,99 @@ "dom" ], "noImplicitAny": true, - "noImplicitThis": false, - "strictNullChecks": false, + "noImplicitThis": true, + "strictNullChecks": true, "strictFunctionTypes": true, "baseUrl": "../", - "jsx": "react", "typeRoots": [ "../" ], + "jsx": "react", "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true - } + }, + "files": [ + "index.d.ts", + "lib/animated/Input.d.ts", + "lib/animated/MultiValue.d.ts", + "lib/animated/Placeholder.d.ts", + "lib/animated/SingleValue.d.ts", + "lib/animated/ValueContainer.d.ts", + "lib/animated/transitions.d.ts", + "lib/animated/index.d.ts", + "lib/components/containers.d.ts", + "lib/components/Control.d.ts", + "lib/components/Group.d.ts", + "lib/components/Input.d.ts", + "lib/components/Menu.d.ts", + "lib/components/MultiValue.d.ts", + "lib/components/Option.d.ts", + "lib/components/Placeholder.d.ts", + "lib/components/SingleValue.d.ts", + "lib/components/indicators.d.ts", + "lib/components/index.d.ts", + "lib/accessibility/index.d.ts", + "lib/theme.d.ts", + "lib/Creatable.d.ts", + "lib/Async.d.ts", + "lib/AsyncCreatable.d.ts", + "lib/filters.d.ts", + "lib/styles.d.ts", + "lib/stateManager.d.ts", + "lib/builtins.d.ts", + "lib/utils.d.ts", + "lib/diacritics.d.ts", + "lib/types.d.ts", + "lib/Select.d.ts", + "test/data.ts", + "test/styled-components.tsx", + "test/AtlaskitDummy.ts", + "test/ChronoNodeDummy.ts", + "test/examples/AccessingInternals.tsx", + "test/examples/AnimatedMulti.tsx", + "test/examples/AsyncCallbacks.tsx", + "test/examples/AsyncCreatable.tsx", + "test/examples/AsyncMulti.tsx", + "test/examples/AsyncPromises.tsx", + "test/examples/BasicGrouped.tsx", + "test/examples/BasicMulti.tsx", + "test/examples/BasicSingle.tsx", + "test/examples/ControlledMenu.tsx", + "test/examples/CreatableAdvanced.tsx", + "test/examples/CreatableInputOnly.tsx", + "test/examples/CreatableMulti.tsx", + "test/examples/CreatableSingle.tsx", + "test/examples/CreateFilter.tsx", + "test/examples/CustomClearIndicator.tsx", + "test/examples/CustomControl.tsx", + "test/examples/CustomDropdownIndicator.tsx", + "test/examples/CustomFilterOptions.tsx", + "test/examples/CustomGetOptionLabel.tsx", + "test/examples/CustomGroup.tsx", + "test/examples/CustomGroupHeading.tsx", + "test/examples/CustomIndicatorsContainer.tsx", + "test/examples/CustomIndicatorSeparator.tsx", + "test/examples/CustomInput.tsx", + "test/examples/CustomIsOptionDisabled.tsx", + "test/examples/CustomLoadingIndicator.tsx", + "test/examples/CustomLoadingMessage.tsx", + "test/examples/CustomMenu.tsx", + "test/examples/CustomMenuList.tsx", + "test/examples/CustomMultiValueContainer.tsx", + "test/examples/CustomMultiValueLabel.tsx", + "test/examples/CustomMultiValueRemove.tsx", + "test/examples/CustomNoOptionsMessage.tsx", + "test/examples/CustomOption.tsx", + "test/examples/CustomPlaceholder.tsx", + "test/examples/CustomSelectContainer.tsx", + "test/examples/CustomSingleValue.tsx", + "test/examples/CustomValueContainer.tsx", + "test/examples/Experimental.tsx", + "test/examples/MenuPortal.tsx", + "test/examples/OnSelectResetsInput.tsx", + "test/examples/Popout.tsx", + "test/examples/StyledMulti.tsx", + "test/examples/StyledSingle.tsx" + ] } diff --git a/types/react-select/tslint.json b/types/react-select/tslint.json index 3db14f85ea..f93cf8562a 100644 --- a/types/react-select/tslint.json +++ b/types/react-select/tslint.json @@ -1 +1,3 @@ -{ "extends": "dtslint/dt.json" } +{ + "extends": "dtslint/dt.json" +} diff --git a/types/react-select/v1/index.d.ts b/types/react-select/v1/index.d.ts new file mode 100644 index 0000000000..31ff0db561 --- /dev/null +++ b/types/react-select/v1/index.d.ts @@ -0,0 +1,654 @@ +// Type definitions for react-select 1.3 +// Project: https://github.com/JedWatson/react-select +// Definitions by: ESQUIBET Hugo +// Gilad Gray +// Izaak Baker +// Tadas Dailyda +// Mark Vujevits +// Mike Deverell +// MartynasZilinskas +// Onat Yigit Mercan +// Ian Johnson +// Anton Novik +// David Schkalee +// Arthur Udalov +// Sebastian Silbermann +// Endurance Idehen +// Guillaume Chartier +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.6 + +import * as React from 'react'; + +export default class ReactSelectClass extends React.Component> { + focus(): void; + setValue(value: Option): void; +} +// Other components +export class Creatable extends React.Component> { } +export class Async extends React.Component> { } +export class AsyncCreatable extends React.Component> { } + +export type OptionComponentType = React.ComponentType>; +export type ValueComponentType = React.ComponentType>; + +export type HandlerRendererResult = JSX.Element | null | false; + +// Handlers +export type FocusOptionHandler = (option: Option) => void; +export type SelectValueHandler = (option: Option) => void; +export type ArrowRendererHandler = (props: ArrowRendererProps) => HandlerRendererResult; +export type ClearRendererHandler = () => HandlerRendererResult; +export type FilterOptionHandler = (option: Option, filter: string) => boolean; +export type FilterOptionsHandler = (options: Options, filter: string, currentValues: Options) => Options; +export type InputRendererHandler = (props: { [key: string]: any }) => HandlerRendererResult; +export type MenuRendererHandler = (props: MenuRendererProps) => HandlerRendererResult; +export type OnCloseHandler = () => void; +export type OnInputChangeHandler = (inputValue: string) => string; +export type OnInputKeyDownHandler = React.KeyboardEventHandler; +export type OnMenuScrollToBottomHandler = () => void; +export type OnOpenHandler = () => void; +export type OnFocusHandler = React.FocusEventHandler; +export type OnBlurHandler = React.FocusEventHandler; +export type OptionRendererHandler = (option: Option) => HandlerRendererResult; +export type ValueRendererHandler = (option: Option, index?: number) => HandlerRendererResult; +export type OnValueClickHandler = (option: Option, event: React.MouseEvent) => void; +export type IsOptionUniqueHandler = (arg: { option: Option, options: Options, labelKey: string, valueKey: string }) => boolean; +export type IsValidNewOptionHandler = (arg: { label: string }) => boolean; +export type NewOptionCreatorHandler = (arg: { label: string, labelKey: string, valueKey: string }) => Option; +export type PromptTextCreatorHandler = (filterText: string) => string; +export type ShouldKeyDownEventCreateNewOptionHandler = (arg: { keyCode: number }) => boolean; + +export type OnChangeSingleHandler = OnChangeHandler>; +export type OnChangeMultipleHandler = OnChangeHandler>; +export type OnChangeHandler | Options> = (newValue: TOption | null) => void; +export type OnNewOptionClickHandler = (option: Option) => void; + +export type LoadOptionsHandler = LoadOptionsAsyncHandler | LoadOptionsLegacyHandler; +export type LoadOptionsAsyncHandler = (input: string) => Promise>; +export type LoadOptionsLegacyHandler = (input: string, callback: (err: any, result: AutocompleteResult) => void) => void; + +export interface AutocompleteResult { + /** The search-results to be displayed */ + options: Options; + /** + * Should be set to true, if and only if a longer query with the same prefix + * would return a subset of the results + * If set to true, more specific queries will not be sent to the server. + */ + complete: boolean; +} + +export type Options = Array>; + +export interface Option { + /** Text for rendering */ + label?: string; + /** Value for searching */ + value?: TValue; + /** + * Allow this option to be cleared + * @default true + */ + clearableValue?: boolean; + /** + * Do not allow this option to be selected + * @default false + */ + disabled?: boolean; + /** + * In the event that a custom menuRenderer is provided, Option should be able + * to accept arbitrary key-value pairs. See react-virtualized-select. + */ + [property: string]: any; +} + +export type OptionValues = string | number | boolean; + +export interface MenuRendererProps { + /** + * The currently focused option; should be visible in the menu by default. + * default {} + */ + focusedOption: Option; + + /** + * Callback to focus a new option; receives the option as a parameter. + */ + focusOption: FocusOptionHandler; + + /** + * Option labels are accessible with this string key. + */ + labelKey: string; + + /** + * Ordered array of options to render. + */ + options: Options; + + /** + * Callback to select a new option; receives the option as a parameter. + */ + selectValue: SelectValueHandler; + + /** + * Array of currently selected options. + */ + valueArray: Options; + + /** + * Callback to remove selection from option; receives the option as a parameter. + */ + removeValue: SelectValueHandler; + + /** + * function which returns a custom way to render the options in the menu + */ + optionRenderer: OptionRendererHandler; +} + +export interface OptionComponentProps { + /** + * Classname(s) to apply to the option component. + */ + className?: string; + + /** + * Currently focused option. + */ + focusOption?: Option; + + inputValue?: string; + instancePrefix?: string; + + /** + * True if this option is disabled. + */ + isDisabled?: boolean; + + /** + * True if this option is focused. + */ + isFocused?: boolean; + + /** + * True if this option is selected. + */ + isSelected?: boolean; + + /** + * Callback to be invoked when this option is focused. + */ + onFocus?: (option: Option, event: any) => void; + + /** + * Callback to be invoked when this option is selected. + */ + onSelect?: (option: Option, event: any) => void; + + /** + * Option to be rendered by this component. + */ + option: Option; + + /** + * Index of the option being rendered in the list + */ + optionIndex?: number; + + /** + * Callback to invoke when removing an option from a multi-selection. (Not necessarily the one + * being rendered) + */ + removeValue?: (value: TValue | TValue[]) => void; + + /** + * Callback to invoke to select an option. (Not necessarily the one being rendered) + */ + selectValue?: (value: TValue | TValue[]) => void; +} + +export interface ArrowRendererProps { + /** + * Arrow mouse down event handler. + */ + onMouseDown: React.MouseEventHandler; + + /** + * whether the Select is open or not. + */ + isOpen: boolean; +} + +export interface ValueComponentProps { + disabled: ReactSelectProps['disabled']; + id: string; + instancePrefix: string; + onClick: OnValueClickHandler | null; + onRemove?: SelectValueHandler; + placeholder: ReactSelectProps['placeholder']; + value: Option; + values?: Array>; +} + +export interface ReactSelectProps extends React.Props> { + /** + * text to display when `allowCreate` is true. + * @default 'Add "{label}"?' + */ + addLabelText?: string; + /** + * renders a custom drop-down arrow to be shown in the right-hand side of the select. + * @default undefined + */ + arrowRenderer?: ArrowRendererHandler | null; + /** + * blurs the input element after a selection has been made. Handy for lowering the keyboard on mobile devices. + * @default false + */ + autoBlur?: boolean; + /** + * autofocus the component on mount + * @deprecated. Use autoFocus instead + * @default false + */ + autofocus?: boolean; + /** + * autofocus the component on mount + * @default false + */ + autoFocus?: boolean; + /** + * If enabled, the input will expand as the length of its value increases + */ + autosize?: boolean; + /** + * whether pressing backspace removes the last item when there is no input value + * @default true + */ + backspaceRemoves?: boolean; + /** + * Message to use for screenreaders to press backspace to remove the current item + * {label} is replaced with the item label + * @default "Press backspace to remove..." + */ + backspaceToRemoveMessage?: string; + /** + * CSS className for the outer element + */ + className?: string; + /** + * Prefix prepended to element default className if no className is defined + */ + classNamePrefix?: string; + /** + * title for the "clear" control when `multi` is true + * @default "Clear all" + */ + clearAllText?: string; + /** + * Renders a custom clear to be shown in the right-hand side of the select when clearable true + * @default undefined + */ + clearRenderer?: ClearRendererHandler; + /** + * title for the "clear" control + * @default "Clear value" + */ + clearValueText?: string; + /** + * whether to close the menu when a value is selected + * @default true + */ + closeOnSelect?: boolean; + /** + * whether it is possible to reset value. if enabled, an X button will appear at the right side. + * @default true + */ + clearable?: boolean; + /** + * whether backspace removes an item if there is no text input + * @default true + */ + deleteRemoves?: boolean; + /** + * delimiter to use to join multiple values + * @default "," + */ + delimiter?: string; + /** + * whether the Select is disabled or not + * @default false + */ + disabled?: boolean; + /** + * whether escape clears the value when the menu is closed + * @default true + */ + escapeClearsValue?: boolean; + /** + * method to filter a single option + */ + filterOption?: FilterOptionHandler; + /** + * method to filter the options array + */ + filterOptions?: FilterOptionsHandler; + /** + * id for the underlying HTML input element + * @default undefined + */ + id?: string; + /** + * whether to strip diacritics when filtering + * @default true + */ + ignoreAccents?: boolean; + /** + * whether to perform case-insensitive filtering + * @default true + */ + ignoreCase?: boolean; + /** + * custom attributes for the Input (in the Select-control) e.g: {'data-foo': 'bar'} + * @default {} + */ + inputProps?: { [key: string]: any }; + /** + * renders a custom input + */ + inputRenderer?: InputRendererHandler; + /** + * allows for synchronization of component id's on server and client. + * @see https://github.com/JedWatson/react-select/pull/1105 + */ + instanceId?: string; + /** + * whether the Select is loading externally or not (such as options being loaded). + * if true, a loading spinner will be shown at the right side. + * @default false + */ + isLoading?: boolean; + /** + * (legacy mode) joins multiple values into a single form field with the delimiter + * @default false + */ + joinValues?: boolean; + /** + * the option property to use for the label + * @default "label" + */ + labelKey?: string; + /** + * (any, start) match the start or entire string when filtering + * @default "any" + */ + matchPos?: string; + /** + * (any, label, value) which option property to filter on + * @default "any" + */ + matchProp?: string; + /** + * buffer of px between the base of the dropdown and the viewport to shift if menu doesnt fit in viewport + * @default 0 + */ + menuBuffer?: number; + /** + * optional style to apply to the menu container + */ + menuContainerStyle?: React.CSSProperties; + /** + * renders a custom menu with options + */ + menuRenderer?: MenuRendererHandler; + /** + * optional style to apply to the menu + */ + menuStyle?: React.CSSProperties; + /** + * multi-value input + * @default false + */ + multi?: boolean; + /** + * field name, for hidden `` tag + */ + name?: string; + /** + * placeholder displayed when there are no matching search results or a falsy value to hide it + * @default "No results found" + */ + noResultsText?: string | JSX.Element; + /** + * onBlur handler: function (event) {} + */ + onBlur?: OnBlurHandler; + /** + * whether to clear input on blur or not + * @default true + */ + onBlurResetsInput?: boolean; + /** + * whether the input value should be reset when options are selected. + * Also input value will be set to empty if 'onSelectResetsInput=true' and + * Select will get new value that not equal previous value. + * @default true + */ + onSelectResetsInput?: boolean; + /** + * whether to clear input when closing the menu through the arrow + * @default true + */ + onCloseResetsInput?: boolean; + /** + * onChange handler: function (newValue) {} + */ + onChange?: OnChangeHandler; + /** + * fires when the menu is closed + */ + onClose?: OnCloseHandler; + /** + * onFocus handler: function (event) {} + */ + onFocus?: OnFocusHandler; + /** + * onInputChange handler: function (inputValue) {} + */ + onInputChange?: OnInputChangeHandler; + /** + * onInputKeyDown handler: function (keyboardEvent) {} + */ + onInputKeyDown?: OnInputKeyDownHandler; + /** + * fires when the menu is scrolled to the bottom; can be used to paginate options + */ + onMenuScrollToBottom?: OnMenuScrollToBottomHandler; + /** + * fires when the menu is opened + */ + onOpen?: OnOpenHandler; + /** + * boolean to enable opening dropdown when focused + * @default false + */ + openOnClick?: boolean; + /** + * open the options menu when the input gets focus (requires searchable = true) + * @default true + */ + openOnFocus?: boolean; + /** + * className to add to each option component + */ + optionClassName?: string; + /** + * option component to render in dropdown + */ + optionComponent?: OptionComponentType; + /** + * function which returns a custom way to render the options in the menu + */ + optionRenderer?: OptionRendererHandler; + /** + * array of Select options + * @default false + */ + options?: Options; + /** + * number of options to jump when using page up/down keys + * @default 5 + */ + pageSize?: number; + /** + * field placeholder, displayed when there's no value + * @default "Select..." + */ + placeholder?: string | JSX.Element; + /** + * whether the selected option is removed from the dropdown on multi selects + * @default true + */ + removeSelected?: boolean; + /** + * applies HTML5 required attribute when needed + * @default false + */ + required?: boolean; + /** + * value to use when you clear the control + */ + resetValue?: any; + /** + * use react-select in right-to-left direction + * @default false + */ + rtl?: boolean; + /** + * whether the viewport will shift to display the entire menu when engaged + * @default true + */ + scrollMenuIntoView?: boolean; + /** + * whether to enable searching feature or not + * @default true; + */ + searchable?: boolean; + /** + * whether to select the currently focused value when the [tab] key is pressed + */ + tabSelectsValue?: boolean; + /** + * initial field value + */ + value?: Option | Options | string | string[] | number | number[] | boolean; + /** + * the option property to use for the value + * @default "value" + */ + valueKey?: string; + /** + * function which returns a custom way to render the value selected + * @default false + */ + valueRenderer?: ValueRendererHandler; + /** + * optional style to apply to the control + */ + style?: React.CSSProperties; + + /** + * optional tab index of the control + */ + tabIndex?: string | number; + + /** + * value component to render + */ + valueComponent?: ValueComponentType; + + /** + * optional style to apply to the component wrapper + */ + wrapperStyle?: React.CSSProperties; + + /** + * onClick handler for value labels: function (value, event) {} + */ + onValueClick?: OnValueClickHandler; + + /** + * pass the value to onChange as a simple value (legacy pre 1.0 mode), defaults to false + */ + simpleValue?: boolean; +} + +export interface ReactCreatableSelectProps extends ReactSelectProps { + /** + * Searches for any matching option within the set of options. This function prevents + * duplicate options from being created. + */ + isOptionUnique?: IsOptionUniqueHandler; + + /** + * Determines if the current input text represents a valid option. + */ + isValidNewOption?: IsValidNewOptionHandler; + + /** + * factory to create new options + */ + newOptionCreator?: NewOptionCreatorHandler; + + /** + * Creates prompt/placeholder for option text. + */ + promptTextCreator?: PromptTextCreatorHandler; + + /** + * Decides if a keyDown event (eg its 'keyCode') should result in the creation of a new option. + */ + shouldKeyDownEventCreateNewOption?: ShouldKeyDownEventCreateNewOptionHandler; + + /** + * new option click handler: function (option) {} + */ + onNewOptionClick?: OnNewOptionClickHandler; + + /** + * true: Show new option at top of list + * false: Show new option at bottom of list + * @default true + */ + showNewOptionAtTop?: boolean; +} + +export interface ReactAsyncSelectProps extends ReactSelectProps { + /** + * Whether to auto-load the default async options set. + */ + autoload?: boolean; + + /** + * object to use to cache results; can be null to disable cache + */ + cache?: { [key: string]: any } | boolean; + + /** + * function to call to load options asynchronously + */ + loadOptions: LoadOptionsHandler; + + /** + * replaces the placeholder while options are loading + */ + loadingPlaceholder?: string | JSX.Element; + /** + * displayed in the drop down list when the user did not type anything yet + */ + searchPromptText?: string; +} + +export type ReactAsyncCreatableSelectProps = ReactAsyncSelectProps & ReactCreatableSelectProps; diff --git a/types/react-select/lib/Option/index.d.ts b/types/react-select/v1/lib/Option/index.d.ts similarity index 100% rename from types/react-select/lib/Option/index.d.ts rename to types/react-select/v1/lib/Option/index.d.ts diff --git a/types/react-select/lib/utils/defaultMenuRenderer/index.d.ts b/types/react-select/v1/lib/utils/defaultMenuRenderer/index.d.ts similarity index 100% rename from types/react-select/lib/utils/defaultMenuRenderer/index.d.ts rename to types/react-select/v1/lib/utils/defaultMenuRenderer/index.d.ts diff --git a/types/react-select/react-select-tests.tsx b/types/react-select/v1/react-select-tests.tsx similarity index 100% rename from types/react-select/react-select-tests.tsx rename to types/react-select/v1/react-select-tests.tsx diff --git a/types/react-select/v1/tsconfig.json b/types/react-select/v1/tsconfig.json new file mode 100644 index 0000000000..e01d55ae8a --- /dev/null +++ b/types/react-select/v1/tsconfig.json @@ -0,0 +1,35 @@ +{ + "files": [ + "index.d.ts", + "lib/Option/index.d.ts", + "lib/utils/defaultMenuRenderer/index.d.ts", + "react-select-tests.tsx" + ], + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": false, + "strictNullChecks": false, + "strictFunctionTypes": true, + "baseUrl": "../../", + "jsx": "react", + "typeRoots": [ + "../../" + ], + "paths": { + "react-select": [ + "react-select/v1" + ], + "react-select/*": [ + "react-select/v1/*" + ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + } +} diff --git a/types/react-select/v1/tslint.json b/types/react-select/v1/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/react-select/v1/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/react-virtualized-select/tsconfig.json b/types/react-virtualized-select/tsconfig.json index b544360da3..42387bc3e0 100644 --- a/types/react-virtualized-select/tsconfig.json +++ b/types/react-virtualized-select/tsconfig.json @@ -10,11 +10,18 @@ "noImplicitThis": true, "strictFunctionTypes": true, "strictNullChecks": true, - "strictFunctionTypes": true, "baseUrl": "../", "typeRoots": [ "../" ], + "paths": { + "react-select": [ + "react-select/v1" + ], + "react-select/*": [ + "react-select/v1/*" + ] + }, "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true