Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[material-ui][Autocomplete] Add custom props support via slotProps #43613

12 changes: 7 additions & 5 deletions packages/mui-material/src/Autocomplete/Autocomplete.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import useAutocomplete, {
import { AutocompleteClasses } from './autocompleteClasses';
import { CreateSlotsAndSlotProps, SlotProps } from '../utils/types';

export interface AutocompletePaperSlotPropsOverrides {}
export interface AutocompletePopperSlotPropsOverrides {}

export {
AutocompleteChangeDetails,
AutocompleteChangeReason,
Expand Down Expand Up @@ -94,12 +97,12 @@ export interface AutocompleteSlots {
* The component used to render the body of the popup.
* @default Paper
*/
paper: React.JSXElementConstructor<PaperProps>;
paper: React.JSXElementConstructor<PaperProps & AutocompletePaperSlotPropsOverrides>;
/**
* The component used to position the popup.
* @default Popper
*/
popper: React.JSXElementConstructor<PopperProps>;
popper: React.JSXElementConstructor<PopperProps & AutocompletePopperSlotPropsOverrides>;
}

export type AutocompleteSlotsAndSlotProps<
Expand Down Expand Up @@ -134,15 +137,14 @@ export type AutocompleteSlotsAndSlotProps<
{},
AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
>;

paper: SlotProps<
React.ElementType<Partial<PaperProps>>,
{},
AutocompletePaperSlotPropsOverrides,
AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
>;
popper: SlotProps<
React.ElementType<Partial<PopperProps>>,
{},
AutocompletePopperSlotPropsOverrides,
AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
>;
popupIndicator: SlotProps<
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import * as React from 'react';
import Autocomplete from '@mui/material/Autocomplete';
import Button from '@mui/material/Button';
import Paper, { PaperProps } from '@mui/material/Paper';
import Popper, { PopperProps } from '@mui/material/Popper';
import TextField from '@mui/material/TextField';

declare module '@mui/material/Autocomplete' {
interface AutocompletePaperSlotPropsOverrides {
value: Option[];
}
interface AutocompletePopperSlotPropsOverrides {
value: Option[];
}
}

function CustomPaper({ children, value, ...paperProps }: PaperProps & { value: Option[] }) {
return (
<Paper {...paperProps} onMouseDown={(event) => event.preventDefault()}>
{children}
<Button disabled={value.length === 0}>Next</Button>
</Paper>
);
}

function CustomPopper({ children, value, ...popperProps }: PopperProps & { value: Option[] }) {
return (
<Popper {...popperProps}>
{children as React.ReactNode}
<Button disabled={value.length === 0}>Next</Button>
</Popper>
);
}

interface Option {
title: string;
year: number;
}

function App() {
const [value, setValue] = React.useState<Option[]>([]);

return (
<React.Fragment>
{/* Testing Paper slot */}
<Autocomplete
multiple
isOptionEqualToValue={(option, valueParam) => option.title === valueParam.title}
renderInput={(params) => <TextField {...params} placeholder="Select" />}
onChange={(event, newValue) => {
setValue(newValue);
}}
getOptionLabel={(option) => `(${option?.year}) ${option?.title}`}
options={[...topFilms]}
value={value}
slots={{ paper: CustomPaper }}
slotProps={{ paper: { value } }}
/>
{/* Testing Popper slot */}
<Autocomplete
multiple
isOptionEqualToValue={(option, valueParam) => option.title === valueParam.title}
renderInput={(params) => <TextField {...params} placeholder="Select" />}
onChange={(event, newValue) => {
setValue(newValue);
}}
getOptionLabel={(option) => `(${option?.year}) ${option?.title}`}
options={[...topFilms]}
value={value}
slots={{ popper: CustomPopper }}
slotProps={{ popper: { value } }}
/>
</React.Fragment>
);
}

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 },
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../../../../tsconfig.json",
"files": ["autocompleteCustomSlotProps.spec.tsx"]
}