From e0881ccbf0802cf70c603406f38fe53b4869045e Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Wed, 29 Apr 2026 06:18:36 +0800 Subject: [PATCH 1/7] reorganize doc --- .../components/autocomplete/autocomplete.md | 402 +++++++++--------- 1 file changed, 200 insertions(+), 202 deletions(-) diff --git a/docs/data/material/components/autocomplete/autocomplete.md b/docs/data/material/components/autocomplete/autocomplete.md index 65f9e004007147..9281757de86079 100644 --- a/docs/data/material/components/autocomplete/autocomplete.md +++ b/docs/data/material/components/autocomplete/autocomplete.md @@ -9,26 +9,33 @@ githubSource: packages/mui-material/src/Autocomplete # Autocomplete -

The autocomplete is a normal text input enhanced by a panel of suggested options.

+

A text input that suggests matching options as you type.

-The widget is useful for setting the value of a single-line textbox in one of two types of scenarios: +Autocomplete supports three core interaction modes: -1. The value for the textbox must be chosen from a predefined set of allowed values, for example a location field must contain a valid location name: [combo box](#combo-box). -2. The textbox may contain any arbitrary value, but it is advantageous to suggest possible values to the user, for example a search field may suggest similar or previous searches to save the user time: [free solo](#free-solo). - -It's meant to be an improved version of the "react-select" and "downshift" packages. +1. Pick a single value from a predefined list, like a country picker: [Combobox](#combobox). +2. Pick multiple values shown as chips, like a tag picker: [Multiple values](#multiple-values). +3. Accept any text with suggestions, like a search field: [Free solo](#free-solo). {{"component": "@mui/internal-core-docs/ComponentLinkHeader"}} -## Combo box +## Usage guidelines + +- **Combobox vs. free solo**: By default, the value must come from a fixed list of options. Set `freeSolo` when the input can be arbitrary text—for example, a search box. See [Combobox](#combobox) and [Free solo](#free-solo). +- **Prefer `Select` for short, non-filterable lists**: If users don't need to filter, the [Select](/material-ui/react-select/) component is lighter and feels more familiar for short lists. +- **Stable controlled values**: When you control `value`, keep the reference stable between renders to avoid unnecessary resets and selection mismatches. See [Controlled states](#controlled-states). +- **Multiple values**: Set `multiple` to let users select more than one option. Selected items appear as removable chips. See [Multiple values](#multiple-values). +- **Visible text label**: Provide a visible label via the `TextField` `label` prop. The component follows the [WAI-ARIA combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/), but a visible label still helps everyone—including screen reader users. + +## Combobox -The value must be chosen from a predefined set of allowed values. +The value must come from a fixed list of options. {{"demo": "ComboBox.js"}} ### Options structure -By default, the component accepts the following options structures: +By default, options can take either of these structures: ```ts interface AutocompleteOption { @@ -38,7 +45,7 @@ interface AutocompleteOption { type AutocompleteOption = string; ``` -for instance: +For example: ```js const options = [ @@ -49,27 +56,44 @@ const options = [ const options = ['The Godfather', 'Pulp Fiction']; ``` -However, you can use different structures by providing a `getOptionLabel` prop. +When using object options, provide `isOptionEqualToValue` so the component can match the current value to the right option. The default comparison uses strict equality (`===`), which only works when the value reference is the same as one of the options: -If your options are objects, you must provide the `isOptionEqualToValue` prop to ensure correct selection and highlighting. By default, it uses strict equality to compare options with the current value. +```tsx + option.id === value.id} +/> +``` -:::warning -If your options have duplicate labels, you must extract a unique key with the `getOptionKey` prop. +To use a different option structure, provide a `getOptionLabel` prop: ```tsx const options = [ - { label: 'The Godfather', id: 1 }, - { label: 'The Godfather', id: 2 }, + { id: '1', email: 'alice@example.com' }, + { id: '2', email: 'bob@example.com' }, ]; -return option.id} />; + option.email} +/>; ``` -::: +If two options share a label, use `getOptionKey` to give each one a unique key: + +```tsx +// Two contacts happen to share the same display name +const options = [ + { label: 'John Smith', id: 'usr_4f12a7b8' }, + { label: 'John Smith', id: 'usr_e9c3d521' }, +]; + + option.id} />; +``` ### Playground -Each of the following examples demonstrates one feature of the Autocomplete component. +Each example below demonstrates one feature. {{"demo": "Playground.js"}} @@ -81,17 +105,17 @@ Choose one of the 248 countries. ### Controlled states -The component has two states that can be controlled: +Autocomplete has two states that can be controlled independently: -1. the "value" state with the `value`/`onChange` props combination. This state represents the value selected by the user, for instance when pressing Enter. -2. the "input value" state with the `inputValue`/`onInputChange` props combination. This state represents the value displayed in the textbox. +1. **`value`** with `value`/`onChange`—the option the user has selected, set when they press Enter or click an option. +2. **`inputValue`** with `inputValue`/`onInputChange`—the text currently shown in the textbox. -These two states are isolated, and should be controlled independently. +Control them independently—the two states aren't linked. :::info -- A component is **controlled** when it's managed by its parent using props. -- A component is **uncontrolled** when it's managed by its own local state. +- A component is **controlled** when its parent manages it through props. +- A component is **uncontrolled** when it manages its own local state. Learn more about controlled and uncontrolled components in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: @@ -100,8 +124,7 @@ Learn more about controlled and uncontrolled components in the [React documentat :::warning -If you control the `value`, make sure it's referentially stable between renders. -In other words, the reference to the value shouldn't change if the value itself doesn't change. +If you control `value`, keep the reference stable between renders by passing the same array or object if its contents haven't changed. ```tsx // ⚠️ BAD @@ -115,105 +138,107 @@ const selectedValues = React.useMemo( return ; ``` -In the first example, `allValues.filter` is called and returns **a new array** every render. -The fix includes memoizing the value, so it changes only when needed. +In the first example, `allValues.filter` returns **a new array** every render. Wrapping it in `useMemo` ensures the array only changes when its contents change. ::: +### Disabled options + +Mark specific options as disabled with the `getOptionDisabled` prop. + +{{"demo": "DisabledOptions.js"}} + +### Grouped + +Group options with the `groupBy` prop. Sort the options by the same field you're grouping on—otherwise the same group header repeats. + +{{"demo": "Grouped.js"}} + +### Custom group rendering + +Customize how groups render with the `renderGroup` prop. It receives an object with: + +- `group`—the group name string +- `children`—the list items in that group + +The demo below uses custom markup and overrides the default group styles. + +{{"demo": "RenderGroup.js"}} + ## Free solo -Set `freeSolo` to true so the textbox can contain any arbitrary value. +Set `freeSolo` to `true` so the textbox accepts any value, not just options from the list. ### Search input -The prop is designed to cover the primary use case of a **search input** with suggestions, for example Google search or react-autowhatever. +Designed for **search inputs** with suggestions—for example, Google search or a typeahead field. {{"demo": "FreeSolo.js"}} :::warning -Be careful when using the free solo mode with non-string options, as it may cause type mismatch. - -The value created by typing into the textbox is always a string, regardless of the type of the options. +Free solo with non-string options can cause type mismatches. Whatever the user types becomes a string, even when the predefined options are objects. ::: ### Creatable -If you intend to use this mode for a [combo box](#combo-box) like experience (an enhanced version of a select element) we recommend setting: +To let users pick an existing option or create a new one, we recommend setting: -- `selectOnFocus` to help the user clear the selected value. -- `clearOnBlur` to help the user enter a new value. -- `handleHomeEndKeys` to move focus inside the popup with the Home and End keys. -- `resetHighlightOnMouseLeave` to clear mouse-created highlights when the pointer leaves the popup. -- A last option, for instance: `Add "YOUR SEARCH"`. +- `selectOnFocus`: highlight the input's current text when it receives focus so the user can overwrite it. +- `clearOnBlur`: clear leftover input text on blur when no option is picked or created. +- `handleHomeEndKeys`: move focus to the first or last option with Home and End. +- `resetHighlightOnMouseLeave`: clear mouse-created highlights when the pointer leaves the popup. +- A trailing option like `Add "${inputValue}"` to make the create action discoverable. {{"demo": "FreeSoloCreateOption.js"}} -You could also display a dialog when the user wants to add a new value. +Or open a dialog when the user wants to add a new value. {{"demo": "FreeSoloCreateOptionDialog.js"}} -## Grouped - -You can group the options with the `groupBy` prop. -If you do so, make sure that the options are also sorted with the same dimension that they are grouped by, -otherwise, you will notice duplicate headers. - -{{"demo": "Grouped.js"}} - -To control how the groups are rendered, provide a custom `renderGroup` prop. -This is a function that accepts an object with two fields: +## Multiple values -- `group`—a string representing a group name -- `children`—a collection of list items that belong to the group +Set `multiple={true}` to let users select more than one value. By default, selected values render as removable Material UI Chips; customize their rendering with `renderValue`. -The following demo shows how to use this prop to define custom markup and override the styles of the default groups: +- Spread the props from `getItemProps` onto each rendered item to preserve the component's built-in behavior. +- If you replace the default Chip, destructure `onDelete` first; it's specific to `Chip`. -{{"demo": "RenderGroup.js"}} - -## Disabled options +{{"demo": "Tags.js"}} -{{"demo": "DisabledOptions.js"}} +### Fixed options -## `useAutocomplete` +To lock certain tags so they can't be removed, mark their chips as disabled. -For advanced customization use cases, a headless `useAutocomplete()` hook is exposed. -It accepts almost the same options as the Autocomplete component minus all the props -related to the rendering of JSX. -The Autocomplete component is built on this hook. +{{"demo": "FixedTags.js"}} -```tsx -import useAutocomplete from '@mui/material/useAutocomplete'; -``` +### Selection indicators -- 📦 [4.6 kB gzipped](https://bundlephobia.com/package/@mui/material). +Use icons as a visual cue for sighted users to show which options are selected. -{{"demo": "UseAutocomplete.js", "defaultCodeOpen": false}} +{{"demo": "CheckboxesTags.js"}} -### Customized hook +### Limit tags -{{"demo": "CustomizedHook.js", "defaultCodeOpen": false}} +Use `limitTags` to limit how many selected items are visible when the input isn't focused. -Head to the [customization](#customization) section for an example with the `Autocomplete` component instead of the hook. +{{"demo": "LimitTags.js"}} ## Asynchronous requests -The component supports two different asynchronous use-cases: +The component supports two async patterns: -- [Load on open](#load-on-open): it waits for the component to be interacted with to load the options. -- [Search as you type](#search-as-you-type): a new request is made for each keystroke. +- [Load on open](#load-on-open): wait until the user interacts before fetching options. +- [Search as you type](#search-as-you-type): make a new request on every keystroke. ### Load on open -It displays a progress state as long as the network request is pending. +Shows a loading state while the request is pending. {{"demo": "Asynchronous.js"}} ### Search as you type -If your logic is fetching new options on each keystroke and using the current value of the textbox -to filter on the server, you may want to consider throttling requests. +If you fetch new options on every keystroke and filter on the server, throttle the requests. -Additionally, you will need to disable the built-in filtering of the `Autocomplete` component by -overriding the `filterOptions` prop: +Also disable the built-in client-side filtering—the server has already filtered the options, so re-filtering them would hide valid matches. Pass an identity function to `filterOptions`: ```jsx x} /> @@ -221,202 +246,183 @@ overriding the `filterOptions` prop: ### Google Maps place -A customized UI for Google Maps Places Autocomplete. -For this demo, we need to load the [Google Maps JavaScript](https://developers.google.com/maps/documentation/javascript/overview) and [Google Places](https://developers.google.com/maps/documentation/places/web-service/overview) API. +A customized UI on top of Google Places Autocomplete. The demo loads the [Google Maps JavaScript](https://developers.google.com/maps/documentation/javascript/overview) and [Google Places](https://developers.google.com/maps/documentation/places/web-service/overview) APIs. {{"demo": "GoogleMaps.js"}} -The demo relies on [autosuggest-highlight](https://github.com/moroshko/autosuggest-highlight), a small (1 kB) utility for highlighting text in autosuggest and autocomplete components. +It uses [autosuggest-highlight](https://github.com/moroshko/autosuggest-highlight), a small (1 kB) utility for highlighting matched text. :::error -Before you can start using the Google Maps JavaScript API and Places API, you need to get your own [API key](https://developers.google.com/maps/documentation/javascript/get-api-key). +You'll need your own [API key](https://developers.google.com/maps/documentation/javascript/get-api-key) to use the Google Maps and Places APIs. -This demo has limited quotas to make API requests. When your quota exceeds, you will see the response for "Paris". +This demo has a limited request quota. Once it's exceeded, results fall back to "Paris". ::: ### Infinite loading -This demo uses `@tanstack/react-query` to additively fetch new data onto existing `options` upon reaching the end of the current list. The list is virtualized using `@tanstack/react-virtual`. +Uses `@tanstack/react-query` to fetch more options when the user scrolls to the bottom of the list. The list is virtualized with `@tanstack/react-virtual`. {{"demo": "InfiniteLoading.js"}} -## Single value rendering +## Customization + +### Single value rendering -By default (when `multiple={false}`), the selected option is displayed as plain text inside the input. -The `renderValue` prop allows you to customize how the selected value is rendered. -This can be useful for adding custom styles, displaying additional information, or formatting the value differently. +In the default single-selection mode (when `multiple={false}`), the selected option appears as plain text inside the input. Use `renderValue` to customize the display—for example, to add icons, badges, or formatted output. -- The `getItemProps` getter provides props like `data-item-index`, `disabled`, `tabIndex` and others. These props should be spread onto the rendered component for proper accessibility. -- If using a custom component other than a Material UI Chip, destructure the `onDelete` prop as it's specific to the Material UI Chip. +- Spread the props from `getItemProps` onto your rendered element to preserve the component's built-in behavior. +- If you replace the default Chip, destructure `onDelete` first; it's specific to `Chip`. {{"demo": "CustomSingleValueRendering.js"}} -## Multiple values +### Highlights -When `multiple={true}`, the user can select multiple values. These selected values, referred to as "items" can be customized using the `renderValue` prop. +Uses [autosuggest-highlight](https://github.com/moroshko/autosuggest-highlight) (1 kB) to highlight the matched portion of each option label. -- The `getItemProps` getter supplies essential props like `data-item-index`, `disabled`, `tabIndex` and others. Make sure to spread them on each rendered item. -- If using a custom component other than a Material UI Chip, destructure the `onDelete` prop as it's specific to the Material UI Chip. +{{"demo": "Highlights.js"}} -{{"demo": "Tags.js"}} +### Custom filter -### Fixed options +Customize how options are filtered with `createFilterOptions`—a factory that returns a function suitable for the `filterOptions` prop. -In the event that you need to lock certain tags so that they can't be removed, you can set the chips disabled. +```js +import { createFilterOptions } from '@mui/material/Autocomplete'; +``` -{{"demo": "FixedTags.js"}} +#### `createFilterOptions(config) => filterOptions` -### Selection indicators +**Arguments** -This example demonstrates how icons are used to indicate the selection state of each item in the listbox. +1. `config` (_object_ [optional]): -{{"demo": "CheckboxesTags.js"}} +- `config.ignoreAccents` (_bool_ [optional]): Defaults to `true`. Removes diacritics. +- `config.ignoreCase` (_bool_ [optional]): Defaults to `true`. Lowercases everything. +- `config.limit` (_number_ [optional]): Defaults to `null`. Limits how many matched options are shown. Useful when many options match and the listbox isn't virtualized. +- `config.matchFrom` (_'any' | 'start'_ [optional]): Defaults to `'any'`. +- `config.stringify` (_func_ [optional]): Controls how an option is converted to a string for matching against the input. +- `config.trim` (_bool_ [optional]): Defaults to `false`. Removes trailing spaces. -### Limit tags +**Returns** -You can use the `limitTags` prop to limit the number of displayed options when not focused. +`filterOptions`: a function ready to pass to the `filterOptions` prop of `Autocomplete` (or the option of the same name in `useAutocomplete`). -{{"demo": "LimitTags.js"}} +In the demo below, options must start with the query string: -## Sizes +```jsx +const filterOptions = createFilterOptions({ + matchFrom: 'start', + stringify: (option) => option.title, +}); -Fancy smaller inputs? Use the `size` prop. +; +``` -{{"demo": "Sizes.js"}} +{{"demo": "Filter.js", "defaultCodeOpen": false}} -## Customization +### Advanced filter + +For richer filtering—like fuzzy matching—we recommend [match-sorter](https://github.com/kentcdodds/match-sorter): + +```jsx +import { matchSorter } from 'match-sorter'; + +const filterOptions = (options, { inputValue }) => matchSorter(options, inputValue); + +; +``` + +### Sizes + +Use the `size` prop to render a smaller input. + +{{"demo": "Sizes.js"}} ### Custom input -The `renderInput` prop allows you to customize the rendered input. -The first argument of this render prop contains props that you need to forward. -Pay specific attention to the `ref` and `inputProps` keys. +Customize the rendered input with the `renderInput` prop. It receives a props object you need to forward, including `ref` and `inputProps`. :::warning -If you're using a custom input component inside the Autocomplete, make sure that you forward the ref to the underlying DOM element. +When using a custom input component, forward the ref to the underlying DOM element. ::: {{"demo": "CustomInputAutocomplete.js"}} ### Globally customized options -To globally customize the Autocomplete options for all components in your app, -you can use the [theme default props](/material-ui/customization/theme-components/#theme-default-props) and set the `renderOption` property in the `defaultProps` key. -The `renderOption` property takes the `ownerState` as the fourth parameter, which includes props and internal component state. -To display the label, you can use the `getOptionLabel` prop from the `ownerState`. -This approach enables different options for each Autocomplete component while keeping the options styling consistent. +To customize option rendering for every Autocomplete in your app, set `renderOption` in [theme default props](/material-ui/customization/theme-components/#theme-default-props). + +`renderOption` receives `ownerState` as its fourth argument, which exposes props and internal state. Use `ownerState.getOptionLabel` to render the label. + +This keeps option styling consistent across the app while letting each instance customize its content. {{"demo": "GloballyCustomizedOptions.js"}} ### GitHub's picker -This demo reproduces GitHub's label picker: +A reproduction of GitHub's label picker: {{"demo": "GitHubLabel.js"}} -Head to the [Customized hook](#customized-hook) section for a customization example with the `useAutocomplete` hook instead of the component. +See [Customized hook](#customized-hook) for the same pattern using the `useAutocomplete` hook. ### Hint -The following demo shows how to add a hint feature to the Autocomplete: +Add a hint (ghost text suggestion) inside the input: {{"demo": "AutocompleteHint.js"}} -## Highlights - -The following demo relies on [autosuggest-highlight](https://github.com/moroshko/autosuggest-highlight), a small (1 kB) utility for highlighting text in autosuggest and autocomplete components. - -{{"demo": "Highlights.js"}} +### Events -## Custom filter - -The component exposes a factory to create a filter method that can be provided to the `filterOptions` prop. -You can use it to change the default option filter behavior. - -```js -import { createFilterOptions } from '@mui/material/Autocomplete'; -``` - -### `createFilterOptions(config) => filterOptions` - -#### Arguments - -1. `config` (_object_ [optional]): - -- `config.ignoreAccents` (_bool_ [optional]): Defaults to `true`. Remove diacritics. -- `config.ignoreCase` (_bool_ [optional]): Defaults to `true`. Lowercase everything. -- `config.limit` (_number_ [optional]): Default to null. Limit the number of suggested options to be shown. For example, if `config.limit` is `100`, only the first `100` matching options are shown. It can be useful if a lot of options match and virtualization wasn't set up. -- `config.matchFrom` (_'any' | 'start'_ [optional]): Defaults to `'any'`. -- `config.stringify` (_func_ [optional]): Controls how an option is converted into a string so that it can be matched against the input text fragment. -- `config.trim` (_bool_ [optional]): Defaults to `false`. Remove trailing spaces. - -#### Returns - -`filterOptions`: the returned filter method can be provided directly to the `filterOptions` prop of the `Autocomplete` component, or the parameter of the same name for the hook. - -In the following demo, the options need to start with the query prefix: +To override the default key handling, set `defaultMuiPrevented` to `true` on the event: ```jsx -const filterOptions = createFilterOptions({ - matchFrom: 'start', - stringify: (option) => option.title, -}); - -; + { + if (event.key === 'Enter') { + // Prevents the default 'Enter' behavior. + event.defaultMuiPrevented = true; + // your handler code + } + }} +/> ``` -{{"demo": "Filter.js", "defaultCodeOpen": false}} +## Virtualization -### Advanced +Searches through a fixed list of 10,000 randomly generated options. The list is virtualized with [react-window](https://github.com/bvaughn/react-window). -For richer filtering mechanisms, like fuzzy matching, it's recommended to look at [match-sorter](https://github.com/kentcdodds/match-sorter). For instance: +{{"demo": "Virtualize.js"}} -```jsx -import { matchSorter } from 'match-sorter'; +## `useAutocomplete` -const filterOptions = (options, { inputValue }) => matchSorter(options, inputValue); +Use the `useAutocomplete` hook for full control over markup. It accepts the same options as `Autocomplete` minus the rendering props. -; +```tsx +import useAutocomplete from '@mui/material/useAutocomplete'; ``` -## Virtualization +- 📦 [4.6 kB gzipped](https://bundlephobia.com/package/@mui/material). -Search within 10,000 randomly generated options. The list is virtualized thanks to [react-window](https://github.com/bvaughn/react-window). +{{"demo": "UseAutocomplete.js", "defaultCodeOpen": false}} -{{"demo": "Virtualize.js"}} +### Customized hook -## Events +{{"demo": "CustomizedHook.js", "defaultCodeOpen": false}} -If you would like to prevent the default key handler behavior, you can set the event's `defaultMuiPrevented` property to `true`: - -```jsx - { - if (event.key === 'Enter') { - // Prevent's default 'Enter' behavior. - event.defaultMuiPrevented = true; - // your handler code - } - }} -/> -``` +See [Customization](#customization) for the same pattern using the `Autocomplete` component. ## Limitations ### autocomplete/autofill -Browsers have heuristics to help the user fill in form inputs. -However, this can harm the UX of the component. +Browsers use heuristics to try to autofill form inputs—but this can interfere with the Autocomplete experience. -By default, the component disables the input **autocomplete** feature (remembering what the user has typed for a given field in a previous session) with the `autoComplete="off"` attribute. -Google Chrome does not currently support this attribute setting ([Issue 41239842](https://issues.chromium.org/issues/41239842)). -A possible workaround is to remove the `id` to have the component generate a random one. +By default, the component sets `autoComplete="off"` to disable the browser's autocomplete history (remembering past entries for a field). Google Chrome ignores this setting ([Issue 41239842](https://issues.chromium.org/issues/41239842)). A workaround: remove the `id` so the component generates a random one. -In addition to remembering past entered values, the browser might also propose **autofill** suggestions (saved login, address, or payment details). -In the event you want the avoid autofill, you can try the following: +Browsers may also propose **autofill** suggestions (saved logins, addresses, payment details). To avoid these: -- Name the input without leaking any information the browser can use. For example `id="field1"` instead of `id="country"`. If you leave the id empty, the component uses a random id. -- Set `autoComplete="new-password"` (some browsers will suggest a strong password for inputs with this attribute setting): +- Use a generic input id that doesn't hint at the field's purpose—`id="field1"` rather than `id="country"`. Leave it empty to get a random id. +- Set `autoComplete="new-password"` (some browsers will offer a strong password for these inputs): ```jsx Date: Thu, 30 Apr 2026 06:51:39 +0800 Subject: [PATCH 2/7] demo cleanup --- .../autocomplete/AutocompleteHint.js | 130 +----------------- .../autocomplete/AutocompleteHint.tsx | 130 +----------------- .../components/autocomplete/CheckboxesTags.js | 1 - .../autocomplete/CheckboxesTags.tsx | 1 - .../autocomplete/ControllableStates.js | 1 - .../autocomplete/ControllableStates.tsx | 3 +- .../components/autocomplete/CountrySelect.js | 12 +- .../components/autocomplete/CountrySelect.tsx | 12 +- .../autocomplete/CustomInputAutocomplete.js | 1 - .../autocomplete/CustomInputAutocomplete.tsx | 1 - .../components/autocomplete/CustomizedHook.js | 1 - .../autocomplete/CustomizedHook.tsx | 1 - .../components/autocomplete/FixedTags.js | 1 - .../components/autocomplete/FixedTags.tsx | 1 - .../components/autocomplete/FreeSolo.js | 3 - .../components/autocomplete/FreeSolo.tsx | 3 - .../autocomplete/FreeSoloCreateOption.js | 1 - .../autocomplete/FreeSoloCreateOption.tsx | 1 - .../FreeSoloCreateOptionDialog.js | 58 ++++---- .../FreeSoloCreateOptionDialog.tsx | 58 ++++---- .../components/autocomplete/GitHubLabel.tsx | 4 +- .../autocomplete/GloballyCustomizedOptions.js | 3 +- .../GloballyCustomizedOptions.tsx | 3 +- .../components/autocomplete/GoogleMaps.tsx | 2 +- .../components/autocomplete/LimitTags.js | 1 - .../components/autocomplete/LimitTags.tsx | 1 - .../components/autocomplete/Playground.js | 53 +++---- .../components/autocomplete/Playground.tsx | 55 +++----- .../material/components/autocomplete/Sizes.js | 35 ----- .../components/autocomplete/Sizes.tsx | 35 ----- .../material/components/autocomplete/Tags.js | 18 +-- .../material/components/autocomplete/Tags.tsx | 18 +-- .../components/autocomplete/autocomplete.md | 5 +- 33 files changed, 120 insertions(+), 533 deletions(-) diff --git a/docs/data/material/components/autocomplete/AutocompleteHint.js b/docs/data/material/components/autocomplete/AutocompleteHint.js index eabea1b08af6f0..9719cd2e81acd7 100644 --- a/docs/data/material/components/autocomplete/AutocompleteHint.js +++ b/docs/data/material/components/autocomplete/AutocompleteHint.js @@ -3,6 +3,7 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; +import top100Films from './top100Films'; export default function AutocompleteHint() { const hint = React.useRef(''); @@ -26,7 +27,6 @@ export default function AutocompleteHint() { disablePortal resetHighlightOnMouseLeave inputValue={inputValue} - id="combo-box-hint-demo" options={top100Films} sx={{ width: 300 }} renderInput={(params) => { @@ -68,131 +68,3 @@ export default function AutocompleteHint() { /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { label: 'The Shawshank Redemption', year: 1994 }, - { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, - { label: 'The Dark Knight', year: 2008 }, - { label: '12 Angry Men', year: 1957 }, - { label: "Schindler's List", year: 1993 }, - { label: 'Pulp Fiction', year: 1994 }, - { - label: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { label: 'The Good, the Bad and the Ugly', year: 1966 }, - { label: 'Fight Club', year: 1999 }, - { - label: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - label: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { label: 'Forrest Gump', year: 1994 }, - { label: 'Inception', year: 2010 }, - { - label: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { label: 'Goodfellas', year: 1990 }, - { label: 'The Matrix', year: 1999 }, - { label: 'Seven Samurai', year: 1954 }, - { - label: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { label: 'City of God', year: 2002 }, - { label: 'Se7en', year: 1995 }, - { label: 'The Silence of the Lambs', year: 1991 }, - { label: "It's a Wonderful Life", year: 1946 }, - { label: 'Life Is Beautiful', year: 1997 }, - { label: 'The Usual Suspects', year: 1995 }, - { label: 'Léon: The Professional', year: 1994 }, - { label: 'Spirited Away', year: 2001 }, - { label: 'Saving Private Ryan', year: 1998 }, - { label: 'Once Upon a Time in the West', year: 1968 }, - { label: 'American History X', year: 1998 }, - { label: 'Interstellar', year: 2014 }, - { label: 'Casablanca', year: 1942 }, - { label: 'City Lights', year: 1931 }, - { label: 'Psycho', year: 1960 }, - { label: 'The Green Mile', year: 1999 }, - { label: 'The Intouchables', year: 2011 }, - { label: 'Modern Times', year: 1936 }, - { label: 'Raiders of the Lost Ark', year: 1981 }, - { label: 'Rear Window', year: 1954 }, - { label: 'The Pianist', year: 2002 }, - { label: 'The Departed', year: 2006 }, - { label: 'Terminator 2: Judgment Day', year: 1991 }, - { label: 'Back to the Future', year: 1985 }, - { label: 'Whiplash', year: 2014 }, - { label: 'Gladiator', year: 2000 }, - { label: 'Memento', year: 2000 }, - { label: 'The Prestige', year: 2006 }, - { label: 'The Lion King', year: 1994 }, - { label: 'Apocalypse Now', year: 1979 }, - { label: 'Alien', year: 1979 }, - { label: 'Sunset Boulevard', year: 1950 }, - { - label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { label: 'The Great Dictator', year: 1940 }, - { label: 'Cinema Paradiso', year: 1988 }, - { label: 'The Lives of Others', year: 2006 }, - { label: 'Grave of the Fireflies', year: 1988 }, - { label: 'Paths of Glory', year: 1957 }, - { label: 'Django Unchained', year: 2012 }, - { label: 'The Shining', year: 1980 }, - { label: 'WALL·E', year: 2008 }, - { label: 'American Beauty', year: 1999 }, - { label: 'The Dark Knight Rises', year: 2012 }, - { label: 'Princess Mononoke', year: 1997 }, - { label: 'Aliens', year: 1986 }, - { label: 'Oldboy', year: 2003 }, - { label: 'Once Upon a Time in America', year: 1984 }, - { label: 'Witness for the Prosecution', year: 1957 }, - { label: 'Das Boot', year: 1981 }, - { label: 'Citizen Kane', year: 1941 }, - { label: 'North by Northwest', year: 1959 }, - { label: 'Vertigo', year: 1958 }, - { - label: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { label: 'Reservoir Dogs', year: 1992 }, - { label: 'Braveheart', year: 1995 }, - { label: 'M', year: 1931 }, - { label: 'Requiem for a Dream', year: 2000 }, - { label: 'Amélie', year: 2001 }, - { label: 'A Clockwork Orange', year: 1971 }, - { label: 'Like Stars on Earth', year: 2007 }, - { label: 'Taxi Driver', year: 1976 }, - { label: 'Lawrence of Arabia', year: 1962 }, - { label: 'Double Indemnity', year: 1944 }, - { - label: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { label: 'Amadeus', year: 1984 }, - { label: 'To Kill a Mockingbird', year: 1962 }, - { label: 'Toy Story 3', year: 2010 }, - { label: 'Logan', year: 2017 }, - { label: 'Full Metal Jacket', year: 1987 }, - { label: 'Dangal', year: 2016 }, - { label: 'The Sting', year: 1973 }, - { label: '2001: A Space Odyssey', year: 1968 }, - { label: "Singin' in the Rain", year: 1952 }, - { label: 'Toy Story', year: 1995 }, - { label: 'Bicycle Thieves', year: 1948 }, - { label: 'The Kid', year: 1921 }, - { label: 'Inglourious Basterds', year: 2009 }, - { label: 'Snatch', year: 2000 }, - { label: '3 Idiots', year: 2009 }, - { label: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/AutocompleteHint.tsx b/docs/data/material/components/autocomplete/AutocompleteHint.tsx index eabea1b08af6f0..9719cd2e81acd7 100644 --- a/docs/data/material/components/autocomplete/AutocompleteHint.tsx +++ b/docs/data/material/components/autocomplete/AutocompleteHint.tsx @@ -3,6 +3,7 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; +import top100Films from './top100Films'; export default function AutocompleteHint() { const hint = React.useRef(''); @@ -26,7 +27,6 @@ export default function AutocompleteHint() { disablePortal resetHighlightOnMouseLeave inputValue={inputValue} - id="combo-box-hint-demo" options={top100Films} sx={{ width: 300 }} renderInput={(params) => { @@ -68,131 +68,3 @@ export default function AutocompleteHint() { /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { label: 'The Shawshank Redemption', year: 1994 }, - { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, - { label: 'The Dark Knight', year: 2008 }, - { label: '12 Angry Men', year: 1957 }, - { label: "Schindler's List", year: 1993 }, - { label: 'Pulp Fiction', year: 1994 }, - { - label: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { label: 'The Good, the Bad and the Ugly', year: 1966 }, - { label: 'Fight Club', year: 1999 }, - { - label: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - label: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { label: 'Forrest Gump', year: 1994 }, - { label: 'Inception', year: 2010 }, - { - label: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { label: 'Goodfellas', year: 1990 }, - { label: 'The Matrix', year: 1999 }, - { label: 'Seven Samurai', year: 1954 }, - { - label: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { label: 'City of God', year: 2002 }, - { label: 'Se7en', year: 1995 }, - { label: 'The Silence of the Lambs', year: 1991 }, - { label: "It's a Wonderful Life", year: 1946 }, - { label: 'Life Is Beautiful', year: 1997 }, - { label: 'The Usual Suspects', year: 1995 }, - { label: 'Léon: The Professional', year: 1994 }, - { label: 'Spirited Away', year: 2001 }, - { label: 'Saving Private Ryan', year: 1998 }, - { label: 'Once Upon a Time in the West', year: 1968 }, - { label: 'American History X', year: 1998 }, - { label: 'Interstellar', year: 2014 }, - { label: 'Casablanca', year: 1942 }, - { label: 'City Lights', year: 1931 }, - { label: 'Psycho', year: 1960 }, - { label: 'The Green Mile', year: 1999 }, - { label: 'The Intouchables', year: 2011 }, - { label: 'Modern Times', year: 1936 }, - { label: 'Raiders of the Lost Ark', year: 1981 }, - { label: 'Rear Window', year: 1954 }, - { label: 'The Pianist', year: 2002 }, - { label: 'The Departed', year: 2006 }, - { label: 'Terminator 2: Judgment Day', year: 1991 }, - { label: 'Back to the Future', year: 1985 }, - { label: 'Whiplash', year: 2014 }, - { label: 'Gladiator', year: 2000 }, - { label: 'Memento', year: 2000 }, - { label: 'The Prestige', year: 2006 }, - { label: 'The Lion King', year: 1994 }, - { label: 'Apocalypse Now', year: 1979 }, - { label: 'Alien', year: 1979 }, - { label: 'Sunset Boulevard', year: 1950 }, - { - label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { label: 'The Great Dictator', year: 1940 }, - { label: 'Cinema Paradiso', year: 1988 }, - { label: 'The Lives of Others', year: 2006 }, - { label: 'Grave of the Fireflies', year: 1988 }, - { label: 'Paths of Glory', year: 1957 }, - { label: 'Django Unchained', year: 2012 }, - { label: 'The Shining', year: 1980 }, - { label: 'WALL·E', year: 2008 }, - { label: 'American Beauty', year: 1999 }, - { label: 'The Dark Knight Rises', year: 2012 }, - { label: 'Princess Mononoke', year: 1997 }, - { label: 'Aliens', year: 1986 }, - { label: 'Oldboy', year: 2003 }, - { label: 'Once Upon a Time in America', year: 1984 }, - { label: 'Witness for the Prosecution', year: 1957 }, - { label: 'Das Boot', year: 1981 }, - { label: 'Citizen Kane', year: 1941 }, - { label: 'North by Northwest', year: 1959 }, - { label: 'Vertigo', year: 1958 }, - { - label: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { label: 'Reservoir Dogs', year: 1992 }, - { label: 'Braveheart', year: 1995 }, - { label: 'M', year: 1931 }, - { label: 'Requiem for a Dream', year: 2000 }, - { label: 'Amélie', year: 2001 }, - { label: 'A Clockwork Orange', year: 1971 }, - { label: 'Like Stars on Earth', year: 2007 }, - { label: 'Taxi Driver', year: 1976 }, - { label: 'Lawrence of Arabia', year: 1962 }, - { label: 'Double Indemnity', year: 1944 }, - { - label: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { label: 'Amadeus', year: 1984 }, - { label: 'To Kill a Mockingbird', year: 1962 }, - { label: 'Toy Story 3', year: 2010 }, - { label: 'Logan', year: 2017 }, - { label: 'Full Metal Jacket', year: 1987 }, - { label: 'Dangal', year: 2016 }, - { label: 'The Sting', year: 1973 }, - { label: '2001: A Space Odyssey', year: 1968 }, - { label: "Singin' in the Rain", year: 1952 }, - { label: 'Toy Story', year: 1995 }, - { label: 'Bicycle Thieves', year: 1948 }, - { label: 'The Kid', year: 1921 }, - { label: 'Inglourious Basterds', year: 2009 }, - { label: 'Snatch', year: 2000 }, - { label: '3 Idiots', year: 2009 }, - { label: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/CheckboxesTags.js b/docs/data/material/components/autocomplete/CheckboxesTags.js index 53dc0603f35c51..992a8dce00fb58 100644 --- a/docs/data/material/components/autocomplete/CheckboxesTags.js +++ b/docs/data/material/components/autocomplete/CheckboxesTags.js @@ -7,7 +7,6 @@ export default function CheckboxesTags() { return ( option.title} diff --git a/docs/data/material/components/autocomplete/CheckboxesTags.tsx b/docs/data/material/components/autocomplete/CheckboxesTags.tsx index 53dc0603f35c51..992a8dce00fb58 100644 --- a/docs/data/material/components/autocomplete/CheckboxesTags.tsx +++ b/docs/data/material/components/autocomplete/CheckboxesTags.tsx @@ -7,7 +7,6 @@ export default function CheckboxesTags() { return ( option.title} diff --git a/docs/data/material/components/autocomplete/ControllableStates.js b/docs/data/material/components/autocomplete/ControllableStates.js index 0911878aedcd76..409d3159223308 100644 --- a/docs/data/material/components/autocomplete/ControllableStates.js +++ b/docs/data/material/components/autocomplete/ControllableStates.js @@ -22,7 +22,6 @@ export default function ControllableStates() { onInputChange={(event, newInputValue) => { setInputValue(newInputValue); }} - id="controllable-states-demo" options={options} sx={{ width: 300 }} renderInput={(params) => } diff --git a/docs/data/material/components/autocomplete/ControllableStates.tsx b/docs/data/material/components/autocomplete/ControllableStates.tsx index 4cd5f442a496c7..c8047e956a0a30 100644 --- a/docs/data/material/components/autocomplete/ControllableStates.tsx +++ b/docs/data/material/components/autocomplete/ControllableStates.tsx @@ -15,14 +15,13 @@ export default function ControllableStates() {
{ + onChange={(event, newValue) => { setValue(newValue); }} inputValue={inputValue} onInputChange={(event, newInputValue) => { setInputValue(newInputValue); }} - id="controllable-states-demo" options={options} sx={{ width: 300 }} renderInput={(params) => } diff --git a/docs/data/material/components/autocomplete/CountrySelect.js b/docs/data/material/components/autocomplete/CountrySelect.js index 4e6c30ac28c059..c4f49b55d92b4d 100644 --- a/docs/data/material/components/autocomplete/CountrySelect.js +++ b/docs/data/material/components/autocomplete/CountrySelect.js @@ -5,8 +5,7 @@ import Autocomplete from '@mui/material/Autocomplete'; export default function CountrySelect() { return ( option.label} @@ -21,12 +20,15 @@ export default function CountrySelect() { > - {option.label} ({option.code}) +{option.phone} + {option.label} ({option.code}) + + +{option.phone} + ); }} diff --git a/docs/data/material/components/autocomplete/CountrySelect.tsx b/docs/data/material/components/autocomplete/CountrySelect.tsx index e91d39d5f3796a..13a196dc7584a7 100644 --- a/docs/data/material/components/autocomplete/CountrySelect.tsx +++ b/docs/data/material/components/autocomplete/CountrySelect.tsx @@ -5,8 +5,7 @@ import Autocomplete from '@mui/material/Autocomplete'; export default function CountrySelect() { return ( option.label} @@ -21,12 +20,15 @@ export default function CountrySelect() { > - {option.label} ({option.code}) +{option.phone} + {option.label} ({option.code}) + + +{option.phone} + ); }} diff --git a/docs/data/material/components/autocomplete/CustomInputAutocomplete.js b/docs/data/material/components/autocomplete/CustomInputAutocomplete.js index 5487c4f1944f75..76efdfed9403de 100644 --- a/docs/data/material/components/autocomplete/CustomInputAutocomplete.js +++ b/docs/data/material/components/autocomplete/CustomInputAutocomplete.js @@ -15,7 +15,6 @@ export default function CustomInputAutocomplete() { color: theme.palette.getContrastText(theme.palette.background.paper), }, })} - id="custom-input-demo" options={options} renderInput={(params) => (
diff --git a/docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx b/docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx index 5487c4f1944f75..76efdfed9403de 100644 --- a/docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx +++ b/docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx @@ -15,7 +15,6 @@ export default function CustomInputAutocomplete() { color: theme.palette.getContrastText(theme.palette.background.paper), }, })} - id="custom-input-demo" options={options} renderInput={(params) => (
diff --git a/docs/data/material/components/autocomplete/CustomizedHook.js b/docs/data/material/components/autocomplete/CustomizedHook.js index df4234c4d8df98..a49b3a42f55186 100644 --- a/docs/data/material/components/autocomplete/CustomizedHook.js +++ b/docs/data/material/components/autocomplete/CustomizedHook.js @@ -231,7 +231,6 @@ CustomAutocomplete.propTypes = { export default function CustomizedHook() { return ( option.title} diff --git a/docs/data/material/components/autocomplete/CustomizedHook.tsx b/docs/data/material/components/autocomplete/CustomizedHook.tsx index dbf0a2cc801080..1de2454253bca3 100644 --- a/docs/data/material/components/autocomplete/CustomizedHook.tsx +++ b/docs/data/material/components/autocomplete/CustomizedHook.tsx @@ -220,7 +220,6 @@ function CustomAutocomplete( export default function CustomizedHook() { return ( - id="customized-hook-demo" defaultValue={[top100Films[1]]} options={top100Films} getOptionLabel={(option) => option.title} diff --git a/docs/data/material/components/autocomplete/FixedTags.js b/docs/data/material/components/autocomplete/FixedTags.js index a36922ba448fb9..610691f3dbc100 100644 --- a/docs/data/material/components/autocomplete/FixedTags.js +++ b/docs/data/material/components/autocomplete/FixedTags.js @@ -10,7 +10,6 @@ export default function FixedTags() { return ( { setValue([ diff --git a/docs/data/material/components/autocomplete/FixedTags.tsx b/docs/data/material/components/autocomplete/FixedTags.tsx index a36922ba448fb9..610691f3dbc100 100644 --- a/docs/data/material/components/autocomplete/FixedTags.tsx +++ b/docs/data/material/components/autocomplete/FixedTags.tsx @@ -10,7 +10,6 @@ export default function FixedTags() { return ( { setValue([ diff --git a/docs/data/material/components/autocomplete/FreeSolo.js b/docs/data/material/components/autocomplete/FreeSolo.js index b3d12a0a75e8a1..115be646f3701c 100644 --- a/docs/data/material/components/autocomplete/FreeSolo.js +++ b/docs/data/material/components/autocomplete/FreeSolo.js @@ -6,7 +6,6 @@ export default function FreeSolo() { return ( option.title)} @@ -15,7 +14,6 @@ export default function FreeSolo() { option.title)} renderInput={(params) => ( @@ -33,7 +31,6 @@ export default function FreeSolo() { )} /> option.title)} @@ -15,7 +14,6 @@ export default function FreeSolo() { option.title)} renderInput={(params) => ( @@ -33,7 +31,6 @@ export default function FreeSolo() { )} /> { // Value selected with enter, right from the input diff --git a/docs/data/material/components/autocomplete/FreeSoloCreateOption.tsx b/docs/data/material/components/autocomplete/FreeSoloCreateOption.tsx index 156a03a620c940..10266c7ba5b708 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOption.tsx +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOption.tsx @@ -42,7 +42,6 @@ export default function FreeSoloCreateOption() { selectOnFocus clearOnBlur handleHomeEndKeys - id="free-solo-with-text-demo" options={top100Films} getOptionLabel={(option) => { // Value selected with enter, right from the input diff --git a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js index a5183040c0d7cb..a46016095b7744 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js @@ -6,6 +6,7 @@ import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogActions from '@mui/material/DialogActions'; import Button from '@mui/material/Button'; +import Stack from '@mui/material/Stack'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; const filter = createFilterOptions(); @@ -72,7 +73,6 @@ export default function FreeSoloCreateOptionDialog() { return filtered; }} - id="free-solo-dialog-demo" options={top100Films} getOptionLabel={(option) => { // for example value selected with enter, right from the input @@ -107,35 +107,33 @@ export default function FreeSoloCreateOptionDialog() { Did you miss any film in our list? Please, add it! - - setDialogValue({ - ...dialogValue, - title: event.target.value, - }) - } - label="title" - type="text" - variant="standard" - /> - - setDialogValue({ - ...dialogValue, - year: event.target.value, - }) - } - label="year" - type="number" - variant="standard" - /> + + + setDialogValue({ + ...dialogValue, + title: event.target.value, + }) + } + label="title" + type="text" + variant="filled" + /> + + setDialogValue({ + ...dialogValue, + year: event.target.value, + }) + } + label="year" + type="number" + variant="filled" + /> + diff --git a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx index cf91675587e4f9..f3fd4bc1803b9a 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx @@ -6,6 +6,7 @@ import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogActions from '@mui/material/DialogActions'; import Button from '@mui/material/Button'; +import Stack from '@mui/material/Stack'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; const filter = createFilterOptions(); @@ -72,7 +73,6 @@ export default function FreeSoloCreateOptionDialog() { return filtered; }} - id="free-solo-dialog-demo" options={top100Films} getOptionLabel={(option) => { // for example value selected with enter, right from the input @@ -107,35 +107,33 @@ export default function FreeSoloCreateOptionDialog() { Did you miss any film in our list? Please, add it! - - setDialogValue({ - ...dialogValue, - title: event.target.value, - }) - } - label="title" - type="text" - variant="standard" - /> - - setDialogValue({ - ...dialogValue, - year: event.target.value, - }) - } - label="year" - type="number" - variant="standard" - /> + + + setDialogValue({ + ...dialogValue, + title: event.target.value, + }) + } + label="title" + type="text" + variant="filled" + /> + + setDialogValue({ + ...dialogValue, + year: event.target.value, + }) + } + label="year" + type="number" + variant="filled" + /> + diff --git a/docs/data/material/components/autocomplete/GitHubLabel.tsx b/docs/data/material/components/autocomplete/GitHubLabel.tsx index 09e83bdecfba54..fe4427fe1bcd6a 100644 --- a/docs/data/material/components/autocomplete/GitHubLabel.tsx +++ b/docs/data/material/components/autocomplete/GitHubLabel.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { useTheme, styled } from '@mui/material/styles'; -import Popper from '@mui/material/Popper'; +import Popper, { PopperProps } from '@mui/material/Popper'; import ClickAwayListener from '@mui/material/ClickAwayListener'; import SettingsIcon from '@mui/icons-material/Settings'; import CloseIcon from '@mui/icons-material/Close'; @@ -14,7 +14,7 @@ import InputBase from '@mui/material/InputBase'; import Box from '@mui/material/Box'; interface PopperComponentProps { - anchorEl?: any; + anchorEl?: PopperProps['anchorEl']; disablePortal?: boolean; open: boolean; } diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js index bf76c5f336256e..c8825bfe0936e6 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js @@ -59,10 +59,9 @@ function MovieSelect() { `${option.title} (${option.year})`} - id="movie-customized-option-demo" disableCloseOnSelect renderInput={(params) => ( - + )} /> ); diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx index 553b30e71178ea..c3109d0f05a2e0 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx @@ -59,10 +59,9 @@ function MovieSelect() { `${option.title} (${option.year})`} - id="movie-customized-option-demo" disableCloseOnSelect renderInput={(params) => ( - + )} /> ); diff --git a/docs/data/material/components/autocomplete/GoogleMaps.tsx b/docs/data/material/components/autocomplete/GoogleMaps.tsx index c4622b5f0d76f8..92b840b5ac5b6c 100644 --- a/docs/data/material/components/autocomplete/GoogleMaps.tsx +++ b/docs/data/material/components/autocomplete/GoogleMaps.tsx @@ -213,7 +213,7 @@ export default function GoogleMaps() { resetHighlightOnMouseLeave value={value} noOptionsText="No locations" - onChange={(event: any, newValue: PlaceType | null) => { + onChange={(event, newValue) => { setOptions(newValue ? [newValue, ...options] : options); setValue(newValue); }} diff --git a/docs/data/material/components/autocomplete/LimitTags.js b/docs/data/material/components/autocomplete/LimitTags.js index c882d0debcfa79..5b4294bbf1ef93 100644 --- a/docs/data/material/components/autocomplete/LimitTags.js +++ b/docs/data/material/components/autocomplete/LimitTags.js @@ -6,7 +6,6 @@ export default function LimitTags() { option.title} defaultValue={[top100Films[13], top100Films[12], top100Films[11]]} diff --git a/docs/data/material/components/autocomplete/LimitTags.tsx b/docs/data/material/components/autocomplete/LimitTags.tsx index c882d0debcfa79..5b4294bbf1ef93 100644 --- a/docs/data/material/components/autocomplete/LimitTags.tsx +++ b/docs/data/material/components/autocomplete/LimitTags.tsx @@ -6,7 +6,6 @@ export default function LimitTags() { option.title} defaultValue={[top100Films[13], top100Films[12], top100Films[11]]} diff --git a/docs/data/material/components/autocomplete/Playground.js b/docs/data/material/components/autocomplete/Playground.js index ea72267877c7f5..3b8edf5a01bb84 100644 --- a/docs/data/material/components/autocomplete/Playground.js +++ b/docs/data/material/components/autocomplete/Playground.js @@ -14,145 +14,128 @@ export default function Playground() { const [value, setValue] = React.useState(null); return ( - + ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> { setValue(newValue); }} renderInput={(params) => ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> diff --git a/docs/data/material/components/autocomplete/Playground.tsx b/docs/data/material/components/autocomplete/Playground.tsx index c2b906f58bb091..e015bed984e26b 100644 --- a/docs/data/material/components/autocomplete/Playground.tsx +++ b/docs/data/material/components/autocomplete/Playground.tsx @@ -14,145 +14,128 @@ export default function Playground() { const [value, setValue] = React.useState(null); return ( - + ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> { + onChange={(event, newValue) => { setValue(newValue); }} renderInput={(params) => ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> diff --git a/docs/data/material/components/autocomplete/Sizes.js b/docs/data/material/components/autocomplete/Sizes.js index 6ad2b064b0046c..c53a60720b0849 100644 --- a/docs/data/material/components/autocomplete/Sizes.js +++ b/docs/data/material/components/autocomplete/Sizes.js @@ -7,38 +7,6 @@ export default function Sizes() { return ( option.title} - defaultValue={top100Films[13]} - renderInput={(params) => ( - - )} - /> - option.title} - defaultValue={[top100Films[13]]} - renderInput={(params) => ( - - )} - /> - option.title} @@ -49,7 +17,6 @@ export default function Sizes() { /> option.title} @@ -59,7 +26,6 @@ export default function Sizes() { )} /> option.title} @@ -75,7 +41,6 @@ export default function Sizes() { /> option.title} diff --git a/docs/data/material/components/autocomplete/Sizes.tsx b/docs/data/material/components/autocomplete/Sizes.tsx index 6ad2b064b0046c..c53a60720b0849 100644 --- a/docs/data/material/components/autocomplete/Sizes.tsx +++ b/docs/data/material/components/autocomplete/Sizes.tsx @@ -7,38 +7,6 @@ export default function Sizes() { return ( option.title} - defaultValue={top100Films[13]} - renderInput={(params) => ( - - )} - /> - option.title} - defaultValue={[top100Films[13]]} - renderInput={(params) => ( - - )} - /> - option.title} @@ -49,7 +17,6 @@ export default function Sizes() { /> option.title} @@ -59,7 +26,6 @@ export default function Sizes() { )} /> option.title} @@ -75,7 +41,6 @@ export default function Sizes() { /> option.title} diff --git a/docs/data/material/components/autocomplete/Tags.js b/docs/data/material/components/autocomplete/Tags.js index ed1e92eab6c4b2..2e6bf6f9efe5d2 100644 --- a/docs/data/material/components/autocomplete/Tags.js +++ b/docs/data/material/components/autocomplete/Tags.js @@ -8,22 +8,15 @@ export default function Tags() { option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( - + )} /> option.title} defaultValue={[top100Films[13]]} @@ -38,7 +31,6 @@ export default function Tags() { /> option.title)} defaultValue={[top100Films[13].title]} freeSolo @@ -51,17 +43,11 @@ export default function Tags() { }) } renderInput={(params) => ( - + )} /> option.title)} defaultValue={[top100Films[12].title, top100Films[13].title]} readOnly diff --git a/docs/data/material/components/autocomplete/Tags.tsx b/docs/data/material/components/autocomplete/Tags.tsx index 99d9d70bf74008..18b225d42a0e74 100644 --- a/docs/data/material/components/autocomplete/Tags.tsx +++ b/docs/data/material/components/autocomplete/Tags.tsx @@ -8,22 +8,15 @@ export default function Tags() { option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( - + )} /> option.title} defaultValue={[top100Films[13]]} @@ -38,7 +31,6 @@ export default function Tags() { /> option.title)} defaultValue={[top100Films[13].title]} freeSolo @@ -51,17 +43,11 @@ export default function Tags() { }) } renderInput={(params) => ( - + )} /> option.title)} defaultValue={[top100Films[12].title, top100Films[13].title]} readOnly diff --git a/docs/data/material/components/autocomplete/autocomplete.md b/docs/data/material/components/autocomplete/autocomplete.md index 9281757de86079..fb60aa6240307c 100644 --- a/docs/data/material/components/autocomplete/autocomplete.md +++ b/docs/data/material/components/autocomplete/autocomplete.md @@ -73,10 +73,7 @@ const options = [ { id: '2', email: 'bob@example.com' }, ]; - option.email} -/>; + option.email} />; ``` If two options share a label, use `getOptionKey` to give each one a unique key: From b376f8c76f88b6655b4e2306546ac56aff78c394 Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Fri, 1 May 2026 07:06:50 +0800 Subject: [PATCH 3/7] rework github label demo --- .../components/autocomplete/GitHubLabel.js | 738 +++++++++++------ .../components/autocomplete/GitHubLabel.tsx | 757 +++++++++++------- 2 files changed, 954 insertions(+), 541 deletions(-) diff --git a/docs/data/material/components/autocomplete/GitHubLabel.js b/docs/data/material/components/autocomplete/GitHubLabel.js index 53baa52180f4f8..fcc6c2ebacbd36 100644 --- a/docs/data/material/components/autocomplete/GitHubLabel.js +++ b/docs/data/material/components/autocomplete/GitHubLabel.js @@ -1,43 +1,173 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import { useTheme, styled } from '@mui/material/styles'; +import useId from '@mui/utils/useId'; +import { alpha, styled } from '@mui/material/styles'; import Popper from '@mui/material/Popper'; import ClickAwayListener from '@mui/material/ClickAwayListener'; -import SettingsIcon from '@mui/icons-material/Settings'; -import CloseIcon from '@mui/icons-material/Close'; -import DoneIcon from '@mui/icons-material/Done'; -import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import ButtonBase from '@mui/material/ButtonBase'; import InputBase from '@mui/material/InputBase'; import Box from '@mui/material/Box'; +import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; + +const TriggerButton = styled(ButtonBase)(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + width: '100%', + paddingBlock: 5, + paddingInline: 8, + borderRadius: 6, + fontSize: 14, + fontWeight: 600, + fontFamily: 'inherit', + textAlign: 'left', + color: primer.light.fgMuted, + transition: 'background-color 80ms', + ...theme.applyStyles('dark', { color: primer.dark.fgMuted }), + '& svg': { color: 'currentColor' }, + '&:hover': { + backgroundColor: primer.light.transparentHover, + ...theme.applyStyles('dark', { backgroundColor: primer.dark.transparentHover }), + }, + '&[aria-expanded="true"]': { + backgroundColor: primer.light.transparentActive, + ...theme.applyStyles('dark', { backgroundColor: primer.dark.transparentActive }), + }, + '&:focus-visible': { + outlineWidth: 2, + outlineStyle: 'solid', + outlineColor: primer.light.fgAccent, + outlineOffset: -2, + ...theme.applyStyles('dark', { outlineColor: primer.dark.fgAccent }), + }, +})); -const StyledAutocompletePopper = styled('div')(({ theme }) => ({ +const Panel = styled(Popper)(({ theme }) => ({ + zIndex: theme.zIndex.modal, + width: PANEL_WIDTH, + maxWidth: `calc(100vw - ${theme.spacing(4)})`, + borderRadius: 12, + borderWidth: 1, + borderStyle: 'solid', + borderColor: primer.light.borderMuted, + boxShadow: `0 ${theme.spacing(1)} ${theme.spacing(3)} ${primer.light.overlayShadowColor}`, + backgroundColor: primer.light.bgDefault, + color: primer.light.fgDefault, + fontSize: 14, + ...theme.applyStyles('dark', { + borderColor: primer.dark.borderMuted, + boxShadow: `0 ${theme.spacing(1)} ${theme.spacing(3)} ${primer.dark.overlayShadowColor}`, + backgroundColor: primer.dark.bgDefault, + color: primer.dark.fgDefault, + }), +})); + +const SearchField = styled('div')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + gap: 8, + minHeight: 32, + paddingBlock: 0, + paddingInline: 8, + borderRadius: 6, + backgroundColor: primer.light.bgInset, + borderWidth: 1, + borderStyle: 'solid', + borderColor: primer.light.borderMuted, + color: primer.light.fgMuted, + fontSize: 14, + lineHeight: 20 / 14, + ...theme.applyStyles('dark', { + backgroundColor: primer.dark.bgInset, + borderColor: primer.dark.borderMuted, + color: primer.dark.fgMuted, + }), + '&:focus-within': { + borderColor: primer.light.fgAccent, + outlineWidth: 2, + outlineStyle: 'solid', + outlineColor: primer.light.fgAccent, + outlineOffset: -1, + ...theme.applyStyles('dark', { + borderColor: primer.dark.fgAccent, + outlineColor: primer.dark.fgAccent, + }), + }, + '& input': { + fontSize: 14, + color: primer.light.fgDefault, + ...theme.applyStyles('dark', { color: primer.dark.fgDefault }), + '&::placeholder': { + color: primer.light.fgMuted, + opacity: 1, + ...theme.applyStyles('dark', { color: primer.dark.fgMuted }), + }, + }, +})); + +// `width: 100%` keeps the listbox flush with the panel; without it, popper.js's +// inline positioning style would constrain the wrapper and leave a gap to the +// right of the scrollbar. +const ListboxContainer = styled('div')(({ theme }) => ({ + width: '100%', [`& .${autocompleteClasses.paper}`]: { - boxShadow: 'none', margin: 0, color: 'inherit', - fontSize: 13, + backgroundColor: 'transparent', + boxShadow: 'none', }, [`& .${autocompleteClasses.listbox}`]: { - padding: 0, - backgroundColor: '#fff', - ...theme.applyStyles('dark', { - backgroundColor: '#1c2128', - }), + // Vertical-only padding so the listbox's content area is full-width. + // Horizontal inset is applied via `margin-inline` on each option. + paddingBlock: 8, + paddingInline: 0, + maxHeight: LISTBOX_MAX_HEIGHT, + backgroundColor: 'transparent', [`& .${autocompleteClasses.option}`]: { - minHeight: 'auto', + position: 'relative', + marginInline: 8, + borderRadius: 6, + paddingBlock: 6, + paddingInline: 8, + gap: 8, alignItems: 'flex-start', - padding: 8, - borderBottom: '1px solid #eaecef', - ...theme.applyStyles('dark', { - borderBottom: '1px solid #30363d', - }), + // Let the focus indicator extend into the listbox gutter. + overflow: 'visible', + '&:not(:first-of-type)::before': { + content: '""', + position: 'absolute', + top: 0, + left: 8, + right: 8, + height: 1, + backgroundColor: primer.light.borderMuted, + ...theme.applyStyles('dark', { backgroundColor: primer.dark.borderMuted }), + }, '&[aria-selected="true"]': { backgroundColor: 'transparent', }, [`&.${autocompleteClasses.focused}, &.${autocompleteClasses.focused}[aria-selected="true"]`]: { - backgroundColor: theme.palette.action.hover, + backgroundColor: primer.light.transparentHover, + ...theme.applyStyles('dark', { + backgroundColor: primer.dark.transparentHover, + }), + }, + [`&.${autocompleteClasses.focused}::after`]: { + content: '""', + position: 'absolute', + top: 6, + bottom: 6, + left: -8, + width: 3, + borderRadius: 6, + backgroundColor: primer.light.fgAccent, + ...theme.applyStyles('dark', { backgroundColor: primer.dark.fgAccent }), + }, + [`&.${autocompleteClasses.focused}::before, &.${autocompleteClasses.focused} + li::before`]: + { + visibility: 'hidden', }, }, }, @@ -46,340 +176,422 @@ const StyledAutocompletePopper = styled('div')(({ theme }) => ({ }, })); -function PopperComponent(props) { - const { disablePortal, anchorEl, open, ...other } = props; - return ; +function ListboxPopper(props) { + // Discard popper.js positioning props — we render inline within the panel. + const { disablePortal, anchorEl, open, style, ...other } = props; + return ; } -PopperComponent.propTypes = { +ListboxPopper.propTypes = { anchorEl: PropTypes.any, disablePortal: PropTypes.bool, open: PropTypes.bool.isRequired, + style: PropTypes.object, }; -const StyledPopper = styled(Popper)(({ theme }) => ({ - border: '1px solid #e1e4e8', - boxShadow: `0 8px 24px ${'rgba(149, 157, 165, 0.2)'}`, - color: '#24292e', - backgroundColor: '#fff', - borderRadius: 6, - width: 300, - zIndex: theme.zIndex.modal, - fontSize: 13, +const OptionIndicator = styled('span')(({ theme }) => ({ + position: 'relative', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexShrink: 0, + width: 16, + height: 16, + marginTop: 4, + borderRadius: 4, + backgroundColor: primer.light.bgDefault, + borderWidth: 1, + borderStyle: 'solid', + borderColor: primer.light.borderEmphasis, ...theme.applyStyles('dark', { - border: '1px solid #30363d', - boxShadow: '0 8px 24px rgb(1, 4, 9)', - color: '#c9d1d9', - backgroundColor: '#1c2128', + backgroundColor: primer.dark.bgDefault, + borderColor: primer.dark.borderEmphasis, }), -})); - -const StyledInput = styled(InputBase)(({ theme }) => ({ - padding: 10, - width: '100%', - borderBottom: '1px solid #eaecef', - ...theme.applyStyles('dark', { - borderBottom: '1px solid #30363d', - }), - '& input': { - borderRadius: 4, - padding: 8, - transition: theme.transitions.create(['border-color', 'box-shadow']), - fontSize: 14, - backgroundColor: '#fff', - border: '1px solid #30363d', + '& svg': { + color: '#ffffff', + visibility: 'hidden', + }, + '&[data-checked]': { + backgroundColor: primer.light.fgAccent, + borderColor: primer.light.fgAccent, ...theme.applyStyles('dark', { - backgroundColor: '#0d1117', - border: '1px solid #eaecef', + backgroundColor: primer.dark.fgAccent, + borderColor: primer.dark.fgAccent, }), - '&:focus': { - boxShadow: '0px 0px 0px 3px rgba(3, 102, 214, 0.3)', - borderColor: '#0366d6', - ...theme.applyStyles('dark', { - boxShadow: '0px 0px 0px 3px rgb(12, 45, 107)', - borderColor: '#388bfd', - }), + '& svg': { + visibility: 'visible', }, }, })); -const Button = styled(ButtonBase)(({ theme }) => ({ - fontSize: 13, - width: '100%', - textAlign: 'left', - paddingBottom: 8, - fontWeight: 600, - color: '#586069', - ...theme.applyStyles('dark', { - color: '#8b949e', - }), - '&:hover,&:focus': { - color: '#0366d6', - ...theme.applyStyles('dark', { - color: '#58a6ff', - }), - }, - '& span': { - width: '100%', - }, - '& svg': { - width: 16, - height: 16, - }, -})); +// Pin already-selected items to the top of the list. +function selectedFirst(all, selected) { + const order = (label) => { + const i = selected.indexOf(label); + return i === -1 ? selected.length + all.indexOf(label) : i; + }; + return [...all].sort((a, b) => order(a) - order(b)); +} + +function isLightLabel(color) { + const red = Number.parseInt(color.slice(1, 3), 16); + const green = Number.parseInt(color.slice(3, 5), 16); + const blue = Number.parseInt(color.slice(5, 7), 16); + const perceivedLightness = (red * 0.2126 + green * 0.7152 + blue * 0.0722) / 255; + return perceivedLightness > 0.96; +} + +function LabelPill({ label }) { + return ( + ({ + display: 'inline-block', + boxSizing: 'border-box', + py: 0, + px: 0.875, + fontSize: 12, + fontWeight: 500, + lineHeight: 18 / 12, + whiteSpace: 'nowrap', + verticalAlign: 'middle', + borderRadius: '2em', + borderWidth: 1, + borderStyle: 'solid', + color: theme.palette.getContrastText(label.color), + backgroundColor: label.color, + borderColor: isLightLabel(label.color) + ? 'rgba(31,35,40,0.15)' + : 'transparent', + ...theme.applyStyles('dark', { + color: theme.lighten(label.color, 0.45), + backgroundColor: alpha(label.color, 0.18), + borderColor: alpha(label.color, 0.3), + }), + })} + > + {label.name} + + ); +} + +LabelPill.propTypes = { + label: PropTypes.shape({ + color: PropTypes.string.isRequired, + description: PropTypes.string, + name: PropTypes.string.isRequired, + }).isRequired, +}; export default function GitHubLabel() { const [anchorEl, setAnchorEl] = React.useState(null); - const [value, setValue] = React.useState([labels[1], labels[11]]); + // `value` is the committed selection rendered in the sidebar. + // `pendingValue` tracks edits while the picker is open and commits on close. + const [value, setValue] = React.useState([labels[0], labels[4]]); const [pendingValue, setPendingValue] = React.useState([]); - const theme = useTheme(); - const handleClick = (event) => { - setPendingValue(value); - setAnchorEl(event.currentTarget); - }; + const open = Boolean(anchorEl); + const panelId = useId(); + const panelTitleId = panelId ? `${panelId}-title` : undefined; - const handleClose = () => { + // `restoreFocus` returns focus to the trigger button — appropriate for + // keyboard dismissal (Escape), but not for click-away or tab-out, which + // should leave focus on whatever the user moved it to. + const handleClose = ({ restoreFocus = false } = {}) => { setValue(pendingValue); - if (anchorEl) { - anchorEl.focus(); + if (restoreFocus) { + anchorEl?.focus(); } setAnchorEl(null); }; - const open = Boolean(anchorEl); - const id = open ? 'github-label' : undefined; + const handleToggle = (event) => { + if (open) { + handleClose(); + } else { + setPendingValue(value); + setAnchorEl(event.currentTarget); + } + }; + + const handleClickAway = (event) => { + if (anchorEl?.contains(event.target)) { + return; + } + handleClose(); + }; return ( - - - {value.map((label) => ( - - {label.name} - - ))} + ({ + width: TRIGGER_WIDTH, + pb: 1.5, + borderBottom: 1, + borderColor: primer.light.borderMuted, + ...theme.applyStyles('dark', { + borderColor: primer.dark.borderMuted, + }), + })} + > + + Labels + + + + {value.length === 0 ? ( + ({ + fontSize: 12, + color: primer.light.fgMuted, + ...theme.applyStyles('dark', { color: primer.dark.fgMuted }), + })} + > + None yet + + ) : ( + value.map((label) => ) + )} + - - -
+ + + + - + ); } -// From https://github.com/abdonrd/github-labels +// GitHub's default issue labels (created on every new repository), +// plus a few common community additions. const labels = [ + { name: 'bug', color: '#d73a4a', description: "Something isn't working" }, { - name: 'good first issue', - color: '#7057ff', - description: 'Good for newcomers', - }, - { - name: 'help wanted', - color: '#008672', - description: 'Extra attention is needed', - }, - { - name: 'priority: critical', - color: '#b60205', - description: '', - }, - { - name: 'priority: high', - color: '#d93f0b', - description: '', - }, - { - name: 'priority: low', - color: '#0e8a16', - description: '', - }, - { - name: 'priority: medium', - color: '#fbca04', - description: '', - }, - { - name: "status: can't reproduce", - color: '#fec1c1', - description: '', - }, - { - name: 'status: confirmed', - color: '#215cea', - description: '', + name: 'documentation', + color: '#0075ca', + description: 'Improvements or additions to documentation', }, { - name: 'status: duplicate', + name: 'duplicate', color: '#cfd3d7', description: 'This issue or pull request already exists', }, { - name: 'status: needs information', - color: '#fef2c0', - description: '', - }, - { - name: 'status: wont do/fix', - color: '#eeeeee', - description: 'This will not be worked on', - }, - { - name: 'type: bug', - color: '#d73a4a', - description: "Something isn't working", - }, - { - name: 'type: discussion', - color: '#d4c5f9', - description: '', - }, - { - name: 'type: documentation', - color: '#006b75', - description: '', - }, - { - name: 'type: enhancement', - color: '#84b6eb', - description: '', + name: 'enhancement', + color: '#a2eeef', + description: 'New feature or request', }, { - name: 'type: epic', - color: '#3e4b9e', - description: 'A theme of work that contain sub-tasks', + name: 'good first issue', + color: '#7057ff', + description: 'Good for newcomers', }, { - name: 'type: feature request', - color: '#fbca04', - description: 'New feature or request', + name: 'help wanted', + color: '#008672', + description: 'Extra attention is needed', }, + { name: 'invalid', color: '#e4e669', description: "This doesn't seem right" }, { - name: 'type: question', + name: 'question', color: '#d876e3', description: 'Further information is requested', }, + { name: 'wontfix', color: '#cfd3d7', description: 'This will not be worked on' }, + { name: 'breaking change', color: '#ee0701' }, + { name: 'needs triage', color: '#d4c5f9' }, + { name: 'security', color: '#b60205' }, ]; + +const primer = { + light: { + borderMuted: '#d1d9e0', + borderEmphasis: '#818b98', + fgMuted: '#59636e', + fgDefault: '#1f2328', + fgAccent: '#0969da', + bgDefault: '#ffffff', + bgInset: '#f6f8fa', + transparentHover: 'rgba(208,215,222,0.32)', + transparentActive: 'rgba(208,215,222,0.48)', + overlayShadowColor: 'rgba(140,149,159,0.2)', + }, + dark: { + borderMuted: '#3d444d', + borderEmphasis: '#7d8590', + fgMuted: '#9198a1', + fgDefault: '#f0f6fc', + fgAccent: '#1f6feb', + bgDefault: '#0d1117', + bgInset: '#010409', + transparentHover: 'rgba(101,108,118,0.18)', + transparentActive: 'rgba(101,108,118,0.32)', + overlayShadowColor: 'rgba(1,4,9,0.85)', + }, +}; + +const TRIGGER_WIDTH = 240; +const PANEL_WIDTH = 320; +const LISTBOX_MAX_HEIGHT = 320; + +function GearIcon() { + return ( + + + + ); +} + +function CheckIcon() { + return ( + + + + ); +} + +function SearchIcon() { + return ( + + + + ); +} diff --git a/docs/data/material/components/autocomplete/GitHubLabel.tsx b/docs/data/material/components/autocomplete/GitHubLabel.tsx index fe4427fe1bcd6a..f274e0182aba3c 100644 --- a/docs/data/material/components/autocomplete/GitHubLabel.tsx +++ b/docs/data/material/components/autocomplete/GitHubLabel.tsx @@ -1,51 +1,188 @@ import * as React from 'react'; -import { useTheme, styled } from '@mui/material/styles'; -import Popper, { PopperProps } from '@mui/material/Popper'; +import useId from '@mui/utils/useId'; +import { alpha, styled } from '@mui/material/styles'; +import Popper from '@mui/material/Popper'; import ClickAwayListener from '@mui/material/ClickAwayListener'; -import SettingsIcon from '@mui/icons-material/Settings'; -import CloseIcon from '@mui/icons-material/Close'; -import DoneIcon from '@mui/icons-material/Done'; +import ButtonBase from '@mui/material/ButtonBase'; +import InputBase from '@mui/material/InputBase'; +import Box from '@mui/material/Box'; import Autocomplete, { AutocompleteCloseReason, autocompleteClasses, } from '@mui/material/Autocomplete'; -import ButtonBase from '@mui/material/ButtonBase'; -import InputBase from '@mui/material/InputBase'; -import Box from '@mui/material/Box'; + +interface IssueLabel { + name: string; + color: string; + description?: string; +} interface PopperComponentProps { - anchorEl?: PopperProps['anchorEl']; + anchorEl?: unknown; disablePortal?: boolean; open: boolean; + style?: React.CSSProperties; } -const StyledAutocompletePopper = styled('div')(({ theme }) => ({ +const TriggerButton = styled(ButtonBase)(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + width: '100%', + paddingBlock: 5, + paddingInline: 8, + borderRadius: 6, + fontSize: 14, + fontWeight: 600, + fontFamily: 'inherit', + textAlign: 'left', + color: primer.light.fgMuted, + transition: 'background-color 80ms', + ...theme.applyStyles('dark', { color: primer.dark.fgMuted }), + '& svg': { color: 'currentColor' }, + '&:hover': { + backgroundColor: primer.light.transparentHover, + ...theme.applyStyles('dark', { backgroundColor: primer.dark.transparentHover }), + }, + '&[aria-expanded="true"]': { + backgroundColor: primer.light.transparentActive, + ...theme.applyStyles('dark', { backgroundColor: primer.dark.transparentActive }), + }, + '&:focus-visible': { + outlineWidth: 2, + outlineStyle: 'solid', + outlineColor: primer.light.fgAccent, + outlineOffset: -2, + ...theme.applyStyles('dark', { outlineColor: primer.dark.fgAccent }), + }, +})); + +const Panel = styled(Popper)(({ theme }) => ({ + zIndex: theme.zIndex.modal, + width: PANEL_WIDTH, + maxWidth: `calc(100vw - ${theme.spacing(4)})`, + borderRadius: 12, + borderWidth: 1, + borderStyle: 'solid', + borderColor: primer.light.borderMuted, + boxShadow: `0 ${theme.spacing(1)} ${theme.spacing(3)} ${primer.light.overlayShadowColor}`, + backgroundColor: primer.light.bgDefault, + color: primer.light.fgDefault, + fontSize: 14, + ...theme.applyStyles('dark', { + borderColor: primer.dark.borderMuted, + boxShadow: `0 ${theme.spacing(1)} ${theme.spacing(3)} ${primer.dark.overlayShadowColor}`, + backgroundColor: primer.dark.bgDefault, + color: primer.dark.fgDefault, + }), +})); + +const SearchField = styled('div')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + gap: 8, + minHeight: 32, + paddingBlock: 0, + paddingInline: 8, + borderRadius: 6, + backgroundColor: primer.light.bgInset, + borderWidth: 1, + borderStyle: 'solid', + borderColor: primer.light.borderMuted, + color: primer.light.fgMuted, + fontSize: 14, + lineHeight: 20 / 14, + ...theme.applyStyles('dark', { + backgroundColor: primer.dark.bgInset, + borderColor: primer.dark.borderMuted, + color: primer.dark.fgMuted, + }), + '&:focus-within': { + borderColor: primer.light.fgAccent, + outlineWidth: 2, + outlineStyle: 'solid', + outlineColor: primer.light.fgAccent, + outlineOffset: -1, + ...theme.applyStyles('dark', { + borderColor: primer.dark.fgAccent, + outlineColor: primer.dark.fgAccent, + }), + }, + '& input': { + fontSize: 14, + color: primer.light.fgDefault, + ...theme.applyStyles('dark', { color: primer.dark.fgDefault }), + '&::placeholder': { + color: primer.light.fgMuted, + opacity: 1, + ...theme.applyStyles('dark', { color: primer.dark.fgMuted }), + }, + }, +})); + +// `width: 100%` keeps the listbox flush with the panel; without it, popper.js's +// inline positioning style would constrain the wrapper and leave a gap to the +// right of the scrollbar. +const ListboxContainer = styled('div')(({ theme }) => ({ + width: '100%', [`& .${autocompleteClasses.paper}`]: { - boxShadow: 'none', margin: 0, color: 'inherit', - fontSize: 13, + backgroundColor: 'transparent', + boxShadow: 'none', }, [`& .${autocompleteClasses.listbox}`]: { - padding: 0, - backgroundColor: '#fff', - ...theme.applyStyles('dark', { - backgroundColor: '#1c2128', - }), + // Vertical-only padding so the listbox's content area is full-width. + // Horizontal inset is applied via `margin-inline` on each option. + paddingBlock: 8, + paddingInline: 0, + maxHeight: LISTBOX_MAX_HEIGHT, + backgroundColor: 'transparent', [`& .${autocompleteClasses.option}`]: { - minHeight: 'auto', + position: 'relative', + marginInline: 8, + borderRadius: 6, + paddingBlock: 6, + paddingInline: 8, + gap: 8, alignItems: 'flex-start', - padding: 8, - borderBottom: '1px solid #eaecef', - ...theme.applyStyles('dark', { - borderBottom: '1px solid #30363d', - }), + // Let the focus indicator extend into the listbox gutter. + overflow: 'visible', + '&:not(:first-of-type)::before': { + content: '""', + position: 'absolute', + top: 0, + left: 8, + right: 8, + height: 1, + backgroundColor: primer.light.borderMuted, + ...theme.applyStyles('dark', { backgroundColor: primer.dark.borderMuted }), + }, '&[aria-selected="true"]': { backgroundColor: 'transparent', }, [`&.${autocompleteClasses.focused}, &.${autocompleteClasses.focused}[aria-selected="true"]`]: { - backgroundColor: theme.palette.action.hover, + backgroundColor: primer.light.transparentHover, + ...theme.applyStyles('dark', { + backgroundColor: primer.dark.transparentHover, + }), + }, + [`&.${autocompleteClasses.focused}::after`]: { + content: '""', + position: 'absolute', + top: 6, + bottom: 6, + left: -8, + width: 3, + borderRadius: 6, + backgroundColor: primer.light.fgAccent, + ...theme.applyStyles('dark', { backgroundColor: primer.dark.fgAccent }), + }, + [`&.${autocompleteClasses.focused}::before, &.${autocompleteClasses.focused} + li::before`]: + { + visibility: 'hidden', }, }, }, @@ -54,344 +191,408 @@ const StyledAutocompletePopper = styled('div')(({ theme }) => ({ }, })); -function PopperComponent(props: PopperComponentProps) { - const { disablePortal, anchorEl, open, ...other } = props; - return ; +function ListboxPopper(props: PopperComponentProps) { + // Discard popper.js positioning props — we render inline within the panel. + const { disablePortal, anchorEl, open, style, ...other } = props; + return ; } -const StyledPopper = styled(Popper)(({ theme }) => ({ - border: '1px solid #e1e4e8', - boxShadow: `0 8px 24px ${'rgba(149, 157, 165, 0.2)'}`, - color: '#24292e', - backgroundColor: '#fff', - borderRadius: 6, - width: 300, - zIndex: theme.zIndex.modal, - fontSize: 13, +const OptionIndicator = styled('span')(({ theme }) => ({ + position: 'relative', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexShrink: 0, + width: 16, + height: 16, + marginTop: 4, + borderRadius: 4, + backgroundColor: primer.light.bgDefault, + borderWidth: 1, + borderStyle: 'solid', + borderColor: primer.light.borderEmphasis, ...theme.applyStyles('dark', { - border: '1px solid #30363d', - boxShadow: '0 8px 24px rgb(1, 4, 9)', - color: '#c9d1d9', - backgroundColor: '#1c2128', + backgroundColor: primer.dark.bgDefault, + borderColor: primer.dark.borderEmphasis, }), -})); - -const StyledInput = styled(InputBase)(({ theme }) => ({ - padding: 10, - width: '100%', - borderBottom: '1px solid #eaecef', - ...theme.applyStyles('dark', { - borderBottom: '1px solid #30363d', - }), - '& input': { - borderRadius: 4, - padding: 8, - transition: theme.transitions.create(['border-color', 'box-shadow']), - fontSize: 14, - backgroundColor: '#fff', - border: '1px solid #30363d', + '& svg': { + color: '#ffffff', + visibility: 'hidden', + }, + '&[data-checked]': { + backgroundColor: primer.light.fgAccent, + borderColor: primer.light.fgAccent, ...theme.applyStyles('dark', { - backgroundColor: '#0d1117', - border: '1px solid #eaecef', + backgroundColor: primer.dark.fgAccent, + borderColor: primer.dark.fgAccent, }), - '&:focus': { - boxShadow: '0px 0px 0px 3px rgba(3, 102, 214, 0.3)', - borderColor: '#0366d6', - ...theme.applyStyles('dark', { - boxShadow: '0px 0px 0px 3px rgb(12, 45, 107)', - borderColor: '#388bfd', - }), + '& svg': { + visibility: 'visible', }, }, })); -const Button = styled(ButtonBase)(({ theme }) => ({ - fontSize: 13, - width: '100%', - textAlign: 'left', - paddingBottom: 8, - fontWeight: 600, - color: '#586069', - ...theme.applyStyles('dark', { - color: '#8b949e', - }), - '&:hover,&:focus': { - color: '#0366d6', - ...theme.applyStyles('dark', { - color: '#58a6ff', - }), - }, - '& span': { - width: '100%', - }, - '& svg': { - width: 16, - height: 16, - }, -})); +// Pin already-selected items to the top of the list. +function selectedFirst(all: readonly IssueLabel[], selected: readonly IssueLabel[]) { + const order = (label: IssueLabel) => { + const i = selected.indexOf(label); + return i === -1 ? selected.length + all.indexOf(label) : i; + }; + return [...all].sort((a, b) => order(a) - order(b)); +} + +function isLightLabel(color: string) { + const red = Number.parseInt(color.slice(1, 3), 16); + const green = Number.parseInt(color.slice(3, 5), 16); + const blue = Number.parseInt(color.slice(5, 7), 16); + const perceivedLightness = (red * 0.2126 + green * 0.7152 + blue * 0.0722) / 255; + return perceivedLightness > 0.96; +} + +function LabelPill({ label }: { label: IssueLabel }) { + return ( + ({ + display: 'inline-block', + boxSizing: 'border-box', + py: 0, + px: 0.875, + fontSize: 12, + fontWeight: 500, + lineHeight: 18 / 12, + whiteSpace: 'nowrap', + verticalAlign: 'middle', + borderRadius: '2em', + borderWidth: 1, + borderStyle: 'solid', + color: theme.palette.getContrastText(label.color), + backgroundColor: label.color, + borderColor: isLightLabel(label.color) + ? 'rgba(31,35,40,0.15)' + : 'transparent', + ...theme.applyStyles('dark', { + color: theme.lighten(label.color, 0.45), + backgroundColor: alpha(label.color, 0.18), + borderColor: alpha(label.color, 0.3), + }), + })} + > + {label.name} + + ); +} export default function GitHubLabel() { - const [anchorEl, setAnchorEl] = React.useState(null); - const [value, setValue] = React.useState([labels[1], labels[11]]); - const [pendingValue, setPendingValue] = React.useState([]); - const theme = useTheme(); + const [anchorEl, setAnchorEl] = React.useState(null); + // `value` is the committed selection rendered in the sidebar. + // `pendingValue` tracks edits while the picker is open and commits on close. + const [value, setValue] = React.useState([labels[0], labels[4]]); + const [pendingValue, setPendingValue] = React.useState([]); - const handleClick = (event: React.MouseEvent) => { - setPendingValue(value); - setAnchorEl(event.currentTarget); - }; + const open = Boolean(anchorEl); + const panelId = useId(); + const panelTitleId = panelId ? `${panelId}-title` : undefined; - const handleClose = () => { + // `restoreFocus` returns focus to the trigger button — appropriate for + // keyboard dismissal (Escape), but not for click-away or tab-out, which + // should leave focus on whatever the user moved it to. + const handleClose = ({ restoreFocus = false } = {}) => { setValue(pendingValue); - if (anchorEl) { - anchorEl.focus(); + if (restoreFocus) { + anchorEl?.focus(); } setAnchorEl(null); }; - const open = Boolean(anchorEl); - const id = open ? 'github-label' : undefined; + const handleToggle = (event: React.MouseEvent) => { + if (open) { + handleClose(); + } else { + setPendingValue(value); + setAnchorEl(event.currentTarget); + } + }; + + const handleClickAway = (event: MouseEvent | TouchEvent) => { + if (anchorEl?.contains(event.target as Node)) { + return; + } + handleClose(); + }; return ( - - - {value.map((label) => ( - - {label.name} - - ))} + ({ + width: TRIGGER_WIDTH, + pb: 1.5, + borderBottom: 1, + borderColor: primer.light.borderMuted, + ...theme.applyStyles('dark', { + borderColor: primer.dark.borderMuted, + }), + })} + > + + Labels + + + + {value.length === 0 ? ( + ({ + fontSize: 12, + color: primer.light.fgMuted, + ...theme.applyStyles('dark', { color: primer.dark.fgMuted }), + })} + > + None yet + + ) : ( + value.map((label) => ) + )} + - - -
+ + + + - + ); } -interface LabelType { - name: string; - color: string; - description?: string; -} - -// From https://github.com/abdonrd/github-labels -const labels = [ - { - name: 'good first issue', - color: '#7057ff', - description: 'Good for newcomers', - }, - { - name: 'help wanted', - color: '#008672', - description: 'Extra attention is needed', - }, - { - name: 'priority: critical', - color: '#b60205', - description: '', - }, - { - name: 'priority: high', - color: '#d93f0b', - description: '', - }, +// GitHub's default issue labels (created on every new repository), +// plus a few common community additions. +const labels: IssueLabel[] = [ + { name: 'bug', color: '#d73a4a', description: "Something isn't working" }, { - name: 'priority: low', - color: '#0e8a16', - description: '', + name: 'documentation', + color: '#0075ca', + description: 'Improvements or additions to documentation', }, { - name: 'priority: medium', - color: '#fbca04', - description: '', - }, - { - name: "status: can't reproduce", - color: '#fec1c1', - description: '', - }, - { - name: 'status: confirmed', - color: '#215cea', - description: '', - }, - { - name: 'status: duplicate', + name: 'duplicate', color: '#cfd3d7', description: 'This issue or pull request already exists', }, { - name: 'status: needs information', - color: '#fef2c0', - description: '', - }, - { - name: 'status: wont do/fix', - color: '#eeeeee', - description: 'This will not be worked on', - }, - { - name: 'type: bug', - color: '#d73a4a', - description: "Something isn't working", - }, - { - name: 'type: discussion', - color: '#d4c5f9', - description: '', - }, - { - name: 'type: documentation', - color: '#006b75', - description: '', - }, - { - name: 'type: enhancement', - color: '#84b6eb', - description: '', + name: 'enhancement', + color: '#a2eeef', + description: 'New feature or request', }, { - name: 'type: epic', - color: '#3e4b9e', - description: 'A theme of work that contain sub-tasks', + name: 'good first issue', + color: '#7057ff', + description: 'Good for newcomers', }, { - name: 'type: feature request', - color: '#fbca04', - description: 'New feature or request', + name: 'help wanted', + color: '#008672', + description: 'Extra attention is needed', }, + { name: 'invalid', color: '#e4e669', description: "This doesn't seem right" }, { - name: 'type: question', + name: 'question', color: '#d876e3', description: 'Further information is requested', }, + { name: 'wontfix', color: '#cfd3d7', description: 'This will not be worked on' }, + { name: 'breaking change', color: '#ee0701' }, + { name: 'needs triage', color: '#d4c5f9' }, + { name: 'security', color: '#b60205' }, ]; + +const primer = { + light: { + borderMuted: '#d1d9e0', + borderEmphasis: '#818b98', + fgMuted: '#59636e', + fgDefault: '#1f2328', + fgAccent: '#0969da', + bgDefault: '#ffffff', + bgInset: '#f6f8fa', + transparentHover: 'rgba(208,215,222,0.32)', + transparentActive: 'rgba(208,215,222,0.48)', + overlayShadowColor: 'rgba(140,149,159,0.2)', + }, + dark: { + borderMuted: '#3d444d', + borderEmphasis: '#7d8590', + fgMuted: '#9198a1', + fgDefault: '#f0f6fc', + fgAccent: '#1f6feb', + bgDefault: '#0d1117', + bgInset: '#010409', + transparentHover: 'rgba(101,108,118,0.18)', + transparentActive: 'rgba(101,108,118,0.32)', + overlayShadowColor: 'rgba(1,4,9,0.85)', + }, +} as const; + +const TRIGGER_WIDTH = 240; +const PANEL_WIDTH = 320; +const LISTBOX_MAX_HEIGHT = 320; + +function GearIcon() { + return ( + + + + ); +} + +function CheckIcon() { + return ( + + + + ); +} + +function SearchIcon() { + return ( + + + + ); +} From c042c65a5fb3338395155af02cab619ffc1f03d7 Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Sat, 2 May 2026 01:39:32 +0800 Subject: [PATCH 4/7] polish demos --- .../components/autocomplete/Asynchronous.js | 76 +- .../components/autocomplete/Asynchronous.tsx | 85 +- .../autocomplete/AutocompleteHint.js | 54 +- .../autocomplete/AutocompleteHint.tsx | 54 +- .../components/autocomplete/CheckboxesTags.js | 59 +- .../autocomplete/CheckboxesTags.tsx | 59 +- .../autocomplete/ControllableStates.js | 25 +- .../autocomplete/ControllableStates.tsx | 30 +- .../components/autocomplete/CountrySelect.js | 448 +--------- .../components/autocomplete/CountrySelect.tsx | 453 +--------- .../autocomplete/CustomInputAutocomplete.js | 27 - .../autocomplete/CustomInputAutocomplete.tsx | 27 - .../CustomSingleValueRendering.js | 268 ++++-- .../CustomSingleValueRendering.tsx | 269 ++++-- .../CustomSingleValueRendering.tsx.preview | 16 - .../components/autocomplete/CustomizedHook.js | 663 +++++++------- .../autocomplete/CustomizedHook.tsx | 662 +++++++------- .../autocomplete/CustomizedHook.tsx.preview | 6 - .../autocomplete/DisabledOptions.js | 27 +- .../autocomplete/DisabledOptions.tsx | 27 +- .../autocomplete/DisabledOptions.tsx.preview | 6 +- .../components/autocomplete/Filter.js | 132 +-- .../components/autocomplete/Filter.tsx | 139 +-- .../autocomplete/Filter.tsx.preview | 1 - .../components/autocomplete/FixedTags.js | 137 +-- .../components/autocomplete/FixedTags.tsx | 137 +-- .../components/autocomplete/FreeSolo.js | 145 +--- .../components/autocomplete/FreeSolo.tsx | 145 +--- .../autocomplete/FreeSoloCreateOption.js | 166 +--- .../autocomplete/FreeSoloCreateOption.tsx | 183 +--- .../FreeSoloCreateOptionDialog.js | 186 +--- .../FreeSoloCreateOptionDialog.tsx | 203 +---- .../autocomplete/GloballyCustomizedOptions.js | 638 ++------------ .../GloballyCustomizedOptions.tsx | 655 ++------------ .../GloballyCustomizedOptions.tsx.preview | 6 +- .../components/autocomplete/GoogleMaps.js | 144 ++-- .../components/autocomplete/GoogleMaps.tsx | 234 +++-- .../components/autocomplete/Grouped.js | 142 +-- .../components/autocomplete/Grouped.tsx | 142 +-- .../autocomplete/Grouped.tsx.preview | 3 +- .../components/autocomplete/Highlights.js | 151 +--- .../components/autocomplete/Highlights.tsx | 151 +--- .../components/autocomplete/LimitTags.js | 132 +-- .../components/autocomplete/LimitTags.tsx | 132 +-- .../autocomplete/LimitTags.tsx.preview | 4 +- .../components/autocomplete/Playground.js | 144 +--- .../components/autocomplete/Playground.tsx | 153 +--- .../components/autocomplete/RenderGroup.js | 174 +--- .../components/autocomplete/RenderGroup.tsx | 174 +--- .../autocomplete/RenderGroup.tsx.preview | 11 +- .../material/components/autocomplete/Sizes.js | 137 +-- .../components/autocomplete/Sizes.tsx | 137 +-- .../material/components/autocomplete/Tags.js | 141 +-- .../material/components/autocomplete/Tags.tsx | 141 +-- .../autocomplete/UseAutocomplete.js | 205 ----- .../autocomplete/UseAutocomplete.tsx | 205 ----- .../autocomplete/UseAutocomplete.tsx.preview | 16 - .../components/autocomplete/Virtualize.js | 62 +- .../components/autocomplete/Virtualize.tsx | 54 +- .../components/autocomplete/autocomplete.md | 109 ++- .../components/autocomplete/countries.js | 815 ++++++++++++++++++ .../components/autocomplete/countries.ts | 346 ++++++++ .../components/autocomplete/top100Films.js | 156 ++-- .../components/autocomplete/top100Films.ts | 156 ++-- 64 files changed, 3410 insertions(+), 7375 deletions(-) delete mode 100644 docs/data/material/components/autocomplete/CustomInputAutocomplete.js delete mode 100644 docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx delete mode 100644 docs/data/material/components/autocomplete/CustomSingleValueRendering.tsx.preview delete mode 100644 docs/data/material/components/autocomplete/CustomizedHook.tsx.preview delete mode 100644 docs/data/material/components/autocomplete/UseAutocomplete.js delete mode 100644 docs/data/material/components/autocomplete/UseAutocomplete.tsx delete mode 100644 docs/data/material/components/autocomplete/UseAutocomplete.tsx.preview create mode 100644 docs/data/material/components/autocomplete/countries.js create mode 100644 docs/data/material/components/autocomplete/countries.ts diff --git a/docs/data/material/components/autocomplete/Asynchronous.js b/docs/data/material/components/autocomplete/Asynchronous.js index fdc8199accc1b6..23ba38d76e4005 100644 --- a/docs/data/material/components/autocomplete/Asynchronous.js +++ b/docs/data/material/components/autocomplete/Asynchronous.js @@ -2,34 +2,33 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import CircularProgress from '@mui/material/CircularProgress'; +import useTimeout from '@mui/utils/useTimeout'; +import top100Films from './top100Films'; -function sleep(duration) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, duration); - }); -} +const LOAD_DELAY = 1000; +const topFilms = top100Films.slice(0, 30); export default function Asynchronous() { + const loadOptions = useTimeout(); const [open, setOpen] = React.useState(false); const [options, setOptions] = React.useState([]); const [loading, setLoading] = React.useState(false); const handleOpen = () => { setOpen(true); - (async () => { - setLoading(true); - await sleep(1e3); // For demo purposes. - setLoading(false); + setLoading(true); + loadOptions.start(LOAD_DELAY, () => { setOptions([...topFilms]); - })(); + setLoading(false); + }); }; const handleClose = () => { + loadOptions.clear(); setOpen(false); setOptions([]); + setLoading(false); }; return ( @@ -38,8 +37,6 @@ export default function Asynchronous() { open={open} onOpen={handleOpen} onClose={handleClose} - isOptionEqualToValue={(option, value) => option.title === value.title} - getOptionLabel={(option) => option.title} options={options} loading={loading} renderInput={(params) => ( @@ -63,54 +60,3 @@ export default function Asynchronous() { /> ); } - -// Top films as rated by IMDb users. http://www.imdb.com/chart/top -const topFilms = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, -]; diff --git a/docs/data/material/components/autocomplete/Asynchronous.tsx b/docs/data/material/components/autocomplete/Asynchronous.tsx index 48a9bb13ab434b..1b37a035a320b2 100644 --- a/docs/data/material/components/autocomplete/Asynchronous.tsx +++ b/docs/data/material/components/autocomplete/Asynchronous.tsx @@ -2,39 +2,35 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import CircularProgress from '@mui/material/CircularProgress'; +import useTimeout from '@mui/utils/useTimeout'; +import top100Films from './top100Films'; -interface Film { - title: string; - year: number; -} - -function sleep(duration: number): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, duration); - }); -} +const LOAD_DELAY = 1000; +const topFilms = top100Films.slice(0, 30); export default function Asynchronous() { + const loadOptions = useTimeout(); const [open, setOpen] = React.useState(false); - const [options, setOptions] = React.useState([]); + const [options, setOptions] = React.useState( + [], + ); const [loading, setLoading] = React.useState(false); const handleOpen = () => { setOpen(true); - (async () => { - setLoading(true); - await sleep(1e3); // For demo purposes. - setLoading(false); + setLoading(true); + loadOptions.start(LOAD_DELAY, () => { setOptions([...topFilms]); - })(); + setLoading(false); + }); }; const handleClose = () => { + loadOptions.clear(); setOpen(false); setOptions([]); + setLoading(false); }; return ( @@ -43,8 +39,6 @@ export default function Asynchronous() { open={open} onOpen={handleOpen} onClose={handleClose} - isOptionEqualToValue={(option, value) => option.title === value.title} - getOptionLabel={(option) => option.title} options={options} loading={loading} renderInput={(params) => ( @@ -68,54 +62,3 @@ export default function Asynchronous() { /> ); } - -// Top films as rated by IMDb users. http://www.imdb.com/chart/top -const topFilms = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, -]; diff --git a/docs/data/material/components/autocomplete/AutocompleteHint.js b/docs/data/material/components/autocomplete/AutocompleteHint.js index 9719cd2e81acd7..8ba7dab31887e3 100644 --- a/docs/data/material/components/autocomplete/AutocompleteHint.js +++ b/docs/data/material/components/autocomplete/AutocompleteHint.js @@ -6,23 +6,38 @@ import Typography from '@mui/material/Typography'; import top100Films from './top100Films'; export default function AutocompleteHint() { - const hint = React.useRef(''); const [inputValue, setInputValue] = React.useState(''); + const [hint, setHint] = React.useState(''); + return ( { - if (event.key === 'Tab') { - if (hint.current) { - setInputValue(hint.current); - event.preventDefault(); - } + if (event.key === 'Tab' && hint) { + setInputValue(hint); + setHint(''); + event.preventDefault(); } }} onClose={() => { - hint.current = ''; + setHint(''); }} onChange={(event, newValue) => { - setInputValue(newValue && newValue.label ? newValue.label : ''); + setInputValue(newValue?.label ?? ''); + setHint(''); + }} + onInputChange={(event, newInputValue, reason) => { + setInputValue(newInputValue); + + if (reason !== 'input') { + setHint(''); + return; + } + + const matchingOption = top100Films.find((option) => + option.label.startsWith(newInputValue), + ); + + setHint(newInputValue && matchingOption ? matchingOption.label : ''); }} disablePortal resetHighlightOnMouseLeave @@ -33,35 +48,20 @@ export default function AutocompleteHint() { return ( - { - const newValue = event.target.value; - setInputValue(newValue); - const matchingOption = top100Films.find((option) => - option.label.startsWith(newValue), - ); - - if (newValue && matchingOption) { - hint.current = matchingOption.label; - } else { - hint.current = ''; - } - }} - label="Movie" - /> + ); }} diff --git a/docs/data/material/components/autocomplete/AutocompleteHint.tsx b/docs/data/material/components/autocomplete/AutocompleteHint.tsx index 9719cd2e81acd7..8ba7dab31887e3 100644 --- a/docs/data/material/components/autocomplete/AutocompleteHint.tsx +++ b/docs/data/material/components/autocomplete/AutocompleteHint.tsx @@ -6,23 +6,38 @@ import Typography from '@mui/material/Typography'; import top100Films from './top100Films'; export default function AutocompleteHint() { - const hint = React.useRef(''); const [inputValue, setInputValue] = React.useState(''); + const [hint, setHint] = React.useState(''); + return ( { - if (event.key === 'Tab') { - if (hint.current) { - setInputValue(hint.current); - event.preventDefault(); - } + if (event.key === 'Tab' && hint) { + setInputValue(hint); + setHint(''); + event.preventDefault(); } }} onClose={() => { - hint.current = ''; + setHint(''); }} onChange={(event, newValue) => { - setInputValue(newValue && newValue.label ? newValue.label : ''); + setInputValue(newValue?.label ?? ''); + setHint(''); + }} + onInputChange={(event, newInputValue, reason) => { + setInputValue(newInputValue); + + if (reason !== 'input') { + setHint(''); + return; + } + + const matchingOption = top100Films.find((option) => + option.label.startsWith(newInputValue), + ); + + setHint(newInputValue && matchingOption ? matchingOption.label : ''); }} disablePortal resetHighlightOnMouseLeave @@ -33,35 +48,20 @@ export default function AutocompleteHint() { return ( - { - const newValue = event.target.value; - setInputValue(newValue); - const matchingOption = top100Films.find((option) => - option.label.startsWith(newValue), - ); - - if (newValue && matchingOption) { - hint.current = matchingOption.label; - } else { - hint.current = ''; - } - }} - label="Movie" - /> + ); }} diff --git a/docs/data/material/components/autocomplete/CheckboxesTags.js b/docs/data/material/components/autocomplete/CheckboxesTags.js index 992a8dce00fb58..709f134b795b5e 100644 --- a/docs/data/material/components/autocomplete/CheckboxesTags.js +++ b/docs/data/material/components/autocomplete/CheckboxesTags.js @@ -2,6 +2,7 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import top100Films from './top100Films'; export default function CheckboxesTags() { return ( @@ -9,7 +10,6 @@ export default function CheckboxesTags() { multiple options={top100Films} disableCloseOnSelect - getOptionLabel={(option) => option.title} renderOption={(props, option, { selected }) => { const { key, ...optionProps } = props; const SelectionIcon = selected ? CheckBoxIcon : CheckBoxOutlineBlankIcon; @@ -18,67 +18,16 @@ export default function CheckboxesTags() {
  • - {option.title} + {option.label}
  • ); }} - style={{ width: 500 }} + sx={{ width: 500 }} renderInput={(params) => ( )} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, -]; diff --git a/docs/data/material/components/autocomplete/CheckboxesTags.tsx b/docs/data/material/components/autocomplete/CheckboxesTags.tsx index 992a8dce00fb58..709f134b795b5e 100644 --- a/docs/data/material/components/autocomplete/CheckboxesTags.tsx +++ b/docs/data/material/components/autocomplete/CheckboxesTags.tsx @@ -2,6 +2,7 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import top100Films from './top100Films'; export default function CheckboxesTags() { return ( @@ -9,7 +10,6 @@ export default function CheckboxesTags() { multiple options={top100Films} disableCloseOnSelect - getOptionLabel={(option) => option.title} renderOption={(props, option, { selected }) => { const { key, ...optionProps } = props; const SelectionIcon = selected ? CheckBoxIcon : CheckBoxOutlineBlankIcon; @@ -18,67 +18,16 @@ export default function CheckboxesTags() {
  • - {option.title} + {option.label}
  • ); }} - style={{ width: 500 }} + sx={{ width: 500 }} renderInput={(params) => ( )} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, -]; diff --git a/docs/data/material/components/autocomplete/ControllableStates.js b/docs/data/material/components/autocomplete/ControllableStates.js index 409d3159223308..ebed98009beaac 100644 --- a/docs/data/material/components/autocomplete/ControllableStates.js +++ b/docs/data/material/components/autocomplete/ControllableStates.js @@ -2,15 +2,27 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -const options = ['Option 1', 'Option 2']; +const langs = [ + { id: 'js', label: 'JavaScript' }, + { id: 'ts', label: 'TypeScript' }, + { id: 'py', label: 'Python' }, + { id: 'java', label: 'Java' }, + { id: 'cpp', label: 'C++' }, + { id: 'cs', label: 'C#' }, + { id: 'php', label: 'PHP' }, + { id: 'ruby', label: 'Ruby' }, + { id: 'go', label: 'Go' }, + { id: 'rust', label: 'Rust' }, + { id: 'swift', label: 'Swift' }, +]; export default function ControllableStates() { - const [value, setValue] = React.useState(options[0]); + const [value, setValue] = React.useState(langs[0]); const [inputValue, setInputValue] = React.useState(''); return (
    -
    {`value: ${value !== null ? `'${value}'` : 'null'}`}
    +
    {`value: ${value !== null ? `'${value.label}'` : 'null'}`}
    {`inputValue: '${inputValue}'`}

    { setInputValue(newInputValue); }} - options={options} + options={langs} + isOptionEqualToValue={(option, selectedValue) => + option.id === selectedValue.id + } sx={{ width: 300 }} - renderInput={(params) => } + renderInput={(params) => } />
    ); diff --git a/docs/data/material/components/autocomplete/ControllableStates.tsx b/docs/data/material/components/autocomplete/ControllableStates.tsx index c8047e956a0a30..dfba4377dab249 100644 --- a/docs/data/material/components/autocomplete/ControllableStates.tsx +++ b/docs/data/material/components/autocomplete/ControllableStates.tsx @@ -2,15 +2,32 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -const options = ['Option 1', 'Option 2']; +interface ProgrammingLanguage { + id: string; + label: string; +} + +const langs: ProgrammingLanguage[] = [ + { id: 'js', label: 'JavaScript' }, + { id: 'ts', label: 'TypeScript' }, + { id: 'py', label: 'Python' }, + { id: 'java', label: 'Java' }, + { id: 'cpp', label: 'C++' }, + { id: 'cs', label: 'C#' }, + { id: 'php', label: 'PHP' }, + { id: 'ruby', label: 'Ruby' }, + { id: 'go', label: 'Go' }, + { id: 'rust', label: 'Rust' }, + { id: 'swift', label: 'Swift' }, +]; export default function ControllableStates() { - const [value, setValue] = React.useState(options[0]); + const [value, setValue] = React.useState(langs[0]); const [inputValue, setInputValue] = React.useState(''); return (
    -
    {`value: ${value !== null ? `'${value}'` : 'null'}`}
    +
    {`value: ${value !== null ? `'${value.label}'` : 'null'}`}
    {`inputValue: '${inputValue}'`}

    { setInputValue(newInputValue); }} - options={options} + options={langs} + isOptionEqualToValue={(option, selectedValue) => + option.id === selectedValue.id + } sx={{ width: 300 }} - renderInput={(params) => } + renderInput={(params) => } />
    ); diff --git a/docs/data/material/components/autocomplete/CountrySelect.js b/docs/data/material/components/autocomplete/CountrySelect.js index c4f49b55d92b4d..76608fe89a7c76 100644 --- a/docs/data/material/components/autocomplete/CountrySelect.js +++ b/docs/data/material/components/autocomplete/CountrySelect.js @@ -1,6 +1,7 @@ import Box from '@mui/material/Box'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import countries from './countries'; export default function CountrySelect() { return ( @@ -21,13 +22,26 @@ export default function CountrySelect() { - {option.label} ({option.code}) - - +{option.phone} + + {option.label} ({option.code}) + + + +{option.countryCallingCode} ); @@ -48,429 +62,3 @@ export default function CountrySelect() { /> ); } - -// From https://bitbucket.org/atlassian/atlaskit-mk-2/raw/4ad0e56649c3e6c973e226b7efaeb28cb240ccb0/packages/core/select/src/data/countries.js -const countries = [ - { code: 'AD', label: 'Andorra', phone: '376' }, - { - code: 'AE', - label: 'United Arab Emirates', - phone: '971', - }, - { code: 'AF', label: 'Afghanistan', phone: '93' }, - { - code: 'AG', - label: 'Antigua and Barbuda', - phone: '1-268', - }, - { code: 'AI', label: 'Anguilla', phone: '1-264' }, - { code: 'AL', label: 'Albania', phone: '355' }, - { code: 'AM', label: 'Armenia', phone: '374' }, - { code: 'AO', label: 'Angola', phone: '244' }, - { code: 'AQ', label: 'Antarctica', phone: '672' }, - { code: 'AR', label: 'Argentina', phone: '54' }, - { code: 'AS', label: 'American Samoa', phone: '1-684' }, - { code: 'AT', label: 'Austria', phone: '43' }, - { - code: 'AU', - label: 'Australia', - phone: '61', - suggested: true, - }, - { code: 'AW', label: 'Aruba', phone: '297' }, - { code: 'AX', label: 'Alland Islands', phone: '358' }, - { code: 'AZ', label: 'Azerbaijan', phone: '994' }, - { - code: 'BA', - label: 'Bosnia and Herzegovina', - phone: '387', - }, - { code: 'BB', label: 'Barbados', phone: '1-246' }, - { code: 'BD', label: 'Bangladesh', phone: '880' }, - { code: 'BE', label: 'Belgium', phone: '32' }, - { code: 'BF', label: 'Burkina Faso', phone: '226' }, - { code: 'BG', label: 'Bulgaria', phone: '359' }, - { code: 'BH', label: 'Bahrain', phone: '973' }, - { code: 'BI', label: 'Burundi', phone: '257' }, - { code: 'BJ', label: 'Benin', phone: '229' }, - { code: 'BL', label: 'Saint Barthelemy', phone: '590' }, - { code: 'BM', label: 'Bermuda', phone: '1-441' }, - { code: 'BN', label: 'Brunei Darussalam', phone: '673' }, - { code: 'BO', label: 'Bolivia', phone: '591' }, - { code: 'BR', label: 'Brazil', phone: '55' }, - { code: 'BS', label: 'Bahamas', phone: '1-242' }, - { code: 'BT', label: 'Bhutan', phone: '975' }, - { code: 'BV', label: 'Bouvet Island', phone: '47' }, - { code: 'BW', label: 'Botswana', phone: '267' }, - { code: 'BY', label: 'Belarus', phone: '375' }, - { code: 'BZ', label: 'Belize', phone: '501' }, - { - code: 'CA', - label: 'Canada', - phone: '1', - suggested: true, - }, - { - code: 'CC', - label: 'Cocos (Keeling) Islands', - phone: '61', - }, - { - code: 'CD', - label: 'Congo, Democratic Republic of the', - phone: '243', - }, - { - code: 'CF', - label: 'Central African Republic', - phone: '236', - }, - { - code: 'CG', - label: 'Congo, Republic of the', - phone: '242', - }, - { code: 'CH', label: 'Switzerland', phone: '41' }, - { code: 'CI', label: "Cote d'Ivoire", phone: '225' }, - { code: 'CK', label: 'Cook Islands', phone: '682' }, - { code: 'CL', label: 'Chile', phone: '56' }, - { code: 'CM', label: 'Cameroon', phone: '237' }, - { code: 'CN', label: 'China', phone: '86' }, - { code: 'CO', label: 'Colombia', phone: '57' }, - { code: 'CR', label: 'Costa Rica', phone: '506' }, - { code: 'CU', label: 'Cuba', phone: '53' }, - { code: 'CV', label: 'Cape Verde', phone: '238' }, - { code: 'CW', label: 'Curacao', phone: '599' }, - { code: 'CX', label: 'Christmas Island', phone: '61' }, - { code: 'CY', label: 'Cyprus', phone: '357' }, - { code: 'CZ', label: 'Czech Republic', phone: '420' }, - { - code: 'DE', - label: 'Germany', - phone: '49', - suggested: true, - }, - { code: 'DJ', label: 'Djibouti', phone: '253' }, - { code: 'DK', label: 'Denmark', phone: '45' }, - { code: 'DM', label: 'Dominica', phone: '1-767' }, - { - code: 'DO', - label: 'Dominican Republic', - phone: '1-809', - }, - { code: 'DZ', label: 'Algeria', phone: '213' }, - { code: 'EC', label: 'Ecuador', phone: '593' }, - { code: 'EE', label: 'Estonia', phone: '372' }, - { code: 'EG', label: 'Egypt', phone: '20' }, - { code: 'EH', label: 'Western Sahara', phone: '212' }, - { code: 'ER', label: 'Eritrea', phone: '291' }, - { code: 'ES', label: 'Spain', phone: '34' }, - { code: 'ET', label: 'Ethiopia', phone: '251' }, - { code: 'FI', label: 'Finland', phone: '358' }, - { code: 'FJ', label: 'Fiji', phone: '679' }, - { - code: 'FK', - label: 'Falkland Islands (Malvinas)', - phone: '500', - }, - { - code: 'FM', - label: 'Micronesia, Federated States of', - phone: '691', - }, - { code: 'FO', label: 'Faroe Islands', phone: '298' }, - { - code: 'FR', - label: 'France', - phone: '33', - suggested: true, - }, - { code: 'GA', label: 'Gabon', phone: '241' }, - { code: 'GB', label: 'United Kingdom', phone: '44' }, - { code: 'GD', label: 'Grenada', phone: '1-473' }, - { code: 'GE', label: 'Georgia', phone: '995' }, - { code: 'GF', label: 'French Guiana', phone: '594' }, - { code: 'GG', label: 'Guernsey', phone: '44' }, - { code: 'GH', label: 'Ghana', phone: '233' }, - { code: 'GI', label: 'Gibraltar', phone: '350' }, - { code: 'GL', label: 'Greenland', phone: '299' }, - { code: 'GM', label: 'Gambia', phone: '220' }, - { code: 'GN', label: 'Guinea', phone: '224' }, - { code: 'GP', label: 'Guadeloupe', phone: '590' }, - { code: 'GQ', label: 'Equatorial Guinea', phone: '240' }, - { code: 'GR', label: 'Greece', phone: '30' }, - { - code: 'GS', - label: 'South Georgia and the South Sandwich Islands', - phone: '500', - }, - { code: 'GT', label: 'Guatemala', phone: '502' }, - { code: 'GU', label: 'Guam', phone: '1-671' }, - { code: 'GW', label: 'Guinea-Bissau', phone: '245' }, - { code: 'GY', label: 'Guyana', phone: '592' }, - { code: 'HK', label: 'Hong Kong', phone: '852' }, - { - code: 'HM', - label: 'Heard Island and McDonald Islands', - phone: '672', - }, - { code: 'HN', label: 'Honduras', phone: '504' }, - { code: 'HR', label: 'Croatia', phone: '385' }, - { code: 'HT', label: 'Haiti', phone: '509' }, - { code: 'HU', label: 'Hungary', phone: '36' }, - { code: 'ID', label: 'Indonesia', phone: '62' }, - { code: 'IE', label: 'Ireland', phone: '353' }, - { code: 'IL', label: 'Israel', phone: '972' }, - { code: 'IM', label: 'Isle of Man', phone: '44' }, - { code: 'IN', label: 'India', phone: '91' }, - { - code: 'IO', - label: 'British Indian Ocean Territory', - phone: '246', - }, - { code: 'IQ', label: 'Iraq', phone: '964' }, - { - code: 'IR', - label: 'Iran, Islamic Republic of', - phone: '98', - }, - { code: 'IS', label: 'Iceland', phone: '354' }, - { code: 'IT', label: 'Italy', phone: '39' }, - { code: 'JE', label: 'Jersey', phone: '44' }, - { code: 'JM', label: 'Jamaica', phone: '1-876' }, - { code: 'JO', label: 'Jordan', phone: '962' }, - { - code: 'JP', - label: 'Japan', - phone: '81', - suggested: true, - }, - { code: 'KE', label: 'Kenya', phone: '254' }, - { code: 'KG', label: 'Kyrgyzstan', phone: '996' }, - { code: 'KH', label: 'Cambodia', phone: '855' }, - { code: 'KI', label: 'Kiribati', phone: '686' }, - { code: 'KM', label: 'Comoros', phone: '269' }, - { - code: 'KN', - label: 'Saint Kitts and Nevis', - phone: '1-869', - }, - { - code: 'KP', - label: "Korea, Democratic People's Republic of", - phone: '850', - }, - { code: 'KR', label: 'Korea, Republic of', phone: '82' }, - { code: 'KW', label: 'Kuwait', phone: '965' }, - { code: 'KY', label: 'Cayman Islands', phone: '1-345' }, - { code: 'KZ', label: 'Kazakhstan', phone: '7' }, - { - code: 'LA', - label: "Lao People's Democratic Republic", - phone: '856', - }, - { code: 'LB', label: 'Lebanon', phone: '961' }, - { code: 'LC', label: 'Saint Lucia', phone: '1-758' }, - { code: 'LI', label: 'Liechtenstein', phone: '423' }, - { code: 'LK', label: 'Sri Lanka', phone: '94' }, - { code: 'LR', label: 'Liberia', phone: '231' }, - { code: 'LS', label: 'Lesotho', phone: '266' }, - { code: 'LT', label: 'Lithuania', phone: '370' }, - { code: 'LU', label: 'Luxembourg', phone: '352' }, - { code: 'LV', label: 'Latvia', phone: '371' }, - { code: 'LY', label: 'Libya', phone: '218' }, - { code: 'MA', label: 'Morocco', phone: '212' }, - { code: 'MC', label: 'Monaco', phone: '377' }, - { - code: 'MD', - label: 'Moldova, Republic of', - phone: '373', - }, - { code: 'ME', label: 'Montenegro', phone: '382' }, - { - code: 'MF', - label: 'Saint Martin (French part)', - phone: '590', - }, - { code: 'MG', label: 'Madagascar', phone: '261' }, - { code: 'MH', label: 'Marshall Islands', phone: '692' }, - { - code: 'MK', - label: 'Macedonia, the Former Yugoslav Republic of', - phone: '389', - }, - { code: 'ML', label: 'Mali', phone: '223' }, - { code: 'MM', label: 'Myanmar', phone: '95' }, - { code: 'MN', label: 'Mongolia', phone: '976' }, - { code: 'MO', label: 'Macao', phone: '853' }, - { - code: 'MP', - label: 'Northern Mariana Islands', - phone: '1-670', - }, - { code: 'MQ', label: 'Martinique', phone: '596' }, - { code: 'MR', label: 'Mauritania', phone: '222' }, - { code: 'MS', label: 'Montserrat', phone: '1-664' }, - { code: 'MT', label: 'Malta', phone: '356' }, - { code: 'MU', label: 'Mauritius', phone: '230' }, - { code: 'MV', label: 'Maldives', phone: '960' }, - { code: 'MW', label: 'Malawi', phone: '265' }, - { code: 'MX', label: 'Mexico', phone: '52' }, - { code: 'MY', label: 'Malaysia', phone: '60' }, - { code: 'MZ', label: 'Mozambique', phone: '258' }, - { code: 'NA', label: 'Namibia', phone: '264' }, - { code: 'NC', label: 'New Caledonia', phone: '687' }, - { code: 'NE', label: 'Niger', phone: '227' }, - { code: 'NF', label: 'Norfolk Island', phone: '672' }, - { code: 'NG', label: 'Nigeria', phone: '234' }, - { code: 'NI', label: 'Nicaragua', phone: '505' }, - { code: 'NL', label: 'Netherlands', phone: '31' }, - { code: 'NO', label: 'Norway', phone: '47' }, - { code: 'NP', label: 'Nepal', phone: '977' }, - { code: 'NR', label: 'Nauru', phone: '674' }, - { code: 'NU', label: 'Niue', phone: '683' }, - { code: 'NZ', label: 'New Zealand', phone: '64' }, - { code: 'OM', label: 'Oman', phone: '968' }, - { code: 'PA', label: 'Panama', phone: '507' }, - { code: 'PE', label: 'Peru', phone: '51' }, - { code: 'PF', label: 'French Polynesia', phone: '689' }, - { code: 'PG', label: 'Papua New Guinea', phone: '675' }, - { code: 'PH', label: 'Philippines', phone: '63' }, - { code: 'PK', label: 'Pakistan', phone: '92' }, - { code: 'PL', label: 'Poland', phone: '48' }, - { - code: 'PM', - label: 'Saint Pierre and Miquelon', - phone: '508', - }, - { code: 'PN', label: 'Pitcairn', phone: '870' }, - { code: 'PR', label: 'Puerto Rico', phone: '1' }, - { - code: 'PS', - label: 'Palestine, State of', - phone: '970', - }, - { code: 'PT', label: 'Portugal', phone: '351' }, - { code: 'PW', label: 'Palau', phone: '680' }, - { code: 'PY', label: 'Paraguay', phone: '595' }, - { code: 'QA', label: 'Qatar', phone: '974' }, - { code: 'RE', label: 'Reunion', phone: '262' }, - { code: 'RO', label: 'Romania', phone: '40' }, - { code: 'RS', label: 'Serbia', phone: '381' }, - { code: 'RU', label: 'Russian Federation', phone: '7' }, - { code: 'RW', label: 'Rwanda', phone: '250' }, - { code: 'SA', label: 'Saudi Arabia', phone: '966' }, - { code: 'SB', label: 'Solomon Islands', phone: '677' }, - { code: 'SC', label: 'Seychelles', phone: '248' }, - { code: 'SD', label: 'Sudan', phone: '249' }, - { code: 'SE', label: 'Sweden', phone: '46' }, - { code: 'SG', label: 'Singapore', phone: '65' }, - { code: 'SH', label: 'Saint Helena', phone: '290' }, - { code: 'SI', label: 'Slovenia', phone: '386' }, - { - code: 'SJ', - label: 'Svalbard and Jan Mayen', - phone: '47', - }, - { code: 'SK', label: 'Slovakia', phone: '421' }, - { code: 'SL', label: 'Sierra Leone', phone: '232' }, - { code: 'SM', label: 'San Marino', phone: '378' }, - { code: 'SN', label: 'Senegal', phone: '221' }, - { code: 'SO', label: 'Somalia', phone: '252' }, - { code: 'SR', label: 'Suriname', phone: '597' }, - { code: 'SS', label: 'South Sudan', phone: '211' }, - { - code: 'ST', - label: 'Sao Tome and Principe', - phone: '239', - }, - { code: 'SV', label: 'El Salvador', phone: '503' }, - { - code: 'SX', - label: 'Sint Maarten (Dutch part)', - phone: '1-721', - }, - { - code: 'SY', - label: 'Syrian Arab Republic', - phone: '963', - }, - { code: 'SZ', label: 'Swaziland', phone: '268' }, - { - code: 'TC', - label: 'Turks and Caicos Islands', - phone: '1-649', - }, - { code: 'TD', label: 'Chad', phone: '235' }, - { - code: 'TF', - label: 'French Southern Territories', - phone: '262', - }, - { code: 'TG', label: 'Togo', phone: '228' }, - { code: 'TH', label: 'Thailand', phone: '66' }, - { code: 'TJ', label: 'Tajikistan', phone: '992' }, - { code: 'TK', label: 'Tokelau', phone: '690' }, - { code: 'TL', label: 'Timor-Leste', phone: '670' }, - { code: 'TM', label: 'Turkmenistan', phone: '993' }, - { code: 'TN', label: 'Tunisia', phone: '216' }, - { code: 'TO', label: 'Tonga', phone: '676' }, - { code: 'TR', label: 'Turkey', phone: '90' }, - { - code: 'TT', - label: 'Trinidad and Tobago', - phone: '1-868', - }, - { code: 'TV', label: 'Tuvalu', phone: '688' }, - { - code: 'TW', - label: 'Taiwan', - phone: '886', - }, - { - code: 'TZ', - label: 'United Republic of Tanzania', - phone: '255', - }, - { code: 'UA', label: 'Ukraine', phone: '380' }, - { code: 'UG', label: 'Uganda', phone: '256' }, - { - code: 'US', - label: 'United States', - phone: '1', - suggested: true, - }, - { code: 'UY', label: 'Uruguay', phone: '598' }, - { code: 'UZ', label: 'Uzbekistan', phone: '998' }, - { - code: 'VA', - label: 'Holy See (Vatican City State)', - phone: '379', - }, - { - code: 'VC', - label: 'Saint Vincent and the Grenadines', - phone: '1-784', - }, - { code: 'VE', label: 'Venezuela', phone: '58' }, - { - code: 'VG', - label: 'British Virgin Islands', - phone: '1-284', - }, - { - code: 'VI', - label: 'US Virgin Islands', - phone: '1-340', - }, - { code: 'VN', label: 'Vietnam', phone: '84' }, - { code: 'VU', label: 'Vanuatu', phone: '678' }, - { code: 'WF', label: 'Wallis and Futuna', phone: '681' }, - { code: 'WS', label: 'Samoa', phone: '685' }, - { code: 'XK', label: 'Kosovo', phone: '383' }, - { code: 'YE', label: 'Yemen', phone: '967' }, - { code: 'YT', label: 'Mayotte', phone: '262' }, - { code: 'ZA', label: 'South Africa', phone: '27' }, - { code: 'ZM', label: 'Zambia', phone: '260' }, - { code: 'ZW', label: 'Zimbabwe', phone: '263' }, -]; diff --git a/docs/data/material/components/autocomplete/CountrySelect.tsx b/docs/data/material/components/autocomplete/CountrySelect.tsx index 13a196dc7584a7..76608fe89a7c76 100644 --- a/docs/data/material/components/autocomplete/CountrySelect.tsx +++ b/docs/data/material/components/autocomplete/CountrySelect.tsx @@ -1,6 +1,7 @@ import Box from '@mui/material/Box'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import countries from './countries'; export default function CountrySelect() { return ( @@ -21,13 +22,26 @@ export default function CountrySelect() { - {option.label} ({option.code}) - - +{option.phone} + + {option.label} ({option.code}) + + + +{option.countryCallingCode} ); @@ -48,434 +62,3 @@ export default function CountrySelect() { /> ); } -interface CountryType { - code: string; - label: string; - phone: string; - suggested?: boolean; -} -// From https://bitbucket.org/atlassian/atlaskit-mk-2/raw/4ad0e56649c3e6c973e226b7efaeb28cb240ccb0/packages/core/select/src/data/countries.js -const countries: readonly CountryType[] = [ - { code: 'AD', label: 'Andorra', phone: '376' }, - { - code: 'AE', - label: 'United Arab Emirates', - phone: '971', - }, - { code: 'AF', label: 'Afghanistan', phone: '93' }, - { - code: 'AG', - label: 'Antigua and Barbuda', - phone: '1-268', - }, - { code: 'AI', label: 'Anguilla', phone: '1-264' }, - { code: 'AL', label: 'Albania', phone: '355' }, - { code: 'AM', label: 'Armenia', phone: '374' }, - { code: 'AO', label: 'Angola', phone: '244' }, - { code: 'AQ', label: 'Antarctica', phone: '672' }, - { code: 'AR', label: 'Argentina', phone: '54' }, - { code: 'AS', label: 'American Samoa', phone: '1-684' }, - { code: 'AT', label: 'Austria', phone: '43' }, - { - code: 'AU', - label: 'Australia', - phone: '61', - suggested: true, - }, - { code: 'AW', label: 'Aruba', phone: '297' }, - { code: 'AX', label: 'Alland Islands', phone: '358' }, - { code: 'AZ', label: 'Azerbaijan', phone: '994' }, - { - code: 'BA', - label: 'Bosnia and Herzegovina', - phone: '387', - }, - { code: 'BB', label: 'Barbados', phone: '1-246' }, - { code: 'BD', label: 'Bangladesh', phone: '880' }, - { code: 'BE', label: 'Belgium', phone: '32' }, - { code: 'BF', label: 'Burkina Faso', phone: '226' }, - { code: 'BG', label: 'Bulgaria', phone: '359' }, - { code: 'BH', label: 'Bahrain', phone: '973' }, - { code: 'BI', label: 'Burundi', phone: '257' }, - { code: 'BJ', label: 'Benin', phone: '229' }, - { code: 'BL', label: 'Saint Barthelemy', phone: '590' }, - { code: 'BM', label: 'Bermuda', phone: '1-441' }, - { code: 'BN', label: 'Brunei Darussalam', phone: '673' }, - { code: 'BO', label: 'Bolivia', phone: '591' }, - { code: 'BR', label: 'Brazil', phone: '55' }, - { code: 'BS', label: 'Bahamas', phone: '1-242' }, - { code: 'BT', label: 'Bhutan', phone: '975' }, - { code: 'BV', label: 'Bouvet Island', phone: '47' }, - { code: 'BW', label: 'Botswana', phone: '267' }, - { code: 'BY', label: 'Belarus', phone: '375' }, - { code: 'BZ', label: 'Belize', phone: '501' }, - { - code: 'CA', - label: 'Canada', - phone: '1', - suggested: true, - }, - { - code: 'CC', - label: 'Cocos (Keeling) Islands', - phone: '61', - }, - { - code: 'CD', - label: 'Congo, Democratic Republic of the', - phone: '243', - }, - { - code: 'CF', - label: 'Central African Republic', - phone: '236', - }, - { - code: 'CG', - label: 'Congo, Republic of the', - phone: '242', - }, - { code: 'CH', label: 'Switzerland', phone: '41' }, - { code: 'CI', label: "Cote d'Ivoire", phone: '225' }, - { code: 'CK', label: 'Cook Islands', phone: '682' }, - { code: 'CL', label: 'Chile', phone: '56' }, - { code: 'CM', label: 'Cameroon', phone: '237' }, - { code: 'CN', label: 'China', phone: '86' }, - { code: 'CO', label: 'Colombia', phone: '57' }, - { code: 'CR', label: 'Costa Rica', phone: '506' }, - { code: 'CU', label: 'Cuba', phone: '53' }, - { code: 'CV', label: 'Cape Verde', phone: '238' }, - { code: 'CW', label: 'Curacao', phone: '599' }, - { code: 'CX', label: 'Christmas Island', phone: '61' }, - { code: 'CY', label: 'Cyprus', phone: '357' }, - { code: 'CZ', label: 'Czech Republic', phone: '420' }, - { - code: 'DE', - label: 'Germany', - phone: '49', - suggested: true, - }, - { code: 'DJ', label: 'Djibouti', phone: '253' }, - { code: 'DK', label: 'Denmark', phone: '45' }, - { code: 'DM', label: 'Dominica', phone: '1-767' }, - { - code: 'DO', - label: 'Dominican Republic', - phone: '1-809', - }, - { code: 'DZ', label: 'Algeria', phone: '213' }, - { code: 'EC', label: 'Ecuador', phone: '593' }, - { code: 'EE', label: 'Estonia', phone: '372' }, - { code: 'EG', label: 'Egypt', phone: '20' }, - { code: 'EH', label: 'Western Sahara', phone: '212' }, - { code: 'ER', label: 'Eritrea', phone: '291' }, - { code: 'ES', label: 'Spain', phone: '34' }, - { code: 'ET', label: 'Ethiopia', phone: '251' }, - { code: 'FI', label: 'Finland', phone: '358' }, - { code: 'FJ', label: 'Fiji', phone: '679' }, - { - code: 'FK', - label: 'Falkland Islands (Malvinas)', - phone: '500', - }, - { - code: 'FM', - label: 'Micronesia, Federated States of', - phone: '691', - }, - { code: 'FO', label: 'Faroe Islands', phone: '298' }, - { - code: 'FR', - label: 'France', - phone: '33', - suggested: true, - }, - { code: 'GA', label: 'Gabon', phone: '241' }, - { code: 'GB', label: 'United Kingdom', phone: '44' }, - { code: 'GD', label: 'Grenada', phone: '1-473' }, - { code: 'GE', label: 'Georgia', phone: '995' }, - { code: 'GF', label: 'French Guiana', phone: '594' }, - { code: 'GG', label: 'Guernsey', phone: '44' }, - { code: 'GH', label: 'Ghana', phone: '233' }, - { code: 'GI', label: 'Gibraltar', phone: '350' }, - { code: 'GL', label: 'Greenland', phone: '299' }, - { code: 'GM', label: 'Gambia', phone: '220' }, - { code: 'GN', label: 'Guinea', phone: '224' }, - { code: 'GP', label: 'Guadeloupe', phone: '590' }, - { code: 'GQ', label: 'Equatorial Guinea', phone: '240' }, - { code: 'GR', label: 'Greece', phone: '30' }, - { - code: 'GS', - label: 'South Georgia and the South Sandwich Islands', - phone: '500', - }, - { code: 'GT', label: 'Guatemala', phone: '502' }, - { code: 'GU', label: 'Guam', phone: '1-671' }, - { code: 'GW', label: 'Guinea-Bissau', phone: '245' }, - { code: 'GY', label: 'Guyana', phone: '592' }, - { code: 'HK', label: 'Hong Kong', phone: '852' }, - { - code: 'HM', - label: 'Heard Island and McDonald Islands', - phone: '672', - }, - { code: 'HN', label: 'Honduras', phone: '504' }, - { code: 'HR', label: 'Croatia', phone: '385' }, - { code: 'HT', label: 'Haiti', phone: '509' }, - { code: 'HU', label: 'Hungary', phone: '36' }, - { code: 'ID', label: 'Indonesia', phone: '62' }, - { code: 'IE', label: 'Ireland', phone: '353' }, - { code: 'IL', label: 'Israel', phone: '972' }, - { code: 'IM', label: 'Isle of Man', phone: '44' }, - { code: 'IN', label: 'India', phone: '91' }, - { - code: 'IO', - label: 'British Indian Ocean Territory', - phone: '246', - }, - { code: 'IQ', label: 'Iraq', phone: '964' }, - { - code: 'IR', - label: 'Iran, Islamic Republic of', - phone: '98', - }, - { code: 'IS', label: 'Iceland', phone: '354' }, - { code: 'IT', label: 'Italy', phone: '39' }, - { code: 'JE', label: 'Jersey', phone: '44' }, - { code: 'JM', label: 'Jamaica', phone: '1-876' }, - { code: 'JO', label: 'Jordan', phone: '962' }, - { - code: 'JP', - label: 'Japan', - phone: '81', - suggested: true, - }, - { code: 'KE', label: 'Kenya', phone: '254' }, - { code: 'KG', label: 'Kyrgyzstan', phone: '996' }, - { code: 'KH', label: 'Cambodia', phone: '855' }, - { code: 'KI', label: 'Kiribati', phone: '686' }, - { code: 'KM', label: 'Comoros', phone: '269' }, - { - code: 'KN', - label: 'Saint Kitts and Nevis', - phone: '1-869', - }, - { - code: 'KP', - label: "Korea, Democratic People's Republic of", - phone: '850', - }, - { code: 'KR', label: 'Korea, Republic of', phone: '82' }, - { code: 'KW', label: 'Kuwait', phone: '965' }, - { code: 'KY', label: 'Cayman Islands', phone: '1-345' }, - { code: 'KZ', label: 'Kazakhstan', phone: '7' }, - { - code: 'LA', - label: "Lao People's Democratic Republic", - phone: '856', - }, - { code: 'LB', label: 'Lebanon', phone: '961' }, - { code: 'LC', label: 'Saint Lucia', phone: '1-758' }, - { code: 'LI', label: 'Liechtenstein', phone: '423' }, - { code: 'LK', label: 'Sri Lanka', phone: '94' }, - { code: 'LR', label: 'Liberia', phone: '231' }, - { code: 'LS', label: 'Lesotho', phone: '266' }, - { code: 'LT', label: 'Lithuania', phone: '370' }, - { code: 'LU', label: 'Luxembourg', phone: '352' }, - { code: 'LV', label: 'Latvia', phone: '371' }, - { code: 'LY', label: 'Libya', phone: '218' }, - { code: 'MA', label: 'Morocco', phone: '212' }, - { code: 'MC', label: 'Monaco', phone: '377' }, - { - code: 'MD', - label: 'Moldova, Republic of', - phone: '373', - }, - { code: 'ME', label: 'Montenegro', phone: '382' }, - { - code: 'MF', - label: 'Saint Martin (French part)', - phone: '590', - }, - { code: 'MG', label: 'Madagascar', phone: '261' }, - { code: 'MH', label: 'Marshall Islands', phone: '692' }, - { - code: 'MK', - label: 'Macedonia, the Former Yugoslav Republic of', - phone: '389', - }, - { code: 'ML', label: 'Mali', phone: '223' }, - { code: 'MM', label: 'Myanmar', phone: '95' }, - { code: 'MN', label: 'Mongolia', phone: '976' }, - { code: 'MO', label: 'Macao', phone: '853' }, - { - code: 'MP', - label: 'Northern Mariana Islands', - phone: '1-670', - }, - { code: 'MQ', label: 'Martinique', phone: '596' }, - { code: 'MR', label: 'Mauritania', phone: '222' }, - { code: 'MS', label: 'Montserrat', phone: '1-664' }, - { code: 'MT', label: 'Malta', phone: '356' }, - { code: 'MU', label: 'Mauritius', phone: '230' }, - { code: 'MV', label: 'Maldives', phone: '960' }, - { code: 'MW', label: 'Malawi', phone: '265' }, - { code: 'MX', label: 'Mexico', phone: '52' }, - { code: 'MY', label: 'Malaysia', phone: '60' }, - { code: 'MZ', label: 'Mozambique', phone: '258' }, - { code: 'NA', label: 'Namibia', phone: '264' }, - { code: 'NC', label: 'New Caledonia', phone: '687' }, - { code: 'NE', label: 'Niger', phone: '227' }, - { code: 'NF', label: 'Norfolk Island', phone: '672' }, - { code: 'NG', label: 'Nigeria', phone: '234' }, - { code: 'NI', label: 'Nicaragua', phone: '505' }, - { code: 'NL', label: 'Netherlands', phone: '31' }, - { code: 'NO', label: 'Norway', phone: '47' }, - { code: 'NP', label: 'Nepal', phone: '977' }, - { code: 'NR', label: 'Nauru', phone: '674' }, - { code: 'NU', label: 'Niue', phone: '683' }, - { code: 'NZ', label: 'New Zealand', phone: '64' }, - { code: 'OM', label: 'Oman', phone: '968' }, - { code: 'PA', label: 'Panama', phone: '507' }, - { code: 'PE', label: 'Peru', phone: '51' }, - { code: 'PF', label: 'French Polynesia', phone: '689' }, - { code: 'PG', label: 'Papua New Guinea', phone: '675' }, - { code: 'PH', label: 'Philippines', phone: '63' }, - { code: 'PK', label: 'Pakistan', phone: '92' }, - { code: 'PL', label: 'Poland', phone: '48' }, - { - code: 'PM', - label: 'Saint Pierre and Miquelon', - phone: '508', - }, - { code: 'PN', label: 'Pitcairn', phone: '870' }, - { code: 'PR', label: 'Puerto Rico', phone: '1' }, - { - code: 'PS', - label: 'Palestine, State of', - phone: '970', - }, - { code: 'PT', label: 'Portugal', phone: '351' }, - { code: 'PW', label: 'Palau', phone: '680' }, - { code: 'PY', label: 'Paraguay', phone: '595' }, - { code: 'QA', label: 'Qatar', phone: '974' }, - { code: 'RE', label: 'Reunion', phone: '262' }, - { code: 'RO', label: 'Romania', phone: '40' }, - { code: 'RS', label: 'Serbia', phone: '381' }, - { code: 'RU', label: 'Russian Federation', phone: '7' }, - { code: 'RW', label: 'Rwanda', phone: '250' }, - { code: 'SA', label: 'Saudi Arabia', phone: '966' }, - { code: 'SB', label: 'Solomon Islands', phone: '677' }, - { code: 'SC', label: 'Seychelles', phone: '248' }, - { code: 'SD', label: 'Sudan', phone: '249' }, - { code: 'SE', label: 'Sweden', phone: '46' }, - { code: 'SG', label: 'Singapore', phone: '65' }, - { code: 'SH', label: 'Saint Helena', phone: '290' }, - { code: 'SI', label: 'Slovenia', phone: '386' }, - { - code: 'SJ', - label: 'Svalbard and Jan Mayen', - phone: '47', - }, - { code: 'SK', label: 'Slovakia', phone: '421' }, - { code: 'SL', label: 'Sierra Leone', phone: '232' }, - { code: 'SM', label: 'San Marino', phone: '378' }, - { code: 'SN', label: 'Senegal', phone: '221' }, - { code: 'SO', label: 'Somalia', phone: '252' }, - { code: 'SR', label: 'Suriname', phone: '597' }, - { code: 'SS', label: 'South Sudan', phone: '211' }, - { - code: 'ST', - label: 'Sao Tome and Principe', - phone: '239', - }, - { code: 'SV', label: 'El Salvador', phone: '503' }, - { - code: 'SX', - label: 'Sint Maarten (Dutch part)', - phone: '1-721', - }, - { - code: 'SY', - label: 'Syrian Arab Republic', - phone: '963', - }, - { code: 'SZ', label: 'Swaziland', phone: '268' }, - { - code: 'TC', - label: 'Turks and Caicos Islands', - phone: '1-649', - }, - { code: 'TD', label: 'Chad', phone: '235' }, - { - code: 'TF', - label: 'French Southern Territories', - phone: '262', - }, - { code: 'TG', label: 'Togo', phone: '228' }, - { code: 'TH', label: 'Thailand', phone: '66' }, - { code: 'TJ', label: 'Tajikistan', phone: '992' }, - { code: 'TK', label: 'Tokelau', phone: '690' }, - { code: 'TL', label: 'Timor-Leste', phone: '670' }, - { code: 'TM', label: 'Turkmenistan', phone: '993' }, - { code: 'TN', label: 'Tunisia', phone: '216' }, - { code: 'TO', label: 'Tonga', phone: '676' }, - { code: 'TR', label: 'Turkey', phone: '90' }, - { - code: 'TT', - label: 'Trinidad and Tobago', - phone: '1-868', - }, - { code: 'TV', label: 'Tuvalu', phone: '688' }, - { - code: 'TW', - label: 'Taiwan', - phone: '886', - }, - { - code: 'TZ', - label: 'United Republic of Tanzania', - phone: '255', - }, - { code: 'UA', label: 'Ukraine', phone: '380' }, - { code: 'UG', label: 'Uganda', phone: '256' }, - { - code: 'US', - label: 'United States', - phone: '1', - suggested: true, - }, - { code: 'UY', label: 'Uruguay', phone: '598' }, - { code: 'UZ', label: 'Uzbekistan', phone: '998' }, - { - code: 'VA', - label: 'Holy See (Vatican City State)', - phone: '379', - }, - { - code: 'VC', - label: 'Saint Vincent and the Grenadines', - phone: '1-784', - }, - { code: 'VE', label: 'Venezuela', phone: '58' }, - { - code: 'VG', - label: 'British Virgin Islands', - phone: '1-284', - }, - { - code: 'VI', - label: 'US Virgin Islands', - phone: '1-340', - }, - { code: 'VN', label: 'Vietnam', phone: '84' }, - { code: 'VU', label: 'Vanuatu', phone: '678' }, - { code: 'WF', label: 'Wallis and Futuna', phone: '681' }, - { code: 'WS', label: 'Samoa', phone: '685' }, - { code: 'XK', label: 'Kosovo', phone: '383' }, - { code: 'YE', label: 'Yemen', phone: '967' }, - { code: 'YT', label: 'Mayotte', phone: '262' }, - { code: 'ZA', label: 'South Africa', phone: '27' }, - { code: 'ZM', label: 'Zambia', phone: '260' }, - { code: 'ZW', label: 'Zimbabwe', phone: '263' }, -]; diff --git a/docs/data/material/components/autocomplete/CustomInputAutocomplete.js b/docs/data/material/components/autocomplete/CustomInputAutocomplete.js deleted file mode 100644 index 76efdfed9403de..00000000000000 --- a/docs/data/material/components/autocomplete/CustomInputAutocomplete.js +++ /dev/null @@ -1,27 +0,0 @@ -import Autocomplete from '@mui/material/Autocomplete'; - -const options = ['Option 1', 'Option 2']; - -export default function CustomInputAutocomplete() { - return ( - - ); -} diff --git a/docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx b/docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx deleted file mode 100644 index 76efdfed9403de..00000000000000 --- a/docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import Autocomplete from '@mui/material/Autocomplete'; - -const options = ['Option 1', 'Option 2']; - -export default function CustomInputAutocomplete() { - return ( - - ); -} diff --git a/docs/data/material/components/autocomplete/CustomSingleValueRendering.js b/docs/data/material/components/autocomplete/CustomSingleValueRendering.js index 47dee0633df665..30bd4d3add2634 100644 --- a/docs/data/material/components/autocomplete/CustomSingleValueRendering.js +++ b/docs/data/material/components/autocomplete/CustomSingleValueRendering.js @@ -1,78 +1,224 @@ +import Box from '@mui/material/Box'; +import PropTypes from 'prop-types'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; export default function CustomSingleValueRendering() { return ( - - option.title} - renderValue={(value, getItemProps) => ( - - )} - renderInput={(params) => } - /> - option.title)} - freeSolo - renderValue={(value, getItemProps) => ( - - )} - renderInput={(params) => } - /> - + + `${option.brand} ending in ${getLastFourDigits(option.number)}` + } + isOptionEqualToValue={(option, value) => option.number === value.number} + renderOption={(props, option) => { + const { key, ...optionProps } = props; + return ( + + + {option.brand} + + *{getLastFourDigits(option.number)} + + + + ); + }} + renderValue={(value, getItemProps) => { + const itemProps = getItemProps(); + + return ( + + + + {value.brand} ending in {getLastFourDigits(value.number)} + + + ); + }} + renderInput={(params) => } + /> ); } -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, +function getLastFourDigits(cardNumber) { + return cardNumber.slice(-4); +} + +// Stripe test card numbers. +// https://docs.stripe.com/testing?testing-method=card-numbers#cards +const paymentMethods = [ { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, + brand: 'Visa', + number: '4242424242424242', }, { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, + brand: 'Mastercard', + number: '5555555555554444', }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, + brand: 'American Express', + number: '378282246310005', }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, + brand: 'Discover', + number: '6011111111111117', }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, ]; + +function CardBrandIcon(props) { + const { brand } = props; + + if (brand === 'Visa') { + return ( + + ); + } + + if (brand === 'Mastercard') { + return ( + + ); + } + + if (brand === 'American Express') { + return ( + + ); + } + + return ( + + ); +} + +CardBrandIcon.propTypes = { + brand: PropTypes.oneOf(['American Express', 'Discover', 'Mastercard', 'Visa']) + .isRequired, +}; diff --git a/docs/data/material/components/autocomplete/CustomSingleValueRendering.tsx b/docs/data/material/components/autocomplete/CustomSingleValueRendering.tsx index 47dee0633df665..4c4b0123ea5225 100644 --- a/docs/data/material/components/autocomplete/CustomSingleValueRendering.tsx +++ b/docs/data/material/components/autocomplete/CustomSingleValueRendering.tsx @@ -1,78 +1,225 @@ +import Box from '@mui/material/Box'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; + +type CardBrand = 'Visa' | 'Mastercard' | 'American Express' | 'Discover'; + +interface PaymentMethod { + brand: CardBrand; + number: string; +} export default function CustomSingleValueRendering() { return ( - - option.title} - renderValue={(value, getItemProps) => ( - - )} - renderInput={(params) => } - /> - option.title)} - freeSolo - renderValue={(value, getItemProps) => ( - - )} - renderInput={(params) => } - /> - + + `${option.brand} ending in ${getLastFourDigits(option.number)}` + } + isOptionEqualToValue={(option, value) => option.number === value.number} + renderOption={(props, option) => { + const { key, ...optionProps } = props; + return ( + + + {option.brand} + + *{getLastFourDigits(option.number)} + + + + ); + }} + renderValue={(value, getItemProps) => { + const itemProps = getItemProps(); + + return ( + + + + {value.brand} ending in {getLastFourDigits(value.number)} + + + ); + }} + renderInput={(params) => } + /> ); } -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, +function getLastFourDigits(cardNumber: string) { + return cardNumber.slice(-4); +} + +// Stripe test card numbers. +// https://docs.stripe.com/testing?testing-method=card-numbers#cards +const paymentMethods: readonly PaymentMethod[] = [ { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, + brand: 'Visa', + number: '4242424242424242', }, { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, + brand: 'Mastercard', + number: '5555555555554444', }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, + brand: 'American Express', + number: '378282246310005', }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, + brand: 'Discover', + number: '6011111111111117', }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, ]; + +function CardBrandIcon(props: { brand: CardBrand }) { + const { brand } = props; + + if (brand === 'Visa') { + return ( + + ); + } + + if (brand === 'Mastercard') { + return ( + + ); + } + + if (brand === 'American Express') { + return ( + + ); + } + + return ( + + ); +} diff --git a/docs/data/material/components/autocomplete/CustomSingleValueRendering.tsx.preview b/docs/data/material/components/autocomplete/CustomSingleValueRendering.tsx.preview deleted file mode 100644 index 62c58aed531d75..00000000000000 --- a/docs/data/material/components/autocomplete/CustomSingleValueRendering.tsx.preview +++ /dev/null @@ -1,16 +0,0 @@ - option.title} - renderValue={(value, getItemProps) => ( - - )} - renderInput={(params) => } -/> - option.title)} - freeSolo - renderValue={(value, getItemProps) => ( - - )} - renderInput={(params) => } -/> \ No newline at end of file diff --git a/docs/data/material/components/autocomplete/CustomizedHook.js b/docs/data/material/components/autocomplete/CustomizedHook.js index a49b3a42f55186..a89d075def1636 100644 --- a/docs/data/material/components/autocomplete/CustomizedHook.js +++ b/docs/data/material/components/autocomplete/CustomizedHook.js @@ -1,367 +1,418 @@ -import useAutocomplete from '@mui/material/useAutocomplete'; +import * as React from 'react'; import PropTypes from 'prop-types'; -import CheckIcon from '@mui/icons-material/Check'; -import CloseIcon from '@mui/icons-material/Close'; +import useAutocomplete from '@mui/material/useAutocomplete'; import { styled } from '@mui/material/styles'; import { autocompleteClasses } from '@mui/material/Autocomplete'; +const langs = [ + { id: 'js', value: 'JavaScript' }, + { id: 'ts', value: 'TypeScript' }, + { id: 'py', value: 'Python' }, + { id: 'java', value: 'Java' }, + { id: 'cpp', value: 'C++' }, + { id: 'cs', value: 'C#' }, + { id: 'php', value: 'PHP' }, + { id: 'ruby', value: 'Ruby' }, + { id: 'go', value: 'Go' }, + { id: 'rust', value: 'Rust' }, + { id: 'swift', value: 'Swift' }, +]; + +const defaultLangs = [langs[0]]; + +export default function CustomizedHook() { + const { + getRootProps, + getInputLabelProps, + getInputProps, + getItemProps, + getListboxProps, + getOptionProps, + groupedOptions, + value, + focusedItem, + popupOpen, + setAnchorEl, + } = useAutocomplete({ + id: 'customized-hook-demo', + multiple: true, + autoHighlight: true, + defaultValue: defaultLangs, + disableCloseOnSelect: true, + options: langs, + getOptionLabel: (option) => option.value, + isOptionEqualToValue: (option, selectedValue) => option.id === selectedValue.id, + }); + + return ( + + + 0 ? 'hasChips' : undefined} + > + {value.map((option, index) => { + const { key, ...itemProps } = getItemProps({ index }); + return ( + + ); + })} + 0 ? '' : 'e.g. TypeScript'} + /> + + {popupOpen ? ( + + {groupedOptions.length === 0 ? ( + No languages found. + ) : ( + groupedOptions.map((option, index) => { + const { key, ...optionProps } = getOptionProps({ option, index }); + return ( + + ); + }) + )} + + ) : null} + + ); +} + +const tokens = { + light: { + foreground: 'oklch(0.145 0 0)', + foregroundRing: 'oklch(0.145 0 0 / 10%)', + popover: 'oklch(1 0 0)', + popoverForeground: 'oklch(0.145 0 0)', + muted: 'oklch(0.97 0 0)', + mutedForeground: 'oklch(0.556 0 0)', + accent: 'oklch(0.97 0 0)', + accentForeground: 'oklch(0.205 0 0)', + input: 'oklch(0.922 0 0)', + ring: 'oklch(0.708 0 0)', + focusRing: 'oklch(0.708 0 0 / 50%)', + }, + dark: { + foreground: 'oklch(0.985 0 0)', + foregroundRing: 'oklch(0.985 0 0 / 10%)', + popover: 'oklch(0.205 0 0)', + popoverForeground: 'oklch(0.985 0 0)', + muted: 'oklch(0.269 0 0)', + mutedForeground: 'oklch(0.708 0 0)', + accent: 'oklch(0.269 0 0)', + accentForeground: 'oklch(0.985 0 0)', + input: 'oklch(1 0 0 / 15%)', + ring: 'oklch(0.556 0 0)', + focusRing: 'oklch(0.556 0 0 / 50%)', + }, +}; + const Root = styled('div')(({ theme }) => ({ - color: 'rgba(0,0,0,0.85)', - fontSize: '14px', + width: '100%', + maxWidth: 320, + position: 'relative', + display: 'flex', + flexDirection: 'column', + gap: 8, ...theme.applyStyles('dark', { - color: 'rgba(255,255,255,0.65)', + colorScheme: 'dark', }), })); -const Label = styled('label')` - padding: 0 0 4px; - line-height: 1.5; - display: block; -`; +const Label = styled('label')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + gap: 8, + fontSize: 14, + lineHeight: 1, + fontWeight: 500, + color: tokens.light.foreground, + userSelect: 'none', + ...theme.applyStyles('dark', { + color: tokens.dark.foreground, + }), +})); const InputWrapper = styled('div')(({ theme }) => ({ - width: '300px', - border: '1px solid #d9d9d9', - backgroundColor: '#fff', - borderRadius: '4px', - padding: '1px', + boxSizing: 'border-box', display: 'flex', flexWrap: 'wrap', - ...theme.applyStyles('dark', { - borderColor: '#434343', - backgroundColor: '#141414', - }), - '&:hover': { - borderColor: '#40a9ff', - ...theme.applyStyles('dark', { - borderColor: '#177ddc', - }), + alignItems: 'center', + gap: 4, + width: '100%', + minHeight: 32, + paddingBlock: 4, + paddingInline: 10, + borderWidth: 1, + borderStyle: 'solid', + borderColor: tokens.light.input, + borderRadius: 10, + backgroundColor: 'transparent', + backgroundClip: 'padding-box', + color: tokens.light.foreground, + cursor: 'text', + fontSize: 14, + transition: 'border-color 150ms, box-shadow 150ms, background-color 150ms', + '&.hasChips': { + paddingInline: 4, }, - '&.focused': { - borderColor: '#40a9ff', - boxShadow: '0 0 0 2px rgb(24 144 255 / 0.2)', - ...theme.applyStyles('dark', { - borderColor: '#177ddc', - }), + '&:focus-within': { + borderColor: tokens.light.ring, + boxShadow: `0 0 0 3px ${tokens.light.focusRing}`, }, '& input': { - backgroundColor: '#fff', - color: 'rgba(0,0,0,.85)', - height: '30px', + flex: 1, boxSizing: 'border-box', - padding: '4px 6px', - width: '0', - minWidth: '30px', - flexGrow: 1, - border: 0, + minWidth: 64, + height: 24, margin: 0, + padding: 0, + border: 0, + backgroundColor: 'transparent', + color: tokens.light.foreground, + fontFamily: 'inherit', + fontSize: 14, + fontWeight: 400, outline: 0, - ...theme.applyStyles('dark', { - color: 'rgba(255,255,255,0.65)', - backgroundColor: '#141414', - }), }, + '& input::placeholder': { + color: tokens.light.mutedForeground, + }, + ...theme.applyStyles('dark', { + borderColor: tokens.dark.input, + backgroundColor: 'oklch(1 0 0 / 4.5%)', + '&:focus-within': { + borderColor: tokens.dark.ring, + boxShadow: `0 0 0 3px ${tokens.dark.focusRing}`, + }, + '& input': { + color: tokens.dark.foreground, + }, + '& input::placeholder': { + color: tokens.dark.mutedForeground, + }, + }), })); -function Item(props) { - const { label, onDelete, ...other } = props; +function Chip(props) { + const { className, highlighted, label, onDelete, ...other } = props; + return ( -
    - {label} - +
    + {label} +
    ); } -Item.propTypes = { +Chip.propTypes = { + className: PropTypes.string, + highlighted: PropTypes.bool.isRequired, label: PropTypes.string.isRequired, onDelete: PropTypes.func.isRequired, }; -const StyledItem = styled(Item)(({ theme }) => ({ +const StyledChip = styled(Chip)(({ theme }) => ({ display: 'flex', alignItems: 'center', - height: '24px', - margin: '2px', - lineHeight: '22px', - backgroundColor: '#fafafa', - border: `1px solid #e8e8e8`, - borderRadius: '2px', - boxSizing: 'content-box', - padding: '0 4px 0 10px', - outline: 0, + justifyContent: 'center', + gap: 4, + width: 'fit-content', + height: 21, overflow: 'hidden', - ...theme.applyStyles('dark', { - backgroundColor: 'rgba(255,255,255,0.08)', - borderColor: '#303030', - }), - '&:focus': { - borderColor: '#40a9ff', - backgroundColor: '#e6f7ff', - ...theme.applyStyles('dark', { - backgroundColor: '#003b57', - borderColor: '#177ddc', - }), + paddingInline: 6, + borderRadius: 6, + backgroundColor: tokens.light.muted, + color: tokens.light.foreground, + fontSize: 12, + fontWeight: 500, + paddingRight: 0, + whiteSpace: 'nowrap', + outline: 0, + cursor: 'default', + userSelect: 'none', + '&.focused, &:focus-within': { + boxShadow: `0 0 0 2px ${tokens.light.focusRing}`, + }, + '& button': { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: 24, + height: 24, + marginLeft: -4, + padding: 0, + border: 0, + borderRadius: 8, + background: 'none', + color: 'inherit', + cursor: 'default', + opacity: 0.5, + transition: 'opacity 150ms, background-color 150ms', }, - '& span': { - overflow: 'hidden', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', + '@media (hover: hover)': { + '& button:hover': { + backgroundColor: tokens.light.muted, + opacity: 1, + }, }, '& svg': { - fontSize: '12px', - cursor: 'pointer', - padding: '4px', + width: 16, + height: 16, + pointerEvents: 'none', + flexShrink: 0, }, + ...theme.applyStyles('dark', { + backgroundColor: tokens.dark.muted, + color: tokens.dark.foreground, + '&.focused, &:focus-within': { + boxShadow: `0 0 0 2px ${tokens.dark.focusRing}`, + }, + '@media (hover: hover)': { + '& button:hover': { + backgroundColor: 'oklch(0.269 0 0 / 50%)', + }, + }, + }), })); const Listbox = styled('ul')(({ theme }) => ({ - width: '300px', - margin: '2px 0 0', - padding: 0, + boxSizing: 'border-box', position: 'absolute', + top: 'calc(100% + 6px)', + left: 0, + zIndex: 50, + width: '100%', + maxWidth: '100vw', + maxHeight: 252, + margin: 0, + padding: 4, + overflowY: 'auto', + overscrollBehavior: 'contain', + scrollPaddingBlock: 4, + borderRadius: 10, + backgroundColor: tokens.light.popover, + boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', + color: tokens.light.popoverForeground, listStyle: 'none', - backgroundColor: '#fff', - overflow: 'auto', - maxHeight: '250px', - borderRadius: '4px', - boxShadow: '0 2px 8px rgb(0 0 0 / 0.15)', - zIndex: 1, + outline: `1px solid ${tokens.light.foregroundRing}`, + transformOrigin: 'var(--transform-origin)', + transitionDuration: '100ms', ...theme.applyStyles('dark', { - backgroundColor: '#141414', + backgroundColor: tokens.dark.popover, + color: tokens.dark.popoverForeground, + outlineColor: tokens.dark.foregroundRing, }), - '& li': { - padding: '5px 12px', +})); + +const Option = styled('li')(({ theme }) => ({ + boxSizing: 'border-box', + position: 'relative', + display: 'flex', + width: '100%', + alignItems: 'center', + gap: 8, + borderRadius: 8, + paddingBlock: 4, + paddingLeft: 6, + paddingRight: 32, + fontSize: 14, + lineHeight: '20px', + outline: 0, + cursor: 'default', + userSelect: 'none', + '& svg': { + position: 'absolute', + right: 8, display: 'flex', - '& span': { - flexGrow: 1, - }, - '& svg': { - color: 'transparent', - }, + width: 16, + height: 16, + alignItems: 'center', + justifyContent: 'center', + pointerEvents: 'none', + flexShrink: 0, + visibility: 'hidden', }, - "& li[aria-selected='true']": { - backgroundColor: '#fafafa', - fontWeight: 600, - ...theme.applyStyles('dark', { - backgroundColor: '#2b2b2b', - }), + "&[aria-selected='true']": { '& svg': { - color: '#1890ff', + visibility: 'visible', }, }, - [`& li.${autocompleteClasses.focused}`]: { - backgroundColor: '#e6f7ff', - cursor: 'pointer', - ...theme.applyStyles('dark', { - backgroundColor: '#003b57', - }), - '& svg': { - color: 'currentColor', - }, + [`&.${autocompleteClasses.focused}`]: { + backgroundColor: tokens.light.accent, + color: tokens.light.accentForeground, }, + ...theme.applyStyles('dark', { + [`&.${autocompleteClasses.focused}`]: { + backgroundColor: tokens.dark.accent, + color: tokens.dark.accentForeground, + }, + }), })); -function CustomAutocomplete(props) { - const { - getRootProps, - getInputLabelProps, - getInputProps, - getItemProps, - getListboxProps, - getOptionProps, - groupedOptions, - value, - focused, - setAnchorEl, - } = useAutocomplete({ - multiple: true, - ...props, - }); +const EmptyOption = styled('li')(({ theme }) => ({ + boxSizing: 'border-box', + display: 'flex', + justifyContent: 'center', + width: '100%', + paddingBlock: 8, + paddingInline: 0, + color: tokens.light.mutedForeground, + fontSize: 14, + lineHeight: '20px', + textAlign: 'center', + ...theme.applyStyles('dark', { + color: tokens.dark.mutedForeground, + }), +})); +function CheckIcon(props) { return ( - -
    - - - {value.map((option, index) => { - const { key, ...itemProps } = getItemProps({ index }); - return ( - - ); - })} - - -
    - {groupedOptions.length > 0 ? ( - - {groupedOptions.map((option, index) => { - const { key, ...optionProps } = getOptionProps({ option, index }); - return ( -
  • - {props.getOptionLabel(option)} - -
  • - ); - })} -
    - ) : null} -
    + + + ); } -CustomAutocomplete.propTypes = { - /** - * 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). - * - * If used in free solo mode, it must accept both the type of the options and a string. - * - * @param {Value|string} option - * @returns {string} - * @default (option) => option.label ?? option - */ - getOptionLabel: PropTypes.func, -}; - -export default function CustomizedHook() { +function XIcon(props) { return ( - option.title} - /> + + + + ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/CustomizedHook.tsx b/docs/data/material/components/autocomplete/CustomizedHook.tsx index 1de2454253bca3..2f1b3d50fc1257 100644 --- a/docs/data/material/components/autocomplete/CustomizedHook.tsx +++ b/docs/data/material/components/autocomplete/CustomizedHook.tsx @@ -1,361 +1,423 @@ +import * as React from 'react'; import useAutocomplete, { - AutocompleteGetItemProps, - UseAutocompleteProps, + type AutocompleteGetItemProps, } from '@mui/material/useAutocomplete'; -import CheckIcon from '@mui/icons-material/Check'; -import CloseIcon from '@mui/icons-material/Close'; import { styled } from '@mui/material/styles'; import { autocompleteClasses } from '@mui/material/Autocomplete'; +interface ProgrammingLanguage { + id: string; + value: string; +} + +const langs: ProgrammingLanguage[] = [ + { id: 'js', value: 'JavaScript' }, + { id: 'ts', value: 'TypeScript' }, + { id: 'py', value: 'Python' }, + { id: 'java', value: 'Java' }, + { id: 'cpp', value: 'C++' }, + { id: 'cs', value: 'C#' }, + { id: 'php', value: 'PHP' }, + { id: 'ruby', value: 'Ruby' }, + { id: 'go', value: 'Go' }, + { id: 'rust', value: 'Rust' }, + { id: 'swift', value: 'Swift' }, +]; + +const defaultLangs = [langs[0]]; + +export default function CustomizedHook() { + const { + getRootProps, + getInputLabelProps, + getInputProps, + getItemProps, + getListboxProps, + getOptionProps, + groupedOptions, + value, + focusedItem, + popupOpen, + setAnchorEl, + } = useAutocomplete({ + id: 'customized-hook-demo', + multiple: true, + autoHighlight: true, + defaultValue: defaultLangs, + disableCloseOnSelect: true, + options: langs, + getOptionLabel: (option) => option.value, + isOptionEqualToValue: (option, selectedValue) => option.id === selectedValue.id, + }); + + return ( + + + 0 ? 'hasChips' : undefined} + > + {value.map((option, index) => { + const { key, ...itemProps } = getItemProps({ index }); + return ( + + ); + })} + 0 ? '' : 'e.g. TypeScript'} + /> + + {popupOpen ? ( + + {groupedOptions.length === 0 ? ( + No languages found. + ) : ( + groupedOptions.map((option, index) => { + const { key, ...optionProps } = getOptionProps({ option, index }); + return ( + + ); + }) + )} + + ) : null} + + ); +} + +const tokens = { + light: { + foreground: 'oklch(0.145 0 0)', + foregroundRing: 'oklch(0.145 0 0 / 10%)', + popover: 'oklch(1 0 0)', + popoverForeground: 'oklch(0.145 0 0)', + muted: 'oklch(0.97 0 0)', + mutedForeground: 'oklch(0.556 0 0)', + accent: 'oklch(0.97 0 0)', + accentForeground: 'oklch(0.205 0 0)', + input: 'oklch(0.922 0 0)', + ring: 'oklch(0.708 0 0)', + focusRing: 'oklch(0.708 0 0 / 50%)', + }, + dark: { + foreground: 'oklch(0.985 0 0)', + foregroundRing: 'oklch(0.985 0 0 / 10%)', + popover: 'oklch(0.205 0 0)', + popoverForeground: 'oklch(0.985 0 0)', + muted: 'oklch(0.269 0 0)', + mutedForeground: 'oklch(0.708 0 0)', + accent: 'oklch(0.269 0 0)', + accentForeground: 'oklch(0.985 0 0)', + input: 'oklch(1 0 0 / 15%)', + ring: 'oklch(0.556 0 0)', + focusRing: 'oklch(0.556 0 0 / 50%)', + }, +}; + const Root = styled('div')(({ theme }) => ({ - color: 'rgba(0,0,0,0.85)', - fontSize: '14px', + width: '100%', + maxWidth: 320, + position: 'relative', + display: 'flex', + flexDirection: 'column', + gap: 8, ...theme.applyStyles('dark', { - color: 'rgba(255,255,255,0.65)', + colorScheme: 'dark', }), })); -const Label = styled('label')` - padding: 0 0 4px; - line-height: 1.5; - display: block; -`; +const Label = styled('label')(({ theme }) => ({ + display: 'flex', + alignItems: 'center', + gap: 8, + fontSize: 14, + lineHeight: 1, + fontWeight: 500, + color: tokens.light.foreground, + userSelect: 'none', + ...theme.applyStyles('dark', { + color: tokens.dark.foreground, + }), +})); const InputWrapper = styled('div')(({ theme }) => ({ - width: '300px', - border: '1px solid #d9d9d9', - backgroundColor: '#fff', - borderRadius: '4px', - padding: '1px', + boxSizing: 'border-box', display: 'flex', flexWrap: 'wrap', - ...theme.applyStyles('dark', { - borderColor: '#434343', - backgroundColor: '#141414', - }), - '&:hover': { - borderColor: '#40a9ff', - ...theme.applyStyles('dark', { - borderColor: '#177ddc', - }), + alignItems: 'center', + gap: 4, + width: '100%', + minHeight: 32, + paddingBlock: 4, + paddingInline: 10, + borderWidth: 1, + borderStyle: 'solid', + borderColor: tokens.light.input, + borderRadius: 10, + backgroundColor: 'transparent', + backgroundClip: 'padding-box', + color: tokens.light.foreground, + cursor: 'text', + fontSize: 14, + transition: 'border-color 150ms, box-shadow 150ms, background-color 150ms', + '&.hasChips': { + paddingInline: 4, }, - '&.focused': { - borderColor: '#40a9ff', - boxShadow: '0 0 0 2px rgb(24 144 255 / 0.2)', - ...theme.applyStyles('dark', { - borderColor: '#177ddc', - }), + '&:focus-within': { + borderColor: tokens.light.ring, + boxShadow: `0 0 0 3px ${tokens.light.focusRing}`, }, '& input': { - backgroundColor: '#fff', - color: 'rgba(0,0,0,.85)', - height: '30px', + flex: 1, boxSizing: 'border-box', - padding: '4px 6px', - width: '0', - minWidth: '30px', - flexGrow: 1, - border: 0, + minWidth: 64, + height: 24, margin: 0, + padding: 0, + border: 0, + backgroundColor: 'transparent', + color: tokens.light.foreground, + fontFamily: 'inherit', + fontSize: 14, + fontWeight: 400, outline: 0, - ...theme.applyStyles('dark', { - color: 'rgba(255,255,255,0.65)', - backgroundColor: '#141414', - }), }, + '& input::placeholder': { + color: tokens.light.mutedForeground, + }, + ...theme.applyStyles('dark', { + borderColor: tokens.dark.input, + backgroundColor: 'oklch(1 0 0 / 4.5%)', + '&:focus-within': { + borderColor: tokens.dark.ring, + boxShadow: `0 0 0 3px ${tokens.dark.focusRing}`, + }, + '& input': { + color: tokens.dark.foreground, + }, + '& input::placeholder': { + color: tokens.dark.mutedForeground, + }, + }), })); -interface ItemProps extends ReturnType> { +interface ChipProps extends ReturnType> { label: string; + className?: string; + highlighted: boolean; } -function Item(props: ItemProps) { - const { label, onDelete, ...other } = props; +function Chip(props: ChipProps) { + const { className, highlighted, label, onDelete, ...other } = props; + return ( -
    - {label} - +
    + {label} +
    ); } -const StyledItem = styled(Item)(({ theme }) => ({ +const StyledChip = styled(Chip)(({ theme }) => ({ display: 'flex', alignItems: 'center', - height: '24px', - margin: '2px', - lineHeight: '22px', - backgroundColor: '#fafafa', - border: `1px solid #e8e8e8`, - borderRadius: '2px', - boxSizing: 'content-box', - padding: '0 4px 0 10px', - outline: 0, + justifyContent: 'center', + gap: 4, + width: 'fit-content', + height: 21, overflow: 'hidden', - ...theme.applyStyles('dark', { - backgroundColor: 'rgba(255,255,255,0.08)', - borderColor: '#303030', - }), - '&:focus': { - borderColor: '#40a9ff', - backgroundColor: '#e6f7ff', - ...theme.applyStyles('dark', { - backgroundColor: '#003b57', - borderColor: '#177ddc', - }), + paddingInline: 6, + borderRadius: 6, + backgroundColor: tokens.light.muted, + color: tokens.light.foreground, + fontSize: 12, + fontWeight: 500, + paddingRight: 0, + whiteSpace: 'nowrap', + outline: 0, + cursor: 'default', + userSelect: 'none', + '&.focused, &:focus-within': { + boxShadow: `0 0 0 2px ${tokens.light.focusRing}`, }, - '& span': { - overflow: 'hidden', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', + '& button': { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: 24, + height: 24, + marginLeft: -4, + padding: 0, + border: 0, + borderRadius: 8, + background: 'none', + color: 'inherit', + cursor: 'default', + opacity: 0.5, + transition: 'opacity 150ms, background-color 150ms', + }, + '@media (hover: hover)': { + '& button:hover': { + backgroundColor: tokens.light.muted, + opacity: 1, + }, }, '& svg': { - fontSize: '12px', - cursor: 'pointer', - padding: '4px', + width: 16, + height: 16, + pointerEvents: 'none', + flexShrink: 0, }, + ...theme.applyStyles('dark', { + backgroundColor: tokens.dark.muted, + color: tokens.dark.foreground, + '&.focused, &:focus-within': { + boxShadow: `0 0 0 2px ${tokens.dark.focusRing}`, + }, + '@media (hover: hover)': { + '& button:hover': { + backgroundColor: 'oklch(0.269 0 0 / 50%)', + }, + }, + }), })); const Listbox = styled('ul')(({ theme }) => ({ - width: '300px', - margin: '2px 0 0', - padding: 0, + boxSizing: 'border-box', position: 'absolute', + top: 'calc(100% + 6px)', + left: 0, + zIndex: 50, + width: '100%', + maxWidth: '100vw', + maxHeight: 252, + margin: 0, + padding: 4, + overflowY: 'auto', + overscrollBehavior: 'contain', + scrollPaddingBlock: 4, + borderRadius: 10, + backgroundColor: tokens.light.popover, + boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', + color: tokens.light.popoverForeground, listStyle: 'none', - backgroundColor: '#fff', - overflow: 'auto', - maxHeight: '250px', - borderRadius: '4px', - boxShadow: '0 2px 8px rgb(0 0 0 / 0.15)', - zIndex: 1, + outline: `1px solid ${tokens.light.foregroundRing}`, + transformOrigin: 'var(--transform-origin)', + transitionDuration: '100ms', ...theme.applyStyles('dark', { - backgroundColor: '#141414', + backgroundColor: tokens.dark.popover, + color: tokens.dark.popoverForeground, + outlineColor: tokens.dark.foregroundRing, }), - '& li': { - padding: '5px 12px', +})); + +const Option = styled('li')(({ theme }) => ({ + boxSizing: 'border-box', + position: 'relative', + display: 'flex', + width: '100%', + alignItems: 'center', + gap: 8, + borderRadius: 8, + paddingBlock: 4, + paddingLeft: 6, + paddingRight: 32, + fontSize: 14, + lineHeight: '20px', + outline: 0, + cursor: 'default', + userSelect: 'none', + '& svg': { + position: 'absolute', + right: 8, display: 'flex', - '& span': { - flexGrow: 1, - }, - '& svg': { - color: 'transparent', - }, + width: 16, + height: 16, + alignItems: 'center', + justifyContent: 'center', + pointerEvents: 'none', + flexShrink: 0, + visibility: 'hidden', }, - "& li[aria-selected='true']": { - backgroundColor: '#fafafa', - fontWeight: 600, - ...theme.applyStyles('dark', { - backgroundColor: '#2b2b2b', - }), + "&[aria-selected='true']": { '& svg': { - color: '#1890ff', + visibility: 'visible', }, }, - [`& li.${autocompleteClasses.focused}`]: { - backgroundColor: '#e6f7ff', - cursor: 'pointer', - ...theme.applyStyles('dark', { - backgroundColor: '#003b57', - }), - '& svg': { - color: 'currentColor', - }, + [`&.${autocompleteClasses.focused}`]: { + backgroundColor: tokens.light.accent, + color: tokens.light.accentForeground, }, + ...theme.applyStyles('dark', { + [`&.${autocompleteClasses.focused}`]: { + backgroundColor: tokens.dark.accent, + color: tokens.dark.accentForeground, + }, + }), })); -function CustomAutocomplete( - props: UseAutocompleteProps, -) { - const { - getRootProps, - getInputLabelProps, - getInputProps, - getItemProps, - getListboxProps, - getOptionProps, - groupedOptions, - value, - focused, - setAnchorEl, - } = useAutocomplete({ - multiple: true, - ...props, - }); +const EmptyOption = styled('li')(({ theme }) => ({ + boxSizing: 'border-box', + display: 'flex', + justifyContent: 'center', + width: '100%', + paddingBlock: 8, + paddingInline: 0, + color: tokens.light.mutedForeground, + fontSize: 14, + lineHeight: '20px', + textAlign: 'center', + ...theme.applyStyles('dark', { + color: tokens.dark.mutedForeground, + }), +})); +function CheckIcon(props: React.ComponentProps<'svg'>) { return ( - -
    - - - {value.map((option, index) => { - const { key, ...itemProps } = getItemProps({ index }); - return ( - - ); - })} - - -
    - {groupedOptions.length > 0 ? ( - - {groupedOptions.map((option, index) => { - const { key, ...optionProps } = getOptionProps({ option, index }); - return ( -
  • - {props.getOptionLabel!(option)} - -
  • - ); - })} -
    - ) : null} -
    + + + ); } -export default function CustomizedHook() { +function XIcon(props: React.ComponentProps<'svg'>) { return ( - - defaultValue={[top100Films[1]]} - options={top100Films} - getOptionLabel={(option) => option.title} - /> + + + + ); } - -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 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/CustomizedHook.tsx.preview b/docs/data/material/components/autocomplete/CustomizedHook.tsx.preview deleted file mode 100644 index 11682646888cc5..00000000000000 --- a/docs/data/material/components/autocomplete/CustomizedHook.tsx.preview +++ /dev/null @@ -1,6 +0,0 @@ - - id="customized-hook-demo" - defaultValue={[top100Films[1]]} - options={top100Films} - getOptionLabel={(option) => option.title} -/> \ No newline at end of file diff --git a/docs/data/material/components/autocomplete/DisabledOptions.js b/docs/data/material/components/autocomplete/DisabledOptions.js index 81d62b703bd189..f872fad8f6faca 100644 --- a/docs/data/material/components/autocomplete/DisabledOptions.js +++ b/docs/data/material/components/autocomplete/DisabledOptions.js @@ -1,23 +1,26 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +// One time slot every 30 minutes. +const timeSlots = Array.from( + { length: 24 * 2 }, + (_, index) => + `${index < 20 ? '0' : ''}${Math.floor(index / 2)}:${ + index % 2 === 0 ? '00' : '30' + }`, +); + +const unavailableTimeSlots = new Set( + timeSlots.filter((_, index) => index % 4 === 0), +); + export default function DisabledOptions() { return ( - option === timeSlots[0] || option === timeSlots[2] - } + getOptionDisabled={(option) => unavailableTimeSlots.has(option)} sx={{ width: 300 }} - renderInput={(params) => } + renderInput={(params) => } /> ); } - -// 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/data/material/components/autocomplete/DisabledOptions.tsx b/docs/data/material/components/autocomplete/DisabledOptions.tsx index 81d62b703bd189..f872fad8f6faca 100644 --- a/docs/data/material/components/autocomplete/DisabledOptions.tsx +++ b/docs/data/material/components/autocomplete/DisabledOptions.tsx @@ -1,23 +1,26 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +// One time slot every 30 minutes. +const timeSlots = Array.from( + { length: 24 * 2 }, + (_, index) => + `${index < 20 ? '0' : ''}${Math.floor(index / 2)}:${ + index % 2 === 0 ? '00' : '30' + }`, +); + +const unavailableTimeSlots = new Set( + timeSlots.filter((_, index) => index % 4 === 0), +); + export default function DisabledOptions() { return ( - option === timeSlots[0] || option === timeSlots[2] - } + getOptionDisabled={(option) => unavailableTimeSlots.has(option)} sx={{ width: 300 }} - renderInput={(params) => } + renderInput={(params) => } /> ); } - -// 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/data/material/components/autocomplete/DisabledOptions.tsx.preview b/docs/data/material/components/autocomplete/DisabledOptions.tsx.preview index 528fc85290a1d3..c45b52b201e8ad 100644 --- a/docs/data/material/components/autocomplete/DisabledOptions.tsx.preview +++ b/docs/data/material/components/autocomplete/DisabledOptions.tsx.preview @@ -1,8 +1,6 @@ - option === timeSlots[0] || option === timeSlots[2] - } + getOptionDisabled={(option) => unavailableTimeSlots.has(option)} sx={{ width: 300 }} - renderInput={(params) => } + renderInput={(params) => } /> \ No newline at end of file diff --git a/docs/data/material/components/autocomplete/Filter.js b/docs/data/material/components/autocomplete/Filter.js index 1b51f236259e4c..e5a566c8abdeb1 100644 --- a/docs/data/material/components/autocomplete/Filter.js +++ b/docs/data/material/components/autocomplete/Filter.js @@ -1,147 +1,19 @@ import TextField from '@mui/material/TextField'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; const filterOptions = createFilterOptions({ matchFrom: 'start', - stringify: (option) => option.title, + stringify: (option) => option.label, }); export default function Filter() { return ( option.title} filterOptions={filterOptions} sx={{ width: 300 }} renderInput={(params) => } /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Filter.tsx b/docs/data/material/components/autocomplete/Filter.tsx index b512bedd4bb0d0..3e3322c1504117 100644 --- a/docs/data/material/components/autocomplete/Filter.tsx +++ b/docs/data/material/components/autocomplete/Filter.tsx @@ -1,152 +1,19 @@ import TextField from '@mui/material/TextField'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; -const filterOptions = createFilterOptions({ +const filterOptions = createFilterOptions<{ label: string; year: number }>({ matchFrom: 'start', - stringify: (option: FilmOptionType) => option.title, + stringify: (option) => option.label, }); export default function Filter() { return ( option.title} filterOptions={filterOptions} sx={{ width: 300 }} renderInput={(params) => } /> ); } - -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 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Filter.tsx.preview b/docs/data/material/components/autocomplete/Filter.tsx.preview index 7ca0d8bb8625c3..fbc0fc1d4d7768 100644 --- a/docs/data/material/components/autocomplete/Filter.tsx.preview +++ b/docs/data/material/components/autocomplete/Filter.tsx.preview @@ -1,6 +1,5 @@ option.title} filterOptions={filterOptions} sx={{ width: 300 }} renderInput={(params) => } diff --git a/docs/data/material/components/autocomplete/FixedTags.js b/docs/data/material/components/autocomplete/FixedTags.js index 610691f3dbc100..224ad8e4c73601 100644 --- a/docs/data/material/components/autocomplete/FixedTags.js +++ b/docs/data/material/components/autocomplete/FixedTags.js @@ -2,9 +2,11 @@ import * as React from 'react'; import Chip from '@mui/material/Chip'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; + +const fixedOptions = [top100Films[6]]; export default function FixedTags() { - const fixedOptions = [top100Films[6]]; const [value, setValue] = React.useState([...fixedOptions, top100Films[13]]); return ( @@ -18,152 +20,23 @@ export default function FixedTags() { ]); }} options={top100Films} - getOptionLabel={(option) => option.title} renderValue={(values, getItemProps) => values.map((option, index) => { const { key, ...itemProps } = getItemProps({ index }); return ( ); }) } - style={{ width: 500 }} + sx={{ width: 500 }} renderInput={(params) => ( )} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/FixedTags.tsx b/docs/data/material/components/autocomplete/FixedTags.tsx index 610691f3dbc100..224ad8e4c73601 100644 --- a/docs/data/material/components/autocomplete/FixedTags.tsx +++ b/docs/data/material/components/autocomplete/FixedTags.tsx @@ -2,9 +2,11 @@ import * as React from 'react'; import Chip from '@mui/material/Chip'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; + +const fixedOptions = [top100Films[6]]; export default function FixedTags() { - const fixedOptions = [top100Films[6]]; const [value, setValue] = React.useState([...fixedOptions, top100Films[13]]); return ( @@ -18,152 +20,23 @@ export default function FixedTags() { ]); }} options={top100Films} - getOptionLabel={(option) => option.title} renderValue={(values, getItemProps) => values.map((option, index) => { const { key, ...itemProps } = getItemProps({ index }); return ( ); }) } - style={{ width: 500 }} + sx={{ width: 500 }} renderInput={(params) => ( )} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/FreeSolo.js b/docs/data/material/components/autocomplete/FreeSolo.js index 115be646f3701c..3354a0ba82f223 100644 --- a/docs/data/material/components/autocomplete/FreeSolo.js +++ b/docs/data/material/components/autocomplete/FreeSolo.js @@ -1,6 +1,9 @@ import TextField from '@mui/material/TextField'; import Stack from '@mui/material/Stack'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; + +const filmTitles = top100Films.map((option) => option.label); export default function FreeSolo() { return ( @@ -8,14 +11,14 @@ export default function FreeSolo() { option.title)} + options={filmTitles} renderInput={(params) => } /> option.title)} + options={filmTitles} renderInput={(params) => ( )} getOptionLabel={(option) => - typeof option === 'string' ? option : option.title + typeof option === 'string' ? option : option.label } - // this demo demonstrates how the value parameter can be either an object (same type as option) or a string - // it could become a string if, for example, you press "Enter" in the input field + // A typed free solo value is a string, but a selected option is an object. + // The equality check needs to compare both shapes. isOptionEqualToValue={(option, value) => { if (typeof value === 'string') { - return option.title === value; + return option.label === value; } - return option.title === value.title; + return option.label === value.label; }} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/FreeSolo.tsx b/docs/data/material/components/autocomplete/FreeSolo.tsx index 115be646f3701c..3354a0ba82f223 100644 --- a/docs/data/material/components/autocomplete/FreeSolo.tsx +++ b/docs/data/material/components/autocomplete/FreeSolo.tsx @@ -1,6 +1,9 @@ import TextField from '@mui/material/TextField'; import Stack from '@mui/material/Stack'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; + +const filmTitles = top100Films.map((option) => option.label); export default function FreeSolo() { return ( @@ -8,14 +11,14 @@ export default function FreeSolo() { option.title)} + options={filmTitles} renderInput={(params) => } /> option.title)} + options={filmTitles} renderInput={(params) => ( )} getOptionLabel={(option) => - typeof option === 'string' ? option : option.title + typeof option === 'string' ? option : option.label } - // this demo demonstrates how the value parameter can be either an object (same type as option) or a string - // it could become a string if, for example, you press "Enter" in the input field + // A typed free solo value is a string, but a selected option is an object. + // The equality check needs to compare both shapes. isOptionEqualToValue={(option, value) => { if (typeof value === 'string') { - return option.title === value; + return option.label === value; } - return option.title === value.title; + return option.label === value.label; }} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/FreeSoloCreateOption.js b/docs/data/material/components/autocomplete/FreeSoloCreateOption.js index ac991ca6142ef2..f77348df852553 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOption.js +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOption.js @@ -1,8 +1,10 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; const filter = createFilterOptions(); +const filmOptions = top100Films; export default function FreeSoloCreateOption() { const [value, setValue] = React.useState(null); @@ -11,30 +13,18 @@ export default function FreeSoloCreateOption() { { - if (typeof newValue === 'string') { - setValue({ - title: newValue, - }); - } else if (newValue && newValue.inputValue) { - // Create a new value from the user input - setValue({ - title: newValue.inputValue, - }); - } else { - setValue(newValue); - } + setValue(newValue); }} filterOptions={(options, params) => { const filtered = filter(options, params); - const { inputValue } = params; + const { inputValue, getOptionLabel } = params; // Suggest the creation of a new value - const isExisting = options.some((option) => inputValue === option.title); + const isExisting = options.some( + (option) => inputValue === getOptionLabel(option), + ); if (inputValue !== '' && !isExisting) { - filtered.push({ - inputValue, - title: `Add "${inputValue}"`, - }); + filtered.push(inputValue); } return filtered; @@ -42,24 +32,18 @@ export default function FreeSoloCreateOption() { selectOnFocus clearOnBlur handleHomeEndKeys - options={top100Films} + options={filmOptions} getOptionLabel={(option) => { - // Value selected with enter, right from the input if (typeof option === 'string') { return option; } - // Add "xxx" option created dynamically - if (option.inputValue) { - return option.inputValue; - } - // Regular option - return option.title; + return option.label; }} renderOption={(props, option) => { const { key, ...optionProps } = props; return (
  • - {option.title} + {typeof option === 'string' ? `Add "${option}"` : option.label}
  • ); }} @@ -72,131 +56,3 @@ export default function FreeSoloCreateOption() { /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/FreeSoloCreateOption.tsx b/docs/data/material/components/autocomplete/FreeSoloCreateOption.tsx index 10266c7ba5b708..cc60fa36873107 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOption.tsx +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOption.tsx @@ -1,40 +1,35 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; -const filter = createFilterOptions(); +interface Film { + label: string; + year: number; +} + +const filter = createFilterOptions(); +const filmOptions: readonly Film[] = top100Films; export default function FreeSoloCreateOption() { - const [value, setValue] = React.useState(null); + const [value, setValue] = React.useState(null); return ( - value={value} onChange={(event, newValue) => { - if (typeof newValue === 'string') { - setValue({ - title: newValue, - }); - } else if (newValue && newValue.inputValue) { - // Create a new value from the user input - setValue({ - title: newValue.inputValue, - }); - } else { - setValue(newValue); - } + setValue(newValue); }} filterOptions={(options, params) => { const filtered = filter(options, params); - const { inputValue } = params; + const { inputValue, getOptionLabel } = params; // Suggest the creation of a new value - const isExisting = options.some((option) => inputValue === option.title); + const isExisting = options.some( + (option) => inputValue === getOptionLabel(option), + ); if (inputValue !== '' && !isExisting) { - filtered.push({ - inputValue, - title: `Add "${inputValue}"`, - }); + filtered.push(inputValue); } return filtered; @@ -42,24 +37,18 @@ export default function FreeSoloCreateOption() { selectOnFocus clearOnBlur handleHomeEndKeys - options={top100Films} + options={filmOptions} getOptionLabel={(option) => { - // Value selected with enter, right from the input if (typeof option === 'string') { return option; } - // Add "xxx" option created dynamically - if (option.inputValue) { - return option.inputValue; - } - // Regular option - return option.title; + return option.label; }} renderOption={(props, option) => { const { key, ...optionProps } = props; return (
  • - {option.title} + {typeof option === 'string' ? `Add "${option}"` : option.label}
  • ); }} @@ -72,137 +61,3 @@ export default function FreeSoloCreateOption() { /> ); } - -interface FilmOptionType { - inputValue?: string; - title: string; - year?: number; -} - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films: readonly FilmOptionType[] = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js index a46016095b7744..44bb5da780924f 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js @@ -8,8 +8,10 @@ import DialogActions from '@mui/material/DialogActions'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; const filter = createFilterOptions(); +const filmOptions = top100Films; export default function FreeSoloCreateOptionDialog() { const [value, setValue] = React.useState(null); @@ -17,45 +19,43 @@ export default function FreeSoloCreateOptionDialog() { const handleClose = () => { setDialogValue({ - title: '', + label: '', year: '', }); toggleOpen(false); }; const [dialogValue, setDialogValue] = React.useState({ - title: '', + label: '', year: '', }); const handleSubmit = (event) => { event.preventDefault(); setValue({ - title: dialogValue.title, - year: parseInt(dialogValue.year, 10), + label: dialogValue.label, + year: Number.parseInt(dialogValue.year, 10), }); handleClose(); }; + const handleCreateOption = (inputValue) => { + toggleOpen(true); + setDialogValue({ + label: inputValue, + year: '', + }); + }; + return ( { if (typeof newValue === 'string') { - // timeout to avoid instant validation of the dialog's form. + // Avoid instant validation of the dialog's form. setTimeout(() => { - toggleOpen(true); - setDialogValue({ - title: newValue, - year: '', - }); - }); - } else if (newValue && newValue.inputValue) { - toggleOpen(true); - setDialogValue({ - title: newValue.inputValue, - year: '', + handleCreateOption(newValue); }); } else { setValue(newValue); @@ -64,25 +64,23 @@ export default function FreeSoloCreateOptionDialog() { filterOptions={(options, params) => { const filtered = filter(options, params); - if (params.inputValue !== '') { - filtered.push({ - inputValue: params.inputValue, - title: `Add "${params.inputValue}"`, - }); + const { inputValue, getOptionLabel } = params; + const isExisting = options.some( + (option) => inputValue === getOptionLabel(option), + ); + + if (inputValue !== '' && !isExisting) { + filtered.push(inputValue); } return filtered; }} - options={top100Films} + options={filmOptions} getOptionLabel={(option) => { - // for example value selected with enter, right from the input if (typeof option === 'string') { return option; } - if (option.inputValue) { - return option.inputValue; - } - return option.title; + return option.label; }} selectOnFocus clearOnBlur @@ -91,7 +89,7 @@ export default function FreeSoloCreateOptionDialog() { const { key, ...optionProps } = props; return (
  • - {option.title} + {typeof option === 'string' ? `Add "${option}"` : option.label}
  • ); }} @@ -110,11 +108,11 @@ export default function FreeSoloCreateOptionDialog() { setDialogValue({ ...dialogValue, - title: event.target.value, + label: event.target.value, }) } label="title" @@ -144,131 +142,3 @@ export default function FreeSoloCreateOptionDialog() {
    ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx index f3fd4bc1803b9a..a712806dbeb0f7 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx @@ -8,54 +8,59 @@ import DialogActions from '@mui/material/DialogActions'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; -const filter = createFilterOptions(); +interface Film { + label: string; + year: number; +} + +const filter = createFilterOptions(); +const filmOptions: readonly Film[] = top100Films; export default function FreeSoloCreateOptionDialog() { - const [value, setValue] = React.useState(null); + const [value, setValue] = React.useState(null); const [open, toggleOpen] = React.useState(false); const handleClose = () => { setDialogValue({ - title: '', + label: '', year: '', }); toggleOpen(false); }; const [dialogValue, setDialogValue] = React.useState({ - title: '', + label: '', year: '', }); const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); setValue({ - title: dialogValue.title, - year: parseInt(dialogValue.year, 10), + label: dialogValue.label, + year: Number.parseInt(dialogValue.year, 10), }); handleClose(); }; + const handleCreateOption = (inputValue: string) => { + toggleOpen(true); + setDialogValue({ + label: inputValue, + year: '', + }); + }; + return ( - value={value} onChange={(event, newValue) => { if (typeof newValue === 'string') { - // timeout to avoid instant validation of the dialog's form. + // Avoid instant validation of the dialog's form. setTimeout(() => { - toggleOpen(true); - setDialogValue({ - title: newValue, - year: '', - }); - }); - } else if (newValue && newValue.inputValue) { - toggleOpen(true); - setDialogValue({ - title: newValue.inputValue, - year: '', + handleCreateOption(newValue); }); } else { setValue(newValue); @@ -64,25 +69,23 @@ export default function FreeSoloCreateOptionDialog() { filterOptions={(options, params) => { const filtered = filter(options, params); - if (params.inputValue !== '') { - filtered.push({ - inputValue: params.inputValue, - title: `Add "${params.inputValue}"`, - }); + const { inputValue, getOptionLabel } = params; + const isExisting = options.some( + (option) => inputValue === getOptionLabel(option), + ); + + if (inputValue !== '' && !isExisting) { + filtered.push(inputValue); } return filtered; }} - options={top100Films} + options={filmOptions} getOptionLabel={(option) => { - // for example value selected with enter, right from the input if (typeof option === 'string') { return option; } - if (option.inputValue) { - return option.inputValue; - } - return option.title; + return option.label; }} selectOnFocus clearOnBlur @@ -91,7 +94,7 @@ export default function FreeSoloCreateOptionDialog() { const { key, ...optionProps } = props; return (
  • - {option.title} + {typeof option === 'string' ? `Add "${option}"` : option.label}
  • ); }} @@ -110,11 +113,11 @@ export default function FreeSoloCreateOptionDialog() { setDialogValue({ ...dialogValue, - title: event.target.value, + label: event.target.value, }) } label="title" @@ -144,137 +147,3 @@ export default function FreeSoloCreateOptionDialog() {
    ); } - -interface FilmOptionType { - inputValue?: string; - title: string; - year?: number; -} - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films: readonly FilmOptionType[] = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js index c8825bfe0936e6..cea3b42dd730ff 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js @@ -1,8 +1,13 @@ import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; +import Chip from '@mui/material/Chip'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; -import { createTheme, useTheme, ThemeProvider } from '@mui/material/styles'; +import { createTheme, ThemeProvider } from '@mui/material/styles'; + +import countries from './countries'; + +const getOptionKey = (option) => `${option.label}-${option.detail}`; // Theme.ts const customTheme = (outerTheme) => @@ -18,20 +23,43 @@ const customTheme = (outerTheme) => defaultProps: { renderOption: (props, option, state, ownerState) => { const { key, ...optionProps } = props; + const { detail } = option; + return ( - {ownerState.getOptionLabel(option)} + + {ownerState.getOptionLabel(option)} + + ); }, @@ -40,28 +68,44 @@ const customTheme = (outerTheme) => }, }); -export default function GloballyCustomizedOptions() { - // useTheme is used to determine the dark or light mode of the docs to maintain the Autocomplete component default styles. - const outerTheme = useTheme(); +const languages = [ + { detail: 'en-US', label: 'English (US)' }, + { detail: 'en-GB', label: 'English (UK)' }, + { detail: 'es-ES', label: 'Spanish (Spain)' }, + { detail: 'es-MX', label: 'Spanish (Mexico)' }, + { detail: 'fr-FR', label: 'French' }, + { detail: 'de-DE', label: 'German' }, + { detail: 'it-IT', label: 'Italian' }, + { detail: 'ja-JP', label: 'Japanese' }, + { detail: 'ko-KR', label: 'Korean' }, + { detail: 'pt-BR', label: 'Portuguese' }, + { detail: 'zh-CN', label: 'Chinese (Simplified)' }, + { detail: 'zh-TW', label: 'Chinese (Traditional)' }, +]; + +const countryOptions = countries.map((country) => ({ + label: `${country.label} (${country.code})`, + detail: `+${country.countryCallingCode}`, +})); +export default function GloballyCustomizedOptions() { return ( - - - + + + ); } -function MovieSelect() { +function LanguageSelect() { return ( `${option.title} (${option.year})`} - disableCloseOnSelect + options={languages} + getOptionLabel={(option) => option.label} renderInput={(params) => ( - + )} /> ); @@ -70,566 +114,10 @@ function MovieSelect() { function CountrySelect() { return ( - `${option.label} (${option.code}) +${option.phone}` - } + options={countryOptions} + getOptionLabel={(option) => option.label} + getOptionKey={getOptionKey} renderInput={(params) => } /> ); } - -// From https://bitbucket.org/atlassian/atlaskit-mk-2/raw/4ad0e56649c3e6c973e226b7efaeb28cb240ccb0/packages/core/select/src/data/countries.js -const countries = [ - { code: 'AD', label: 'Andorra', phone: '376' }, - { - code: 'AE', - label: 'United Arab Emirates', - phone: '971', - }, - { code: 'AF', label: 'Afghanistan', phone: '93' }, - { - code: 'AG', - label: 'Antigua and Barbuda', - phone: '1-268', - }, - { code: 'AI', label: 'Anguilla', phone: '1-264' }, - { code: 'AL', label: 'Albania', phone: '355' }, - { code: 'AM', label: 'Armenia', phone: '374' }, - { code: 'AO', label: 'Angola', phone: '244' }, - { code: 'AQ', label: 'Antarctica', phone: '672' }, - { code: 'AR', label: 'Argentina', phone: '54' }, - { code: 'AS', label: 'American Samoa', phone: '1-684' }, - { code: 'AT', label: 'Austria', phone: '43' }, - { - code: 'AU', - label: 'Australia', - phone: '61', - suggested: true, - }, - { code: 'AW', label: 'Aruba', phone: '297' }, - { code: 'AX', label: 'Alland Islands', phone: '358' }, - { code: 'AZ', label: 'Azerbaijan', phone: '994' }, - { - code: 'BA', - label: 'Bosnia and Herzegovina', - phone: '387', - }, - { code: 'BB', label: 'Barbados', phone: '1-246' }, - { code: 'BD', label: 'Bangladesh', phone: '880' }, - { code: 'BE', label: 'Belgium', phone: '32' }, - { code: 'BF', label: 'Burkina Faso', phone: '226' }, - { code: 'BG', label: 'Bulgaria', phone: '359' }, - { code: 'BH', label: 'Bahrain', phone: '973' }, - { code: 'BI', label: 'Burundi', phone: '257' }, - { code: 'BJ', label: 'Benin', phone: '229' }, - { code: 'BL', label: 'Saint Barthelemy', phone: '590' }, - { code: 'BM', label: 'Bermuda', phone: '1-441' }, - { code: 'BN', label: 'Brunei Darussalam', phone: '673' }, - { code: 'BO', label: 'Bolivia', phone: '591' }, - { code: 'BR', label: 'Brazil', phone: '55' }, - { code: 'BS', label: 'Bahamas', phone: '1-242' }, - { code: 'BT', label: 'Bhutan', phone: '975' }, - { code: 'BV', label: 'Bouvet Island', phone: '47' }, - { code: 'BW', label: 'Botswana', phone: '267' }, - { code: 'BY', label: 'Belarus', phone: '375' }, - { code: 'BZ', label: 'Belize', phone: '501' }, - { - code: 'CA', - label: 'Canada', - phone: '1', - suggested: true, - }, - { - code: 'CC', - label: 'Cocos (Keeling) Islands', - phone: '61', - }, - { - code: 'CD', - label: 'Congo, Democratic Republic of the', - phone: '243', - }, - { - code: 'CF', - label: 'Central African Republic', - phone: '236', - }, - { - code: 'CG', - label: 'Congo, Republic of the', - phone: '242', - }, - { code: 'CH', label: 'Switzerland', phone: '41' }, - { code: 'CI', label: "Cote d'Ivoire", phone: '225' }, - { code: 'CK', label: 'Cook Islands', phone: '682' }, - { code: 'CL', label: 'Chile', phone: '56' }, - { code: 'CM', label: 'Cameroon', phone: '237' }, - { code: 'CN', label: 'China', phone: '86' }, - { code: 'CO', label: 'Colombia', phone: '57' }, - { code: 'CR', label: 'Costa Rica', phone: '506' }, - { code: 'CU', label: 'Cuba', phone: '53' }, - { code: 'CV', label: 'Cape Verde', phone: '238' }, - { code: 'CW', label: 'Curacao', phone: '599' }, - { code: 'CX', label: 'Christmas Island', phone: '61' }, - { code: 'CY', label: 'Cyprus', phone: '357' }, - { code: 'CZ', label: 'Czech Republic', phone: '420' }, - { - code: 'DE', - label: 'Germany', - phone: '49', - suggested: true, - }, - { code: 'DJ', label: 'Djibouti', phone: '253' }, - { code: 'DK', label: 'Denmark', phone: '45' }, - { code: 'DM', label: 'Dominica', phone: '1-767' }, - { - code: 'DO', - label: 'Dominican Republic', - phone: '1-809', - }, - { code: 'DZ', label: 'Algeria', phone: '213' }, - { code: 'EC', label: 'Ecuador', phone: '593' }, - { code: 'EE', label: 'Estonia', phone: '372' }, - { code: 'EG', label: 'Egypt', phone: '20' }, - { code: 'EH', label: 'Western Sahara', phone: '212' }, - { code: 'ER', label: 'Eritrea', phone: '291' }, - { code: 'ES', label: 'Spain', phone: '34' }, - { code: 'ET', label: 'Ethiopia', phone: '251' }, - { code: 'FI', label: 'Finland', phone: '358' }, - { code: 'FJ', label: 'Fiji', phone: '679' }, - { - code: 'FK', - label: 'Falkland Islands (Malvinas)', - phone: '500', - }, - { - code: 'FM', - label: 'Micronesia, Federated States of', - phone: '691', - }, - { code: 'FO', label: 'Faroe Islands', phone: '298' }, - { - code: 'FR', - label: 'France', - phone: '33', - suggested: true, - }, - { code: 'GA', label: 'Gabon', phone: '241' }, - { code: 'GB', label: 'United Kingdom', phone: '44' }, - { code: 'GD', label: 'Grenada', phone: '1-473' }, - { code: 'GE', label: 'Georgia', phone: '995' }, - { code: 'GF', label: 'French Guiana', phone: '594' }, - { code: 'GG', label: 'Guernsey', phone: '44' }, - { code: 'GH', label: 'Ghana', phone: '233' }, - { code: 'GI', label: 'Gibraltar', phone: '350' }, - { code: 'GL', label: 'Greenland', phone: '299' }, - { code: 'GM', label: 'Gambia', phone: '220' }, - { code: 'GN', label: 'Guinea', phone: '224' }, - { code: 'GP', label: 'Guadeloupe', phone: '590' }, - { code: 'GQ', label: 'Equatorial Guinea', phone: '240' }, - { code: 'GR', label: 'Greece', phone: '30' }, - { - code: 'GS', - label: 'South Georgia and the South Sandwich Islands', - phone: '500', - }, - { code: 'GT', label: 'Guatemala', phone: '502' }, - { code: 'GU', label: 'Guam', phone: '1-671' }, - { code: 'GW', label: 'Guinea-Bissau', phone: '245' }, - { code: 'GY', label: 'Guyana', phone: '592' }, - { code: 'HK', label: 'Hong Kong', phone: '852' }, - { - code: 'HM', - label: 'Heard Island and McDonald Islands', - phone: '672', - }, - { code: 'HN', label: 'Honduras', phone: '504' }, - { code: 'HR', label: 'Croatia', phone: '385' }, - { code: 'HT', label: 'Haiti', phone: '509' }, - { code: 'HU', label: 'Hungary', phone: '36' }, - { code: 'ID', label: 'Indonesia', phone: '62' }, - { code: 'IE', label: 'Ireland', phone: '353' }, - { code: 'IL', label: 'Israel', phone: '972' }, - { code: 'IM', label: 'Isle of Man', phone: '44' }, - { code: 'IN', label: 'India', phone: '91' }, - { - code: 'IO', - label: 'British Indian Ocean Territory', - phone: '246', - }, - { code: 'IQ', label: 'Iraq', phone: '964' }, - { - code: 'IR', - label: 'Iran, Islamic Republic of', - phone: '98', - }, - { code: 'IS', label: 'Iceland', phone: '354' }, - { code: 'IT', label: 'Italy', phone: '39' }, - { code: 'JE', label: 'Jersey', phone: '44' }, - { code: 'JM', label: 'Jamaica', phone: '1-876' }, - { code: 'JO', label: 'Jordan', phone: '962' }, - { - code: 'JP', - label: 'Japan', - phone: '81', - suggested: true, - }, - { code: 'KE', label: 'Kenya', phone: '254' }, - { code: 'KG', label: 'Kyrgyzstan', phone: '996' }, - { code: 'KH', label: 'Cambodia', phone: '855' }, - { code: 'KI', label: 'Kiribati', phone: '686' }, - { code: 'KM', label: 'Comoros', phone: '269' }, - { - code: 'KN', - label: 'Saint Kitts and Nevis', - phone: '1-869', - }, - { - code: 'KP', - label: "Korea, Democratic People's Republic of", - phone: '850', - }, - { code: 'KR', label: 'Korea, Republic of', phone: '82' }, - { code: 'KW', label: 'Kuwait', phone: '965' }, - { code: 'KY', label: 'Cayman Islands', phone: '1-345' }, - { code: 'KZ', label: 'Kazakhstan', phone: '7' }, - { - code: 'LA', - label: "Lao People's Democratic Republic", - phone: '856', - }, - { code: 'LB', label: 'Lebanon', phone: '961' }, - { code: 'LC', label: 'Saint Lucia', phone: '1-758' }, - { code: 'LI', label: 'Liechtenstein', phone: '423' }, - { code: 'LK', label: 'Sri Lanka', phone: '94' }, - { code: 'LR', label: 'Liberia', phone: '231' }, - { code: 'LS', label: 'Lesotho', phone: '266' }, - { code: 'LT', label: 'Lithuania', phone: '370' }, - { code: 'LU', label: 'Luxembourg', phone: '352' }, - { code: 'LV', label: 'Latvia', phone: '371' }, - { code: 'LY', label: 'Libya', phone: '218' }, - { code: 'MA', label: 'Morocco', phone: '212' }, - { code: 'MC', label: 'Monaco', phone: '377' }, - { - code: 'MD', - label: 'Moldova, Republic of', - phone: '373', - }, - { code: 'ME', label: 'Montenegro', phone: '382' }, - { - code: 'MF', - label: 'Saint Martin (French part)', - phone: '590', - }, - { code: 'MG', label: 'Madagascar', phone: '261' }, - { code: 'MH', label: 'Marshall Islands', phone: '692' }, - { - code: 'MK', - label: 'Macedonia, the Former Yugoslav Republic of', - phone: '389', - }, - { code: 'ML', label: 'Mali', phone: '223' }, - { code: 'MM', label: 'Myanmar', phone: '95' }, - { code: 'MN', label: 'Mongolia', phone: '976' }, - { code: 'MO', label: 'Macao', phone: '853' }, - { - code: 'MP', - label: 'Northern Mariana Islands', - phone: '1-670', - }, - { code: 'MQ', label: 'Martinique', phone: '596' }, - { code: 'MR', label: 'Mauritania', phone: '222' }, - { code: 'MS', label: 'Montserrat', phone: '1-664' }, - { code: 'MT', label: 'Malta', phone: '356' }, - { code: 'MU', label: 'Mauritius', phone: '230' }, - { code: 'MV', label: 'Maldives', phone: '960' }, - { code: 'MW', label: 'Malawi', phone: '265' }, - { code: 'MX', label: 'Mexico', phone: '52' }, - { code: 'MY', label: 'Malaysia', phone: '60' }, - { code: 'MZ', label: 'Mozambique', phone: '258' }, - { code: 'NA', label: 'Namibia', phone: '264' }, - { code: 'NC', label: 'New Caledonia', phone: '687' }, - { code: 'NE', label: 'Niger', phone: '227' }, - { code: 'NF', label: 'Norfolk Island', phone: '672' }, - { code: 'NG', label: 'Nigeria', phone: '234' }, - { code: 'NI', label: 'Nicaragua', phone: '505' }, - { code: 'NL', label: 'Netherlands', phone: '31' }, - { code: 'NO', label: 'Norway', phone: '47' }, - { code: 'NP', label: 'Nepal', phone: '977' }, - { code: 'NR', label: 'Nauru', phone: '674' }, - { code: 'NU', label: 'Niue', phone: '683' }, - { code: 'NZ', label: 'New Zealand', phone: '64' }, - { code: 'OM', label: 'Oman', phone: '968' }, - { code: 'PA', label: 'Panama', phone: '507' }, - { code: 'PE', label: 'Peru', phone: '51' }, - { code: 'PF', label: 'French Polynesia', phone: '689' }, - { code: 'PG', label: 'Papua New Guinea', phone: '675' }, - { code: 'PH', label: 'Philippines', phone: '63' }, - { code: 'PK', label: 'Pakistan', phone: '92' }, - { code: 'PL', label: 'Poland', phone: '48' }, - { - code: 'PM', - label: 'Saint Pierre and Miquelon', - phone: '508', - }, - { code: 'PN', label: 'Pitcairn', phone: '870' }, - { code: 'PR', label: 'Puerto Rico', phone: '1' }, - { - code: 'PS', - label: 'Palestine, State of', - phone: '970', - }, - { code: 'PT', label: 'Portugal', phone: '351' }, - { code: 'PW', label: 'Palau', phone: '680' }, - { code: 'PY', label: 'Paraguay', phone: '595' }, - { code: 'QA', label: 'Qatar', phone: '974' }, - { code: 'RE', label: 'Reunion', phone: '262' }, - { code: 'RO', label: 'Romania', phone: '40' }, - { code: 'RS', label: 'Serbia', phone: '381' }, - { code: 'RU', label: 'Russian Federation', phone: '7' }, - { code: 'RW', label: 'Rwanda', phone: '250' }, - { code: 'SA', label: 'Saudi Arabia', phone: '966' }, - { code: 'SB', label: 'Solomon Islands', phone: '677' }, - { code: 'SC', label: 'Seychelles', phone: '248' }, - { code: 'SD', label: 'Sudan', phone: '249' }, - { code: 'SE', label: 'Sweden', phone: '46' }, - { code: 'SG', label: 'Singapore', phone: '65' }, - { code: 'SH', label: 'Saint Helena', phone: '290' }, - { code: 'SI', label: 'Slovenia', phone: '386' }, - { - code: 'SJ', - label: 'Svalbard and Jan Mayen', - phone: '47', - }, - { code: 'SK', label: 'Slovakia', phone: '421' }, - { code: 'SL', label: 'Sierra Leone', phone: '232' }, - { code: 'SM', label: 'San Marino', phone: '378' }, - { code: 'SN', label: 'Senegal', phone: '221' }, - { code: 'SO', label: 'Somalia', phone: '252' }, - { code: 'SR', label: 'Suriname', phone: '597' }, - { code: 'SS', label: 'South Sudan', phone: '211' }, - { - code: 'ST', - label: 'Sao Tome and Principe', - phone: '239', - }, - { code: 'SV', label: 'El Salvador', phone: '503' }, - { - code: 'SX', - label: 'Sint Maarten (Dutch part)', - phone: '1-721', - }, - { - code: 'SY', - label: 'Syrian Arab Republic', - phone: '963', - }, - { code: 'SZ', label: 'Swaziland', phone: '268' }, - { - code: 'TC', - label: 'Turks and Caicos Islands', - phone: '1-649', - }, - { code: 'TD', label: 'Chad', phone: '235' }, - { - code: 'TF', - label: 'French Southern Territories', - phone: '262', - }, - { code: 'TG', label: 'Togo', phone: '228' }, - { code: 'TH', label: 'Thailand', phone: '66' }, - { code: 'TJ', label: 'Tajikistan', phone: '992' }, - { code: 'TK', label: 'Tokelau', phone: '690' }, - { code: 'TL', label: 'Timor-Leste', phone: '670' }, - { code: 'TM', label: 'Turkmenistan', phone: '993' }, - { code: 'TN', label: 'Tunisia', phone: '216' }, - { code: 'TO', label: 'Tonga', phone: '676' }, - { code: 'TR', label: 'Turkey', phone: '90' }, - { - code: 'TT', - label: 'Trinidad and Tobago', - phone: '1-868', - }, - { code: 'TV', label: 'Tuvalu', phone: '688' }, - { - code: 'TW', - label: 'Taiwan', - phone: '886', - }, - { - code: 'TZ', - label: 'United Republic of Tanzania', - phone: '255', - }, - { code: 'UA', label: 'Ukraine', phone: '380' }, - { code: 'UG', label: 'Uganda', phone: '256' }, - { - code: 'US', - label: 'United States', - phone: '1', - suggested: true, - }, - { code: 'UY', label: 'Uruguay', phone: '598' }, - { code: 'UZ', label: 'Uzbekistan', phone: '998' }, - { - code: 'VA', - label: 'Holy See (Vatican City State)', - phone: '379', - }, - { - code: 'VC', - label: 'Saint Vincent and the Grenadines', - phone: '1-784', - }, - { code: 'VE', label: 'Venezuela', phone: '58' }, - { - code: 'VG', - label: 'British Virgin Islands', - phone: '1-284', - }, - { - code: 'VI', - label: 'US Virgin Islands', - phone: '1-340', - }, - { code: 'VN', label: 'Vietnam', phone: '84' }, - { code: 'VU', label: 'Vanuatu', phone: '678' }, - { code: 'WF', label: 'Wallis and Futuna', phone: '681' }, - { code: 'WS', label: 'Samoa', phone: '685' }, - { code: 'XK', label: 'Kosovo', phone: '383' }, - { code: 'YE', label: 'Yemen', phone: '967' }, - { code: 'YT', label: 'Mayotte', phone: '262' }, - { code: 'ZA', label: 'South Africa', phone: '27' }, - { code: 'ZM', label: 'Zambia', phone: '260' }, - { code: 'ZW', label: 'Zimbabwe', phone: '263' }, -]; - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx index c3109d0f05a2e0..08352f92ee7ade 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx @@ -1,8 +1,18 @@ import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import Box from '@mui/material/Box'; +import Chip from '@mui/material/Chip'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; -import { createTheme, useTheme, ThemeProvider, Theme } from '@mui/material/styles'; +import { createTheme, ThemeProvider } from '@mui/material/styles'; +import type { Theme } from '@mui/material/styles'; +import countries from './countries'; + +interface Option { + label: string; + detail: string; +} + +const getOptionKey = (option: Option) => `${option.label}-${option.detail}`; // Theme.ts const customTheme = (outerTheme: Theme) => @@ -18,20 +28,43 @@ const customTheme = (outerTheme: Theme) => defaultProps: { renderOption: (props, option, state, ownerState) => { const { key, ...optionProps } = props; + const { detail } = option as Option; + return ( - {ownerState.getOptionLabel(option)} + + {ownerState.getOptionLabel(option)} + + ); }, @@ -40,28 +73,44 @@ const customTheme = (outerTheme: Theme) => }, }); -export default function GloballyCustomizedOptions() { - // useTheme is used to determine the dark or light mode of the docs to maintain the Autocomplete component default styles. - const outerTheme = useTheme(); +const languages: readonly Option[] = [ + { detail: 'en-US', label: 'English (US)' }, + { detail: 'en-GB', label: 'English (UK)' }, + { detail: 'es-ES', label: 'Spanish (Spain)' }, + { detail: 'es-MX', label: 'Spanish (Mexico)' }, + { detail: 'fr-FR', label: 'French' }, + { detail: 'de-DE', label: 'German' }, + { detail: 'it-IT', label: 'Italian' }, + { detail: 'ja-JP', label: 'Japanese' }, + { detail: 'ko-KR', label: 'Korean' }, + { detail: 'pt-BR', label: 'Portuguese' }, + { detail: 'zh-CN', label: 'Chinese (Simplified)' }, + { detail: 'zh-TW', label: 'Chinese (Traditional)' }, +]; +const countryOptions: readonly Option[] = countries.map((country) => ({ + label: `${country.label} (${country.code})`, + detail: `+${country.countryCallingCode}`, +})); + +export default function GloballyCustomizedOptions() { return ( - - - + + + ); } -function MovieSelect() { +function LanguageSelect() { return ( `${option.title} (${option.year})`} - disableCloseOnSelect + options={languages} + getOptionLabel={(option) => option.label} renderInput={(params) => ( - + )} /> ); @@ -70,578 +119,10 @@ function MovieSelect() { function CountrySelect() { return ( - `${option.label} (${option.code}) +${option.phone}` - } + options={countryOptions} + getOptionLabel={(option) => option.label} + getOptionKey={getOptionKey} renderInput={(params) => } /> ); } - -interface CountryType { - code: string; - label: string; - phone: string; - suggested?: boolean; -} - -// From https://bitbucket.org/atlassian/atlaskit-mk-2/raw/4ad0e56649c3e6c973e226b7efaeb28cb240ccb0/packages/core/select/src/data/countries.js -const countries: readonly CountryType[] = [ - { code: 'AD', label: 'Andorra', phone: '376' }, - { - code: 'AE', - label: 'United Arab Emirates', - phone: '971', - }, - { code: 'AF', label: 'Afghanistan', phone: '93' }, - { - code: 'AG', - label: 'Antigua and Barbuda', - phone: '1-268', - }, - { code: 'AI', label: 'Anguilla', phone: '1-264' }, - { code: 'AL', label: 'Albania', phone: '355' }, - { code: 'AM', label: 'Armenia', phone: '374' }, - { code: 'AO', label: 'Angola', phone: '244' }, - { code: 'AQ', label: 'Antarctica', phone: '672' }, - { code: 'AR', label: 'Argentina', phone: '54' }, - { code: 'AS', label: 'American Samoa', phone: '1-684' }, - { code: 'AT', label: 'Austria', phone: '43' }, - { - code: 'AU', - label: 'Australia', - phone: '61', - suggested: true, - }, - { code: 'AW', label: 'Aruba', phone: '297' }, - { code: 'AX', label: 'Alland Islands', phone: '358' }, - { code: 'AZ', label: 'Azerbaijan', phone: '994' }, - { - code: 'BA', - label: 'Bosnia and Herzegovina', - phone: '387', - }, - { code: 'BB', label: 'Barbados', phone: '1-246' }, - { code: 'BD', label: 'Bangladesh', phone: '880' }, - { code: 'BE', label: 'Belgium', phone: '32' }, - { code: 'BF', label: 'Burkina Faso', phone: '226' }, - { code: 'BG', label: 'Bulgaria', phone: '359' }, - { code: 'BH', label: 'Bahrain', phone: '973' }, - { code: 'BI', label: 'Burundi', phone: '257' }, - { code: 'BJ', label: 'Benin', phone: '229' }, - { code: 'BL', label: 'Saint Barthelemy', phone: '590' }, - { code: 'BM', label: 'Bermuda', phone: '1-441' }, - { code: 'BN', label: 'Brunei Darussalam', phone: '673' }, - { code: 'BO', label: 'Bolivia', phone: '591' }, - { code: 'BR', label: 'Brazil', phone: '55' }, - { code: 'BS', label: 'Bahamas', phone: '1-242' }, - { code: 'BT', label: 'Bhutan', phone: '975' }, - { code: 'BV', label: 'Bouvet Island', phone: '47' }, - { code: 'BW', label: 'Botswana', phone: '267' }, - { code: 'BY', label: 'Belarus', phone: '375' }, - { code: 'BZ', label: 'Belize', phone: '501' }, - { - code: 'CA', - label: 'Canada', - phone: '1', - suggested: true, - }, - { - code: 'CC', - label: 'Cocos (Keeling) Islands', - phone: '61', - }, - { - code: 'CD', - label: 'Congo, Democratic Republic of the', - phone: '243', - }, - { - code: 'CF', - label: 'Central African Republic', - phone: '236', - }, - { - code: 'CG', - label: 'Congo, Republic of the', - phone: '242', - }, - { code: 'CH', label: 'Switzerland', phone: '41' }, - { code: 'CI', label: "Cote d'Ivoire", phone: '225' }, - { code: 'CK', label: 'Cook Islands', phone: '682' }, - { code: 'CL', label: 'Chile', phone: '56' }, - { code: 'CM', label: 'Cameroon', phone: '237' }, - { code: 'CN', label: 'China', phone: '86' }, - { code: 'CO', label: 'Colombia', phone: '57' }, - { code: 'CR', label: 'Costa Rica', phone: '506' }, - { code: 'CU', label: 'Cuba', phone: '53' }, - { code: 'CV', label: 'Cape Verde', phone: '238' }, - { code: 'CW', label: 'Curacao', phone: '599' }, - { code: 'CX', label: 'Christmas Island', phone: '61' }, - { code: 'CY', label: 'Cyprus', phone: '357' }, - { code: 'CZ', label: 'Czech Republic', phone: '420' }, - { - code: 'DE', - label: 'Germany', - phone: '49', - suggested: true, - }, - { code: 'DJ', label: 'Djibouti', phone: '253' }, - { code: 'DK', label: 'Denmark', phone: '45' }, - { code: 'DM', label: 'Dominica', phone: '1-767' }, - { - code: 'DO', - label: 'Dominican Republic', - phone: '1-809', - }, - { code: 'DZ', label: 'Algeria', phone: '213' }, - { code: 'EC', label: 'Ecuador', phone: '593' }, - { code: 'EE', label: 'Estonia', phone: '372' }, - { code: 'EG', label: 'Egypt', phone: '20' }, - { code: 'EH', label: 'Western Sahara', phone: '212' }, - { code: 'ER', label: 'Eritrea', phone: '291' }, - { code: 'ES', label: 'Spain', phone: '34' }, - { code: 'ET', label: 'Ethiopia', phone: '251' }, - { code: 'FI', label: 'Finland', phone: '358' }, - { code: 'FJ', label: 'Fiji', phone: '679' }, - { - code: 'FK', - label: 'Falkland Islands (Malvinas)', - phone: '500', - }, - { - code: 'FM', - label: 'Micronesia, Federated States of', - phone: '691', - }, - { code: 'FO', label: 'Faroe Islands', phone: '298' }, - { - code: 'FR', - label: 'France', - phone: '33', - suggested: true, - }, - { code: 'GA', label: 'Gabon', phone: '241' }, - { code: 'GB', label: 'United Kingdom', phone: '44' }, - { code: 'GD', label: 'Grenada', phone: '1-473' }, - { code: 'GE', label: 'Georgia', phone: '995' }, - { code: 'GF', label: 'French Guiana', phone: '594' }, - { code: 'GG', label: 'Guernsey', phone: '44' }, - { code: 'GH', label: 'Ghana', phone: '233' }, - { code: 'GI', label: 'Gibraltar', phone: '350' }, - { code: 'GL', label: 'Greenland', phone: '299' }, - { code: 'GM', label: 'Gambia', phone: '220' }, - { code: 'GN', label: 'Guinea', phone: '224' }, - { code: 'GP', label: 'Guadeloupe', phone: '590' }, - { code: 'GQ', label: 'Equatorial Guinea', phone: '240' }, - { code: 'GR', label: 'Greece', phone: '30' }, - { - code: 'GS', - label: 'South Georgia and the South Sandwich Islands', - phone: '500', - }, - { code: 'GT', label: 'Guatemala', phone: '502' }, - { code: 'GU', label: 'Guam', phone: '1-671' }, - { code: 'GW', label: 'Guinea-Bissau', phone: '245' }, - { code: 'GY', label: 'Guyana', phone: '592' }, - { code: 'HK', label: 'Hong Kong', phone: '852' }, - { - code: 'HM', - label: 'Heard Island and McDonald Islands', - phone: '672', - }, - { code: 'HN', label: 'Honduras', phone: '504' }, - { code: 'HR', label: 'Croatia', phone: '385' }, - { code: 'HT', label: 'Haiti', phone: '509' }, - { code: 'HU', label: 'Hungary', phone: '36' }, - { code: 'ID', label: 'Indonesia', phone: '62' }, - { code: 'IE', label: 'Ireland', phone: '353' }, - { code: 'IL', label: 'Israel', phone: '972' }, - { code: 'IM', label: 'Isle of Man', phone: '44' }, - { code: 'IN', label: 'India', phone: '91' }, - { - code: 'IO', - label: 'British Indian Ocean Territory', - phone: '246', - }, - { code: 'IQ', label: 'Iraq', phone: '964' }, - { - code: 'IR', - label: 'Iran, Islamic Republic of', - phone: '98', - }, - { code: 'IS', label: 'Iceland', phone: '354' }, - { code: 'IT', label: 'Italy', phone: '39' }, - { code: 'JE', label: 'Jersey', phone: '44' }, - { code: 'JM', label: 'Jamaica', phone: '1-876' }, - { code: 'JO', label: 'Jordan', phone: '962' }, - { - code: 'JP', - label: 'Japan', - phone: '81', - suggested: true, - }, - { code: 'KE', label: 'Kenya', phone: '254' }, - { code: 'KG', label: 'Kyrgyzstan', phone: '996' }, - { code: 'KH', label: 'Cambodia', phone: '855' }, - { code: 'KI', label: 'Kiribati', phone: '686' }, - { code: 'KM', label: 'Comoros', phone: '269' }, - { - code: 'KN', - label: 'Saint Kitts and Nevis', - phone: '1-869', - }, - { - code: 'KP', - label: "Korea, Democratic People's Republic of", - phone: '850', - }, - { code: 'KR', label: 'Korea, Republic of', phone: '82' }, - { code: 'KW', label: 'Kuwait', phone: '965' }, - { code: 'KY', label: 'Cayman Islands', phone: '1-345' }, - { code: 'KZ', label: 'Kazakhstan', phone: '7' }, - { - code: 'LA', - label: "Lao People's Democratic Republic", - phone: '856', - }, - { code: 'LB', label: 'Lebanon', phone: '961' }, - { code: 'LC', label: 'Saint Lucia', phone: '1-758' }, - { code: 'LI', label: 'Liechtenstein', phone: '423' }, - { code: 'LK', label: 'Sri Lanka', phone: '94' }, - { code: 'LR', label: 'Liberia', phone: '231' }, - { code: 'LS', label: 'Lesotho', phone: '266' }, - { code: 'LT', label: 'Lithuania', phone: '370' }, - { code: 'LU', label: 'Luxembourg', phone: '352' }, - { code: 'LV', label: 'Latvia', phone: '371' }, - { code: 'LY', label: 'Libya', phone: '218' }, - { code: 'MA', label: 'Morocco', phone: '212' }, - { code: 'MC', label: 'Monaco', phone: '377' }, - { - code: 'MD', - label: 'Moldova, Republic of', - phone: '373', - }, - { code: 'ME', label: 'Montenegro', phone: '382' }, - { - code: 'MF', - label: 'Saint Martin (French part)', - phone: '590', - }, - { code: 'MG', label: 'Madagascar', phone: '261' }, - { code: 'MH', label: 'Marshall Islands', phone: '692' }, - { - code: 'MK', - label: 'Macedonia, the Former Yugoslav Republic of', - phone: '389', - }, - { code: 'ML', label: 'Mali', phone: '223' }, - { code: 'MM', label: 'Myanmar', phone: '95' }, - { code: 'MN', label: 'Mongolia', phone: '976' }, - { code: 'MO', label: 'Macao', phone: '853' }, - { - code: 'MP', - label: 'Northern Mariana Islands', - phone: '1-670', - }, - { code: 'MQ', label: 'Martinique', phone: '596' }, - { code: 'MR', label: 'Mauritania', phone: '222' }, - { code: 'MS', label: 'Montserrat', phone: '1-664' }, - { code: 'MT', label: 'Malta', phone: '356' }, - { code: 'MU', label: 'Mauritius', phone: '230' }, - { code: 'MV', label: 'Maldives', phone: '960' }, - { code: 'MW', label: 'Malawi', phone: '265' }, - { code: 'MX', label: 'Mexico', phone: '52' }, - { code: 'MY', label: 'Malaysia', phone: '60' }, - { code: 'MZ', label: 'Mozambique', phone: '258' }, - { code: 'NA', label: 'Namibia', phone: '264' }, - { code: 'NC', label: 'New Caledonia', phone: '687' }, - { code: 'NE', label: 'Niger', phone: '227' }, - { code: 'NF', label: 'Norfolk Island', phone: '672' }, - { code: 'NG', label: 'Nigeria', phone: '234' }, - { code: 'NI', label: 'Nicaragua', phone: '505' }, - { code: 'NL', label: 'Netherlands', phone: '31' }, - { code: 'NO', label: 'Norway', phone: '47' }, - { code: 'NP', label: 'Nepal', phone: '977' }, - { code: 'NR', label: 'Nauru', phone: '674' }, - { code: 'NU', label: 'Niue', phone: '683' }, - { code: 'NZ', label: 'New Zealand', phone: '64' }, - { code: 'OM', label: 'Oman', phone: '968' }, - { code: 'PA', label: 'Panama', phone: '507' }, - { code: 'PE', label: 'Peru', phone: '51' }, - { code: 'PF', label: 'French Polynesia', phone: '689' }, - { code: 'PG', label: 'Papua New Guinea', phone: '675' }, - { code: 'PH', label: 'Philippines', phone: '63' }, - { code: 'PK', label: 'Pakistan', phone: '92' }, - { code: 'PL', label: 'Poland', phone: '48' }, - { - code: 'PM', - label: 'Saint Pierre and Miquelon', - phone: '508', - }, - { code: 'PN', label: 'Pitcairn', phone: '870' }, - { code: 'PR', label: 'Puerto Rico', phone: '1' }, - { - code: 'PS', - label: 'Palestine, State of', - phone: '970', - }, - { code: 'PT', label: 'Portugal', phone: '351' }, - { code: 'PW', label: 'Palau', phone: '680' }, - { code: 'PY', label: 'Paraguay', phone: '595' }, - { code: 'QA', label: 'Qatar', phone: '974' }, - { code: 'RE', label: 'Reunion', phone: '262' }, - { code: 'RO', label: 'Romania', phone: '40' }, - { code: 'RS', label: 'Serbia', phone: '381' }, - { code: 'RU', label: 'Russian Federation', phone: '7' }, - { code: 'RW', label: 'Rwanda', phone: '250' }, - { code: 'SA', label: 'Saudi Arabia', phone: '966' }, - { code: 'SB', label: 'Solomon Islands', phone: '677' }, - { code: 'SC', label: 'Seychelles', phone: '248' }, - { code: 'SD', label: 'Sudan', phone: '249' }, - { code: 'SE', label: 'Sweden', phone: '46' }, - { code: 'SG', label: 'Singapore', phone: '65' }, - { code: 'SH', label: 'Saint Helena', phone: '290' }, - { code: 'SI', label: 'Slovenia', phone: '386' }, - { - code: 'SJ', - label: 'Svalbard and Jan Mayen', - phone: '47', - }, - { code: 'SK', label: 'Slovakia', phone: '421' }, - { code: 'SL', label: 'Sierra Leone', phone: '232' }, - { code: 'SM', label: 'San Marino', phone: '378' }, - { code: 'SN', label: 'Senegal', phone: '221' }, - { code: 'SO', label: 'Somalia', phone: '252' }, - { code: 'SR', label: 'Suriname', phone: '597' }, - { code: 'SS', label: 'South Sudan', phone: '211' }, - { - code: 'ST', - label: 'Sao Tome and Principe', - phone: '239', - }, - { code: 'SV', label: 'El Salvador', phone: '503' }, - { - code: 'SX', - label: 'Sint Maarten (Dutch part)', - phone: '1-721', - }, - { - code: 'SY', - label: 'Syrian Arab Republic', - phone: '963', - }, - { code: 'SZ', label: 'Swaziland', phone: '268' }, - { - code: 'TC', - label: 'Turks and Caicos Islands', - phone: '1-649', - }, - { code: 'TD', label: 'Chad', phone: '235' }, - { - code: 'TF', - label: 'French Southern Territories', - phone: '262', - }, - { code: 'TG', label: 'Togo', phone: '228' }, - { code: 'TH', label: 'Thailand', phone: '66' }, - { code: 'TJ', label: 'Tajikistan', phone: '992' }, - { code: 'TK', label: 'Tokelau', phone: '690' }, - { code: 'TL', label: 'Timor-Leste', phone: '670' }, - { code: 'TM', label: 'Turkmenistan', phone: '993' }, - { code: 'TN', label: 'Tunisia', phone: '216' }, - { code: 'TO', label: 'Tonga', phone: '676' }, - { code: 'TR', label: 'Turkey', phone: '90' }, - { - code: 'TT', - label: 'Trinidad and Tobago', - phone: '1-868', - }, - { code: 'TV', label: 'Tuvalu', phone: '688' }, - { - code: 'TW', - label: 'Taiwan', - phone: '886', - }, - { - code: 'TZ', - label: 'United Republic of Tanzania', - phone: '255', - }, - { code: 'UA', label: 'Ukraine', phone: '380' }, - { code: 'UG', label: 'Uganda', phone: '256' }, - { - code: 'US', - label: 'United States', - phone: '1', - suggested: true, - }, - { code: 'UY', label: 'Uruguay', phone: '598' }, - { code: 'UZ', label: 'Uzbekistan', phone: '998' }, - { - code: 'VA', - label: 'Holy See (Vatican City State)', - phone: '379', - }, - { - code: 'VC', - label: 'Saint Vincent and the Grenadines', - phone: '1-784', - }, - { code: 'VE', label: 'Venezuela', phone: '58' }, - { - code: 'VG', - label: 'British Virgin Islands', - phone: '1-284', - }, - { - code: 'VI', - label: 'US Virgin Islands', - phone: '1-340', - }, - { code: 'VN', label: 'Vietnam', phone: '84' }, - { code: 'VU', label: 'Vanuatu', phone: '678' }, - { code: 'WF', label: 'Wallis and Futuna', phone: '681' }, - { code: 'WS', label: 'Samoa', phone: '685' }, - { code: 'XK', label: 'Kosovo', phone: '383' }, - { code: 'YE', label: 'Yemen', phone: '967' }, - { code: 'YT', label: 'Mayotte', phone: '262' }, - { code: 'ZA', label: 'South Africa', phone: '27' }, - { code: 'ZM', label: 'Zambia', phone: '260' }, - { code: 'ZW', label: 'Zimbabwe', phone: '263' }, -]; - -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 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx.preview b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx.preview index 711bb6e91ce57c..f87e3a8d0d98aa 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx.preview +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx.preview @@ -1,6 +1,6 @@ - - - + + + \ No newline at end of file diff --git a/docs/data/material/components/autocomplete/GoogleMaps.js b/docs/data/material/components/autocomplete/GoogleMaps.js index 5054d0ba84be56..8551f0a73b70c8 100644 --- a/docs/data/material/components/autocomplete/GoogleMaps.js +++ b/docs/data/material/components/autocomplete/GoogleMaps.js @@ -8,10 +8,10 @@ import LocationOnIcon from '@mui/icons-material/LocationOn'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import parse from 'autosuggest-highlight/parse'; -// For the sake of this demo, we have to use debounce to reduce Google Maps Places API quote use -// But prefer to use throttle in practice +// For this demo, debounce limits Google Maps Places API quota usage. // import throttle from 'lodash/throttle'; import { debounce } from '@mui/material/utils'; +import useId from '@mui/utils/useId'; // This key was created specifically for the demo in mui.com. // You need to create a new one for your application. @@ -37,7 +37,9 @@ function CustomPaper(props) { sx={(staticTheme) => ({ display: 'flex', justifyContent: 'flex-end', - p: '5px 10px 6px 10px', + paddingBlockStart: 5, + paddingBlockEnd: 6, + paddingInline: 10, opacity: 0.9, '& path': { fill: '#5e5e5e', @@ -50,15 +52,7 @@ function CustomPaper(props) { }), })} > - - - + ); @@ -71,68 +65,42 @@ CustomPaper.propTypes = { children: PropTypes.node, }; -const fetch = debounce(async (request, callback) => { - try { - const { suggestions } = - await window.google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions( - request, - ); - - callback( - suggestions.map((suggestion) => { - const place = suggestion.placePrediction; - // Map to the old AutocompleteService.getPlacePredictions format - // https://developers.google.com/maps/documentation/javascript/places-migration-autocomplete - return { - description: place.text.text, - structured_formatting: { - main_text: place.mainText.text, - main_text_matched_substrings: place.mainText.matches.map((match) => ({ - offset: match.startOffset, - length: match.endOffset - match.startOffset, - })), - secondary_text: place.secondaryText?.text, - }, - }; - }), - ); - } catch (err) { - if (err.message.startsWith('Quota exceeded for quota')) { - callback(request.input.length === 1 ? fakeAnswer.p : fakeAnswer.paris); - } - - throw err; - } -}, 400); - const emptyOptions = []; -let sessionToken; +let sessionToken = null; export default function GoogleMaps() { const [value, setValue] = React.useState(null); const [inputValue, setInputValue] = React.useState(''); const [options, setOptions] = React.useState(emptyOptions); - const callbackId = React.useId().replace(/[^\w]/g, ''); + const callbackId = useId(); + const scriptCallbackId = callbackId?.replace(/[^\w]/g, ''); const [loaded, setLoaded] = React.useState(false); - if (typeof window !== 'undefined') { + useEnhancedEffect(() => { + if (!scriptCallbackId) { + return; + } + + const googleMapsWindow = window; + if (!document.querySelector('#google-maps')) { const GOOGLE_NAMESPACE = '_google_callback'; const globalContext = - window[GOOGLE_NAMESPACE] || (window[GOOGLE_NAMESPACE] = {}); - globalContext[callbackId] = () => { + googleMapsWindow[GOOGLE_NAMESPACE] || + (googleMapsWindow[GOOGLE_NAMESPACE] = {}); + globalContext[scriptCallbackId] = () => { setLoaded(true); }; const script = loadScript( - `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAPS_API_KEY}&libraries=places&loading=async&callback=${GOOGLE_NAMESPACE}.${callbackId}`, + `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAPS_API_KEY}&libraries=places&loading=async&callback=${GOOGLE_NAMESPACE}.${scriptCallbackId}`, document.querySelector('head'), ); script.id = 'google-maps'; - } else if (window.google && !loaded) { + } else if (googleMapsWindow.google && !loaded) { setLoaded(true); } - } + }, [loaded, scriptCallbackId]); useEnhancedEffect(() => { if (!loaded) { @@ -144,14 +112,19 @@ export default function GoogleMaps() { return undefined; } - // Allow to resolve the out of order request resolution. + // Ignore out-of-order responses. let active = true; + const google = window.google; + + if (!google) { + return undefined; + } if (!sessionToken) { - sessionToken = new window.google.maps.places.AutocompleteSessionToken(); + sessionToken = new google.maps.places.AutocompleteSessionToken(); } - fetch({ input: inputValue, sessionToken }, (results) => { + fetchPredictions({ input: inputValue, sessionToken }, (results) => { if (!active) { return; } @@ -330,3 +303,60 @@ const fakeAnswer = { }, ], }; + +const fetchPredictions = debounce(async (request, callback) => { + try { + const google = window.google; + if (!google) { + return; + } + + const { suggestions } = + await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions( + request, + ); + + callback( + suggestions.map((suggestion) => { + const place = suggestion.placePrediction; + // Map to the old AutocompleteService.getPlacePredictions format + // https://developers.google.com/maps/documentation/javascript/places-migration-autocomplete + return { + description: place.text.text, + structured_formatting: { + main_text: place.mainText.text, + main_text_matched_substrings: place.mainText.matches.map((match) => ({ + offset: match.startOffset, + length: match.endOffset - match.startOffset, + })), + secondary_text: place.secondaryText?.text, + }, + }; + }), + ); + } catch (error) { + if ( + error instanceof Error && + error.message.startsWith('Quota exceeded for quota') + ) { + callback(request.input.length === 1 ? fakeAnswer.p : fakeAnswer.paris); + return; + } + + throw error; + } +}, 400); + +function GoogleMapsLogo() { + return ( + + + + ); +} diff --git a/docs/data/material/components/autocomplete/GoogleMaps.tsx b/docs/data/material/components/autocomplete/GoogleMaps.tsx index 92b840b5ac5b6c..dc7488955bf7f5 100644 --- a/docs/data/material/components/autocomplete/GoogleMaps.tsx +++ b/docs/data/material/components/autocomplete/GoogleMaps.tsx @@ -7,10 +7,10 @@ import LocationOnIcon from '@mui/icons-material/LocationOn'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import parse from 'autosuggest-highlight/parse'; -// For the sake of this demo, we have to use debounce to reduce Google Maps Places API quote use -// But prefer to use throttle in practice +// For this demo, debounce limits Google Maps Places API quota usage. // import throttle from 'lodash/throttle'; import { debounce } from '@mui/material/utils'; +import useId from '@mui/utils/useId'; // This key was created specifically for the demo in mui.com. // You need to create a new one for your application. @@ -40,6 +40,39 @@ interface PlaceType { description: string; structured_formatting: StructuredFormatting; } +interface AutocompleteSessionToken {} +interface PlacePredictionMatch { + startOffset: number; + endOffset: number; +} +interface PlacePredictionText { + text: string; + matches: readonly PlacePredictionMatch[]; +} +interface PlacePrediction { + text: { text: string }; + mainText: PlacePredictionText; + secondaryText?: { text: string }; +} +interface AutocompleteSuggestion { + placePrediction: PlacePrediction; +} +interface GoogleMapsWindow extends Window { + _google_callback?: Record void>; + google?: { + maps: { + places: { + AutocompleteSessionToken: new () => AutocompleteSessionToken; + AutocompleteSuggestion: { + fetchAutocompleteSuggestions: (request: { + input: string; + sessionToken: AutocompleteSessionToken; + }) => Promise<{ suggestions: readonly AutocompleteSuggestion[] }>; + }; + }; + }; + }; +} function CustomPaper(props: PaperProps) { return ( @@ -50,7 +83,9 @@ function CustomPaper(props: PaperProps) { sx={(staticTheme) => ({ display: 'flex', justifyContent: 'flex-end', - p: '5px 10px 6px 10px', + paddingBlockStart: 5, + paddingBlockEnd: 6, + paddingInline: 10, opacity: 0.9, '& path': { fill: '#5e5e5e', @@ -63,92 +98,48 @@ function CustomPaper(props: PaperProps) { }), })} > - - - + ); } -const fetch = debounce( - async ( - request: { input: string; sessionToken: any }, - callback: (results?: readonly PlaceType[]) => void, - ) => { - try { - const { suggestions } = await ( - window as any - ).google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions( - request, - ); - - callback( - suggestions.map((suggestion: any) => { - const place = suggestion.placePrediction; - // Map to the old AutocompleteService.getPlacePredictions format - // https://developers.google.com/maps/documentation/javascript/places-migration-autocomplete - return { - description: place.text.text, - structured_formatting: { - main_text: place.mainText.text, - main_text_matched_substrings: place.mainText.matches.map( - (match: any) => ({ - offset: match.startOffset, - length: match.endOffset - match.startOffset, - }), - ), - secondary_text: place.secondaryText?.text, - }, - }; - }), - ); - } catch (err: any) { - if (err.message.startsWith('Quota exceeded for quota')) { - callback(request.input.length === 1 ? fakeAnswer.p : fakeAnswer.paris); - } - - throw err; - } - }, - 400, -); - -const emptyOptions = [] as any; -let sessionToken: any; +const emptyOptions: readonly PlaceType[] = []; +let sessionToken: AutocompleteSessionToken | null = null; export default function GoogleMaps() { const [value, setValue] = React.useState(null); const [inputValue, setInputValue] = React.useState(''); const [options, setOptions] = React.useState(emptyOptions); - const callbackId = React.useId().replace(/[^\w]/g, ''); + const callbackId = useId(); + const scriptCallbackId = callbackId?.replace(/[^\w]/g, ''); const [loaded, setLoaded] = React.useState(false); - if (typeof window !== 'undefined') { + useEnhancedEffect(() => { + if (!scriptCallbackId) { + return; + } + + const googleMapsWindow = window as GoogleMapsWindow; + if (!document.querySelector('#google-maps')) { const GOOGLE_NAMESPACE = '_google_callback'; const globalContext = - // @ts-ignore - window[GOOGLE_NAMESPACE] || (window[GOOGLE_NAMESPACE] = {}); - globalContext[callbackId] = () => { + googleMapsWindow[GOOGLE_NAMESPACE] || + (googleMapsWindow[GOOGLE_NAMESPACE] = {}); + globalContext[scriptCallbackId] = () => { setLoaded(true); }; const script = loadScript( - `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAPS_API_KEY}&libraries=places&loading=async&callback=${GOOGLE_NAMESPACE}.${callbackId}`, + `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAPS_API_KEY}&libraries=places&loading=async&callback=${GOOGLE_NAMESPACE}.${scriptCallbackId}`, document.querySelector('head')!, ); script.id = 'google-maps'; - } else if ((window as any).google && !loaded) { + } else if (googleMapsWindow.google && !loaded) { setLoaded(true); } - } + }, [loaded, scriptCallbackId]); useEnhancedEffect(() => { if (!loaded) { @@ -160,36 +151,44 @@ export default function GoogleMaps() { return undefined; } - // Allow to resolve the out of order request resolution. + // Ignore out-of-order responses. let active = true; + const google = (window as GoogleMapsWindow).google; + + if (!google) { + return undefined; + } if (!sessionToken) { - sessionToken = new ( - window as any - ).google.maps.places.AutocompleteSessionToken(); + sessionToken = new google.maps.places.AutocompleteSessionToken(); } - fetch({ input: inputValue, sessionToken }, (results?: readonly PlaceType[]) => { - if (!active) { - return; - } + fetchPredictions( + { input: inputValue, sessionToken }, + (results?: readonly PlaceType[]) => { + if (!active) { + return; + } - let newOptions: readonly PlaceType[] = []; + let newOptions: readonly PlaceType[] = []; - if (results) { - newOptions = results; + if (results) { + newOptions = results; - if (value) { - newOptions = [ - value, - ...results.filter((result) => result.description !== value.description), - ]; + if (value) { + newOptions = [ + value, + ...results.filter( + (result) => result.description !== value.description, + ), + ]; + } + } else if (value) { + newOptions = [value]; } - } else if (value) { - newOptions = [value]; - } - setOptions(newOptions); - }); + setOptions(newOptions); + }, + ); return () => { active = false; @@ -348,3 +347,66 @@ const fakeAnswer = { }, ], }; + +const fetchPredictions = debounce( + async ( + request: { input: string; sessionToken: AutocompleteSessionToken }, + callback: (results?: readonly PlaceType[]) => void, + ) => { + try { + const google = (window as GoogleMapsWindow).google; + if (!google) { + return; + } + + const { suggestions } = + await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions( + request, + ); + + callback( + suggestions.map((suggestion) => { + const place = suggestion.placePrediction; + // Map to the old AutocompleteService.getPlacePredictions format + // https://developers.google.com/maps/documentation/javascript/places-migration-autocomplete + return { + description: place.text.text, + structured_formatting: { + main_text: place.mainText.text, + main_text_matched_substrings: place.mainText.matches.map((match) => ({ + offset: match.startOffset, + length: match.endOffset - match.startOffset, + })), + secondary_text: place.secondaryText?.text, + }, + }; + }), + ); + } catch (error: unknown) { + if ( + error instanceof Error && + error.message.startsWith('Quota exceeded for quota') + ) { + callback(request.input.length === 1 ? fakeAnswer.p : fakeAnswer.paris); + return; + } + + throw error; + } + }, + 400, +); + +function GoogleMapsLogo() { + return ( + + + + ); +} diff --git a/docs/data/material/components/autocomplete/Grouped.js b/docs/data/material/components/autocomplete/Grouped.js index 345c9d4521a531..90008475d76161 100644 --- a/docs/data/material/components/autocomplete/Grouped.js +++ b/docs/data/material/components/autocomplete/Grouped.js @@ -1,150 +1,24 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; -export default function Grouped() { - const options = top100Films.map((option) => { - const firstLetter = option.title[0].toUpperCase(); +const options = top100Films + .map((option) => { + const firstLetter = option.label[0].toUpperCase(); return { firstLetter: /[0-9]/.test(firstLetter) ? '0-9' : firstLetter, ...option, }; - }); + }) + .sort((a, b) => a.firstLetter.localeCompare(b.firstLetter)); +export default function Grouped() { return ( -b.firstLetter.localeCompare(a.firstLetter))} + options={options} groupBy={(option) => option.firstLetter} - getOptionLabel={(option) => option.title} sx={{ width: 300 }} renderInput={(params) => } /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Grouped.tsx b/docs/data/material/components/autocomplete/Grouped.tsx index 345c9d4521a531..90008475d76161 100644 --- a/docs/data/material/components/autocomplete/Grouped.tsx +++ b/docs/data/material/components/autocomplete/Grouped.tsx @@ -1,150 +1,24 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import top100Films from './top100Films'; -export default function Grouped() { - const options = top100Films.map((option) => { - const firstLetter = option.title[0].toUpperCase(); +const options = top100Films + .map((option) => { + const firstLetter = option.label[0].toUpperCase(); return { firstLetter: /[0-9]/.test(firstLetter) ? '0-9' : firstLetter, ...option, }; - }); + }) + .sort((a, b) => a.firstLetter.localeCompare(b.firstLetter)); +export default function Grouped() { return ( -b.firstLetter.localeCompare(a.firstLetter))} + options={options} groupBy={(option) => option.firstLetter} - getOptionLabel={(option) => option.title} sx={{ width: 300 }} renderInput={(params) => } /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Grouped.tsx.preview b/docs/data/material/components/autocomplete/Grouped.tsx.preview index 861cf451662757..ea4dd9d83c4b2e 100644 --- a/docs/data/material/components/autocomplete/Grouped.tsx.preview +++ b/docs/data/material/components/autocomplete/Grouped.tsx.preview @@ -1,7 +1,6 @@ -b.firstLetter.localeCompare(a.firstLetter))} + options={options} groupBy={(option) => option.firstLetter} - getOptionLabel={(option) => option.title} sx={{ width: 300 }} renderInput={(params) => } /> \ No newline at end of file diff --git a/docs/data/material/components/autocomplete/Highlights.js b/docs/data/material/components/autocomplete/Highlights.js index 8902223d812529..3c5a430d241657 100644 --- a/docs/data/material/components/autocomplete/Highlights.js +++ b/docs/data/material/components/autocomplete/Highlights.js @@ -1,34 +1,43 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import Box from '@mui/material/Box'; +import { alpha } from '@mui/material/styles'; import parse from 'autosuggest-highlight/parse'; import match from 'autosuggest-highlight/match'; +import top100Films from './top100Films'; export default function Highlights() { return ( option.title} renderInput={(params) => ( )} renderOption={(props, option, { inputValue }) => { const { key, ...optionProps } = props; - const matches = match(option.title, inputValue, { insideWords: true }); - const parts = parse(option.title, matches); + const matches = match(option.label, inputValue, { insideWords: true }); + const parts = parse(option.label, matches); return (
  • {parts.map((part, index) => ( - ({ + backgroundColor: part.highlight + ? alpha(theme.palette.warning.main, 0.24) + : 'transparent', + borderRadius: 0.5, + color: 'inherit', fontWeight: part.highlight ? 700 : 400, - }} + paddingInline: part.highlight ? 0.25 : 0, + })} > {part.text} - + ))}
  • @@ -37,131 +46,3 @@ export default function Highlights() { /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Highlights.tsx b/docs/data/material/components/autocomplete/Highlights.tsx index 8902223d812529..3c5a430d241657 100644 --- a/docs/data/material/components/autocomplete/Highlights.tsx +++ b/docs/data/material/components/autocomplete/Highlights.tsx @@ -1,34 +1,43 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import Box from '@mui/material/Box'; +import { alpha } from '@mui/material/styles'; import parse from 'autosuggest-highlight/parse'; import match from 'autosuggest-highlight/match'; +import top100Films from './top100Films'; export default function Highlights() { return ( option.title} renderInput={(params) => ( )} renderOption={(props, option, { inputValue }) => { const { key, ...optionProps } = props; - const matches = match(option.title, inputValue, { insideWords: true }); - const parts = parse(option.title, matches); + const matches = match(option.label, inputValue, { insideWords: true }); + const parts = parse(option.label, matches); return (
  • {parts.map((part, index) => ( - ({ + backgroundColor: part.highlight + ? alpha(theme.palette.warning.main, 0.24) + : 'transparent', + borderRadius: 0.5, + color: 'inherit', fontWeight: part.highlight ? 700 : 400, - }} + paddingInline: part.highlight ? 0.25 : 0, + })} > {part.text} - + ))}
  • @@ -37,131 +46,3 @@ export default function Highlights() { /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/LimitTags.js b/docs/data/material/components/autocomplete/LimitTags.js index 5b4294bbf1ef93..a73963e35c72e9 100644 --- a/docs/data/material/components/autocomplete/LimitTags.js +++ b/docs/data/material/components/autocomplete/LimitTags.js @@ -1,5 +1,6 @@ import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; +import top100Films from './top100Films'; export default function LimitTags() { return ( @@ -7,140 +8,11 @@ export default function LimitTags() { multiple limitTags={2} options={top100Films} - getOptionLabel={(option) => option.title} defaultValue={[top100Films[13], top100Films[12], top100Films[11]]} renderInput={(params) => ( )} - sx={{ width: '500px' }} + sx={{ width: 500 }} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/LimitTags.tsx b/docs/data/material/components/autocomplete/LimitTags.tsx index 5b4294bbf1ef93..a73963e35c72e9 100644 --- a/docs/data/material/components/autocomplete/LimitTags.tsx +++ b/docs/data/material/components/autocomplete/LimitTags.tsx @@ -1,5 +1,6 @@ import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; +import top100Films from './top100Films'; export default function LimitTags() { return ( @@ -7,140 +8,11 @@ export default function LimitTags() { multiple limitTags={2} options={top100Films} - getOptionLabel={(option) => option.title} defaultValue={[top100Films[13], top100Films[12], top100Films[11]]} renderInput={(params) => ( )} - sx={{ width: '500px' }} + sx={{ width: 500 }} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/LimitTags.tsx.preview b/docs/data/material/components/autocomplete/LimitTags.tsx.preview index 4e447dea48e520..fa24eec8ccf912 100644 --- a/docs/data/material/components/autocomplete/LimitTags.tsx.preview +++ b/docs/data/material/components/autocomplete/LimitTags.tsx.preview @@ -1,12 +1,10 @@ option.title} defaultValue={[top100Films[13], top100Films[12], top100Films[11]]} renderInput={(params) => ( )} - sx={{ width: '500px' }} + sx={{ width: 500 }} /> \ No newline at end of file diff --git a/docs/data/material/components/autocomplete/Playground.js b/docs/data/material/components/autocomplete/Playground.js index 3b8edf5a01bb84..ceb2864465f55e 100644 --- a/docs/data/material/components/autocomplete/Playground.js +++ b/docs/data/material/components/autocomplete/Playground.js @@ -2,15 +2,17 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import Stack from '@mui/material/Stack'; +import top100Films from './top100Films'; + +const filmTitles = top100Films.map((option) => option.label); +const defaultProps = { + options: top100Films, +}; +const flatProps = { + options: filmTitles, +}; export default function Playground() { - const defaultProps = { - options: top100Films, - getOptionLabel: (option) => option.title, - }; - const flatProps = { - options: top100Films.map((option) => option.title), - }; const [value, setValue] = React.useState(null); return ( @@ -141,131 +143,3 @@ export default function Playground() {
    ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Playground.tsx b/docs/data/material/components/autocomplete/Playground.tsx index e015bed984e26b..b00648bae148e5 100644 --- a/docs/data/material/components/autocomplete/Playground.tsx +++ b/docs/data/material/components/autocomplete/Playground.tsx @@ -2,16 +2,20 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; import Stack from '@mui/material/Stack'; +import top100Films from './top100Films'; + +type Film = (typeof top100Films)[number]; + +const filmTitles = top100Films.map((option) => option.label); +const defaultProps = { + options: top100Films, +}; +const flatProps = { + options: filmTitles, +}; export default function Playground() { - const defaultProps = { - options: top100Films, - getOptionLabel: (option: FilmOptionType) => option.title, - }; - const flatProps = { - options: top100Films.map((option) => option.title), - }; - const [value, setValue] = React.useState(null); + const [value, setValue] = React.useState(null); return ( @@ -141,136 +145,3 @@ export default function Playground() { ); } - -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 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/RenderGroup.js b/docs/data/material/components/autocomplete/RenderGroup.js index 5e5737b75f0480..28a7025e46a037 100644 --- a/docs/data/material/components/autocomplete/RenderGroup.js +++ b/docs/data/material/components/autocomplete/RenderGroup.js @@ -1,16 +1,25 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -import { styled, lighten, darken } from '@mui/system'; +import { styled } from '@mui/material/styles'; +import countries from './countries'; + +const options = [...countries].sort( + (a, b) => a.continent.localeCompare(b.continent) || a.label.localeCompare(b.label), +); + +const Group = styled('li')(({ theme }) => ({ + '& + &': { + marginTop: theme.spacing(0.5), + paddingTop: theme.spacing(0.5), + borderTop: `1px solid ${(theme.vars || theme).palette.divider}`, + }, +})); const GroupHeader = styled('div')(({ theme }) => ({ - position: 'sticky', - top: '-8px', - padding: '4px 10px', - color: theme.palette.primary.main, - backgroundColor: lighten(theme.palette.primary.light, 0.85), - ...theme.applyStyles('dark', { - backgroundColor: darken(theme.palette.primary.main, 0.8), - }), + ...theme.typography.body2, + padding: theme.spacing(1.25, 2, 0.75), + color: (theme.vars || theme).palette.text.secondary, + fontWeight: theme.typography.fontWeightMedium, })); const GroupItems = styled('ul')({ @@ -18,155 +27,18 @@ const GroupItems = styled('ul')({ }); export default function RenderGroup() { - const options = top100Films.map((option) => { - const firstLetter = option.title[0].toUpperCase(); - return { - firstLetter: /[0-9]/.test(firstLetter) ? '0-9' : firstLetter, - ...option, - }; - }); - return ( -b.firstLetter.localeCompare(a.firstLetter))} - groupBy={(option) => option.firstLetter} - getOptionLabel={(option) => option.title} + options={options} + groupBy={(option) => option.continent} sx={{ width: 300 }} - renderInput={(params) => } + renderInput={(params) => } renderGroup={(params) => ( -
  • + {params.group} {params.children} -
  • + )} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/RenderGroup.tsx b/docs/data/material/components/autocomplete/RenderGroup.tsx index 5e5737b75f0480..28a7025e46a037 100644 --- a/docs/data/material/components/autocomplete/RenderGroup.tsx +++ b/docs/data/material/components/autocomplete/RenderGroup.tsx @@ -1,16 +1,25 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -import { styled, lighten, darken } from '@mui/system'; +import { styled } from '@mui/material/styles'; +import countries from './countries'; + +const options = [...countries].sort( + (a, b) => a.continent.localeCompare(b.continent) || a.label.localeCompare(b.label), +); + +const Group = styled('li')(({ theme }) => ({ + '& + &': { + marginTop: theme.spacing(0.5), + paddingTop: theme.spacing(0.5), + borderTop: `1px solid ${(theme.vars || theme).palette.divider}`, + }, +})); const GroupHeader = styled('div')(({ theme }) => ({ - position: 'sticky', - top: '-8px', - padding: '4px 10px', - color: theme.palette.primary.main, - backgroundColor: lighten(theme.palette.primary.light, 0.85), - ...theme.applyStyles('dark', { - backgroundColor: darken(theme.palette.primary.main, 0.8), - }), + ...theme.typography.body2, + padding: theme.spacing(1.25, 2, 0.75), + color: (theme.vars || theme).palette.text.secondary, + fontWeight: theme.typography.fontWeightMedium, })); const GroupItems = styled('ul')({ @@ -18,155 +27,18 @@ const GroupItems = styled('ul')({ }); export default function RenderGroup() { - const options = top100Films.map((option) => { - const firstLetter = option.title[0].toUpperCase(); - return { - firstLetter: /[0-9]/.test(firstLetter) ? '0-9' : firstLetter, - ...option, - }; - }); - return ( -b.firstLetter.localeCompare(a.firstLetter))} - groupBy={(option) => option.firstLetter} - getOptionLabel={(option) => option.title} + options={options} + groupBy={(option) => option.continent} sx={{ width: 300 }} - renderInput={(params) => } + renderInput={(params) => } renderGroup={(params) => ( -
  • + {params.group} {params.children} -
  • + )} /> ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/RenderGroup.tsx.preview b/docs/data/material/components/autocomplete/RenderGroup.tsx.preview index 85d7b49d75f0d7..58b847d76d5c31 100644 --- a/docs/data/material/components/autocomplete/RenderGroup.tsx.preview +++ b/docs/data/material/components/autocomplete/RenderGroup.tsx.preview @@ -1,13 +1,12 @@ -b.firstLetter.localeCompare(a.firstLetter))} - groupBy={(option) => option.firstLetter} - getOptionLabel={(option) => option.title} + options={options} + groupBy={(option) => option.continent} sx={{ width: 300 }} - renderInput={(params) => } + renderInput={(params) => } renderGroup={(params) => ( -
  • + {params.group} {params.children} -
  • + )} /> \ No newline at end of file diff --git a/docs/data/material/components/autocomplete/Sizes.js b/docs/data/material/components/autocomplete/Sizes.js index c53a60720b0849..a04a61389f54ca 100644 --- a/docs/data/material/components/autocomplete/Sizes.js +++ b/docs/data/material/components/autocomplete/Sizes.js @@ -2,14 +2,14 @@ import Stack from '@mui/material/Stack'; import Chip from '@mui/material/Chip'; import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; +import top100Films from './top100Films'; export default function Sizes() { return ( - + option.title} defaultValue={top100Films[13]} renderInput={(params) => ( @@ -19,7 +19,6 @@ export default function Sizes() { multiple size="small" options={top100Films} - getOptionLabel={(option) => option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( @@ -28,7 +27,6 @@ export default function Sizes() { option.title} defaultValue={top100Films[13]} renderInput={(params) => ( option.title} defaultValue={[top100Films[13]]} renderValue={(values, getItemProps) => values.map((option, index) => { @@ -52,7 +49,7 @@ export default function Sizes() { @@ -71,131 +68,3 @@ export default function Sizes() { ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Sizes.tsx b/docs/data/material/components/autocomplete/Sizes.tsx index c53a60720b0849..a04a61389f54ca 100644 --- a/docs/data/material/components/autocomplete/Sizes.tsx +++ b/docs/data/material/components/autocomplete/Sizes.tsx @@ -2,14 +2,14 @@ import Stack from '@mui/material/Stack'; import Chip from '@mui/material/Chip'; import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; +import top100Films from './top100Films'; export default function Sizes() { return ( - + option.title} defaultValue={top100Films[13]} renderInput={(params) => ( @@ -19,7 +19,6 @@ export default function Sizes() { multiple size="small" options={top100Films} - getOptionLabel={(option) => option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( @@ -28,7 +27,6 @@ export default function Sizes() { option.title} defaultValue={top100Films[13]} renderInput={(params) => ( option.title} defaultValue={[top100Films[13]]} renderValue={(values, getItemProps) => values.map((option, index) => { @@ -52,7 +49,7 @@ export default function Sizes() { @@ -71,131 +68,3 @@ export default function Sizes() { ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Tags.js b/docs/data/material/components/autocomplete/Tags.js index 2e6bf6f9efe5d2..f646e239cf61de 100644 --- a/docs/data/material/components/autocomplete/Tags.js +++ b/docs/data/material/components/autocomplete/Tags.js @@ -2,6 +2,9 @@ import Chip from '@mui/material/Chip'; import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; import Stack from '@mui/material/Stack'; +import top100Films from './top100Films'; + +const filmTitles = top100Films.map((option) => option.label); export default function Tags() { return ( @@ -9,7 +12,6 @@ export default function Tags() { option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( @@ -18,7 +20,6 @@ export default function Tags() { option.title} defaultValue={[top100Films[13]]} filterSelectedOptions renderInput={(params) => ( @@ -31,8 +32,8 @@ export default function Tags() { /> option.title)} - defaultValue={[top100Films[13].title]} + options={filmTitles} + defaultValue={[top100Films[13].label]} freeSolo renderValue={(value, getItemProps) => value.map((option, index) => { @@ -48,8 +49,8 @@ export default function Tags() { /> option.title)} - defaultValue={[top100Films[12].title, top100Films[13].title]} + options={filmTitles} + defaultValue={[top100Films[12].label, top100Films[13].label]} readOnly renderInput={(params) => ( @@ -58,131 +59,3 @@ export default function Tags() { ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/Tags.tsx b/docs/data/material/components/autocomplete/Tags.tsx index 18b225d42a0e74..ec9dab2cb08199 100644 --- a/docs/data/material/components/autocomplete/Tags.tsx +++ b/docs/data/material/components/autocomplete/Tags.tsx @@ -2,6 +2,9 @@ import Chip from '@mui/material/Chip'; import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; import Stack from '@mui/material/Stack'; +import top100Films from './top100Films'; + +const filmTitles = top100Films.map((option) => option.label); export default function Tags() { return ( @@ -9,7 +12,6 @@ export default function Tags() { option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( @@ -18,7 +20,6 @@ export default function Tags() { option.title} defaultValue={[top100Films[13]]} filterSelectedOptions renderInput={(params) => ( @@ -31,8 +32,8 @@ export default function Tags() { /> option.title)} - defaultValue={[top100Films[13].title]} + options={filmTitles} + defaultValue={[top100Films[13].label]} freeSolo renderValue={(value: readonly string[], getItemProps) => value.map((option: string, index: number) => { @@ -48,8 +49,8 @@ export default function Tags() { /> option.title)} - defaultValue={[top100Films[12].title, top100Films[13].title]} + options={filmTitles} + defaultValue={[top100Films[12].label, top100Films[13].label]} readOnly renderInput={(params) => ( @@ -58,131 +59,3 @@ export default function Tags() { ); } - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/UseAutocomplete.js b/docs/data/material/components/autocomplete/UseAutocomplete.js deleted file mode 100644 index 97f404f936568e..00000000000000 --- a/docs/data/material/components/autocomplete/UseAutocomplete.js +++ /dev/null @@ -1,205 +0,0 @@ -import useAutocomplete from '@mui/material/useAutocomplete'; -import { styled } from '@mui/system'; - -const Label = styled('label')({ - display: 'block', -}); - -const Input = styled('input')(({ theme }) => ({ - width: 200, - backgroundColor: '#fff', - color: '#000', - ...theme.applyStyles('dark', { - backgroundColor: '#000', - color: '#fff', - }), -})); - -const Listbox = styled('ul')(({ theme }) => ({ - width: 200, - margin: 0, - padding: 0, - zIndex: 1, - position: 'absolute', - listStyle: 'none', - backgroundColor: '#fff', - overflow: 'auto', - maxHeight: 200, - border: '1px solid rgba(0,0,0,.25)', - '& li.Mui-focused': { - backgroundColor: '#4a8df6', - color: 'white', - cursor: 'pointer', - }, - '& li:active': { - backgroundColor: '#2977f5', - color: 'white', - }, - ...theme.applyStyles('dark', { - backgroundColor: '#000', - }), -})); - -export default function UseAutocomplete() { - const { - getRootProps, - getInputLabelProps, - getInputProps, - getListboxProps, - getOptionProps, - groupedOptions, - } = useAutocomplete({ - id: 'use-autocomplete-demo', - options: top100Films, - getOptionLabel: (option) => option.title, - }); - - return ( -
    -
    - - -
    - {groupedOptions.length > 0 ? ( - - {groupedOptions.map((option, index) => { - const { key, ...optionProps } = getOptionProps({ option, index }); - return ( -
  • - {option.title} -
  • - ); - })} -
    - ) : null} -
    - ); -} - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/UseAutocomplete.tsx b/docs/data/material/components/autocomplete/UseAutocomplete.tsx deleted file mode 100644 index 97f404f936568e..00000000000000 --- a/docs/data/material/components/autocomplete/UseAutocomplete.tsx +++ /dev/null @@ -1,205 +0,0 @@ -import useAutocomplete from '@mui/material/useAutocomplete'; -import { styled } from '@mui/system'; - -const Label = styled('label')({ - display: 'block', -}); - -const Input = styled('input')(({ theme }) => ({ - width: 200, - backgroundColor: '#fff', - color: '#000', - ...theme.applyStyles('dark', { - backgroundColor: '#000', - color: '#fff', - }), -})); - -const Listbox = styled('ul')(({ theme }) => ({ - width: 200, - margin: 0, - padding: 0, - zIndex: 1, - position: 'absolute', - listStyle: 'none', - backgroundColor: '#fff', - overflow: 'auto', - maxHeight: 200, - border: '1px solid rgba(0,0,0,.25)', - '& li.Mui-focused': { - backgroundColor: '#4a8df6', - color: 'white', - cursor: 'pointer', - }, - '& li:active': { - backgroundColor: '#2977f5', - color: 'white', - }, - ...theme.applyStyles('dark', { - backgroundColor: '#000', - }), -})); - -export default function UseAutocomplete() { - const { - getRootProps, - getInputLabelProps, - getInputProps, - getListboxProps, - getOptionProps, - groupedOptions, - } = useAutocomplete({ - id: 'use-autocomplete-demo', - options: top100Films, - getOptionLabel: (option) => option.title, - }); - - return ( -
    -
    - - -
    - {groupedOptions.length > 0 ? ( - - {groupedOptions.map((option, index) => { - const { key, ...optionProps } = getOptionProps({ option, index }); - return ( -
  • - {option.title} -
  • - ); - })} -
    - ) : null} -
    - ); -} - -// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top -const top100Films = [ - { title: 'The Shawshank Redemption', year: 1994 }, - { title: 'The Godfather', year: 1972 }, - { title: 'The Godfather: Part II', year: 1974 }, - { title: 'The Dark Knight', year: 2008 }, - { title: '12 Angry Men', year: 1957 }, - { title: "Schindler's List", year: 1993 }, - { title: 'Pulp Fiction', year: 1994 }, - { - title: 'The Lord of the Rings: The Return of the King', - year: 2003, - }, - { title: 'The Good, the Bad and the Ugly', year: 1966 }, - { title: 'Fight Club', year: 1999 }, - { - title: 'The Lord of the Rings: The Fellowship of the Ring', - year: 2001, - }, - { - title: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, - }, - { title: 'Forrest Gump', year: 1994 }, - { title: 'Inception', year: 2010 }, - { - title: 'The Lord of the Rings: The Two Towers', - year: 2002, - }, - { title: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { title: 'Goodfellas', year: 1990 }, - { title: 'The Matrix', year: 1999 }, - { title: 'Seven Samurai', year: 1954 }, - { - title: 'Star Wars: Episode IV - A New Hope', - year: 1977, - }, - { title: 'City of God', year: 2002 }, - { title: 'Se7en', year: 1995 }, - { title: 'The Silence of the Lambs', year: 1991 }, - { title: "It's a Wonderful Life", year: 1946 }, - { title: 'Life Is Beautiful', year: 1997 }, - { title: 'The Usual Suspects', year: 1995 }, - { title: 'Léon: The Professional', year: 1994 }, - { title: 'Spirited Away', year: 2001 }, - { title: 'Saving Private Ryan', year: 1998 }, - { title: 'Once Upon a Time in the West', year: 1968 }, - { title: 'American History X', year: 1998 }, - { title: 'Interstellar', year: 2014 }, - { title: 'Casablanca', year: 1942 }, - { title: 'City Lights', year: 1931 }, - { title: 'Psycho', year: 1960 }, - { title: 'The Green Mile', year: 1999 }, - { title: 'The Intouchables', year: 2011 }, - { title: 'Modern Times', year: 1936 }, - { title: 'Raiders of the Lost Ark', year: 1981 }, - { title: 'Rear Window', year: 1954 }, - { title: 'The Pianist', year: 2002 }, - { title: 'The Departed', year: 2006 }, - { title: 'Terminator 2: Judgment Day', year: 1991 }, - { title: 'Back to the Future', year: 1985 }, - { title: 'Whiplash', year: 2014 }, - { title: 'Gladiator', year: 2000 }, - { title: 'Memento', year: 2000 }, - { title: 'The Prestige', year: 2006 }, - { title: 'The Lion King', year: 1994 }, - { title: 'Apocalypse Now', year: 1979 }, - { title: 'Alien', year: 1979 }, - { title: 'Sunset Boulevard', year: 1950 }, - { - title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', - year: 1964, - }, - { title: 'The Great Dictator', year: 1940 }, - { title: 'Cinema Paradiso', year: 1988 }, - { title: 'The Lives of Others', year: 2006 }, - { title: 'Grave of the Fireflies', year: 1988 }, - { title: 'Paths of Glory', year: 1957 }, - { title: 'Django Unchained', year: 2012 }, - { title: 'The Shining', year: 1980 }, - { title: 'WALL·E', year: 2008 }, - { title: 'American Beauty', year: 1999 }, - { title: 'The Dark Knight Rises', year: 2012 }, - { title: 'Princess Mononoke', year: 1997 }, - { title: 'Aliens', year: 1986 }, - { title: 'Oldboy', year: 2003 }, - { title: 'Once Upon a Time in America', year: 1984 }, - { title: 'Witness for the Prosecution', year: 1957 }, - { title: 'Das Boot', year: 1981 }, - { title: 'Citizen Kane', year: 1941 }, - { title: 'North by Northwest', year: 1959 }, - { title: 'Vertigo', year: 1958 }, - { - title: 'Star Wars: Episode VI - Return of the Jedi', - year: 1983, - }, - { title: 'Reservoir Dogs', year: 1992 }, - { title: 'Braveheart', year: 1995 }, - { title: 'M', year: 1931 }, - { title: 'Requiem for a Dream', year: 2000 }, - { title: 'Amélie', year: 2001 }, - { title: 'A Clockwork Orange', year: 1971 }, - { title: 'Like Stars on Earth', year: 2007 }, - { title: 'Taxi Driver', year: 1976 }, - { title: 'Lawrence of Arabia', year: 1962 }, - { title: 'Double Indemnity', year: 1944 }, - { - title: 'Eternal Sunshine of the Spotless Mind', - year: 2004, - }, - { title: 'Amadeus', year: 1984 }, - { title: 'To Kill a Mockingbird', year: 1962 }, - { title: 'Toy Story 3', year: 2010 }, - { title: 'Logan', year: 2017 }, - { title: 'Full Metal Jacket', year: 1987 }, - { title: 'Dangal', year: 2016 }, - { title: 'The Sting', year: 1973 }, - { title: '2001: A Space Odyssey', year: 1968 }, - { title: "Singin' in the Rain", year: 1952 }, - { title: 'Toy Story', year: 1995 }, - { title: 'Bicycle Thieves', year: 1948 }, - { title: 'The Kid', year: 1921 }, - { title: 'Inglourious Basterds', year: 2009 }, - { title: 'Snatch', year: 2000 }, - { title: '3 Idiots', year: 2009 }, - { title: 'Monty Python and the Holy Grail', year: 1975 }, -]; diff --git a/docs/data/material/components/autocomplete/UseAutocomplete.tsx.preview b/docs/data/material/components/autocomplete/UseAutocomplete.tsx.preview deleted file mode 100644 index 6bd1f59e445bfe..00000000000000 --- a/docs/data/material/components/autocomplete/UseAutocomplete.tsx.preview +++ /dev/null @@ -1,16 +0,0 @@ -
    - - -
    -{groupedOptions.length > 0 ? ( - - {groupedOptions.map((option, index) => { - const { key, ...optionProps } = getOptionProps({ option, index }); - return ( -
  • - {option.title} -
  • - ); - })} -
    -) : null} \ No newline at end of file diff --git a/docs/data/material/components/autocomplete/Virtualize.js b/docs/data/material/components/autocomplete/Virtualize.js index b431dc73e84860..50d0bd25050ba2 100644 --- a/docs/data/material/components/autocomplete/Virtualize.js +++ b/docs/data/material/components/autocomplete/Virtualize.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import TextField from '@mui/material/TextField'; import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import useMediaQuery from '@mui/material/useMediaQuery'; -import ListSubheader from '@mui/material/ListSubheader'; import Popper from '@mui/material/Popper'; import { useTheme, styled } from '@mui/material/styles'; import { List, useListRef } from 'react-window'; @@ -18,14 +17,6 @@ function RowComponent({ index, itemData, style }) { top: (style.top ?? 0) + LISTBOX_PADDING, }; - if ('group' in dataSet) { - return ( - - {dataSet.group} - - ); - } - const { key, ...optionProps } = dataSet[0]; return ( @@ -40,39 +31,27 @@ function RowComponent({ index, itemData, style }) { RowComponent.propTypes = { index: PropTypes.number.isRequired, itemData: PropTypes.arrayOf( - PropTypes.oneOfType([ - PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.element, PropTypes.number, PropTypes.string]) - .isRequired, - ), - PropTypes.shape({ - children: PropTypes.node, - group: PropTypes.string.isRequired, - key: PropTypes.number.isRequired, - }), - ]).isRequired, + PropTypes.arrayOf( + PropTypes.oneOfType([PropTypes.number, PropTypes.object, PropTypes.string]) + .isRequired, + ), ).isRequired, style: PropTypes.object.isRequired, }; const ListboxComponent = React.forwardRef(function ListboxComponent(props, ref) { const { children, internalListRef, onItemsBuilt, ...other } = props; - const itemData = []; - const optionIndexMap = React.useMemo(() => new Map(), []); + const itemData = children; - children.forEach((item) => { - itemData.push(item); - if ('children' in item && Array.isArray(item.children)) { - itemData.push(...item.children); - } - }); + const optionIndexMap = React.useMemo(() => { + const map = new Map(); - // Map option values to their indices in the flattened array - itemData.forEach((item, index) => { - if (Array.isArray(item) && item[1]) { - optionIndexMap.set(item[1], index); - } - }); + itemData.forEach((item, index) => { + map.set(item[1], index); + }); + + return map; + }, [itemData]); React.useEffect(() => { if (onItemsBuilt) { @@ -87,18 +66,11 @@ const ListboxComponent = React.forwardRef(function ListboxComponent(props, ref) const itemCount = itemData.length; const itemSize = smUp ? 36 : 48; - const getChildSize = (child) => { - if (child.hasOwnProperty('group')) { - return 48; - } - return itemSize; - }; - const getHeight = () => { if (itemCount > 8) { return 8 * itemSize; } - return itemData.map(getChildSize).reduce((a, b) => a + b, 0); + return itemCount * itemSize; }; // Separate className for List, other props for wrapper div (ARIA, handlers) @@ -111,7 +83,7 @@ const ListboxComponent = React.forwardRef(function ListboxComponent(props, ref) listRef={internalListRef} key={itemCount} rowCount={itemCount} - rowHeight={(index) => getChildSize(itemData[index])} + rowHeight={itemSize} rowComponent={RowComponent} rowProps={{ itemData }} style={{ @@ -177,7 +149,7 @@ export default function Virtualize() { }, []); // Handle keyboard navigation by scrolling to highlighted option - const handleHighlightChange = (event, option) => { + const handleHighlightChange = (_event, option) => { if (option && internalListRef.current) { const index = optionIndexMapRef.current.get(option); if (index !== undefined) { @@ -191,10 +163,8 @@ export default function Virtualize() { sx={{ width: 300 }} disableListWrap options={OPTIONS} - groupBy={(option) => option[0].toUpperCase()} renderInput={(params) => } renderOption={(props, option, state) => [props, option, state.index]} - renderGroup={(params) => params} onHighlightChange={handleHighlightChange} slots={{ popper: StyledPopper, diff --git a/docs/data/material/components/autocomplete/Virtualize.tsx b/docs/data/material/components/autocomplete/Virtualize.tsx index 50418c99264b61..030998ade62770 100644 --- a/docs/data/material/components/autocomplete/Virtualize.tsx +++ b/docs/data/material/components/autocomplete/Virtualize.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete, { autocompleteClasses } from '@mui/material/Autocomplete'; import useMediaQuery from '@mui/material/useMediaQuery'; -import ListSubheader from '@mui/material/ListSubheader'; import Popper from '@mui/material/Popper'; import { useTheme, styled } from '@mui/material/styles'; import { @@ -16,12 +15,7 @@ import Typography from '@mui/material/Typography'; const LISTBOX_PADDING = 8; // px type ItemData = Array< - | { - key: number; - group: string; - children: React.ReactNode; - } - | [React.ReactElement, string, number] + [React.HTMLAttributes & { key: React.Key }, string, number] >; function RowComponent({ @@ -37,14 +31,6 @@ function RowComponent({ top: ((style.top as number) ?? 0) + LISTBOX_PADDING, }; - if ('group' in dataSet) { - return ( - - {dataSet.group} - - ); - } - const { key, ...optionProps } = dataSet[0]; return ( @@ -63,22 +49,17 @@ const ListboxComponent = React.forwardRef< } >(function ListboxComponent(props, ref) { const { children, internalListRef, onItemsBuilt, ...other } = props; - const itemData: ItemData = []; - const optionIndexMap = React.useMemo(() => new Map(), []); + const itemData = children as ItemData; - (children as ItemData).forEach((item) => { - itemData.push(item); - if ('children' in item && Array.isArray(item.children)) { - itemData.push(...item.children); - } - }); + const optionIndexMap = React.useMemo(() => { + const map = new Map(); - // Map option values to their indices in the flattened array - itemData.forEach((item, index) => { - if (Array.isArray(item) && item[1]) { - optionIndexMap.set(item[1], index); - } - }); + itemData.forEach((item, index) => { + map.set(item[1], index); + }); + + return map; + }, [itemData]); React.useEffect(() => { if (onItemsBuilt) { @@ -93,18 +74,11 @@ const ListboxComponent = React.forwardRef< const itemCount = itemData.length; const itemSize = smUp ? 36 : 48; - const getChildSize = (child: ItemData[number]) => { - if (child.hasOwnProperty('group')) { - return 48; - } - return itemSize; - }; - const getHeight = () => { if (itemCount > 8) { return 8 * itemSize; } - return itemData.map(getChildSize).reduce((a, b) => a + b, 0); + return itemCount * itemSize; }; // Separate className for List, other props for wrapper div (ARIA, handlers) @@ -117,7 +91,7 @@ const ListboxComponent = React.forwardRef< listRef={internalListRef} key={itemCount} rowCount={itemCount} - rowHeight={(index) => getChildSize(itemData[index])} + rowHeight={itemSize} rowComponent={RowComponent} rowProps={{ itemData }} style={{ @@ -171,7 +145,7 @@ export default function Virtualize() { // Handle keyboard navigation by scrolling to highlighted option const handleHighlightChange = ( - event: React.SyntheticEvent, + _event: React.SyntheticEvent, option: string | null, ) => { if (option && internalListRef.current) { @@ -187,12 +161,10 @@ export default function Virtualize() { sx={{ width: 300 }} disableListWrap options={OPTIONS} - groupBy={(option) => option[0].toUpperCase()} renderInput={(params) => } renderOption={(props, option, state) => [props, option, state.index] as React.ReactNode } - renderGroup={(params) => params as any} onHighlightChange={handleHighlightChange} slots={{ popper: StyledPopper, diff --git a/docs/data/material/components/autocomplete/autocomplete.md b/docs/data/material/components/autocomplete/autocomplete.md index fb60aa6240307c..2b623cd8a3fc2c 100644 --- a/docs/data/material/components/autocomplete/autocomplete.md +++ b/docs/data/material/components/autocomplete/autocomplete.md @@ -21,25 +21,25 @@ Autocomplete supports three core interaction modes: ## Usage guidelines -- **Combobox vs. free solo**: By default, the value must come from a fixed list of options. Set `freeSolo` when the input can be arbitrary text—for example, a search box. See [Combobox](#combobox) and [Free solo](#free-solo). -- **Prefer `Select` for short, non-filterable lists**: If users don't need to filter, the [Select](/material-ui/react-select/) component is lighter and feels more familiar for short lists. -- **Stable controlled values**: When you control `value`, keep the reference stable between renders to avoid unnecessary resets and selection mismatches. See [Controlled states](#controlled-states). -- **Multiple values**: Set `multiple` to let users select more than one option. Selected items appear as removable chips. See [Multiple values](#multiple-values). -- **Visible text label**: Provide a visible label via the `TextField` `label` prop. The component follows the [WAI-ARIA combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/), but a visible label still helps everyone—including screen reader users. +- **Use it for filterable choices**: Autocomplete is best when users need typeahead to choose from a longer list. Use [Select](/material-ui/react-select/) instead for short lists that don't need filtering. +- **Choose fixed list or free text**: By default, values must come from `options`. Use `freeSolo` only when arbitrary text is valid, such as in a search field. +- **Keep controlled values stable**: When controlling `value`, preserve object and array references when their contents don't change. See [Controlled states](#controlled-states). +- **Label the input**: Provide a visible `TextField` `label` when possible, or another accessible name if the label is hidden. This follows the [WAI-ARIA combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) and helps all users. ## Combobox -The value must come from a fixed list of options. +Use the basic combobox when users need to search a predefined list and pick one value. {{"demo": "ComboBox.js"}} ### Options structure -By default, options can take either of these structures: +By default, options can be strings or objects with a `label` string. You can add fields that model your data, such as a stable ID, timestamp, or grouping field. TypeScript infers the option type from the `options` prop, so callbacks like `onChange` are strongly typed. ```ts interface AutocompleteOption { label: string; + id?: string | number; } // or type AutocompleteOption = string; @@ -65,7 +65,7 @@ When using object options, provide `isOptionEqualToValue` so the component can m /> ``` -To use a different option structure, provide a `getOptionLabel` prop: +To display a value other than `label`, use `getOptionLabel` to return a string representing each option: ```tsx const options = [ @@ -76,7 +76,7 @@ const options = [ option.email} />; ``` -If two options share a label, use `getOptionKey` to give each one a unique key: +Autocomplete uses the label as the React key for each option by default. If two options share the same label, keep `getOptionLabel` for the display text and use `getOptionKey` to provide a stable key for each rendered option: ```tsx // Two contacts happen to share the same display name @@ -96,7 +96,7 @@ Each example below demonstrates one feature. ### Country select -Choose one of the 248 countries. +Use `renderOption` to customize each option. This country picker renders a flag, country code, and calling code. {{"demo": "CountrySelect.js"}} @@ -193,7 +193,7 @@ Or open a dialog when the user wants to add a new value. ## Multiple values -Set `multiple={true}` to let users select more than one value. By default, selected values render as removable Material UI Chips; customize their rendering with `renderValue`. +Set `multiple={true}` to let users select more than one value. By default, selected values render as removable Material UI Chips; customize their rendering with `renderValue`. - Spread the props from `getItemProps` onto each rendered item to preserve the component's built-in behavior. - If you replace the default Chip, destructure `onDelete` first; it's specific to `Chip`. @@ -267,8 +267,10 @@ Uses `@tanstack/react-query` to fetch more options when the user scrolls to the In the default single-selection mode (when `multiple={false}`), the selected option appears as plain text inside the input. Use `renderValue` to customize the display—for example, to add icons, badges, or formatted output. -- Spread the props from `getItemProps` onto your rendered element to preserve the component's built-in behavior. -- If you replace the default Chip, destructure `onDelete` first; it's specific to `Chip`. +The `renderValue` callback receives two parameters: + +- `value`: the selected option to render inside the input. +- `getItemProps`: returns props for the rendered item. Forward the DOM-safe props you need, such as `className`, `data-item-index`, and `tabIndex`; omit `onDelete` unless you render a Chip. {{"demo": "CustomSingleValueRendering.js"}} @@ -336,13 +338,22 @@ Use the `size` prop to render a smaller input. ### Custom input -Customize the rendered input with the `renderInput` prop. It receives a props object you need to forward, including `ref` and `inputProps`. +Customize the rendered input with the `renderInput` prop. Forward the input ref and HTML input props to preserve the Autocomplete behavior. :::warning When using a custom input component, forward the ref to the underlying DOM element. ::: -{{"demo": "CustomInputAutocomplete.js"}} +```tsx + ( +
    + +
    + )} +/> +``` ### Globally customized options @@ -360,8 +371,6 @@ A reproduction of GitHub's label picker: {{"demo": "GitHubLabel.js"}} -See [Customized hook](#customized-hook) for the same pattern using the `useAutocomplete` hook. - ### Hint Add a hint (ghost text suggestion) inside the input: @@ -392,21 +401,75 @@ Searches through a fixed list of 10,000 randomly generated options. The list is ## `useAutocomplete` -Use the `useAutocomplete` hook for full control over markup. It accepts the same options as `Autocomplete` minus the rendering props. +Use the `useAutocomplete` hook when you need full control over markup. Import it from `@mui/material/useAutocomplete` ([4.6 kB gzipped](https://bundlephobia.com/package/@mui/material)); it accepts the same options as `Autocomplete`, minus the rendering props. The snippet shows the essential setup for a headless combobox. ```tsx import useAutocomplete from '@mui/material/useAutocomplete'; -``` -- 📦 [4.6 kB gzipped](https://bundlephobia.com/package/@mui/material). +interface Option { + label: string; +} + +interface MyAutocompleteProps { + id: string; + label: string; + options: readonly Option[]; +} + +function MyAutocomplete({ id, label, options }: MyAutocompleteProps) { + const { + getRootProps, + getInputLabelProps, + getInputProps, + getListboxProps, + getOptionProps, + groupedOptions, + } = useAutocomplete({ + id, + options, + }); + + return ( +
    +
    + + +
    + {groupedOptions.length > 0 ? ( +
      + {groupedOptions.map((option, index) => { + const { key, ...optionProps } = getOptionProps({ option, index }); + return ( +
    • + {option.label} +
    • + ); + })} +
    + ) : null} +
    + ); +} + +export default function App() { + return ; +} -{{"demo": "UseAutocomplete.js", "defaultCodeOpen": false}} +interface Film extends Option { + year: number; +} + +const movies: readonly Film[] = [ + { label: 'The Shawshank Redemption', year: 1994 }, + { label: 'The Godfather', year: 1972 }, +]; +``` ### Customized hook -{{"demo": "CustomizedHook.js", "defaultCodeOpen": false}} +This demo shows a fully customized multi-selection combobox built with `useAutocomplete`. -See [Customization](#customization) for the same pattern using the `Autocomplete` component. +{{"demo": "CustomizedHook.js", "defaultCodeOpen": false}} ## Limitations diff --git a/docs/data/material/components/autocomplete/countries.js b/docs/data/material/components/autocomplete/countries.js new file mode 100644 index 00000000000000..d395d679bbeffe --- /dev/null +++ b/docs/data/material/components/autocomplete/countries.js @@ -0,0 +1,815 @@ +// Country metadata is adapted from countries-list (MIT): +// https://github.com/annexare/Countries +// Country calling codes are kept in display format for this demo. +const countries = [ + { code: 'AD', label: 'Andorra', countryCallingCode: '376', continent: 'Europe' }, + { + code: 'AE', + label: 'United Arab Emirates', + countryCallingCode: '971', + continent: 'Asia', + }, + { code: 'AF', label: 'Afghanistan', countryCallingCode: '93', continent: 'Asia' }, + { + code: 'AG', + label: 'Antigua and Barbuda', + countryCallingCode: '1-268', + continent: 'North America', + }, + { + code: 'AI', + label: 'Anguilla', + countryCallingCode: '1-264', + continent: 'North America', + }, + { code: 'AL', label: 'Albania', countryCallingCode: '355', continent: 'Europe' }, + { code: 'AM', label: 'Armenia', countryCallingCode: '374', continent: 'Asia' }, + { code: 'AO', label: 'Angola', countryCallingCode: '244', continent: 'Africa' }, + { + code: 'AQ', + label: 'Antarctica', + countryCallingCode: '672', + continent: 'Antarctica', + }, + { + code: 'AR', + label: 'Argentina', + countryCallingCode: '54', + continent: 'South America', + }, + { + code: 'AS', + label: 'American Samoa', + countryCallingCode: '1-684', + continent: 'Oceania', + }, + { code: 'AT', label: 'Austria', countryCallingCode: '43', continent: 'Europe' }, + { code: 'AU', label: 'Australia', countryCallingCode: '61', continent: 'Oceania' }, + { + code: 'AW', + label: 'Aruba', + countryCallingCode: '297', + continent: 'North America', + }, + { code: 'AX', label: 'Aland', countryCallingCode: '358', continent: 'Europe' }, + { code: 'AZ', label: 'Azerbaijan', countryCallingCode: '994', continent: 'Asia' }, + { + code: 'BA', + label: 'Bosnia and Herzegovina', + countryCallingCode: '387', + continent: 'Europe', + }, + { + code: 'BB', + label: 'Barbados', + countryCallingCode: '1-246', + continent: 'North America', + }, + { code: 'BD', label: 'Bangladesh', countryCallingCode: '880', continent: 'Asia' }, + { code: 'BE', label: 'Belgium', countryCallingCode: '32', continent: 'Europe' }, + { + code: 'BF', + label: 'Burkina Faso', + countryCallingCode: '226', + continent: 'Africa', + }, + { code: 'BG', label: 'Bulgaria', countryCallingCode: '359', continent: 'Europe' }, + { code: 'BH', label: 'Bahrain', countryCallingCode: '973', continent: 'Asia' }, + { code: 'BI', label: 'Burundi', countryCallingCode: '257', continent: 'Africa' }, + { code: 'BJ', label: 'Benin', countryCallingCode: '229', continent: 'Africa' }, + { + code: 'BL', + label: 'Saint Barthelemy', + countryCallingCode: '590', + continent: 'North America', + }, + { + code: 'BM', + label: 'Bermuda', + countryCallingCode: '1-441', + continent: 'North America', + }, + { code: 'BN', label: 'Brunei', countryCallingCode: '673', continent: 'Asia' }, + { + code: 'BO', + label: 'Bolivia', + countryCallingCode: '591', + continent: 'South America', + }, + { + code: 'BR', + label: 'Brazil', + countryCallingCode: '55', + continent: 'South America', + }, + { + code: 'BS', + label: 'Bahamas', + countryCallingCode: '1-242', + continent: 'North America', + }, + { code: 'BT', label: 'Bhutan', countryCallingCode: '975', continent: 'Asia' }, + { + code: 'BV', + label: 'Bouvet Island', + countryCallingCode: '47', + continent: 'Antarctica', + }, + { code: 'BW', label: 'Botswana', countryCallingCode: '267', continent: 'Africa' }, + { code: 'BY', label: 'Belarus', countryCallingCode: '375', continent: 'Europe' }, + { + code: 'BZ', + label: 'Belize', + countryCallingCode: '501', + continent: 'North America', + }, + { + code: 'CA', + label: 'Canada', + countryCallingCode: '1', + continent: 'North America', + }, + { + code: 'CC', + label: 'Cocos (Keeling) Islands', + countryCallingCode: '61', + continent: 'Asia', + }, + { + code: 'CD', + label: 'Democratic Republic of the Congo', + countryCallingCode: '243', + continent: 'Africa', + }, + { + code: 'CF', + label: 'Central African Republic', + countryCallingCode: '236', + continent: 'Africa', + }, + { + code: 'CG', + label: 'Republic of the Congo', + countryCallingCode: '242', + continent: 'Africa', + }, + { + code: 'CH', + label: 'Switzerland', + countryCallingCode: '41', + continent: 'Europe', + }, + { + code: 'CI', + label: 'Ivory Coast', + countryCallingCode: '225', + continent: 'Africa', + }, + { + code: 'CK', + label: 'Cook Islands', + countryCallingCode: '682', + continent: 'Oceania', + }, + { + code: 'CL', + label: 'Chile', + countryCallingCode: '56', + continent: 'South America', + }, + { code: 'CM', label: 'Cameroon', countryCallingCode: '237', continent: 'Africa' }, + { code: 'CN', label: 'China', countryCallingCode: '86', continent: 'Asia' }, + { + code: 'CO', + label: 'Colombia', + countryCallingCode: '57', + continent: 'South America', + }, + { + code: 'CR', + label: 'Costa Rica', + countryCallingCode: '506', + continent: 'North America', + }, + { + code: 'CU', + label: 'Cuba', + countryCallingCode: '53', + continent: 'North America', + }, + { + code: 'CV', + label: 'Cape Verde', + countryCallingCode: '238', + continent: 'Africa', + }, + { + code: 'CW', + label: 'Curacao', + countryCallingCode: '599', + continent: 'North America', + }, + { + code: 'CX', + label: 'Christmas Island', + countryCallingCode: '61', + continent: 'Asia', + }, + { code: 'CY', label: 'Cyprus', countryCallingCode: '357', continent: 'Europe' }, + { + code: 'CZ', + label: 'Czech Republic', + countryCallingCode: '420', + continent: 'Europe', + }, + { code: 'DE', label: 'Germany', countryCallingCode: '49', continent: 'Europe' }, + { code: 'DJ', label: 'Djibouti', countryCallingCode: '253', continent: 'Africa' }, + { code: 'DK', label: 'Denmark', countryCallingCode: '45', continent: 'Europe' }, + { + code: 'DM', + label: 'Dominica', + countryCallingCode: '1-767', + continent: 'North America', + }, + { + code: 'DO', + label: 'Dominican Republic', + countryCallingCode: '1-809', + continent: 'North America', + }, + { code: 'DZ', label: 'Algeria', countryCallingCode: '213', continent: 'Africa' }, + { + code: 'EC', + label: 'Ecuador', + countryCallingCode: '593', + continent: 'South America', + }, + { code: 'EE', label: 'Estonia', countryCallingCode: '372', continent: 'Europe' }, + { code: 'EG', label: 'Egypt', countryCallingCode: '20', continent: 'Africa' }, + { + code: 'EH', + label: 'Western Sahara', + countryCallingCode: '212', + continent: 'Africa', + }, + { code: 'ER', label: 'Eritrea', countryCallingCode: '291', continent: 'Africa' }, + { code: 'ES', label: 'Spain', countryCallingCode: '34', continent: 'Europe' }, + { code: 'ET', label: 'Ethiopia', countryCallingCode: '251', continent: 'Africa' }, + { code: 'FI', label: 'Finland', countryCallingCode: '358', continent: 'Europe' }, + { code: 'FJ', label: 'Fiji', countryCallingCode: '679', continent: 'Oceania' }, + { + code: 'FK', + label: 'Falkland Islands', + countryCallingCode: '500', + continent: 'South America', + }, + { + code: 'FM', + label: 'Micronesia', + countryCallingCode: '691', + continent: 'Oceania', + }, + { + code: 'FO', + label: 'Faroe Islands', + countryCallingCode: '298', + continent: 'Europe', + }, + { code: 'FR', label: 'France', countryCallingCode: '33', continent: 'Europe' }, + { code: 'GA', label: 'Gabon', countryCallingCode: '241', continent: 'Africa' }, + { + code: 'GB', + label: 'United Kingdom', + countryCallingCode: '44', + continent: 'Europe', + }, + { + code: 'GD', + label: 'Grenada', + countryCallingCode: '1-473', + continent: 'North America', + }, + { code: 'GE', label: 'Georgia', countryCallingCode: '995', continent: 'Asia' }, + { + code: 'GF', + label: 'French Guiana', + countryCallingCode: '594', + continent: 'South America', + }, + { code: 'GG', label: 'Guernsey', countryCallingCode: '44', continent: 'Europe' }, + { code: 'GH', label: 'Ghana', countryCallingCode: '233', continent: 'Africa' }, + { code: 'GI', label: 'Gibraltar', countryCallingCode: '350', continent: 'Europe' }, + { + code: 'GL', + label: 'Greenland', + countryCallingCode: '299', + continent: 'North America', + }, + { code: 'GM', label: 'Gambia', countryCallingCode: '220', continent: 'Africa' }, + { code: 'GN', label: 'Guinea', countryCallingCode: '224', continent: 'Africa' }, + { + code: 'GP', + label: 'Guadeloupe', + countryCallingCode: '590', + continent: 'North America', + }, + { + code: 'GQ', + label: 'Equatorial Guinea', + countryCallingCode: '240', + continent: 'Africa', + }, + { code: 'GR', label: 'Greece', countryCallingCode: '30', continent: 'Europe' }, + { + code: 'GS', + label: 'South Georgia and the South Sandwich Islands', + countryCallingCode: '500', + continent: 'Antarctica', + }, + { + code: 'GT', + label: 'Guatemala', + countryCallingCode: '502', + continent: 'North America', + }, + { code: 'GU', label: 'Guam', countryCallingCode: '1-671', continent: 'Oceania' }, + { + code: 'GW', + label: 'Guinea-Bissau', + countryCallingCode: '245', + continent: 'Africa', + }, + { + code: 'GY', + label: 'Guyana', + countryCallingCode: '592', + continent: 'South America', + }, + { code: 'HK', label: 'Hong Kong', countryCallingCode: '852', continent: 'Asia' }, + { + code: 'HM', + label: 'Heard Island and McDonald Islands', + countryCallingCode: '672', + continent: 'Antarctica', + }, + { + code: 'HN', + label: 'Honduras', + countryCallingCode: '504', + continent: 'North America', + }, + { code: 'HR', label: 'Croatia', countryCallingCode: '385', continent: 'Europe' }, + { + code: 'HT', + label: 'Haiti', + countryCallingCode: '509', + continent: 'North America', + }, + { code: 'HU', label: 'Hungary', countryCallingCode: '36', continent: 'Europe' }, + { code: 'ID', label: 'Indonesia', countryCallingCode: '62', continent: 'Asia' }, + { code: 'IE', label: 'Ireland', countryCallingCode: '353', continent: 'Europe' }, + { code: 'IL', label: 'Israel', countryCallingCode: '972', continent: 'Asia' }, + { + code: 'IM', + label: 'Isle of Man', + countryCallingCode: '44', + continent: 'Europe', + }, + { code: 'IN', label: 'India', countryCallingCode: '91', continent: 'Asia' }, + { + code: 'IO', + label: 'British Indian Ocean Territory', + countryCallingCode: '246', + continent: 'Asia', + }, + { code: 'IQ', label: 'Iraq', countryCallingCode: '964', continent: 'Asia' }, + { code: 'IR', label: 'Iran', countryCallingCode: '98', continent: 'Asia' }, + { code: 'IS', label: 'Iceland', countryCallingCode: '354', continent: 'Europe' }, + { code: 'IT', label: 'Italy', countryCallingCode: '39', continent: 'Europe' }, + { code: 'JE', label: 'Jersey', countryCallingCode: '44', continent: 'Europe' }, + { + code: 'JM', + label: 'Jamaica', + countryCallingCode: '1-876', + continent: 'North America', + }, + { code: 'JO', label: 'Jordan', countryCallingCode: '962', continent: 'Asia' }, + { code: 'JP', label: 'Japan', countryCallingCode: '81', continent: 'Asia' }, + { code: 'KE', label: 'Kenya', countryCallingCode: '254', continent: 'Africa' }, + { code: 'KG', label: 'Kyrgyzstan', countryCallingCode: '996', continent: 'Asia' }, + { code: 'KH', label: 'Cambodia', countryCallingCode: '855', continent: 'Asia' }, + { code: 'KI', label: 'Kiribati', countryCallingCode: '686', continent: 'Oceania' }, + { code: 'KM', label: 'Comoros', countryCallingCode: '269', continent: 'Africa' }, + { + code: 'KN', + label: 'Saint Kitts and Nevis', + countryCallingCode: '1-869', + continent: 'North America', + }, + { code: 'KP', label: 'North Korea', countryCallingCode: '850', continent: 'Asia' }, + { code: 'KR', label: 'South Korea', countryCallingCode: '82', continent: 'Asia' }, + { code: 'KW', label: 'Kuwait', countryCallingCode: '965', continent: 'Asia' }, + { + code: 'KY', + label: 'Cayman Islands', + countryCallingCode: '1-345', + continent: 'North America', + }, + { code: 'KZ', label: 'Kazakhstan', countryCallingCode: '7', continent: 'Asia' }, + { code: 'LA', label: 'Laos', countryCallingCode: '856', continent: 'Asia' }, + { code: 'LB', label: 'Lebanon', countryCallingCode: '961', continent: 'Asia' }, + { + code: 'LC', + label: 'Saint Lucia', + countryCallingCode: '1-758', + continent: 'North America', + }, + { + code: 'LI', + label: 'Liechtenstein', + countryCallingCode: '423', + continent: 'Europe', + }, + { code: 'LK', label: 'Sri Lanka', countryCallingCode: '94', continent: 'Asia' }, + { code: 'LR', label: 'Liberia', countryCallingCode: '231', continent: 'Africa' }, + { code: 'LS', label: 'Lesotho', countryCallingCode: '266', continent: 'Africa' }, + { code: 'LT', label: 'Lithuania', countryCallingCode: '370', continent: 'Europe' }, + { + code: 'LU', + label: 'Luxembourg', + countryCallingCode: '352', + continent: 'Europe', + }, + { code: 'LV', label: 'Latvia', countryCallingCode: '371', continent: 'Europe' }, + { code: 'LY', label: 'Libya', countryCallingCode: '218', continent: 'Africa' }, + { code: 'MA', label: 'Morocco', countryCallingCode: '212', continent: 'Africa' }, + { code: 'MC', label: 'Monaco', countryCallingCode: '377', continent: 'Europe' }, + { code: 'MD', label: 'Moldova', countryCallingCode: '373', continent: 'Europe' }, + { + code: 'ME', + label: 'Montenegro', + countryCallingCode: '382', + continent: 'Europe', + }, + { + code: 'MF', + label: 'Saint Martin', + countryCallingCode: '590', + continent: 'North America', + }, + { + code: 'MG', + label: 'Madagascar', + countryCallingCode: '261', + continent: 'Africa', + }, + { + code: 'MH', + label: 'Marshall Islands', + countryCallingCode: '692', + continent: 'Oceania', + }, + { + code: 'MK', + label: 'North Macedonia', + countryCallingCode: '389', + continent: 'Europe', + }, + { code: 'ML', label: 'Mali', countryCallingCode: '223', continent: 'Africa' }, + { + code: 'MM', + label: 'Myanmar (Burma)', + countryCallingCode: '95', + continent: 'Asia', + }, + { code: 'MN', label: 'Mongolia', countryCallingCode: '976', continent: 'Asia' }, + { code: 'MO', label: 'Macao', countryCallingCode: '853', continent: 'Asia' }, + { + code: 'MP', + label: 'Northern Mariana Islands', + countryCallingCode: '1-670', + continent: 'Oceania', + }, + { + code: 'MQ', + label: 'Martinique', + countryCallingCode: '596', + continent: 'North America', + }, + { + code: 'MR', + label: 'Mauritania', + countryCallingCode: '222', + continent: 'Africa', + }, + { + code: 'MS', + label: 'Montserrat', + countryCallingCode: '1-664', + continent: 'North America', + }, + { code: 'MT', label: 'Malta', countryCallingCode: '356', continent: 'Europe' }, + { code: 'MU', label: 'Mauritius', countryCallingCode: '230', continent: 'Africa' }, + { code: 'MV', label: 'Maldives', countryCallingCode: '960', continent: 'Asia' }, + { code: 'MW', label: 'Malawi', countryCallingCode: '265', continent: 'Africa' }, + { + code: 'MX', + label: 'Mexico', + countryCallingCode: '52', + continent: 'North America', + }, + { code: 'MY', label: 'Malaysia', countryCallingCode: '60', continent: 'Asia' }, + { + code: 'MZ', + label: 'Mozambique', + countryCallingCode: '258', + continent: 'Africa', + }, + { code: 'NA', label: 'Namibia', countryCallingCode: '264', continent: 'Africa' }, + { + code: 'NC', + label: 'New Caledonia', + countryCallingCode: '687', + continent: 'Oceania', + }, + { code: 'NE', label: 'Niger', countryCallingCode: '227', continent: 'Africa' }, + { + code: 'NF', + label: 'Norfolk Island', + countryCallingCode: '672', + continent: 'Oceania', + }, + { code: 'NG', label: 'Nigeria', countryCallingCode: '234', continent: 'Africa' }, + { + code: 'NI', + label: 'Nicaragua', + countryCallingCode: '505', + continent: 'North America', + }, + { + code: 'NL', + label: 'Netherlands', + countryCallingCode: '31', + continent: 'Europe', + }, + { code: 'NO', label: 'Norway', countryCallingCode: '47', continent: 'Europe' }, + { code: 'NP', label: 'Nepal', countryCallingCode: '977', continent: 'Asia' }, + { code: 'NR', label: 'Nauru', countryCallingCode: '674', continent: 'Oceania' }, + { code: 'NU', label: 'Niue', countryCallingCode: '683', continent: 'Oceania' }, + { + code: 'NZ', + label: 'New Zealand', + countryCallingCode: '64', + continent: 'Oceania', + }, + { code: 'OM', label: 'Oman', countryCallingCode: '968', continent: 'Asia' }, + { + code: 'PA', + label: 'Panama', + countryCallingCode: '507', + continent: 'North America', + }, + { + code: 'PE', + label: 'Peru', + countryCallingCode: '51', + continent: 'South America', + }, + { + code: 'PF', + label: 'French Polynesia', + countryCallingCode: '689', + continent: 'Oceania', + }, + { + code: 'PG', + label: 'Papua New Guinea', + countryCallingCode: '675', + continent: 'Oceania', + }, + { code: 'PH', label: 'Philippines', countryCallingCode: '63', continent: 'Asia' }, + { code: 'PK', label: 'Pakistan', countryCallingCode: '92', continent: 'Asia' }, + { code: 'PL', label: 'Poland', countryCallingCode: '48', continent: 'Europe' }, + { + code: 'PM', + label: 'Saint Pierre and Miquelon', + countryCallingCode: '508', + continent: 'North America', + }, + { + code: 'PN', + label: 'Pitcairn Islands', + countryCallingCode: '870', + continent: 'Oceania', + }, + { + code: 'PR', + label: 'Puerto Rico', + countryCallingCode: '1', + continent: 'North America', + }, + { code: 'PS', label: 'Palestine', countryCallingCode: '970', continent: 'Asia' }, + { code: 'PT', label: 'Portugal', countryCallingCode: '351', continent: 'Europe' }, + { code: 'PW', label: 'Palau', countryCallingCode: '680', continent: 'Oceania' }, + { + code: 'PY', + label: 'Paraguay', + countryCallingCode: '595', + continent: 'South America', + }, + { code: 'QA', label: 'Qatar', countryCallingCode: '974', continent: 'Asia' }, + { code: 'RE', label: 'Reunion', countryCallingCode: '262', continent: 'Africa' }, + { code: 'RO', label: 'Romania', countryCallingCode: '40', continent: 'Europe' }, + { code: 'RS', label: 'Serbia', countryCallingCode: '381', continent: 'Europe' }, + { code: 'RU', label: 'Russia', countryCallingCode: '7', continent: 'Asia' }, + { code: 'RW', label: 'Rwanda', countryCallingCode: '250', continent: 'Africa' }, + { + code: 'SA', + label: 'Saudi Arabia', + countryCallingCode: '966', + continent: 'Asia', + }, + { + code: 'SB', + label: 'Solomon Islands', + countryCallingCode: '677', + continent: 'Oceania', + }, + { + code: 'SC', + label: 'Seychelles', + countryCallingCode: '248', + continent: 'Africa', + }, + { code: 'SD', label: 'Sudan', countryCallingCode: '249', continent: 'Africa' }, + { code: 'SE', label: 'Sweden', countryCallingCode: '46', continent: 'Europe' }, + { code: 'SG', label: 'Singapore', countryCallingCode: '65', continent: 'Asia' }, + { + code: 'SH', + label: 'Saint Helena', + countryCallingCode: '290', + continent: 'Africa', + }, + { code: 'SI', label: 'Slovenia', countryCallingCode: '386', continent: 'Europe' }, + { + code: 'SJ', + label: 'Svalbard and Jan Mayen', + countryCallingCode: '47', + continent: 'Europe', + }, + { code: 'SK', label: 'Slovakia', countryCallingCode: '421', continent: 'Europe' }, + { + code: 'SL', + label: 'Sierra Leone', + countryCallingCode: '232', + continent: 'Africa', + }, + { + code: 'SM', + label: 'San Marino', + countryCallingCode: '378', + continent: 'Europe', + }, + { code: 'SN', label: 'Senegal', countryCallingCode: '221', continent: 'Africa' }, + { code: 'SO', label: 'Somalia', countryCallingCode: '252', continent: 'Africa' }, + { + code: 'SR', + label: 'Suriname', + countryCallingCode: '597', + continent: 'South America', + }, + { + code: 'SS', + label: 'South Sudan', + countryCallingCode: '211', + continent: 'Africa', + }, + { + code: 'ST', + label: 'Sao Tome and Principe', + countryCallingCode: '239', + continent: 'Africa', + }, + { + code: 'SV', + label: 'El Salvador', + countryCallingCode: '503', + continent: 'North America', + }, + { + code: 'SX', + label: 'Sint Maarten', + countryCallingCode: '1-721', + continent: 'North America', + }, + { code: 'SY', label: 'Syria', countryCallingCode: '963', continent: 'Asia' }, + { code: 'SZ', label: 'Eswatini', countryCallingCode: '268', continent: 'Africa' }, + { + code: 'TC', + label: 'Turks and Caicos Islands', + countryCallingCode: '1-649', + continent: 'North America', + }, + { code: 'TD', label: 'Chad', countryCallingCode: '235', continent: 'Africa' }, + { + code: 'TF', + label: 'French Southern Territories', + countryCallingCode: '262', + continent: 'Antarctica', + }, + { code: 'TG', label: 'Togo', countryCallingCode: '228', continent: 'Africa' }, + { code: 'TH', label: 'Thailand', countryCallingCode: '66', continent: 'Asia' }, + { code: 'TJ', label: 'Tajikistan', countryCallingCode: '992', continent: 'Asia' }, + { code: 'TK', label: 'Tokelau', countryCallingCode: '690', continent: 'Oceania' }, + { + code: 'TL', + label: 'East Timor', + countryCallingCode: '670', + continent: 'Oceania', + }, + { + code: 'TM', + label: 'Turkmenistan', + countryCallingCode: '993', + continent: 'Asia', + }, + { code: 'TN', label: 'Tunisia', countryCallingCode: '216', continent: 'Africa' }, + { code: 'TO', label: 'Tonga', countryCallingCode: '676', continent: 'Oceania' }, + { code: 'TR', label: 'Türkiye', countryCallingCode: '90', continent: 'Asia' }, + { + code: 'TT', + label: 'Trinidad and Tobago', + countryCallingCode: '1-868', + continent: 'North America', + }, + { code: 'TV', label: 'Tuvalu', countryCallingCode: '688', continent: 'Oceania' }, + { code: 'TW', label: 'Taiwan', countryCallingCode: '886', continent: 'Asia' }, + { code: 'TZ', label: 'Tanzania', countryCallingCode: '255', continent: 'Africa' }, + { code: 'UA', label: 'Ukraine', countryCallingCode: '380', continent: 'Europe' }, + { code: 'UG', label: 'Uganda', countryCallingCode: '256', continent: 'Africa' }, + { + code: 'US', + label: 'United States', + countryCallingCode: '1', + continent: 'North America', + }, + { + code: 'UY', + label: 'Uruguay', + countryCallingCode: '598', + continent: 'South America', + }, + { code: 'UZ', label: 'Uzbekistan', countryCallingCode: '998', continent: 'Asia' }, + { + code: 'VA', + label: 'Vatican City', + countryCallingCode: '379', + continent: 'Europe', + }, + { + code: 'VC', + label: 'Saint Vincent and the Grenadines', + countryCallingCode: '1-784', + continent: 'North America', + }, + { + code: 'VE', + label: 'Venezuela', + countryCallingCode: '58', + continent: 'South America', + }, + { + code: 'VG', + label: 'British Virgin Islands', + countryCallingCode: '1-284', + continent: 'North America', + }, + { + code: 'VI', + label: 'U.S. Virgin Islands', + countryCallingCode: '1-340', + continent: 'North America', + }, + { code: 'VN', label: 'Vietnam', countryCallingCode: '84', continent: 'Asia' }, + { code: 'VU', label: 'Vanuatu', countryCallingCode: '678', continent: 'Oceania' }, + { + code: 'WF', + label: 'Wallis and Futuna', + countryCallingCode: '681', + continent: 'Oceania', + }, + { code: 'WS', label: 'Samoa', countryCallingCode: '685', continent: 'Oceania' }, + { code: 'XK', label: 'Kosovo', countryCallingCode: '383', continent: 'Europe' }, + { code: 'YE', label: 'Yemen', countryCallingCode: '967', continent: 'Asia' }, + { code: 'YT', label: 'Mayotte', countryCallingCode: '262', continent: 'Africa' }, + { + code: 'ZA', + label: 'South Africa', + countryCallingCode: '27', + continent: 'Africa', + }, + { code: 'ZM', label: 'Zambia', countryCallingCode: '260', continent: 'Africa' }, + { code: 'ZW', label: 'Zimbabwe', countryCallingCode: '263', continent: 'Africa' }, +]; + +export default countries; diff --git a/docs/data/material/components/autocomplete/countries.ts b/docs/data/material/components/autocomplete/countries.ts new file mode 100644 index 00000000000000..3491f68a057d0d --- /dev/null +++ b/docs/data/material/components/autocomplete/countries.ts @@ -0,0 +1,346 @@ +type Continent = + | 'Africa' + | 'Antarctica' + | 'Asia' + | 'Europe' + | 'North America' + | 'Oceania' + | 'South America'; + +export interface Country { + code: string; + label: string; + countryCallingCode: string; + continent: Continent; +} + +// Country metadata is adapted from countries-list (MIT): +// https://github.com/annexare/Countries +// Country calling codes are kept in display format for this demo. +const countries: readonly Country[] = [ + { code: 'AD', label: 'Andorra', countryCallingCode: '376', continent: 'Europe' }, + { code: 'AE', label: 'United Arab Emirates', countryCallingCode: '971', continent: 'Asia' }, + { code: 'AF', label: 'Afghanistan', countryCallingCode: '93', continent: 'Asia' }, + { + code: 'AG', + label: 'Antigua and Barbuda', + countryCallingCode: '1-268', + continent: 'North America', + }, + { code: 'AI', label: 'Anguilla', countryCallingCode: '1-264', continent: 'North America' }, + { code: 'AL', label: 'Albania', countryCallingCode: '355', continent: 'Europe' }, + { code: 'AM', label: 'Armenia', countryCallingCode: '374', continent: 'Asia' }, + { code: 'AO', label: 'Angola', countryCallingCode: '244', continent: 'Africa' }, + { code: 'AQ', label: 'Antarctica', countryCallingCode: '672', continent: 'Antarctica' }, + { code: 'AR', label: 'Argentina', countryCallingCode: '54', continent: 'South America' }, + { code: 'AS', label: 'American Samoa', countryCallingCode: '1-684', continent: 'Oceania' }, + { code: 'AT', label: 'Austria', countryCallingCode: '43', continent: 'Europe' }, + { code: 'AU', label: 'Australia', countryCallingCode: '61', continent: 'Oceania' }, + { code: 'AW', label: 'Aruba', countryCallingCode: '297', continent: 'North America' }, + { code: 'AX', label: 'Aland', countryCallingCode: '358', continent: 'Europe' }, + { code: 'AZ', label: 'Azerbaijan', countryCallingCode: '994', continent: 'Asia' }, + { code: 'BA', label: 'Bosnia and Herzegovina', countryCallingCode: '387', continent: 'Europe' }, + { code: 'BB', label: 'Barbados', countryCallingCode: '1-246', continent: 'North America' }, + { code: 'BD', label: 'Bangladesh', countryCallingCode: '880', continent: 'Asia' }, + { code: 'BE', label: 'Belgium', countryCallingCode: '32', continent: 'Europe' }, + { code: 'BF', label: 'Burkina Faso', countryCallingCode: '226', continent: 'Africa' }, + { code: 'BG', label: 'Bulgaria', countryCallingCode: '359', continent: 'Europe' }, + { code: 'BH', label: 'Bahrain', countryCallingCode: '973', continent: 'Asia' }, + { code: 'BI', label: 'Burundi', countryCallingCode: '257', continent: 'Africa' }, + { code: 'BJ', label: 'Benin', countryCallingCode: '229', continent: 'Africa' }, + { code: 'BL', label: 'Saint Barthelemy', countryCallingCode: '590', continent: 'North America' }, + { code: 'BM', label: 'Bermuda', countryCallingCode: '1-441', continent: 'North America' }, + { code: 'BN', label: 'Brunei', countryCallingCode: '673', continent: 'Asia' }, + { code: 'BO', label: 'Bolivia', countryCallingCode: '591', continent: 'South America' }, + { code: 'BR', label: 'Brazil', countryCallingCode: '55', continent: 'South America' }, + { code: 'BS', label: 'Bahamas', countryCallingCode: '1-242', continent: 'North America' }, + { code: 'BT', label: 'Bhutan', countryCallingCode: '975', continent: 'Asia' }, + { code: 'BV', label: 'Bouvet Island', countryCallingCode: '47', continent: 'Antarctica' }, + { code: 'BW', label: 'Botswana', countryCallingCode: '267', continent: 'Africa' }, + { code: 'BY', label: 'Belarus', countryCallingCode: '375', continent: 'Europe' }, + { code: 'BZ', label: 'Belize', countryCallingCode: '501', continent: 'North America' }, + { code: 'CA', label: 'Canada', countryCallingCode: '1', continent: 'North America' }, + { code: 'CC', label: 'Cocos (Keeling) Islands', countryCallingCode: '61', continent: 'Asia' }, + { + code: 'CD', + label: 'Democratic Republic of the Congo', + countryCallingCode: '243', + continent: 'Africa', + }, + { code: 'CF', label: 'Central African Republic', countryCallingCode: '236', continent: 'Africa' }, + { code: 'CG', label: 'Republic of the Congo', countryCallingCode: '242', continent: 'Africa' }, + { code: 'CH', label: 'Switzerland', countryCallingCode: '41', continent: 'Europe' }, + { code: 'CI', label: 'Ivory Coast', countryCallingCode: '225', continent: 'Africa' }, + { code: 'CK', label: 'Cook Islands', countryCallingCode: '682', continent: 'Oceania' }, + { code: 'CL', label: 'Chile', countryCallingCode: '56', continent: 'South America' }, + { code: 'CM', label: 'Cameroon', countryCallingCode: '237', continent: 'Africa' }, + { code: 'CN', label: 'China', countryCallingCode: '86', continent: 'Asia' }, + { code: 'CO', label: 'Colombia', countryCallingCode: '57', continent: 'South America' }, + { code: 'CR', label: 'Costa Rica', countryCallingCode: '506', continent: 'North America' }, + { code: 'CU', label: 'Cuba', countryCallingCode: '53', continent: 'North America' }, + { code: 'CV', label: 'Cape Verde', countryCallingCode: '238', continent: 'Africa' }, + { code: 'CW', label: 'Curacao', countryCallingCode: '599', continent: 'North America' }, + { code: 'CX', label: 'Christmas Island', countryCallingCode: '61', continent: 'Asia' }, + { code: 'CY', label: 'Cyprus', countryCallingCode: '357', continent: 'Europe' }, + { code: 'CZ', label: 'Czech Republic', countryCallingCode: '420', continent: 'Europe' }, + { code: 'DE', label: 'Germany', countryCallingCode: '49', continent: 'Europe' }, + { code: 'DJ', label: 'Djibouti', countryCallingCode: '253', continent: 'Africa' }, + { code: 'DK', label: 'Denmark', countryCallingCode: '45', continent: 'Europe' }, + { code: 'DM', label: 'Dominica', countryCallingCode: '1-767', continent: 'North America' }, + { + code: 'DO', + label: 'Dominican Republic', + countryCallingCode: '1-809', + continent: 'North America', + }, + { code: 'DZ', label: 'Algeria', countryCallingCode: '213', continent: 'Africa' }, + { code: 'EC', label: 'Ecuador', countryCallingCode: '593', continent: 'South America' }, + { code: 'EE', label: 'Estonia', countryCallingCode: '372', continent: 'Europe' }, + { code: 'EG', label: 'Egypt', countryCallingCode: '20', continent: 'Africa' }, + { code: 'EH', label: 'Western Sahara', countryCallingCode: '212', continent: 'Africa' }, + { code: 'ER', label: 'Eritrea', countryCallingCode: '291', continent: 'Africa' }, + { code: 'ES', label: 'Spain', countryCallingCode: '34', continent: 'Europe' }, + { code: 'ET', label: 'Ethiopia', countryCallingCode: '251', continent: 'Africa' }, + { code: 'FI', label: 'Finland', countryCallingCode: '358', continent: 'Europe' }, + { code: 'FJ', label: 'Fiji', countryCallingCode: '679', continent: 'Oceania' }, + { code: 'FK', label: 'Falkland Islands', countryCallingCode: '500', continent: 'South America' }, + { code: 'FM', label: 'Micronesia', countryCallingCode: '691', continent: 'Oceania' }, + { code: 'FO', label: 'Faroe Islands', countryCallingCode: '298', continent: 'Europe' }, + { code: 'FR', label: 'France', countryCallingCode: '33', continent: 'Europe' }, + { code: 'GA', label: 'Gabon', countryCallingCode: '241', continent: 'Africa' }, + { code: 'GB', label: 'United Kingdom', countryCallingCode: '44', continent: 'Europe' }, + { code: 'GD', label: 'Grenada', countryCallingCode: '1-473', continent: 'North America' }, + { code: 'GE', label: 'Georgia', countryCallingCode: '995', continent: 'Asia' }, + { code: 'GF', label: 'French Guiana', countryCallingCode: '594', continent: 'South America' }, + { code: 'GG', label: 'Guernsey', countryCallingCode: '44', continent: 'Europe' }, + { code: 'GH', label: 'Ghana', countryCallingCode: '233', continent: 'Africa' }, + { code: 'GI', label: 'Gibraltar', countryCallingCode: '350', continent: 'Europe' }, + { code: 'GL', label: 'Greenland', countryCallingCode: '299', continent: 'North America' }, + { code: 'GM', label: 'Gambia', countryCallingCode: '220', continent: 'Africa' }, + { code: 'GN', label: 'Guinea', countryCallingCode: '224', continent: 'Africa' }, + { code: 'GP', label: 'Guadeloupe', countryCallingCode: '590', continent: 'North America' }, + { code: 'GQ', label: 'Equatorial Guinea', countryCallingCode: '240', continent: 'Africa' }, + { code: 'GR', label: 'Greece', countryCallingCode: '30', continent: 'Europe' }, + { + code: 'GS', + label: 'South Georgia and the South Sandwich Islands', + countryCallingCode: '500', + continent: 'Antarctica', + }, + { code: 'GT', label: 'Guatemala', countryCallingCode: '502', continent: 'North America' }, + { code: 'GU', label: 'Guam', countryCallingCode: '1-671', continent: 'Oceania' }, + { code: 'GW', label: 'Guinea-Bissau', countryCallingCode: '245', continent: 'Africa' }, + { code: 'GY', label: 'Guyana', countryCallingCode: '592', continent: 'South America' }, + { code: 'HK', label: 'Hong Kong', countryCallingCode: '852', continent: 'Asia' }, + { + code: 'HM', + label: 'Heard Island and McDonald Islands', + countryCallingCode: '672', + continent: 'Antarctica', + }, + { code: 'HN', label: 'Honduras', countryCallingCode: '504', continent: 'North America' }, + { code: 'HR', label: 'Croatia', countryCallingCode: '385', continent: 'Europe' }, + { code: 'HT', label: 'Haiti', countryCallingCode: '509', continent: 'North America' }, + { code: 'HU', label: 'Hungary', countryCallingCode: '36', continent: 'Europe' }, + { code: 'ID', label: 'Indonesia', countryCallingCode: '62', continent: 'Asia' }, + { code: 'IE', label: 'Ireland', countryCallingCode: '353', continent: 'Europe' }, + { code: 'IL', label: 'Israel', countryCallingCode: '972', continent: 'Asia' }, + { code: 'IM', label: 'Isle of Man', countryCallingCode: '44', continent: 'Europe' }, + { code: 'IN', label: 'India', countryCallingCode: '91', continent: 'Asia' }, + { + code: 'IO', + label: 'British Indian Ocean Territory', + countryCallingCode: '246', + continent: 'Asia', + }, + { code: 'IQ', label: 'Iraq', countryCallingCode: '964', continent: 'Asia' }, + { code: 'IR', label: 'Iran', countryCallingCode: '98', continent: 'Asia' }, + { code: 'IS', label: 'Iceland', countryCallingCode: '354', continent: 'Europe' }, + { code: 'IT', label: 'Italy', countryCallingCode: '39', continent: 'Europe' }, + { code: 'JE', label: 'Jersey', countryCallingCode: '44', continent: 'Europe' }, + { code: 'JM', label: 'Jamaica', countryCallingCode: '1-876', continent: 'North America' }, + { code: 'JO', label: 'Jordan', countryCallingCode: '962', continent: 'Asia' }, + { code: 'JP', label: 'Japan', countryCallingCode: '81', continent: 'Asia' }, + { code: 'KE', label: 'Kenya', countryCallingCode: '254', continent: 'Africa' }, + { code: 'KG', label: 'Kyrgyzstan', countryCallingCode: '996', continent: 'Asia' }, + { code: 'KH', label: 'Cambodia', countryCallingCode: '855', continent: 'Asia' }, + { code: 'KI', label: 'Kiribati', countryCallingCode: '686', continent: 'Oceania' }, + { code: 'KM', label: 'Comoros', countryCallingCode: '269', continent: 'Africa' }, + { + code: 'KN', + label: 'Saint Kitts and Nevis', + countryCallingCode: '1-869', + continent: 'North America', + }, + { code: 'KP', label: 'North Korea', countryCallingCode: '850', continent: 'Asia' }, + { code: 'KR', label: 'South Korea', countryCallingCode: '82', continent: 'Asia' }, + { code: 'KW', label: 'Kuwait', countryCallingCode: '965', continent: 'Asia' }, + { code: 'KY', label: 'Cayman Islands', countryCallingCode: '1-345', continent: 'North America' }, + { code: 'KZ', label: 'Kazakhstan', countryCallingCode: '7', continent: 'Asia' }, + { code: 'LA', label: 'Laos', countryCallingCode: '856', continent: 'Asia' }, + { code: 'LB', label: 'Lebanon', countryCallingCode: '961', continent: 'Asia' }, + { code: 'LC', label: 'Saint Lucia', countryCallingCode: '1-758', continent: 'North America' }, + { code: 'LI', label: 'Liechtenstein', countryCallingCode: '423', continent: 'Europe' }, + { code: 'LK', label: 'Sri Lanka', countryCallingCode: '94', continent: 'Asia' }, + { code: 'LR', label: 'Liberia', countryCallingCode: '231', continent: 'Africa' }, + { code: 'LS', label: 'Lesotho', countryCallingCode: '266', continent: 'Africa' }, + { code: 'LT', label: 'Lithuania', countryCallingCode: '370', continent: 'Europe' }, + { code: 'LU', label: 'Luxembourg', countryCallingCode: '352', continent: 'Europe' }, + { code: 'LV', label: 'Latvia', countryCallingCode: '371', continent: 'Europe' }, + { code: 'LY', label: 'Libya', countryCallingCode: '218', continent: 'Africa' }, + { code: 'MA', label: 'Morocco', countryCallingCode: '212', continent: 'Africa' }, + { code: 'MC', label: 'Monaco', countryCallingCode: '377', continent: 'Europe' }, + { code: 'MD', label: 'Moldova', countryCallingCode: '373', continent: 'Europe' }, + { code: 'ME', label: 'Montenegro', countryCallingCode: '382', continent: 'Europe' }, + { code: 'MF', label: 'Saint Martin', countryCallingCode: '590', continent: 'North America' }, + { code: 'MG', label: 'Madagascar', countryCallingCode: '261', continent: 'Africa' }, + { code: 'MH', label: 'Marshall Islands', countryCallingCode: '692', continent: 'Oceania' }, + { code: 'MK', label: 'North Macedonia', countryCallingCode: '389', continent: 'Europe' }, + { code: 'ML', label: 'Mali', countryCallingCode: '223', continent: 'Africa' }, + { code: 'MM', label: 'Myanmar (Burma)', countryCallingCode: '95', continent: 'Asia' }, + { code: 'MN', label: 'Mongolia', countryCallingCode: '976', continent: 'Asia' }, + { code: 'MO', label: 'Macao', countryCallingCode: '853', continent: 'Asia' }, + { + code: 'MP', + label: 'Northern Mariana Islands', + countryCallingCode: '1-670', + continent: 'Oceania', + }, + { code: 'MQ', label: 'Martinique', countryCallingCode: '596', continent: 'North America' }, + { code: 'MR', label: 'Mauritania', countryCallingCode: '222', continent: 'Africa' }, + { code: 'MS', label: 'Montserrat', countryCallingCode: '1-664', continent: 'North America' }, + { code: 'MT', label: 'Malta', countryCallingCode: '356', continent: 'Europe' }, + { code: 'MU', label: 'Mauritius', countryCallingCode: '230', continent: 'Africa' }, + { code: 'MV', label: 'Maldives', countryCallingCode: '960', continent: 'Asia' }, + { code: 'MW', label: 'Malawi', countryCallingCode: '265', continent: 'Africa' }, + { code: 'MX', label: 'Mexico', countryCallingCode: '52', continent: 'North America' }, + { code: 'MY', label: 'Malaysia', countryCallingCode: '60', continent: 'Asia' }, + { code: 'MZ', label: 'Mozambique', countryCallingCode: '258', continent: 'Africa' }, + { code: 'NA', label: 'Namibia', countryCallingCode: '264', continent: 'Africa' }, + { code: 'NC', label: 'New Caledonia', countryCallingCode: '687', continent: 'Oceania' }, + { code: 'NE', label: 'Niger', countryCallingCode: '227', continent: 'Africa' }, + { code: 'NF', label: 'Norfolk Island', countryCallingCode: '672', continent: 'Oceania' }, + { code: 'NG', label: 'Nigeria', countryCallingCode: '234', continent: 'Africa' }, + { code: 'NI', label: 'Nicaragua', countryCallingCode: '505', continent: 'North America' }, + { code: 'NL', label: 'Netherlands', countryCallingCode: '31', continent: 'Europe' }, + { code: 'NO', label: 'Norway', countryCallingCode: '47', continent: 'Europe' }, + { code: 'NP', label: 'Nepal', countryCallingCode: '977', continent: 'Asia' }, + { code: 'NR', label: 'Nauru', countryCallingCode: '674', continent: 'Oceania' }, + { code: 'NU', label: 'Niue', countryCallingCode: '683', continent: 'Oceania' }, + { code: 'NZ', label: 'New Zealand', countryCallingCode: '64', continent: 'Oceania' }, + { code: 'OM', label: 'Oman', countryCallingCode: '968', continent: 'Asia' }, + { code: 'PA', label: 'Panama', countryCallingCode: '507', continent: 'North America' }, + { code: 'PE', label: 'Peru', countryCallingCode: '51', continent: 'South America' }, + { code: 'PF', label: 'French Polynesia', countryCallingCode: '689', continent: 'Oceania' }, + { code: 'PG', label: 'Papua New Guinea', countryCallingCode: '675', continent: 'Oceania' }, + { code: 'PH', label: 'Philippines', countryCallingCode: '63', continent: 'Asia' }, + { code: 'PK', label: 'Pakistan', countryCallingCode: '92', continent: 'Asia' }, + { code: 'PL', label: 'Poland', countryCallingCode: '48', continent: 'Europe' }, + { + code: 'PM', + label: 'Saint Pierre and Miquelon', + countryCallingCode: '508', + continent: 'North America', + }, + { code: 'PN', label: 'Pitcairn Islands', countryCallingCode: '870', continent: 'Oceania' }, + { code: 'PR', label: 'Puerto Rico', countryCallingCode: '1', continent: 'North America' }, + { code: 'PS', label: 'Palestine', countryCallingCode: '970', continent: 'Asia' }, + { code: 'PT', label: 'Portugal', countryCallingCode: '351', continent: 'Europe' }, + { code: 'PW', label: 'Palau', countryCallingCode: '680', continent: 'Oceania' }, + { code: 'PY', label: 'Paraguay', countryCallingCode: '595', continent: 'South America' }, + { code: 'QA', label: 'Qatar', countryCallingCode: '974', continent: 'Asia' }, + { code: 'RE', label: 'Reunion', countryCallingCode: '262', continent: 'Africa' }, + { code: 'RO', label: 'Romania', countryCallingCode: '40', continent: 'Europe' }, + { code: 'RS', label: 'Serbia', countryCallingCode: '381', continent: 'Europe' }, + { code: 'RU', label: 'Russia', countryCallingCode: '7', continent: 'Asia' }, + { code: 'RW', label: 'Rwanda', countryCallingCode: '250', continent: 'Africa' }, + { code: 'SA', label: 'Saudi Arabia', countryCallingCode: '966', continent: 'Asia' }, + { code: 'SB', label: 'Solomon Islands', countryCallingCode: '677', continent: 'Oceania' }, + { code: 'SC', label: 'Seychelles', countryCallingCode: '248', continent: 'Africa' }, + { code: 'SD', label: 'Sudan', countryCallingCode: '249', continent: 'Africa' }, + { code: 'SE', label: 'Sweden', countryCallingCode: '46', continent: 'Europe' }, + { code: 'SG', label: 'Singapore', countryCallingCode: '65', continent: 'Asia' }, + { code: 'SH', label: 'Saint Helena', countryCallingCode: '290', continent: 'Africa' }, + { code: 'SI', label: 'Slovenia', countryCallingCode: '386', continent: 'Europe' }, + { code: 'SJ', label: 'Svalbard and Jan Mayen', countryCallingCode: '47', continent: 'Europe' }, + { code: 'SK', label: 'Slovakia', countryCallingCode: '421', continent: 'Europe' }, + { code: 'SL', label: 'Sierra Leone', countryCallingCode: '232', continent: 'Africa' }, + { code: 'SM', label: 'San Marino', countryCallingCode: '378', continent: 'Europe' }, + { code: 'SN', label: 'Senegal', countryCallingCode: '221', continent: 'Africa' }, + { code: 'SO', label: 'Somalia', countryCallingCode: '252', continent: 'Africa' }, + { code: 'SR', label: 'Suriname', countryCallingCode: '597', continent: 'South America' }, + { code: 'SS', label: 'South Sudan', countryCallingCode: '211', continent: 'Africa' }, + { code: 'ST', label: 'Sao Tome and Principe', countryCallingCode: '239', continent: 'Africa' }, + { code: 'SV', label: 'El Salvador', countryCallingCode: '503', continent: 'North America' }, + { code: 'SX', label: 'Sint Maarten', countryCallingCode: '1-721', continent: 'North America' }, + { code: 'SY', label: 'Syria', countryCallingCode: '963', continent: 'Asia' }, + { code: 'SZ', label: 'Eswatini', countryCallingCode: '268', continent: 'Africa' }, + { + code: 'TC', + label: 'Turks and Caicos Islands', + countryCallingCode: '1-649', + continent: 'North America', + }, + { code: 'TD', label: 'Chad', countryCallingCode: '235', continent: 'Africa' }, + { + code: 'TF', + label: 'French Southern Territories', + countryCallingCode: '262', + continent: 'Antarctica', + }, + { code: 'TG', label: 'Togo', countryCallingCode: '228', continent: 'Africa' }, + { code: 'TH', label: 'Thailand', countryCallingCode: '66', continent: 'Asia' }, + { code: 'TJ', label: 'Tajikistan', countryCallingCode: '992', continent: 'Asia' }, + { code: 'TK', label: 'Tokelau', countryCallingCode: '690', continent: 'Oceania' }, + { code: 'TL', label: 'East Timor', countryCallingCode: '670', continent: 'Oceania' }, + { code: 'TM', label: 'Turkmenistan', countryCallingCode: '993', continent: 'Asia' }, + { code: 'TN', label: 'Tunisia', countryCallingCode: '216', continent: 'Africa' }, + { code: 'TO', label: 'Tonga', countryCallingCode: '676', continent: 'Oceania' }, + { code: 'TR', label: 'Türkiye', countryCallingCode: '90', continent: 'Asia' }, + { + code: 'TT', + label: 'Trinidad and Tobago', + countryCallingCode: '1-868', + continent: 'North America', + }, + { code: 'TV', label: 'Tuvalu', countryCallingCode: '688', continent: 'Oceania' }, + { code: 'TW', label: 'Taiwan', countryCallingCode: '886', continent: 'Asia' }, + { code: 'TZ', label: 'Tanzania', countryCallingCode: '255', continent: 'Africa' }, + { code: 'UA', label: 'Ukraine', countryCallingCode: '380', continent: 'Europe' }, + { code: 'UG', label: 'Uganda', countryCallingCode: '256', continent: 'Africa' }, + { code: 'US', label: 'United States', countryCallingCode: '1', continent: 'North America' }, + { code: 'UY', label: 'Uruguay', countryCallingCode: '598', continent: 'South America' }, + { code: 'UZ', label: 'Uzbekistan', countryCallingCode: '998', continent: 'Asia' }, + { code: 'VA', label: 'Vatican City', countryCallingCode: '379', continent: 'Europe' }, + { + code: 'VC', + label: 'Saint Vincent and the Grenadines', + countryCallingCode: '1-784', + continent: 'North America', + }, + { code: 'VE', label: 'Venezuela', countryCallingCode: '58', continent: 'South America' }, + { + code: 'VG', + label: 'British Virgin Islands', + countryCallingCode: '1-284', + continent: 'North America', + }, + { + code: 'VI', + label: 'U.S. Virgin Islands', + countryCallingCode: '1-340', + continent: 'North America', + }, + { code: 'VN', label: 'Vietnam', countryCallingCode: '84', continent: 'Asia' }, + { code: 'VU', label: 'Vanuatu', countryCallingCode: '678', continent: 'Oceania' }, + { code: 'WF', label: 'Wallis and Futuna', countryCallingCode: '681', continent: 'Oceania' }, + { code: 'WS', label: 'Samoa', countryCallingCode: '685', continent: 'Oceania' }, + { code: 'XK', label: 'Kosovo', countryCallingCode: '383', continent: 'Europe' }, + { code: 'YE', label: 'Yemen', countryCallingCode: '967', continent: 'Asia' }, + { code: 'YT', label: 'Mayotte', countryCallingCode: '262', continent: 'Africa' }, + { code: 'ZA', label: 'South Africa', countryCallingCode: '27', continent: 'Africa' }, + { code: 'ZM', label: 'Zambia', countryCallingCode: '260', continent: 'Africa' }, + { code: 'ZW', label: 'Zimbabwe', countryCallingCode: '263', continent: 'Africa' }, +]; + +export default countries; diff --git a/docs/data/material/components/autocomplete/top100Films.js b/docs/data/material/components/autocomplete/top100Films.js index 3226dcbc8ba7f3..f9dfdcf5513e58 100644 --- a/docs/data/material/components/autocomplete/top100Films.js +++ b/docs/data/material/components/autocomplete/top100Films.js @@ -2,128 +2,128 @@ const top100Films = [ { label: 'The Shawshank Redemption', year: 1994 }, { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, { label: 'The Dark Knight', year: 2008 }, + { label: 'The Godfather Part II', year: 1974 }, { label: '12 Angry Men', year: 1957 }, - { label: "Schindler's List", year: 1993 }, - { label: 'Pulp Fiction', year: 1994 }, { label: 'The Lord of the Rings: The Return of the King', year: 2003, }, - { label: 'The Good, the Bad and the Ugly', year: 1966 }, - { label: 'Fight Club', year: 1999 }, + { label: "Schindler's List", year: 1993 }, { label: 'The Lord of the Rings: The Fellowship of the Ring', year: 2001, }, + { label: 'Pulp Fiction', year: 1994 }, + { label: 'The Good, the Bad and the Ugly', year: 1966 }, { - label: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, + label: 'The Lord of the Rings: The Two Towers', + year: 2002, }, { label: 'Forrest Gump', year: 1994 }, + { label: 'Fight Club', year: 1999 }, { label: 'Inception', year: 2010 }, { - label: 'The Lord of the Rings: The Two Towers', - year: 2002, + label: 'Star Wars: Episode V - The Empire Strikes Back', + year: 1980, }, - { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { label: 'Goodfellas', year: 1990 }, { label: 'The Matrix', year: 1999 }, + { label: 'GoodFellas', year: 1990 }, + { label: 'Interstellar', year: 2014 }, + { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, + { label: 'Seven', year: 1995 }, + { label: "It's a Wonderful Life", year: 1946 }, + { label: 'The Silence of the Lambs', year: 1991 }, { label: 'Seven Samurai', year: 1954 }, + { label: 'Saving Private Ryan', year: 1998 }, + { label: 'The Green Mile', year: 1999 }, + { label: 'City of God', year: 2002 }, + { label: 'Life Is Beautiful', year: 1997 }, + { label: 'Terminator 2: Judgment Day', year: 1991 }, + { label: 'Back to the Future', year: 1985 }, { label: 'Star Wars: Episode IV - A New Hope', year: 1977, }, - { label: 'City of God', year: 2002 }, - { label: 'Se7en', year: 1995 }, - { label: 'The Silence of the Lambs', year: 1991 }, - { label: "It's a Wonderful Life", year: 1946 }, - { label: 'Life Is Beautiful', year: 1997 }, - { label: 'The Usual Suspects', year: 1995 }, - { label: 'Léon: The Professional', year: 1994 }, { label: 'Spirited Away', year: 2001 }, - { label: 'Saving Private Ryan', year: 1998 }, - { label: 'Once Upon a Time in the West', year: 1968 }, - { label: 'American History X', year: 1998 }, - { label: 'Interstellar', year: 2014 }, - { label: 'Casablanca', year: 1942 }, - { label: 'City Lights', year: 1931 }, - { label: 'Psycho', year: 1960 }, - { label: 'The Green Mile', year: 1999 }, - { label: 'The Intouchables', year: 2011 }, - { label: 'Modern Times', year: 1936 }, - { label: 'Raiders of the Lost Ark', year: 1981 }, - { label: 'Rear Window', year: 1954 }, { label: 'The Pianist', year: 2002 }, + { label: 'Gladiator', year: 2000 }, + { label: 'Parasite', year: 2019 }, + { label: 'Kill Bill: The Whole Bloody Affair', year: 2004 }, + { label: 'Grave of the Fireflies', year: 1988 }, + { label: 'Psycho', year: 1960 }, + { label: 'The Lion King', year: 1994 }, + { label: 'Harakiri', year: 1962 }, { label: 'The Departed', year: 2006 }, - { label: 'Terminator 2: Judgment Day', year: 1991 }, - { label: 'Back to the Future', year: 1985 }, { label: 'Whiplash', year: 2014 }, - { label: 'Gladiator', year: 2000 }, - { label: 'Memento', year: 2000 }, { label: 'The Prestige', year: 2006 }, - { label: 'The Lion King', year: 1994 }, - { label: 'Apocalypse Now', year: 1979 }, + { label: 'American History X', year: 1998 }, + { label: 'Léon: The Professional', year: 1994 }, + { label: 'Spider-Man: Across the Spider-Verse', year: 2023 }, + { label: 'Cinema Paradiso', year: 1988 }, + { label: 'Casablanca', year: 1942 }, + { label: 'The Intouchables', year: 2011 }, + { label: 'The Usual Suspects', year: 1995 }, + { label: 'Django Unchained', year: 2012 }, { label: 'Alien', year: 1979 }, + { label: 'Rear Window', year: 1954 }, + { label: 'Modern Times', year: 1936 }, + { label: 'Once Upon a Time in the West', year: 1968 }, + { label: 'City Lights', year: 1931 }, + { label: 'Apocalypse Now', year: 1979 }, + { label: 'WALL·E', year: 2008 }, + { label: 'Memento', year: 2000 }, + { label: 'Dune: Part Two', year: 2024 }, + { label: 'Avengers: Infinity War', year: 2018 }, + { label: 'Raiders of the Lost Ark', year: 1981 }, + { label: 'The Lives of Others', year: 2006 }, + { label: 'Spider-Man: Into the Spider-Verse', year: 2018 }, { label: 'Sunset Boulevard', year: 1950 }, + { label: 'Witness for the Prosecution', year: 1957 }, + { label: 'Paths of Glory', year: 1957 }, + { label: 'The Shining', year: 1980 }, + { label: 'The Great Dictator', year: 1940 }, + { label: 'Inglourious Basterds', year: 2009 }, + { label: '12th Fail', year: 2023 }, + { label: 'Aliens', year: 1986 }, + { label: 'High and Low', year: 1963 }, + { label: 'Avengers: Endgame', year: 2019 }, + { label: 'Good Will Hunting', year: 1997 }, + { label: 'The Dark Knight Rises', year: 2012 }, + { label: 'Coco', year: 2017 }, + { label: 'Amadeus', year: 1984 }, + { label: 'Toy Story', year: 1995 }, + { label: 'Your Name.', year: 2016 }, + { label: 'Das Boot', year: 1981 }, + { label: 'Braveheart', year: 1995 }, + { label: 'Oldboy', year: 2003 }, + { label: 'Princess Mononoke', year: 1997 }, { label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', year: 1964, }, - { label: 'The Great Dictator', year: 1940 }, - { label: 'Cinema Paradiso', year: 1988 }, - { label: 'The Lives of Others', year: 2006 }, - { label: 'Grave of the Fireflies', year: 1988 }, - { label: 'Paths of Glory', year: 1957 }, - { label: 'Django Unchained', year: 2012 }, - { label: 'The Shining', year: 1980 }, - { label: 'WALL·E', year: 2008 }, + { label: '3 Idiots', year: 2009 }, { label: 'American Beauty', year: 1999 }, - { label: 'The Dark Knight Rises', year: 2012 }, - { label: 'Princess Mononoke', year: 1997 }, - { label: 'Aliens', year: 1986 }, - { label: 'Oldboy', year: 2003 }, + { label: 'Capernaum', year: 2018 }, + { label: "Singin' in the Rain", year: 1952 }, + { label: 'Joker', year: 2019 }, { label: 'Once Upon a Time in America', year: 1984 }, - { label: 'Witness for the Prosecution', year: 1957 }, - { label: 'Das Boot', year: 1981 }, - { label: 'Citizen Kane', year: 1941 }, - { label: 'North by Northwest', year: 1959 }, - { label: 'Vertigo', year: 1958 }, { label: 'Star Wars: Episode VI - Return of the Jedi', year: 1983, }, - { label: 'Reservoir Dogs', year: 1992 }, - { label: 'Braveheart', year: 1995 }, - { label: 'M', year: 1931 }, + { label: 'Come and See', year: 1985 }, { label: 'Requiem for a Dream', year: 2000 }, - { label: 'Amélie', year: 2001 }, - { label: 'A Clockwork Orange', year: 1971 }, - { label: 'Like Stars on Earth', year: 2007 }, - { label: 'Taxi Driver', year: 1976 }, - { label: 'Lawrence of Arabia', year: 1962 }, - { label: 'Double Indemnity', year: 1944 }, + { label: 'Toy Story 3', year: 2010 }, + { label: 'Project Hail Mary', year: 2026 }, + { label: 'Ikiru', year: 1952 }, + { label: 'The Hunt', year: 2012 }, + { label: 'Incendies', year: 2010 }, { label: 'Eternal Sunshine of the Spotless Mind', year: 2004, }, - { label: 'Amadeus', year: 1984 }, - { label: 'To Kill a Mockingbird', year: 1962 }, - { label: 'Toy Story 3', year: 2010 }, - { label: 'Logan', year: 2017 }, - { label: 'Full Metal Jacket', year: 1987 }, - { label: 'Dangal', year: 2016 }, - { label: 'The Sting', year: 1973 }, - { label: '2001: A Space Odyssey', year: 1968 }, - { label: "Singin' in the Rain", year: 1952 }, - { label: 'Toy Story', year: 1995 }, - { label: 'Bicycle Thieves', year: 1948 }, - { label: 'The Kid', year: 1921 }, - { label: 'Inglourious Basterds', year: 2009 }, - { label: 'Snatch', year: 2000 }, - { label: '3 Idiots', year: 2009 }, - { label: 'Monty Python and the Holy Grail', year: 1975 }, + { label: 'The Apartment', year: 1960 }, ]; export default top100Films; diff --git a/docs/data/material/components/autocomplete/top100Films.ts b/docs/data/material/components/autocomplete/top100Films.ts index 3226dcbc8ba7f3..f9dfdcf5513e58 100644 --- a/docs/data/material/components/autocomplete/top100Films.ts +++ b/docs/data/material/components/autocomplete/top100Films.ts @@ -2,128 +2,128 @@ const top100Films = [ { label: 'The Shawshank Redemption', year: 1994 }, { label: 'The Godfather', year: 1972 }, - { label: 'The Godfather: Part II', year: 1974 }, { label: 'The Dark Knight', year: 2008 }, + { label: 'The Godfather Part II', year: 1974 }, { label: '12 Angry Men', year: 1957 }, - { label: "Schindler's List", year: 1993 }, - { label: 'Pulp Fiction', year: 1994 }, { label: 'The Lord of the Rings: The Return of the King', year: 2003, }, - { label: 'The Good, the Bad and the Ugly', year: 1966 }, - { label: 'Fight Club', year: 1999 }, + { label: "Schindler's List", year: 1993 }, { label: 'The Lord of the Rings: The Fellowship of the Ring', year: 2001, }, + { label: 'Pulp Fiction', year: 1994 }, + { label: 'The Good, the Bad and the Ugly', year: 1966 }, { - label: 'Star Wars: Episode V - The Empire Strikes Back', - year: 1980, + label: 'The Lord of the Rings: The Two Towers', + year: 2002, }, { label: 'Forrest Gump', year: 1994 }, + { label: 'Fight Club', year: 1999 }, { label: 'Inception', year: 2010 }, { - label: 'The Lord of the Rings: The Two Towers', - year: 2002, + label: 'Star Wars: Episode V - The Empire Strikes Back', + year: 1980, }, - { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, - { label: 'Goodfellas', year: 1990 }, { label: 'The Matrix', year: 1999 }, + { label: 'GoodFellas', year: 1990 }, + { label: 'Interstellar', year: 2014 }, + { label: "One Flew Over the Cuckoo's Nest", year: 1975 }, + { label: 'Seven', year: 1995 }, + { label: "It's a Wonderful Life", year: 1946 }, + { label: 'The Silence of the Lambs', year: 1991 }, { label: 'Seven Samurai', year: 1954 }, + { label: 'Saving Private Ryan', year: 1998 }, + { label: 'The Green Mile', year: 1999 }, + { label: 'City of God', year: 2002 }, + { label: 'Life Is Beautiful', year: 1997 }, + { label: 'Terminator 2: Judgment Day', year: 1991 }, + { label: 'Back to the Future', year: 1985 }, { label: 'Star Wars: Episode IV - A New Hope', year: 1977, }, - { label: 'City of God', year: 2002 }, - { label: 'Se7en', year: 1995 }, - { label: 'The Silence of the Lambs', year: 1991 }, - { label: "It's a Wonderful Life", year: 1946 }, - { label: 'Life Is Beautiful', year: 1997 }, - { label: 'The Usual Suspects', year: 1995 }, - { label: 'Léon: The Professional', year: 1994 }, { label: 'Spirited Away', year: 2001 }, - { label: 'Saving Private Ryan', year: 1998 }, - { label: 'Once Upon a Time in the West', year: 1968 }, - { label: 'American History X', year: 1998 }, - { label: 'Interstellar', year: 2014 }, - { label: 'Casablanca', year: 1942 }, - { label: 'City Lights', year: 1931 }, - { label: 'Psycho', year: 1960 }, - { label: 'The Green Mile', year: 1999 }, - { label: 'The Intouchables', year: 2011 }, - { label: 'Modern Times', year: 1936 }, - { label: 'Raiders of the Lost Ark', year: 1981 }, - { label: 'Rear Window', year: 1954 }, { label: 'The Pianist', year: 2002 }, + { label: 'Gladiator', year: 2000 }, + { label: 'Parasite', year: 2019 }, + { label: 'Kill Bill: The Whole Bloody Affair', year: 2004 }, + { label: 'Grave of the Fireflies', year: 1988 }, + { label: 'Psycho', year: 1960 }, + { label: 'The Lion King', year: 1994 }, + { label: 'Harakiri', year: 1962 }, { label: 'The Departed', year: 2006 }, - { label: 'Terminator 2: Judgment Day', year: 1991 }, - { label: 'Back to the Future', year: 1985 }, { label: 'Whiplash', year: 2014 }, - { label: 'Gladiator', year: 2000 }, - { label: 'Memento', year: 2000 }, { label: 'The Prestige', year: 2006 }, - { label: 'The Lion King', year: 1994 }, - { label: 'Apocalypse Now', year: 1979 }, + { label: 'American History X', year: 1998 }, + { label: 'Léon: The Professional', year: 1994 }, + { label: 'Spider-Man: Across the Spider-Verse', year: 2023 }, + { label: 'Cinema Paradiso', year: 1988 }, + { label: 'Casablanca', year: 1942 }, + { label: 'The Intouchables', year: 2011 }, + { label: 'The Usual Suspects', year: 1995 }, + { label: 'Django Unchained', year: 2012 }, { label: 'Alien', year: 1979 }, + { label: 'Rear Window', year: 1954 }, + { label: 'Modern Times', year: 1936 }, + { label: 'Once Upon a Time in the West', year: 1968 }, + { label: 'City Lights', year: 1931 }, + { label: 'Apocalypse Now', year: 1979 }, + { label: 'WALL·E', year: 2008 }, + { label: 'Memento', year: 2000 }, + { label: 'Dune: Part Two', year: 2024 }, + { label: 'Avengers: Infinity War', year: 2018 }, + { label: 'Raiders of the Lost Ark', year: 1981 }, + { label: 'The Lives of Others', year: 2006 }, + { label: 'Spider-Man: Into the Spider-Verse', year: 2018 }, { label: 'Sunset Boulevard', year: 1950 }, + { label: 'Witness for the Prosecution', year: 1957 }, + { label: 'Paths of Glory', year: 1957 }, + { label: 'The Shining', year: 1980 }, + { label: 'The Great Dictator', year: 1940 }, + { label: 'Inglourious Basterds', year: 2009 }, + { label: '12th Fail', year: 2023 }, + { label: 'Aliens', year: 1986 }, + { label: 'High and Low', year: 1963 }, + { label: 'Avengers: Endgame', year: 2019 }, + { label: 'Good Will Hunting', year: 1997 }, + { label: 'The Dark Knight Rises', year: 2012 }, + { label: 'Coco', year: 2017 }, + { label: 'Amadeus', year: 1984 }, + { label: 'Toy Story', year: 1995 }, + { label: 'Your Name.', year: 2016 }, + { label: 'Das Boot', year: 1981 }, + { label: 'Braveheart', year: 1995 }, + { label: 'Oldboy', year: 2003 }, + { label: 'Princess Mononoke', year: 1997 }, { label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', year: 1964, }, - { label: 'The Great Dictator', year: 1940 }, - { label: 'Cinema Paradiso', year: 1988 }, - { label: 'The Lives of Others', year: 2006 }, - { label: 'Grave of the Fireflies', year: 1988 }, - { label: 'Paths of Glory', year: 1957 }, - { label: 'Django Unchained', year: 2012 }, - { label: 'The Shining', year: 1980 }, - { label: 'WALL·E', year: 2008 }, + { label: '3 Idiots', year: 2009 }, { label: 'American Beauty', year: 1999 }, - { label: 'The Dark Knight Rises', year: 2012 }, - { label: 'Princess Mononoke', year: 1997 }, - { label: 'Aliens', year: 1986 }, - { label: 'Oldboy', year: 2003 }, + { label: 'Capernaum', year: 2018 }, + { label: "Singin' in the Rain", year: 1952 }, + { label: 'Joker', year: 2019 }, { label: 'Once Upon a Time in America', year: 1984 }, - { label: 'Witness for the Prosecution', year: 1957 }, - { label: 'Das Boot', year: 1981 }, - { label: 'Citizen Kane', year: 1941 }, - { label: 'North by Northwest', year: 1959 }, - { label: 'Vertigo', year: 1958 }, { label: 'Star Wars: Episode VI - Return of the Jedi', year: 1983, }, - { label: 'Reservoir Dogs', year: 1992 }, - { label: 'Braveheart', year: 1995 }, - { label: 'M', year: 1931 }, + { label: 'Come and See', year: 1985 }, { label: 'Requiem for a Dream', year: 2000 }, - { label: 'Amélie', year: 2001 }, - { label: 'A Clockwork Orange', year: 1971 }, - { label: 'Like Stars on Earth', year: 2007 }, - { label: 'Taxi Driver', year: 1976 }, - { label: 'Lawrence of Arabia', year: 1962 }, - { label: 'Double Indemnity', year: 1944 }, + { label: 'Toy Story 3', year: 2010 }, + { label: 'Project Hail Mary', year: 2026 }, + { label: 'Ikiru', year: 1952 }, + { label: 'The Hunt', year: 2012 }, + { label: 'Incendies', year: 2010 }, { label: 'Eternal Sunshine of the Spotless Mind', year: 2004, }, - { label: 'Amadeus', year: 1984 }, - { label: 'To Kill a Mockingbird', year: 1962 }, - { label: 'Toy Story 3', year: 2010 }, - { label: 'Logan', year: 2017 }, - { label: 'Full Metal Jacket', year: 1987 }, - { label: 'Dangal', year: 2016 }, - { label: 'The Sting', year: 1973 }, - { label: '2001: A Space Odyssey', year: 1968 }, - { label: "Singin' in the Rain", year: 1952 }, - { label: 'Toy Story', year: 1995 }, - { label: 'Bicycle Thieves', year: 1948 }, - { label: 'The Kid', year: 1921 }, - { label: 'Inglourious Basterds', year: 2009 }, - { label: 'Snatch', year: 2000 }, - { label: '3 Idiots', year: 2009 }, - { label: 'Monty Python and the Holy Grail', year: 1975 }, + { label: 'The Apartment', year: 1960 }, ]; export default top100Films; From 9eddc51017bad72d462cbe9a85a80f57562de136 Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Sat, 2 May 2026 06:00:52 +0800 Subject: [PATCH 5/7] reorganize sections --- docs/data/material/components/autocomplete/autocomplete.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/data/material/components/autocomplete/autocomplete.md b/docs/data/material/components/autocomplete/autocomplete.md index 2b623cd8a3fc2c..2346bd7bb5b3ea 100644 --- a/docs/data/material/components/autocomplete/autocomplete.md +++ b/docs/data/material/components/autocomplete/autocomplete.md @@ -393,13 +393,13 @@ To override the default key handling, set `defaultMuiPrevented` to `true` on the /> ``` -## Virtualization +### Virtualization Searches through a fixed list of 10,000 randomly generated options. The list is virtualized with [react-window](https://github.com/bvaughn/react-window). {{"demo": "Virtualize.js"}} -## `useAutocomplete` +### `useAutocomplete` Use the `useAutocomplete` hook when you need full control over markup. Import it from `@mui/material/useAutocomplete` ([4.6 kB gzipped](https://bundlephobia.com/package/@mui/material)); it accepts the same options as `Autocomplete`, minus the rendering props. The snippet shows the essential setup for a headless combobox. @@ -465,8 +465,6 @@ const movies: readonly Film[] = [ ]; ``` -### Customized hook - This demo shows a fully customized multi-selection combobox built with `useAutocomplete`. {{"demo": "CustomizedHook.js", "defaultCodeOpen": false}} From 29c346d4fefc4e78a198c8d16d01cc0b79de910f Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Mon, 4 May 2026 17:24:57 +0800 Subject: [PATCH 6/7] polish --- .../autocomplete/ControllableStates.js | 37 ++++++++++---- .../autocomplete/ControllableStates.tsx | 37 ++++++++++---- .../components/autocomplete/FixedTags.js | 1 + .../components/autocomplete/FixedTags.tsx | 1 + .../autocomplete/GloballyCustomizedOptions.js | 7 +-- .../GloballyCustomizedOptions.tsx | 7 +-- .../components/autocomplete/LimitTags.js | 1 + .../components/autocomplete/LimitTags.tsx | 1 + .../autocomplete/LimitTags.tsx.preview | 1 + .../material/components/autocomplete/Sizes.js | 2 + .../components/autocomplete/Sizes.tsx | 2 + .../material/components/autocomplete/Tags.js | 3 ++ .../material/components/autocomplete/Tags.tsx | 3 ++ .../components/autocomplete/Virtualize.js | 10 +++- .../components/autocomplete/Virtualize.tsx | 10 +++- .../components/autocomplete/autocomplete.md | 49 +++++++++++++++---- .../components/autocomplete/countries.js | 4 +- .../components/autocomplete/countries.ts | 4 +- 18 files changed, 134 insertions(+), 46 deletions(-) diff --git a/docs/data/material/components/autocomplete/ControllableStates.js b/docs/data/material/components/autocomplete/ControllableStates.js index ebed98009beaac..074341301330b7 100644 --- a/docs/data/material/components/autocomplete/ControllableStates.js +++ b/docs/data/material/components/autocomplete/ControllableStates.js @@ -1,6 +1,8 @@ import * as React from 'react'; -import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import Box from '@mui/material/Box'; +import Stack from '@mui/material/Stack'; +import TextField from '@mui/material/TextField'; const langs = [ { id: 'js', label: 'JavaScript' }, @@ -21,26 +23,43 @@ export default function ControllableStates() { const [inputValue, setInputValue] = React.useState(''); return ( -
    -
    {`value: ${value !== null ? `'${value.label}'` : 'null'}`}
    -
    {`inputValue: '${inputValue}'`}
    -
    + + +
    + value:{' '} + + {value?.label ?? 'null'} + +
    +
    + inputValue:{' '} + + {`"${inputValue}"`} + +
    +
    { + onChange={(_event, newValue) => { setValue(newValue); }} inputValue={inputValue} - onInputChange={(event, newInputValue) => { + onInputChange={(_event, newInputValue) => { setInputValue(newInputValue); }} options={langs} isOptionEqualToValue={(option, selectedValue) => option.id === selectedValue.id } - sx={{ width: 300 }} + sx={{ width: 1 }} renderInput={(params) => } /> -
    +
    ); } diff --git a/docs/data/material/components/autocomplete/ControllableStates.tsx b/docs/data/material/components/autocomplete/ControllableStates.tsx index dfba4377dab249..b18768e3e8939d 100644 --- a/docs/data/material/components/autocomplete/ControllableStates.tsx +++ b/docs/data/material/components/autocomplete/ControllableStates.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; -import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; +import Box from '@mui/material/Box'; +import Stack from '@mui/material/Stack'; +import TextField from '@mui/material/TextField'; interface ProgrammingLanguage { id: string; @@ -26,26 +28,43 @@ export default function ControllableStates() { const [inputValue, setInputValue] = React.useState(''); return ( -
    -
    {`value: ${value !== null ? `'${value.label}'` : 'null'}`}
    -
    {`inputValue: '${inputValue}'`}
    -
    + + +
    + value:{' '} + + {value?.label ?? 'null'} + +
    +
    + inputValue:{' '} + + {`"${inputValue}"`} + +
    +
    { + onChange={(_event, newValue) => { setValue(newValue); }} inputValue={inputValue} - onInputChange={(event, newInputValue) => { + onInputChange={(_event, newInputValue) => { setInputValue(newInputValue); }} options={langs} isOptionEqualToValue={(option, selectedValue) => option.id === selectedValue.id } - sx={{ width: 300 }} + sx={{ width: 1 }} renderInput={(params) => } /> -
    +
    ); } diff --git a/docs/data/material/components/autocomplete/FixedTags.js b/docs/data/material/components/autocomplete/FixedTags.js index 224ad8e4c73601..87160ff349e288 100644 --- a/docs/data/material/components/autocomplete/FixedTags.js +++ b/docs/data/material/components/autocomplete/FixedTags.js @@ -12,6 +12,7 @@ export default function FixedTags() { return ( { setValue([ diff --git a/docs/data/material/components/autocomplete/FixedTags.tsx b/docs/data/material/components/autocomplete/FixedTags.tsx index 224ad8e4c73601..87160ff349e288 100644 --- a/docs/data/material/components/autocomplete/FixedTags.tsx +++ b/docs/data/material/components/autocomplete/FixedTags.tsx @@ -12,6 +12,7 @@ export default function FixedTags() { return ( { setValue([ diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js index cea3b42dd730ff..332aaee7f7af04 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js @@ -12,12 +12,7 @@ const getOptionKey = (option) => `${option.label}-${option.detail}`; // Theme.ts const customTheme = (outerTheme) => createTheme({ - cssVariables: { - colorSchemeSelector: 'class', - }, - palette: { - mode: outerTheme.palette.mode, - }, + ...outerTheme, components: { MuiAutocomplete: { defaultProps: { diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx index 08352f92ee7ade..b4c40ff051a353 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx @@ -17,12 +17,7 @@ const getOptionKey = (option: Option) => `${option.label}-${option.detail}`; // Theme.ts const customTheme = (outerTheme: Theme) => createTheme({ - cssVariables: { - colorSchemeSelector: 'class', - }, - palette: { - mode: outerTheme.palette.mode, - }, + ...outerTheme, components: { MuiAutocomplete: { defaultProps: { diff --git a/docs/data/material/components/autocomplete/LimitTags.js b/docs/data/material/components/autocomplete/LimitTags.js index a73963e35c72e9..eb7611fd59b9a3 100644 --- a/docs/data/material/components/autocomplete/LimitTags.js +++ b/docs/data/material/components/autocomplete/LimitTags.js @@ -6,6 +6,7 @@ export default function LimitTags() { return ( ( @@ -19,6 +20,7 @@ export default function Tags() { /> ( @@ -19,6 +20,7 @@ export default function Tags() { /> + {`#${dataSet[2] + 1} - ${dataSet[1]}`} ); diff --git a/docs/data/material/components/autocomplete/Virtualize.tsx b/docs/data/material/components/autocomplete/Virtualize.tsx index 030998ade62770..85b7fda04b11b7 100644 --- a/docs/data/material/components/autocomplete/Virtualize.tsx +++ b/docs/data/material/components/autocomplete/Virtualize.tsx @@ -34,7 +34,15 @@ function RowComponent({ const { key, ...optionProps } = dataSet[0]; return ( - + {`#${dataSet[2] + 1} - ${dataSet[1]}`} ); diff --git a/docs/data/material/components/autocomplete/autocomplete.md b/docs/data/material/components/autocomplete/autocomplete.md index 2346bd7bb5b3ea..5b0749f9fd4a1b 100644 --- a/docs/data/material/components/autocomplete/autocomplete.md +++ b/docs/data/material/components/autocomplete/autocomplete.md @@ -21,10 +21,9 @@ Autocomplete supports three core interaction modes: ## Usage guidelines -- **Use it for filterable choices**: Autocomplete is best when users need typeahead to choose from a longer list. Use [Select](/material-ui/react-select/) instead for short lists that don't need filtering. -- **Choose fixed list or free text**: By default, values must come from `options`. Use `freeSolo` only when arbitrary text is valid, such as in a search field. -- **Keep controlled values stable**: When controlling `value`, preserve object and array references when their contents don't change. See [Controlled states](#controlled-states). -- **Label the input**: Provide a visible `TextField` `label` when possible, or another accessible name if the label is hidden. This follows the [WAI-ARIA combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) and helps all users. +- **Use for filterable choices**: Autocomplete is best for lists that are too long to scan. Use [Select](/material-ui/react-select/) instead for short lists. +- **Form controls must have an accessible name**: Use a visible `TextField` `label` when possible, or add `aria-label` if the label is hidden. +- **Keep the popup option-only**: The listbox should only contain selectable options. Avoid buttons, links, or non-option controls such as "Select all" because they disrupt keyboard semantics and assistive technology behavior. ## Combobox @@ -56,7 +55,7 @@ const options = [ const options = ['The Godfather', 'Pulp Fiction']; ``` -When using object options, provide `isOptionEqualToValue` so the component can match the current value to the right option. The default comparison uses strict equality (`===`), which only works when the value reference is the same as one of the options: +When using object options, you must provide `isOptionEqualToValue` so the component can match the current value to the right option. The default comparison uses strict equality (`===`), which only works when the value reference is the same as one of the options: ```tsx option.id} />; + option.label} + getOptionKey={(option) => option.id} +/>; ``` ### Playground @@ -154,16 +157,17 @@ Group options with the `groupBy` prop. Sort the options by the same field you're Customize how groups render with the `renderGroup` prop. It receives an object with: +- `key`—the React key to apply to the rendered group - `group`—the group name string - `children`—the list items in that group -The demo below uses custom markup and overrides the default group styles. +The demo below groups countries by continent and customizes the group rendering. {{"demo": "RenderGroup.js"}} ## Free solo -Set `freeSolo` to `true` so the textbox accepts any value, not just options from the list. +Use `freeSolo` when the input should accept values outside the provided options. ### Search input @@ -172,7 +176,16 @@ Designed for **search inputs** with suggestions—for example, Google search or {{"demo": "FreeSolo.js"}} :::warning -Free solo with non-string options can cause type mismatches. Whatever the user types becomes a string, even when the predefined options are objects. +Free solo with non-string options can cause type mismatches. The typed value is always a string, so make sure your callbacks can handle both strings and option objects: + +```tsx + (typeof option === 'string' ? option : option.label)} +/> +``` + ::: ### Creatable @@ -379,6 +392,22 @@ Add a hint (ghost text suggestion) inside the input: ### Events +Callbacks such as `onChange`, `onClose`, `onHighlightChange`, and `onInputChange` include a `reason` argument. Use it to distinguish user input from selection, clear, and other internal updates: + +- Selected value changes use `AutocompleteChangeReason`, covering selection, creation, removal, clear, and blur transitions. +- Textbox changes use `AutocompleteInputChangeReason`, which separates user typing from resets, clears, blur, and option selection or removal. +- Popup and highlight changes use `AutocompleteCloseReason` and `AutocompleteHighlightChangeReason` to describe why the popup closed or how the highlighted option moved. + +```jsx + { + if (reason === 'input') { + setQuery(value); + } + }} +/> +``` + To override the default key handling, set `defaultMuiPrevented` to `true` on the event: ```jsx @@ -501,6 +530,6 @@ Read [the guide on MDN](https://developer.mozilla.org/en-US/docs/Web/Security/Pr VoiceOver on iOS Safari has poor support for `aria-owns`. Work around it with the `disablePortal` prop. -### ListboxComponent +### Custom listbox component When you provide a custom `listbox` slot, set `role="listbox"` on the scroll container. This is what keyboard navigation looks for to scroll the highlighted item into view. diff --git a/docs/data/material/components/autocomplete/countries.js b/docs/data/material/components/autocomplete/countries.js index d395d679bbeffe..0b174814504d0e 100644 --- a/docs/data/material/components/autocomplete/countries.js +++ b/docs/data/material/components/autocomplete/countries.js @@ -1,6 +1,6 @@ -// Country metadata is adapted from countries-list (MIT): +// Labels and continents from countries-list; calling codes from Atlaskit: // https://github.com/annexare/Countries -// Country calling codes are kept in display format for this demo. +// https://bitbucket.org/atlassian/atlaskit-mk-2/raw/4ad0e56649c3e6c973e226b7efaeb28cb240ccb0/packages/core/select/src/data/countries.js const countries = [ { code: 'AD', label: 'Andorra', countryCallingCode: '376', continent: 'Europe' }, { diff --git a/docs/data/material/components/autocomplete/countries.ts b/docs/data/material/components/autocomplete/countries.ts index 3491f68a057d0d..4b3423cb4ad6df 100644 --- a/docs/data/material/components/autocomplete/countries.ts +++ b/docs/data/material/components/autocomplete/countries.ts @@ -14,9 +14,9 @@ export interface Country { continent: Continent; } -// Country metadata is adapted from countries-list (MIT): +// Labels and continents from countries-list; calling codes from Atlaskit: // https://github.com/annexare/Countries -// Country calling codes are kept in display format for this demo. +// https://bitbucket.org/atlassian/atlaskit-mk-2/raw/4ad0e56649c3e6c973e226b7efaeb28cb240ccb0/packages/core/select/src/data/countries.js const countries: readonly Country[] = [ { code: 'AD', label: 'Andorra', countryCallingCode: '376', continent: 'Europe' }, { code: 'AE', label: 'United Arab Emirates', countryCallingCode: '971', continent: 'Asia' }, From 18a6493da32dfbcd5ccb5fcc44b67b3efe37f056 Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Wed, 13 May 2026 23:56:40 +0800 Subject: [PATCH 7/7] update slotProps.htmlInput related docs --- .../experiments/renderers/renderCountry.js | 4 +-- .../components/autocomplete/autocomplete.md | 31 +++++++++++++++--- .../migrating-from-deprecated-apis.md | 32 +++++++++++++++++++ .../migration/upgrade-to-v9/upgrade-to-v9.md | 13 ++++++++ .../api-docs/autocomplete/autocomplete.json | 2 +- .../src/Autocomplete/Autocomplete.d.ts | 23 +++++++++++-- .../src/Autocomplete/Autocomplete.js | 23 +++++++++++-- .../src/Autocomplete/Autocomplete.spec.tsx | 2 +- 8 files changed, 117 insertions(+), 13 deletions(-) diff --git a/docs/data/experiments/renderers/renderCountry.js b/docs/data/experiments/renderers/renderCountry.js index 9eb632490950d5..3c1e2a73cb3cc1 100644 --- a/docs/data/experiments/renderers/renderCountry.js +++ b/docs/data/experiments/renderers/renderCountry.js @@ -101,10 +101,10 @@ function EditCountry(props) { fullWidth id={params.id} inputProps={{ - ...params.inputProps, + ...params.slotProps.htmlInput, autoComplete: 'new-password', // disable autocomplete and autofill }} - {...params.InputProps} + {...params.slotProps.input} /> )} /> diff --git a/docs/data/material/components/autocomplete/autocomplete.md b/docs/data/material/components/autocomplete/autocomplete.md index 5b0749f9fd4a1b..e63ebd057037f3 100644 --- a/docs/data/material/components/autocomplete/autocomplete.md +++ b/docs/data/material/components/autocomplete/autocomplete.md @@ -349,13 +349,34 @@ Use the `size` prop to render a smaller input. {{"demo": "Sizes.js"}} -### Custom input +### HTML input attributes -Customize the rendered input with the `renderInput` prop. Forward the input ref and HTML input props to preserve the Autocomplete behavior. +When setting native input attributes on `TextField`—for example `maxLength`—merge them with `params.slotProps.htmlInput` instead of replacing the whole slot object. +Autocomplete passes its input ref and event handlers through that object, and dropping them can break focus, keyboard, and selection behavior. -:::warning -When using a custom input component, forward the ref to the underlying DOM element. -::: +```tsx + ( + + )} +/> +``` + +### Custom input + +Customize the rendered input with the `renderInput` prop. +If you don't use `TextField`, attach `params.slotProps.input.ref` to the element that wraps the native input, and spread `params.slotProps.htmlInput` on the native input. ```tsx ``` +### renderInput params + +Older Autocomplete versions pass `InputProps`, `InputLabelProps`, and `inputProps` to `renderInput`. +When migrating the returned `TextField` to slots, map those params to the matching `TextField` slots. +Keep the spreads because these props include the ref and event handlers Autocomplete needs. + +```diff + ( ++ renderInput={({ InputProps, InputLabelProps, inputProps, ...params }) => ( + + )} + /> +``` + +Omitting `...inputProps` drops the input ref and can trigger the "Unable to find the input element" warning. + ## Avatar Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#avatar-props) below to migrate the code as described in the following sections: @@ -2445,6 +2475,8 @@ All of the TextField's slot props (`*Props`) props were deprecated in favor of e /> ``` +When migrating a `TextField` returned from Autocomplete's `renderInput`, also see the [Autocomplete renderInput params](#renderinput-params) section because the params must be mapped to `TextField` slots. + ## Tooltip Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#tooltip-props) below to migrate the code as described in the following sections: diff --git a/docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md b/docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md index e6d7549f6c59c0..47b51f7e8789b2 100644 --- a/docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md +++ b/docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md @@ -2191,6 +2191,19 @@ If you render a `TextField` from `Autocomplete`, the `params` shape also changed )} ``` +Preserve the props that Autocomplete passes to `TextField` by spreading `params.slotProps` into `slotProps`. +When customizing a specific slot, such as `htmlInput`, spread the matching nested object (`params.slotProps.htmlInput`) before adding your own attributes. + +```tsx +slotProps={{ + ...params.slotProps, + htmlInput: { + ...params.slotProps.htmlInput, + maxLength: 20, + }, +}} +``` + ### Tooltip props Use the [tooltip-props codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-codemod#tooltip-props) below to migrate the code as described in the following section: diff --git a/docs/translations/api-docs/autocomplete/autocomplete.json b/docs/translations/api-docs/autocomplete/autocomplete.json index 43cb77f5e7cdf6..fa306118efdcdd 100644 --- a/docs/translations/api-docs/autocomplete/autocomplete.json +++ b/docs/translations/api-docs/autocomplete/autocomplete.json @@ -189,7 +189,7 @@ "typeDescriptions": { "params": { "name": "params", "description": "The group to render." } } }, "renderInput": { - "description": "Render the input.
    Note: The renderInput prop must return a TextField component or a compatible custom component that correctly forwards InputProps.ref and spreads inputProps. This ensures proper integration with the Autocomplete's internal logic (e.g., focus management and keyboard navigation).
    Avoid using components like DatePicker or Select directly, as they may not forward the required props, leading to runtime errors or unexpected behavior." + "description": "Render the input.
    Note: The renderInput prop must return a TextField component or a compatible custom component that forwards params.slotProps.input.ref to the input wrapper and spreads params.slotProps.htmlInput on the native input. This preserves focus management, keyboard navigation, and ARIA attributes.
    Avoid using components like DatePicker or Select directly, as they may not forward the required props, leading to runtime errors or unexpected behavior." }, "renderOption": { "description": "Render the option, use getOptionLabel by default.", diff --git a/packages/mui-material/src/Autocomplete/Autocomplete.d.ts b/packages/mui-material/src/Autocomplete/Autocomplete.d.ts index ba75c4c69747fb..c7810dd92b9d27 100644 --- a/packages/mui-material/src/Autocomplete/Autocomplete.d.ts +++ b/packages/mui-material/src/Autocomplete/Autocomplete.d.ts @@ -324,12 +324,31 @@ export interface AutocompleteProps< * Render the input. * * **Note:** The `renderInput` prop must return a `TextField` component or a compatible custom component - * that correctly forwards `InputProps.ref` and spreads `inputProps`. This ensures proper integration - * with the Autocomplete's internal logic (e.g., focus management and keyboard navigation). + * that forwards `params.slotProps.input.ref` to the input wrapper and spreads `params.slotProps.htmlInput` + * on the native input. This preserves focus management, keyboard navigation, and ARIA attributes. * * Avoid using components like `DatePicker` or `Select` directly, as they may not forward the required props, * leading to runtime errors or unexpected behavior. * + * @example + * + * ```tsx + * ( + * + * )} + * /> + * ``` + * * @param {object} params * @returns {ReactNode} */ diff --git a/packages/mui-material/src/Autocomplete/Autocomplete.js b/packages/mui-material/src/Autocomplete/Autocomplete.js index 92e1ea35eae833..09fad25fd4c7b4 100644 --- a/packages/mui-material/src/Autocomplete/Autocomplete.js +++ b/packages/mui-material/src/Autocomplete/Autocomplete.js @@ -1171,12 +1171,31 @@ Autocomplete.propTypes /* remove-proptypes */ = { * Render the input. * * **Note:** The `renderInput` prop must return a `TextField` component or a compatible custom component - * that correctly forwards `InputProps.ref` and spreads `inputProps`. This ensures proper integration - * with the Autocomplete's internal logic (e.g., focus management and keyboard navigation). + * that forwards `params.slotProps.input.ref` to the input wrapper and spreads `params.slotProps.htmlInput` + * on the native input. This preserves focus management, keyboard navigation, and ARIA attributes. * * Avoid using components like `DatePicker` or `Select` directly, as they may not forward the required props, * leading to runtime errors or unexpected behavior. * + * @example + * + * ```tsx + * ( + * + * )} + * /> + * ``` + * * @param {object} params * @returns {ReactNode} */ diff --git a/packages/mui-material/src/Autocomplete/Autocomplete.spec.tsx b/packages/mui-material/src/Autocomplete/Autocomplete.spec.tsx index cf9baa121a2e52..b116dd6ff3d920 100644 --- a/packages/mui-material/src/Autocomplete/Autocomplete.spec.tsx +++ b/packages/mui-material/src/Autocomplete/Autocomplete.spec.tsx @@ -67,7 +67,7 @@ function MyAutocomplete< renderInput={() => null} />; -// Tests presence of onMouseDown prop in InputProps +// Tests presence of onMouseDown prop in the input slot props. {