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/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 eabea1b08af6f0..8ba7dab31887e3 100644 --- a/docs/data/material/components/autocomplete/AutocompleteHint.js +++ b/docs/data/material/components/autocomplete/AutocompleteHint.js @@ -3,196 +3,68 @@ 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(''); 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 inputValue={inputValue} - id="combo-box-hint-demo" options={top100Films} sx={{ width: 300 }} renderInput={(params) => { 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" - /> + ); }} /> ); } - -// 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..8ba7dab31887e3 100644 --- a/docs/data/material/components/autocomplete/AutocompleteHint.tsx +++ b/docs/data/material/components/autocomplete/AutocompleteHint.tsx @@ -3,196 +3,68 @@ 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(''); 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 inputValue={inputValue} - id="combo-box-hint-demo" options={top100Films} sx={{ width: 300 }} renderInput={(params) => { 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" - /> + ); }} /> ); } - -// 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..709f134b795b5e 100644 --- a/docs/data/material/components/autocomplete/CheckboxesTags.js +++ b/docs/data/material/components/autocomplete/CheckboxesTags.js @@ -2,15 +2,14 @@ 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 ( option.title} renderOption={(props, option, { selected }) => { const { key, ...optionProps } = props; const SelectionIcon = selected ? CheckBoxIcon : CheckBoxOutlineBlankIcon; @@ -19,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 53dc0603f35c51..709f134b795b5e 100644 --- a/docs/data/material/components/autocomplete/CheckboxesTags.tsx +++ b/docs/data/material/components/autocomplete/CheckboxesTags.tsx @@ -2,15 +2,14 @@ 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 ( option.title} renderOption={(props, option, { selected }) => { const { key, ...optionProps } = props; const SelectionIcon = selected ? CheckBoxIcon : CheckBoxOutlineBlankIcon; @@ -19,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 0911878aedcd76..074341301330b7 100644 --- a/docs/data/material/components/autocomplete/ControllableStates.js +++ b/docs/data/material/components/autocomplete/ControllableStates.js @@ -1,32 +1,65 @@ 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 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'}`}
    -
    {`inputValue: '${inputValue}'`}
    -
    + + +
    + value:{' '} + + {value?.label ?? 'null'} + +
    +
    + inputValue:{' '} + + {`"${inputValue}"`} + +
    +
    { + onChange={(_event, newValue) => { setValue(newValue); }} inputValue={inputValue} - onInputChange={(event, newInputValue) => { + onInputChange={(_event, newInputValue) => { setInputValue(newInputValue); }} - id="controllable-states-demo" - options={options} - sx={{ width: 300 }} - renderInput={(params) => } + options={langs} + isOptionEqualToValue={(option, selectedValue) => + option.id === selectedValue.id + } + sx={{ width: 1 }} + renderInput={(params) => } /> -
    + ); } diff --git a/docs/data/material/components/autocomplete/ControllableStates.tsx b/docs/data/material/components/autocomplete/ControllableStates.tsx index 4cd5f442a496c7..b18768e3e8939d 100644 --- a/docs/data/material/components/autocomplete/ControllableStates.tsx +++ b/docs/data/material/components/autocomplete/ControllableStates.tsx @@ -1,32 +1,70 @@ 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 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'}`}
    -
    {`inputValue: '${inputValue}'`}
    -
    + + +
    + value:{' '} + + {value?.label ?? 'null'} + +
    +
    + inputValue:{' '} + + {`"${inputValue}"`} + +
    +
    { + onChange={(_event, newValue) => { setValue(newValue); }} inputValue={inputValue} - onInputChange={(event, newInputValue) => { + onInputChange={(_event, newInputValue) => { setInputValue(newInputValue); }} - id="controllable-states-demo" - options={options} - sx={{ width: 300 }} - renderInput={(params) => } + options={langs} + isOptionEqualToValue={(option, selectedValue) => + option.id === selectedValue.id + } + sx={{ width: 1 }} + renderInput={(params) => } /> -
    + ); } diff --git a/docs/data/material/components/autocomplete/CountrySelect.js b/docs/data/material/components/autocomplete/CountrySelect.js index 4e6c30ac28c059..76608fe89a7c76 100644 --- a/docs/data/material/components/autocomplete/CountrySelect.js +++ b/docs/data/material/components/autocomplete/CountrySelect.js @@ -1,12 +1,12 @@ 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 ( option.label} @@ -21,12 +21,28 @@ export default function CountrySelect() { > - {option.label} ({option.code}) +{option.phone} + + {option.label} ({option.code}) + + + +{option.countryCallingCode} + ); }} @@ -46,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 e91d39d5f3796a..76608fe89a7c76 100644 --- a/docs/data/material/components/autocomplete/CountrySelect.tsx +++ b/docs/data/material/components/autocomplete/CountrySelect.tsx @@ -1,12 +1,12 @@ 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 ( option.label} @@ -21,12 +21,28 @@ export default function CountrySelect() { > - {option.label} ({option.code}) +{option.phone} + + {option.label} ({option.code}) + + + +{option.countryCallingCode} + ); }} @@ -46,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 5487c4f1944f75..00000000000000 --- a/docs/data/material/components/autocomplete/CustomInputAutocomplete.js +++ /dev/null @@ -1,28 +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 5487c4f1944f75..00000000000000 --- a/docs/data/material/components/autocomplete/CustomInputAutocomplete.tsx +++ /dev/null @@ -1,28 +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 df4234c4d8df98..a89d075def1636 100644 --- a/docs/data/material/components/autocomplete/CustomizedHook.js +++ b/docs/data/material/components/autocomplete/CustomizedHook.js @@ -1,368 +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 dbf0a2cc801080..2f1b3d50fc1257 100644 --- a/docs/data/material/components/autocomplete/CustomizedHook.tsx +++ b/docs/data/material/components/autocomplete/CustomizedHook.tsx @@ -1,362 +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 ( - - id="customized-hook-demo" - 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 a36922ba448fb9..87160ff349e288 100644 --- a/docs/data/material/components/autocomplete/FixedTags.js +++ b/docs/data/material/components/autocomplete/FixedTags.js @@ -2,15 +2,17 @@ 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 ( { setValue([ @@ -19,152 +21,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 a36922ba448fb9..87160ff349e288 100644 --- a/docs/data/material/components/autocomplete/FixedTags.tsx +++ b/docs/data/material/components/autocomplete/FixedTags.tsx @@ -2,15 +2,17 @@ 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 ( { setValue([ @@ -19,152 +21,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 b3d12a0a75e8a1..3354a0ba82f223 100644 --- a/docs/data/material/components/autocomplete/FreeSolo.js +++ b/docs/data/material/components/autocomplete/FreeSolo.js @@ -1,23 +1,24 @@ 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 ( 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 b3d12a0a75e8a1..3354a0ba82f223 100644 --- a/docs/data/material/components/autocomplete/FreeSolo.tsx +++ b/docs/data/material/components/autocomplete/FreeSolo.tsx @@ -1,23 +1,24 @@ 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 ( 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 23d73370af7ef5..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,25 +32,18 @@ export default function FreeSoloCreateOption() { selectOnFocus clearOnBlur handleHomeEndKeys - id="free-solo-with-text-demo" - 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}
  • ); }} @@ -73,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 156a03a620c940..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,25 +37,18 @@ export default function FreeSoloCreateOption() { selectOnFocus clearOnBlur handleHomeEndKeys - id="free-solo-with-text-demo" - 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}
  • ); }} @@ -73,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 a5183040c0d7cb..44bb5da780924f 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.js @@ -6,9 +6,12 @@ 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'; +import top100Films from './top100Films'; const filter = createFilterOptions(); +const filmOptions = top100Films; export default function FreeSoloCreateOptionDialog() { const [value, setValue] = React.useState(null); @@ -16,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); @@ -63,26 +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; }} - id="free-solo-dialog-demo" - 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}
  • ); }} @@ -107,35 +105,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, + label: event.target.value, + }) + } + label="title" + type="text" + variant="filled" + /> + + setDialogValue({ + ...dialogValue, + year: event.target.value, + }) + } + label="year" + type="number" + variant="filled" + /> + @@ -146,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 cf91675587e4f9..a712806dbeb0f7 100644 --- a/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx +++ b/docs/data/material/components/autocomplete/FreeSoloCreateOptionDialog.tsx @@ -6,55 +6,61 @@ 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'; +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); @@ -63,26 +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; }} - id="free-solo-dialog-demo" - 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}
  • ); }} @@ -107,35 +110,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, + label: event.target.value, + }) + } + label="title" + type="text" + variant="filled" + /> + + setDialogValue({ + ...dialogValue, + year: event.target.value, + }) + } + label="year" + type="number" + variant="filled" + /> + @@ -146,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/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 09e83bdecfba54..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 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?: any; + 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 ( + + + + ); +} diff --git a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js index bf76c5f336256e..332aaee7f7af04 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.js @@ -1,37 +1,60 @@ 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) => createTheme({ - cssVariables: { - colorSchemeSelector: 'class', - }, - palette: { - mode: outerTheme.palette.mode, - }, + ...outerTheme, components: { MuiAutocomplete: { defaultProps: { renderOption: (props, option, state, ownerState) => { const { key, ...optionProps } = props; + const { detail } = option; + return ( - {ownerState.getOptionLabel(option)} + + {ownerState.getOptionLabel(option)} + + ); }, @@ -40,29 +63,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})`} - id="movie-customized-option-demo" - disableCloseOnSelect + options={languages} + getOptionLabel={(option) => option.label} renderInput={(params) => ( - + )} /> ); @@ -71,566 +109,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 553b30e71178ea..b4c40ff051a353 100644 --- a/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx +++ b/docs/data/material/components/autocomplete/GloballyCustomizedOptions.tsx @@ -1,37 +1,65 @@ 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) => createTheme({ - cssVariables: { - colorSchemeSelector: 'class', - }, - palette: { - mode: outerTheme.palette.mode, - }, + ...outerTheme, components: { MuiAutocomplete: { defaultProps: { renderOption: (props, option, state, ownerState) => { const { key, ...optionProps } = props; + const { detail } = option as Option; + return ( - {ownerState.getOptionLabel(option)} + + {ownerState.getOptionLabel(option)} + + ); }, @@ -40,29 +68,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})`} - id="movie-customized-option-demo" - disableCloseOnSelect + options={languages} + getOptionLabel={(option) => option.label} renderInput={(params) => ( - + )} /> ); @@ -71,578 +114,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 c4622b5f0d76f8..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; @@ -213,7 +212,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); }} @@ -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 c882d0debcfa79..eb7611fd59b9a3 100644 --- a/docs/data/material/components/autocomplete/LimitTags.js +++ b/docs/data/material/components/autocomplete/LimitTags.js @@ -1,147 +1,19 @@ import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; +import top100Films from './top100Films'; export default function LimitTags() { return ( 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 c882d0debcfa79..eb7611fd59b9a3 100644 --- a/docs/data/material/components/autocomplete/LimitTags.tsx +++ b/docs/data/material/components/autocomplete/LimitTags.tsx @@ -1,147 +1,19 @@ import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; +import top100Films from './top100Films'; export default function LimitTags() { return ( 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..953c110389d697 100644 --- a/docs/data/material/components/autocomplete/LimitTags.tsx.preview +++ b/docs/data/material/components/autocomplete/LimitTags.tsx.preview @@ -1,12 +1,11 @@ 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 ea72267877c7f5..ceb2864465f55e 100644 --- a/docs/data/material/components/autocomplete/Playground.js +++ b/docs/data/material/components/autocomplete/Playground.js @@ -2,287 +2,144 @@ 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 ( - + ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> { setValue(newValue); }} 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/Playground.tsx b/docs/data/material/components/autocomplete/Playground.tsx index c2b906f58bb091..b00648bae148e5 100644 --- a/docs/data/material/components/autocomplete/Playground.tsx +++ b/docs/data/material/components/autocomplete/Playground.tsx @@ -2,292 +2,146 @@ 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 ( - + ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> ( - + )} /> { + onChange={(event, newValue) => { setValue(newValue); }} 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/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 6ad2b064b0046c..1048f441a975c9 100644 --- a/docs/data/material/components/autocomplete/Sizes.js +++ b/docs/data/material/components/autocomplete/Sizes.js @@ -2,46 +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) => ( - - )} - /> - option.title} - defaultValue={[top100Films[13]]} - renderInput={(params) => ( - - )} - /> - option.title} defaultValue={top100Films[13]} renderInput={(params) => ( @@ -49,20 +17,17 @@ export default function Sizes() { /> option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( )} /> option.title} defaultValue={top100Films[13]} renderInput={(params) => ( option.title} defaultValue={[top100Films[13]]} renderValue={(values, getItemProps) => values.map((option, index) => { @@ -87,7 +51,7 @@ export default function Sizes() { @@ -106,131 +70,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 6ad2b064b0046c..1048f441a975c9 100644 --- a/docs/data/material/components/autocomplete/Sizes.tsx +++ b/docs/data/material/components/autocomplete/Sizes.tsx @@ -2,46 +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) => ( - - )} - /> - option.title} - defaultValue={[top100Films[13]]} - renderInput={(params) => ( - - )} - /> - option.title} defaultValue={top100Films[13]} renderInput={(params) => ( @@ -49,20 +17,17 @@ export default function Sizes() { /> option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( )} /> option.title} defaultValue={top100Films[13]} renderInput={(params) => ( option.title} defaultValue={[top100Films[13]]} renderValue={(values, getItemProps) => values.map((option, index) => { @@ -87,7 +51,7 @@ export default function Sizes() { @@ -106,131 +70,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 ed1e92eab6c4b2..844a9a45f13d5d 100644 --- a/docs/data/material/components/autocomplete/Tags.js +++ b/docs/data/material/components/autocomplete/Tags.js @@ -2,30 +2,26 @@ 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 ( option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( - + )} /> option.title} defaultValue={[top100Films[13]]} filterSelectedOptions renderInput={(params) => ( @@ -38,9 +34,9 @@ export default function Tags() { /> option.title)} - defaultValue={[top100Films[13].title]} + disableCloseOnSelect + options={filmTitles} + defaultValue={[top100Films[13].label]} freeSolo renderValue={(value, getItemProps) => value.map((option, index) => { @@ -51,19 +47,13 @@ export default function Tags() { }) } renderInput={(params) => ( - + )} /> option.title)} - defaultValue={[top100Films[12].title, top100Films[13].title]} + options={filmTitles} + defaultValue={[top100Films[12].label, top100Films[13].label]} readOnly renderInput={(params) => ( @@ -72,131 +62,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 99d9d70bf74008..918a6c358399b5 100644 --- a/docs/data/material/components/autocomplete/Tags.tsx +++ b/docs/data/material/components/autocomplete/Tags.tsx @@ -2,30 +2,26 @@ 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 ( option.title} defaultValue={[top100Films[13]]} renderInput={(params) => ( - + )} /> option.title} defaultValue={[top100Films[13]]} filterSelectedOptions renderInput={(params) => ( @@ -38,9 +34,9 @@ export default function Tags() { /> option.title)} - defaultValue={[top100Films[13].title]} + disableCloseOnSelect + options={filmTitles} + defaultValue={[top100Films[13].label]} freeSolo renderValue={(value: readonly string[], getItemProps) => value.map((option: string, index: number) => { @@ -51,19 +47,13 @@ export default function Tags() { }) } renderInput={(params) => ( - + )} /> option.title)} - defaultValue={[top100Films[12].title, top100Films[13].title]} + options={filmTitles} + defaultValue={[top100Films[12].label, top100Films[13].label]} readOnly renderInput={(params) => ( @@ -72,131 +62,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..b8716bb3e4164e 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,18 +17,18 @@ function RowComponent({ index, itemData, style }) { top: (style.top ?? 0) + LISTBOX_PADDING, }; - if ('group' in dataSet) { - return ( - - {dataSet.group} - - ); - } - const { key, ...optionProps } = dataSet[0]; return ( - + {`#${dataSet[2] + 1} - ${dataSet[1]}`} ); @@ -40,39 +39,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 +74,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 +91,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 +157,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 +171,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..85b7fda04b11b7 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,18 +31,18 @@ function RowComponent({ top: ((style.top as number) ?? 0) + LISTBOX_PADDING, }; - if ('group' in dataSet) { - return ( - - {dataSet.group} - - ); - } - const { key, ...optionProps } = dataSet[0]; return ( - + {`#${dataSet[2] + 1} - ${dataSet[1]}`} ); @@ -63,22 +57,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 +82,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 +99,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 +153,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 +169,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 65f9e004007147..e63ebd057037f3 100644 --- a/docs/data/material/components/autocomplete/autocomplete.md +++ b/docs/data/material/components/autocomplete/autocomplete.md @@ -9,36 +9,42 @@ 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 + +- **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 -The value must be chosen from a predefined set of allowed values. +Use the basic combobox when users need to search a predefined list and pick one value. {{"demo": "ComboBox.js"}} ### Options structure -By default, the component accepts the following options 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; ``` -for instance: +For example: ```js const options = [ @@ -49,49 +55,67 @@ const options = [ const options = ['The Godfather', 'Pulp Fiction']; ``` -However, you can use different structures by providing a `getOptionLabel` prop. +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: -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 display a value other than `label`, use `getOptionLabel` to return a string representing each option: ```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} />; ``` -::: +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 +const options = [ + { label: 'John Smith', id: 'usr_4f12a7b8' }, + { label: 'John Smith', id: 'usr_e9c3d521' }, +]; + + option.label} + getOptionKey={(option) => option.id} +/>; +``` ### Playground -Each of the following examples demonstrates one feature of the Autocomplete component. +Each example below demonstrates one feature. {{"demo": "Playground.js"}} ### 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"}} ### 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,117 @@ 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: + +- `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 groups countries by continent and customizes the group rendering. + +{{"demo": "RenderGroup.js"}} + ## Free solo -Set `freeSolo` to true so the textbox can contain any arbitrary value. +Use `freeSolo` when the input should accept values outside the provided options. ### 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. +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)} +/> +``` -The value created by typing into the textbox is always a string, regardless of the type of the options. ::: ### 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: - -- `group`—a string representing a group name -- `children`—a collection of list items that belong to the group +## Multiple values -The following demo shows how to use this prop to define custom markup and override the styles of the default groups: +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`. -{{"demo": "RenderGroup.js"}} +- 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`. -## 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 +256,281 @@ 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. +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"}} -## 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 -### Custom input +For richer filtering—like fuzzy matching—we recommend [match-sorter](https://github.com/kentcdodds/match-sorter): -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. +```jsx +import { matchSorter } from 'match-sorter'; -:::warning -If you're using a custom input component inside the Autocomplete, make sure that you forward the ref to the underlying DOM element. -::: +const filterOptions = (options, { inputValue }) => matchSorter(options, inputValue); -{{"demo": "CustomInputAutocomplete.js"}} +; +``` -### Globally customized options +### Sizes -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. +Use the `size` prop to render a smaller input. -{{"demo": "GloballyCustomizedOptions.js"}} +{{"demo": "Sizes.js"}} -### GitHub's picker +### HTML input attributes -This demo reproduces GitHub's label picker: +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. -{{"demo": "GitHubLabel.js"}} +```tsx + ( + + )} +/> +``` -Head to the [Customized hook](#customized-hook) section for a customization example with the `useAutocomplete` hook instead of the component. +### Custom input -### Hint +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. -The following demo shows how to add a hint feature to the Autocomplete: +```tsx + ( +
    + +
    + )} +/> +``` -{{"demo": "AutocompleteHint.js"}} +### Globally customized options -## Highlights +To customize option rendering for every Autocomplete in your app, set `renderOption` in [theme default props](/material-ui/customization/theme-components/#theme-default-props). -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. +`renderOption` receives `ownerState` as its fourth argument, which exposes props and internal state. Use `ownerState.getOptionLabel` to render the label. -{{"demo": "Highlights.js"}} +This keeps option styling consistent across the app while letting each instance customize its content. -## Custom filter +{{"demo": "GloballyCustomizedOptions.js"}} -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. +### GitHub's picker -```js -import { createFilterOptions } from '@mui/material/Autocomplete'; -``` +A reproduction of GitHub's label picker: -### `createFilterOptions(config) => filterOptions` +{{"demo": "GitHubLabel.js"}} -#### Arguments +### Hint -1. `config` (_object_ [optional]): +Add a hint (ghost text suggestion) inside the input: -- `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. +{{"demo": "AutocompleteHint.js"}} -#### Returns +### Events -`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. +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: -In the following demo, the options need to start with the query prefix: +- 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 -const filterOptions = createFilterOptions({ - matchFrom: 'start', - stringify: (option) => option.title, -}); + { + if (reason === 'input') { + setQuery(value); + } + }} +/> +``` -; +To override the default key handling, set `defaultMuiPrevented` to `true` on the event: + +```jsx + { + 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 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'; -## Virtualization +interface Option { + label: string; +} -Search within 10,000 randomly generated options. The list is virtualized thanks to [react-window](https://github.com/bvaughn/react-window). +interface MyAutocompleteProps { + id: string; + label: string; + options: readonly Option[]; +} -{{"demo": "Virtualize.js"}} +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} +
    + ); +} -## Events +export default function App() { + return ; +} -If you would like to prevent the default key handler behavior, you can set the event's `defaultMuiPrevented` property to `true`: +interface Film extends Option { + year: number; +} -```jsx - { - if (event.key === 'Enter') { - // Prevent's default 'Enter' behavior. - event.defaultMuiPrevented = true; - // your handler code - } - }} -/> +const movies: readonly Film[] = [ + { label: 'The Shawshank Redemption', year: 1994 }, + { label: 'The Godfather', year: 1972 }, +]; ``` +This demo shows a fully customized multi-selection combobox built with `useAutocomplete`. + +{{"demo": "CustomizedHook.js", "defaultCodeOpen": false}} + ## 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 ``` +### 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. {