diff --git a/docs/pages/api/autocomplete.md b/docs/pages/api/autocomplete.md index d244b1094203d4..a56335724980d0 100644 --- a/docs/pages/api/autocomplete.md +++ b/docs/pages/api/autocomplete.md @@ -35,7 +35,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi | closeIcon | node | <CloseIcon fontSize="small" /> | The icon to display in place of the default close icon. | | closeText | string | 'Close' | Override the default text for the *close popup* icon button.
For localization purposes, you can use the provided [translations](/guides/localization/). | | debug | bool | false | If `true`, the popup will ignore the blur event if the input if filled. You can inspect the popup markup with your browser tools. Consider this option when you need to customize the component. | -| defaultValue | any | | The default input value. Use when the component is not controlled. | +| defaultValue | any
| array
| | The default input value. Use when the component is not controlled. | | disableClearable | bool | false | If `true`, the input can't be cleared. | | disableCloseOnSelect | bool | false | If `true`, the popup won't close when a value is selected. | | disabled | bool | false | If `true`, the input will be disabled. | @@ -49,7 +49,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi | getOptionDisabled | func | | Used to determine the disabled state for a given option. | | getOptionLabel | func | x => x | Used to determine the string value for a given option. It's used to fill the input (and the list box options if `renderOption` is not provided). | | getOptionSelected | func | | Used to determine if an option is selected. Uses strict equality by default. | -| groupBy | func | | If provided, the options will be grouped under the returned string. The groupBy value is also used as the text for group headings when `renderGroup` is not provided.

**Signature:**
`function(options: any) => string`
*options:* The option to group. | +| groupBy | func | | If provided, the options will be grouped under the returned string. The groupBy value is also used as the text for group headings when `renderGroup` is not provided.

**Signature:**
`function(options: T) => string`
*options:* The option to group. | | id | string | | This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id. | | includeInputInList | bool | false | If `true`, the highlight can move to the input. | | inputValue | string | | The input value. | @@ -59,7 +59,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi | loadingText | node | 'Loading…' | Text to display when in a loading state.
For localization purposes, you can use the provided [translations](/guides/localization/). | | multiple | bool | false | If `true`, `value` must be an array and the menu will support multiple selections. | | noOptionsText | node | 'No options' | Text to display when there are no options.
For localization purposes, you can use the provided [translations](/guides/localization/). | -| onChange | func | | Callback fired when the value changes.

**Signature:**
`function(event: object, value: any) => void`
*event:* The event source of the callback.
*value:* null | +| onChange | func | | Callback fired when the value changes.

**Signature:**
`function(event: object, value: T) => void`
*event:* The event source of the callback.
*value:* null | | onClose | func | | Callback fired when the popup requests to be closed. Use in controlled mode (see open).

**Signature:**
`function(event: object) => void`
*event:* The event source of the callback. | | onInputChange | func | | Callback fired when the input value changes.

**Signature:**
`function(event: object, value: string, reason: string) => void`
*event:* The event source of the callback.
*value:* The new value of the text input.
*reason:* Can be: "input" (user input), "reset" (programmatic change), `"clear"`. | | onOpen | func | | Callback fired when the popup requests to be opened. Use in controlled mode (see open).

**Signature:**
`function(event: object) => void`
*event:* The event source of the callback. | @@ -71,10 +71,10 @@ You can learn more about the difference by [reading this guide](/guides/minimizi | popupIcon | node | <ArrowDropDownIcon /> | The icon to display in place of the default popup icon. | | renderGroup | func | | Render the group.

**Signature:**
`function(option: any) => ReactNode`
*option:* The group to render. | | renderInput * | func | | Render the input.

**Signature:**
`function(params: object) => ReactNode`
*params:* null | -| renderOption | func | | Render the option, use `getOptionLabel` by default.

**Signature:**
`function(option: any, state: object) => ReactNode`
*option:* The option to render.
*state:* The state of the component. | -| renderTags | func | | Render the selected value.

**Signature:**
`function(value: any, getTagProps: function) => ReactNode`
*value:* The `value` provided to the component.
*getTagProps:* A tag props getter. | +| renderOption | func | | Render the option, use `getOptionLabel` by default.

**Signature:**
`function(option: T, state: object) => ReactNode`
*option:* The option to render.
*state:* The state of the component. | +| renderTags | func | | Render the selected value.

**Signature:**
`function(value: undefined, getTagProps: function) => ReactNode`
*value:* The `value` provided to the component.
*getTagProps:* A tag props getter. | | size | 'medium'
| 'small'
| 'medium' | The size of the autocomplete. | -| value | any | | The value of the autocomplete.
The value must have reference equality with the option in order to be selected. You can customize the equality behavior with the `getOptionSelected` prop. | +| value | any
| array
| | The value of the autocomplete.
The value must have reference equality with the option in order to be selected. You can customize the equality behavior with the `getOptionSelected` prop. | The `ref` is forwarded to the root element. diff --git a/docs/pages/api/bottom-navigation.md b/docs/pages/api/bottom-navigation.md index fc12d88092764b..9b5d34583411a2 100644 --- a/docs/pages/api/bottom-navigation.md +++ b/docs/pages/api/bottom-navigation.md @@ -27,7 +27,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi | children | node | | The content of the component. | | classes | object | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | | component | elementType | 'div' | The component used for the root node. Either a string to use a DOM element or a component. | -| onChange | func | | Callback fired when the value changes.

**Signature:**
`function(event: object, value: any) => void`
*event:* The event source of the callback
*value:* We default to the index of the child | +| onChange | func | | Callback fired when the value changes.

**Signature:**
`function(event: object, value: any) => void`
*event:* The event source of the callback.
*value:* We default to the index of the child. | | showLabels | bool | false | If `true`, all `BottomNavigationAction`s will show their labels. By default, only the selected `BottomNavigationAction` will show its label. | | value | any | | The value of the currently selected `BottomNavigationAction`. | diff --git a/docs/pages/api/tree-view.md b/docs/pages/api/tree-view.md index e5edac0ec42cd5..056f48ce199866 100644 --- a/docs/pages/api/tree-view.md +++ b/docs/pages/api/tree-view.md @@ -32,7 +32,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi | defaultExpandIcon | node | | The default icon used to expand the node. | | defaultParentIcon | node | | The default icon displayed next to a parent node. This is applied to all parent nodes and can be overridden by the TreeItem `icon` prop. | | expanded | Array<string> | | Expanded node ids. (Controlled) | -| onNodeToggle | func | | Callback fired when tree items are expanded/collapsed.

**Signature:**
`function(event: object, nodeIds: array) => void`
*event:* The event source of the callback
*nodeIds:* The ids of the expanded nodes. | +| onNodeToggle | func | | Callback fired when tree items are expanded/collapsed.

**Signature:**
`function(event: object, nodeIds: array) => void`
*event:* The event source of the callback.
*nodeIds:* The ids of the expanded nodes. | The `ref` is forwarded to the root element. diff --git a/docs/src/pages/components/autocomplete/CheckboxesTags.tsx b/docs/src/pages/components/autocomplete/CheckboxesTags.tsx index b70923c9c7b5d9..81f00eb8c8e78a 100644 --- a/docs/src/pages/components/autocomplete/CheckboxesTags.tsx +++ b/docs/src/pages/components/autocomplete/CheckboxesTags.tsx @@ -17,8 +17,8 @@ export default function CheckboxesTags() { id="checkboxes-tags-demo" options={top100Films} disableCloseOnSelect - getOptionLabel={(option: FilmOptionType) => option.title} - renderOption={(option: FilmOptionType, { selected }) => ( + getOptionLabel={option => option.title} + renderOption={(option, { selected }) => ( option.title} + getOptionLabel={option => option.title} style={{ width: 300 }} renderInput={params => ( @@ -17,11 +17,6 @@ export default function ComboBox() { ); } -interface FilmOptionType { - title: string; - year: number; -} - // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top const top100Films = [ { title: 'The Shawshank Redemption', year: 1994 }, diff --git a/docs/src/pages/components/autocomplete/CountrySelect.tsx b/docs/src/pages/components/autocomplete/CountrySelect.tsx index aa3401e34b1626..f028dc5c725ab7 100644 --- a/docs/src/pages/components/autocomplete/CountrySelect.tsx +++ b/docs/src/pages/components/autocomplete/CountrySelect.tsx @@ -29,13 +29,13 @@ export default function CountrySelect() { option.label} - renderOption={(option: CountryType) => ( + getOptionLabel={option => option.label} + renderOption={option => ( {countryToFlag(option.code)} {option.label} ({option.code}) +{option.phone} diff --git a/docs/src/pages/components/autocomplete/DisabledOptions.tsx b/docs/src/pages/components/autocomplete/DisabledOptions.tsx index 34256ea6dbfe21..268e2e28969452 100644 --- a/docs/src/pages/components/autocomplete/DisabledOptions.tsx +++ b/docs/src/pages/components/autocomplete/DisabledOptions.tsx @@ -8,7 +8,7 @@ export default function DisabledOptions() { option === timeSlots[0] || option === timeSlots[2]} + getOptionDisabled={option => option === timeSlots[0] || option === timeSlots[2]} style={{ width: 300 }} renderInput={params => ( @@ -17,8 +17,6 @@ export default function DisabledOptions() { ); } -type TimeSlot = string; - // One time slot every 30 minutes. const timeSlots = Array.from(new Array(24 * 2)).map( (_, index) => `${index < 20 ? '0' : ''}${Math.floor(index / 2)}:${index % 2 === 0 ? '00' : '30'}`, diff --git a/docs/src/pages/components/autocomplete/Filter.tsx b/docs/src/pages/components/autocomplete/Filter.tsx index 5e00d3e8af8d62..7c6112708dc2b0 100644 --- a/docs/src/pages/components/autocomplete/Filter.tsx +++ b/docs/src/pages/components/autocomplete/Filter.tsx @@ -13,7 +13,7 @@ export default function Filter() { option.title} + getOptionLabel={option => option.title} filterOptions={filterOptions} style={{ width: 300 }} renderInput={params => ( diff --git a/docs/src/pages/components/autocomplete/FixedTags.tsx b/docs/src/pages/components/autocomplete/FixedTags.tsx index be3aca0eaae2be..a76eaaa5a4bcd6 100644 --- a/docs/src/pages/components/autocomplete/FixedTags.tsx +++ b/docs/src/pages/components/autocomplete/FixedTags.tsx @@ -10,10 +10,10 @@ export default function FixedTags() { multiple id="fixed-tags-demo" options={top100Films} - getOptionLabel={(option: FilmOptionType) => option.title} + getOptionLabel={option => option.title} defaultValue={[top100Films[6], top100Films[13]]} - renderTags={(value: FilmOptionType[], getTagProps) => - value.map((option: FilmOptionType, index: number) => ( + renderTags={(value, getTagProps) => + value.map((option, index) => ( )) } @@ -31,11 +31,6 @@ export default function FixedTags() { ); } -interface FilmOptionType { - title: string; - year: number; -} - // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top const top100Films = [ { title: 'The Shawshank Redemption', year: 1994 }, diff --git a/docs/src/pages/components/autocomplete/GitHubLabel.tsx b/docs/src/pages/components/autocomplete/GitHubLabel.tsx index f94b361559eb37..40e96300c61807 100644 --- a/docs/src/pages/components/autocomplete/GitHubLabel.tsx +++ b/docs/src/pages/components/autocomplete/GitHubLabel.tsx @@ -153,7 +153,7 @@ export default function GitHubLabel() { Labels - {value.map((label: LabelType) => ( + {value.map(label => (
null} noOptionsText="No labels" - renderOption={(option: LabelType, { selected }) => ( + renderOption={(option, { selected }) => ( option.name} + getOptionLabel={option => option.name} renderInput={params => ( ({ })); interface PlaceType { + description: string; structured_formatting: { + main_text: string; secondary_text: string; main_text_matched_substrings: [ { diff --git a/docs/src/pages/components/autocomplete/Grouped.tsx b/docs/src/pages/components/autocomplete/Grouped.tsx index 41294950f531bf..cf233d53353b0f 100644 --- a/docs/src/pages/components/autocomplete/Grouped.tsx +++ b/docs/src/pages/components/autocomplete/Grouped.tsx @@ -16,8 +16,8 @@ export default function Grouped() { -b.firstLetter.localeCompare(a.firstLetter))} - groupBy={(option: FilmOptionType) => option.firstLetter} - getOptionLabel={(option: FilmOptionType) => option.title} + groupBy={option => option.firstLetter} + getOptionLabel={option => option.title} style={{ width: 300 }} renderInput={params => ( @@ -26,12 +26,6 @@ export default function Grouped() { ); } -interface FilmOptionType { - firstLetter: string; - title: string; - year: number; -} - // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top const top100Films = [ { title: 'The Shawshank Redemption', year: 1994 }, diff --git a/docs/src/pages/components/autocomplete/Highlights.tsx b/docs/src/pages/components/autocomplete/Highlights.tsx index 47d56b32419ec6..a886cd6ecc3f4e 100644 --- a/docs/src/pages/components/autocomplete/Highlights.tsx +++ b/docs/src/pages/components/autocomplete/Highlights.tsx @@ -11,7 +11,7 @@ export default function Highlights() { id="highlights-demo" style={{ width: 300 }} options={top100Films} - getOptionLabel={(option: FilmOptionType) => option.title} + getOptionLabel={option => option.title} renderInput={params => ( )} @@ -33,11 +33,6 @@ export default function Highlights() { ); } -interface FilmOptionType { - title: string; - year: number; -} - // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top const top100Films = [ { title: 'The Shawshank Redemption', year: 1994 }, diff --git a/docs/src/pages/components/autocomplete/Playground.tsx b/docs/src/pages/components/autocomplete/Playground.tsx index 84c10ad8768126..c3cae2e6f196b8 100644 --- a/docs/src/pages/components/autocomplete/Playground.tsx +++ b/docs/src/pages/components/autocomplete/Playground.tsx @@ -11,7 +11,7 @@ export default function Playground() { const flatProps = { options: top100Films.map(option => option.title), }; - const [value, setValue] = React.useState(null); + const [value, setValue] = React.useState(null); return (
@@ -62,7 +62,7 @@ export default function Playground() { {...defaultProps} id="controlled-demo" value={value} - onChange={(event, newValue) => { + onChange={(event: any, newValue: FilmOptionType | null) => { setValue(newValue); }} renderInput={params => ( diff --git a/docs/src/pages/components/autocomplete/Sizes.tsx b/docs/src/pages/components/autocomplete/Sizes.tsx index db58315fa3f47c..5ade96cf2438b5 100644 --- a/docs/src/pages/components/autocomplete/Sizes.tsx +++ b/docs/src/pages/components/autocomplete/Sizes.tsx @@ -25,7 +25,7 @@ export default function Sizes() { id="size-small-standard" size="small" options={top100Films} - getOptionLabel={(option: FilmOptionType) => option.title} + getOptionLabel={option => option.title} defaultValue={top100Films[13]} renderInput={params => ( option.title} + getOptionLabel={option => option.title} defaultValue={[top100Films[13]]} renderInput={params => ( option.title} + getOptionLabel={option => option.title} defaultValue={top100Films[13]} renderInput={params => ( option.title} + getOptionLabel={option => option.title} defaultValue={[top100Films[13]]} renderInput={params => ( option.title} + getOptionLabel={option => option.title} defaultValue={top100Films[13]} - renderTags={(value: FilmOptionType[], getTagProps) => - value.map((option: FilmOptionType, index: number) => ( + renderTags={(value, getTagProps) => + value.map((option, index) => ( option.title} + getOptionLabel={option => option.title} defaultValue={[top100Films[13]]} - renderTags={(value: FilmOptionType[], getTagProps) => - value.map((option: FilmOptionType, index: number) => ( + renderTags={(value, getTagProps) => + value.map((option, index) => ( option.title} + getOptionLabel={option => option.title} defaultValue={[top100Films[13]]} renderInput={params => ( option.title} + getOptionLabel={option => option.title} defaultValue={[top100Films[13]]} filterSelectedOptions renderInput={params => ( @@ -79,11 +79,6 @@ export default function Tags() { ); } -interface FilmOptionType { - title: string; - year: number; -} - // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top const top100Films = [ { title: 'The Shawshank Redemption', year: 1994 }, diff --git a/docs/src/pages/components/autocomplete/autocomplete.md b/docs/src/pages/components/autocomplete/autocomplete.md index 32eec630074a24..b3de3cc8f1ffba 100644 --- a/docs/src/pages/components/autocomplete/autocomplete.md +++ b/docs/src/pages/components/autocomplete/autocomplete.md @@ -172,6 +172,12 @@ Search within 10,000 randomly generated options. The list is virtualized thanks VoiceOver on iOS Safari doesn't support the `aria-owns` attribute very well. You can work around the issue with the `disablePortal` prop. +### TypeScript + +To fully take advantage of type inference, you need to set the `multiple` prop to `undefined`, `false` or `true`. +See [this discussion](https://github.com/mui-org/material-ui/pull/18854#discussion_r364215153) for more details. +TypeScript might solve this bug in the future. + ## Accessibility (WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#combobox) diff --git a/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts b/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts index 0b37afc815bf39..90e798807e3f08 100644 --- a/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts +++ b/packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts @@ -1,7 +1,11 @@ import * as React from 'react'; import { StandardProps } from '@material-ui/core'; import { PopperProps } from '@material-ui/core/Popper'; -import { UseAutocompleteProps, CreateFilterOptions, createFilterOptions } from '../useAutocomplete'; +import { + UseAutocompleteCommonProps, + createFilterOptions, + UseAutocompleteProps, +} from '../useAutocomplete'; export { createFilterOptions }; @@ -30,8 +34,8 @@ export interface RenderInputParams { inputProps: object; } -export interface AutocompleteProps - extends UseAutocompleteProps, +export interface AutocompleteProps + extends UseAutocompleteCommonProps, StandardProps< React.HTMLAttributes, AutocompleteClassKey, @@ -129,19 +133,19 @@ export interface AutocompleteProps /** * Render the option, use `getOptionLabel` by default. * - * @param {any} option The option to render. + * @param {T} option The option to render. * @param {object} state The state of the component. * @returns {ReactNode} */ - renderOption?: (option: any, state: RenderOptionState) => React.ReactNode; + renderOption?: (option: T, state: RenderOptionState) => React.ReactNode; /** * Render the selected value. * - * @param {any} value The `value` provided to the component. + * @param {T[]} value The `value` provided to the component. * @param {function} getTagProps A tag props getter. * @returns {ReactNode} */ - renderTags?: (value: any, getTagProps: GetTagProps) => React.ReactNode; + renderTags?: (value: T[], getTagProps: GetTagProps) => React.ReactNode; /** * The size of the autocomplete. */ @@ -171,4 +175,6 @@ export type AutocompleteClassKey = | 'groupLabel' | 'groupUl'; -export default function Autocomplete(props: AutocompleteProps): JSX.Element; +export default function Autocomplete( + props: AutocompleteProps & UseAutocompleteProps, +): JSX.Element; diff --git a/packages/material-ui-lab/src/Autocomplete/Autocomplete.js b/packages/material-ui-lab/src/Autocomplete/Autocomplete.js index 2e3f53d09880bc..53685cc7c56430 100644 --- a/packages/material-ui-lab/src/Autocomplete/Autocomplete.js +++ b/packages/material-ui-lab/src/Autocomplete/Autocomplete.js @@ -524,7 +524,7 @@ Autocomplete.propTypes = { /** * The default input value. Use when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.oneOfType([PropTypes.any, PropTypes.array]), /** * If `true`, the input can't be cleared. */ @@ -553,9 +553,9 @@ Autocomplete.propTypes = { /** * A filter function that determines the options that are eligible. * - * @param {any[]} options The options to render. + * @param {T[]} options The options to render. * @param {object} state The state of the component. - * @returns {any[]} + * @returns {T[]} */ filterOptions: PropTypes.func, /** @@ -588,7 +588,7 @@ Autocomplete.propTypes = { * If provided, the options will be grouped under the returned string. * The groupBy value is also used as the text for group headings when `renderGroup` is not provided. * - * @param {any} options The option to group. + * @param {T} options The option to group. * @returns {string} */ groupBy: PropTypes.func, @@ -637,7 +637,7 @@ Autocomplete.propTypes = { * Callback fired when the value changes. * * @param {object} event The event source of the callback. - * @param {any} value + * @param {T} value */ onChange: PropTypes.func, /** @@ -705,7 +705,7 @@ Autocomplete.propTypes = { /** * Render the option, use `getOptionLabel` by default. * - * @param {any} option The option to render. + * @param {T} option The option to render. * @param {object} state The state of the component. * @returns {ReactNode} */ @@ -713,7 +713,7 @@ Autocomplete.propTypes = { /** * Render the selected value. * - * @param {any} value The `value` provided to the component. + * @param {T[]} value The `value` provided to the component. * @param {function} getTagProps A tag props getter. * @returns {ReactNode} */ @@ -728,7 +728,7 @@ Autocomplete.propTypes = { * The value must have reference equality with the option in order to be selected. * You can customize the equality behavior with the `getOptionSelected` prop. */ - value: PropTypes.any, + value: PropTypes.oneOfType([PropTypes.any, PropTypes.array]), }; export default withStyles(styles, { name: 'MuiAutocomplete' })(Autocomplete); diff --git a/packages/material-ui-lab/src/TreeView/TreeView.d.ts b/packages/material-ui-lab/src/TreeView/TreeView.d.ts index 8c1bf405624ace..5298492a583a77 100644 --- a/packages/material-ui-lab/src/TreeView/TreeView.d.ts +++ b/packages/material-ui-lab/src/TreeView/TreeView.d.ts @@ -32,7 +32,7 @@ export interface TreeViewProps /** * Callback fired when tree items are expanded/collapsed. * - * @param {object} event The event source of the callback + * @param {object} event The event source of the callback. * @param {array} nodeIds The ids of the expanded nodes. */ onNodeToggle?: (event: React.ChangeEvent<{}>, nodeIds: string[]) => void; diff --git a/packages/material-ui-lab/src/TreeView/TreeView.js b/packages/material-ui-lab/src/TreeView/TreeView.js index b13f75561fb4e0..6f4eebe56d963a 100644 --- a/packages/material-ui-lab/src/TreeView/TreeView.js +++ b/packages/material-ui-lab/src/TreeView/TreeView.js @@ -394,7 +394,7 @@ TreeView.propTypes = { /** * Callback fired when tree items are expanded/collapsed. * - * @param {object} event The event source of the callback + * @param {object} event The event source of the callback. * @param {array} nodeIds The ids of the expanded nodes. */ onNodeToggle: PropTypes.func, diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts index 1a706f55746125..934233fe1995aa 100644 --- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts +++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts @@ -1,10 +1,10 @@ import * as React from 'react'; -export interface CreateFilterOptionsConfig { +export interface CreateFilterOptionsConfig { ignoreAccents?: boolean; ignoreCase?: boolean; matchFrom?: 'any' | 'start'; - stringify?: (option: any) => string; + stringify?: (option: T) => string; trim?: boolean; } @@ -12,13 +12,11 @@ export interface FilterOptionsState { inputValue: string; } -export type CreateFilterOptions = ( - config?: CreateFilterOptionsConfig, -) => (option: any, state: FilterOptionsState) => any[]; +export function createFilterOptions( + config?: CreateFilterOptionsConfig, +): (options: T[], state: FilterOptionsState) => T[]; -export const createFilterOptions: CreateFilterOptions; - -export interface UseAutocompleteProps { +export interface UseAutocompleteCommonProps { /** * If `true`, the portion of the selected suggestion that has not been typed by the user, * known as the completion string, appears inline after the input cursor in the textbox. @@ -54,10 +52,6 @@ export interface UseAutocompleteProps { * Consider this option when you need to customize the component. */ debug?: boolean; - /** - * The default input value. Use when the component is not controlled. - */ - defaultValue?: any; /** * If `true`, the input can't be cleared. */ @@ -77,11 +71,11 @@ export interface UseAutocompleteProps { /** * A filter function that determines the options that are eligible. * - * @param {any[]} options The options to render. + * @param {T[]} options The options to render. * @param {object} state The state of the component. - * @returns {any[]} + * @returns {T[]} */ - filterOptions?: (options: any[], state: FilterOptionsState) => any[]; + filterOptions?: (options: T[], state: FilterOptionsState) => T[]; /** * If `true`, hide the selected options from the list box. */ @@ -93,25 +87,25 @@ export interface UseAutocompleteProps { /** * Used to determine the disabled state for a given option. */ - getOptionDisabled?: (option: any) => boolean; + getOptionDisabled?: (option: T) => boolean; /** * Used to determine the string value for a given option. * It's used to fill the input (and the list box options if `renderOption` is not provided). */ - getOptionLabel?: (option: any) => string; + getOptionLabel?: (option: T) => string; /** * Used to determine if an option is selected. * Uses strict equality by default. */ - getOptionSelected?: (option: any, value: any) => boolean; + getOptionSelected?: (option: T, value: T) => boolean; /** * If provided, the options will be grouped under the returned string. * The groupBy value is also used as the text for group headings when `renderGroup` is not provided. * - * @param {any} options The option to group. + * @param {T} options The option to group. * @returns {string} */ - groupBy?: (option: any) => string; + groupBy?: (option: T) => string; /** * This prop is used to help implement the accessibility logic. * If you don't provide this prop. It falls back to a randomly generated id. @@ -125,17 +119,6 @@ export interface UseAutocompleteProps { * The input value. */ inputValue?: string; - /** - * If `true`, `value` must be an array and the menu will support multiple selections. - */ - multiple?: boolean; - /** - * Callback fired when the value changes. - * - * @param {object} event The event source of the callback. - * @param {any} value - */ - onChange?: (event: React.ChangeEvent<{}>, value: any) => void; /** * Callback fired when the popup requests to be closed. * Use in controlled mode (see open). @@ -150,7 +133,7 @@ export interface UseAutocompleteProps { * @param {string} value The new value of the text input. * @param {string} reason Can be: "input" (user input), "reset" (programmatic change), `"clear"`. */ - onInputChange?: (event: React.ChangeEvent<{}>, value: any, reason: 'input' | 'reset') => void; + onInputChange?: (event: React.ChangeEvent<{}>, value: string, reason: 'input' | 'reset') => void; /** * Callback fired when the popup requests to be opened. * Use in controlled mode (see open). @@ -165,18 +148,65 @@ export interface UseAutocompleteProps { /** * Array of options. */ - options?: any[]; + options?: T[]; +} + +export interface UseAutocompleteMultipleProps extends UseAutocompleteCommonProps { + /** + * If `true`, `value` must be an array and the menu will support multiple selections. + */ + multiple: true; /** * The value of the autocomplete. * * The value must have reference equality with the option in order to be selected. * You can customize the equality behavior with the `getOptionSelected` prop. */ - value?: any; + value?: T[]; + /** + * The default input value. Use when the component is not controlled. + */ + defaultValue?: T[]; + /** + * Callback fired when the value changes. + * + * @param {object} event The event source of the callback. + * @param {T[]} value + */ + onChange?: (event: React.ChangeEvent<{}>, value: T[]) => void; +} + +export interface UseAutocompleteSingleProps extends UseAutocompleteCommonProps { + /** + * If `true`, `value` must be an array and the menu will support multiple selections. + */ + multiple?: false; + /** + * The value of the autocomplete. + * + * The value must have reference equality with the option in order to be selected. + * You can customize the equality behavior with the `getOptionSelected` prop. + */ + value?: T | null; + /** + * The default input value. Use when the component is not controlled. + */ + defaultValue?: T; + /** + * Callback fired when the value changes. + * + * @param {object} event The event source of the callback. + * @param {T} value + */ + onChange?: (event: React.ChangeEvent<{}>, value: T | null) => void; } -export default function useAutocomplete( - props: UseAutocompleteProps, +export type UseAutocompleteProps = + | UseAutocompleteSingleProps + | UseAutocompleteMultipleProps; + +export default function useAutocomplete( + props: UseAutocompleteProps, ): { getRootProps: () => {}; getInputProps: () => {}; @@ -185,15 +215,17 @@ export default function useAutocomplete( getPopupIndicatorProps: () => {}; getTagProps: ({ index }: { index: number }) => {}; getListboxProps: () => {}; - getOptionProps: ({ option, index }: { option: any; index: number }) => {}; + getOptionProps: ({ option, index }: { option: T; index: number }) => {}; id: string; inputValue: string; - value: any; + // TODO: infer the right type when the issue is resolved + // https://github.com/microsoft/TypeScript/issues/13995 + value: any; // or T | T[] dirty: boolean; popupOpen: boolean; focused: boolean; anchorEl: null | HTMLElement; setAnchorEl: () => void; focusedTag: number; - groupedOptions: any[]; + groupedOptions: T[]; }; diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js index 4037be9ee9ae2e..47443f48a59ada 100644 --- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js +++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js @@ -1007,9 +1007,9 @@ useAutocomplete.propTypes = { /** * Callback fired when the text input value changes. * - * @param {object} event The event source of the callback - * @param {string} value The new value of the text input - * @param {string} reason One of "input" (user input) or "reset" (programmatic change) + * @param {object} event The event source of the callback. + * @param {string} value The new value of the text input. + * @param {string} reason One of "input" (user input) or "reset" (programmatic change). */ onInputChange: PropTypes.func, /** diff --git a/packages/material-ui/src/BottomNavigation/BottomNavigation.d.ts b/packages/material-ui/src/BottomNavigation/BottomNavigation.d.ts index a1fdf776480a78..cd1a6dc921b40d 100644 --- a/packages/material-ui/src/BottomNavigation/BottomNavigation.d.ts +++ b/packages/material-ui/src/BottomNavigation/BottomNavigation.d.ts @@ -15,8 +15,8 @@ export interface BottomNavigationProps /** * Callback fired when the value changes. * - * @param {object} event The event source of the callback - * @param {any} value We default to the index of the child + * @param {object} event The event source of the callback. + * @param {any} value We default to the index of the child. */ onChange?(event: React.ChangeEvent<{}>, value: any): void; /** diff --git a/packages/material-ui/src/BottomNavigation/BottomNavigation.js b/packages/material-ui/src/BottomNavigation/BottomNavigation.js index b76a1ff0fc2f8f..b0d7c1c6dee8d1 100755 --- a/packages/material-ui/src/BottomNavigation/BottomNavigation.js +++ b/packages/material-ui/src/BottomNavigation/BottomNavigation.js @@ -83,8 +83,8 @@ BottomNavigation.propTypes = { /** * Callback fired when the value changes. * - * @param {object} event The event source of the callback - * @param {any} value We default to the index of the child + * @param {object} event The event source of the callback. + * @param {any} value We default to the index of the child. */ onChange: PropTypes.func, /**