I'm following various examples from https://material-ui.com/components/autocomplete/ to create a custom autocomplete. I'm trying to use the renderInput
property to use a custom input component. All of the examples I find use the TextField
component, but I'd like to use a regular input
component.
Problem is, the options are never displayed. I've created a demonstration here (swap renderInput
with renderInputWORKING
to see working version):
https://codesandbox.io/s/epic-johnson-oxy7b?file=/src/App.tsx
with the following code in renderInput
:
const renderInput = (params: AutocompleteRenderInputParams) => {
console.log(params);
const { InputLabelProps, inputProps, InputProps } = params;
return (
<div>
<label {...InputLabelProps}>foo</label>
<input {...InputProps} {...inputProps} />
</div>
);
};
How can I use the <input />
component for renderInput
prop on <Autocomplete />
?
UPDATE
The 4.10.1 release of Material-UI (on June 1, 2020) included a new example in the documentation for this exact case: https://material-ui.com/components/autocomplete/#custom-input.
Pull request: https://github.com/mui-org/material-ui/pull/21257
The most useful example to look at in the documentation is the Customized Autocomplete example which uses InputBase
instead of TextField
. This example contains the following code for renderInput
:
renderInput={(params) => (
<InputBase
ref={params.InputProps.ref}
inputProps={params.inputProps}
autoFocus
className={classes.inputBase}
/>
)}
The InputProps
passed to TextField
are placed on a div that wraps the <input>
, so most of those props are not appropriate to put directly on the <input>
element as you were. In the code above from the documentation example, you can see that it only uses one thing from params.InputProps
which is the ref
. This ref is used for controlling the anchor element for the listbox of options. A ref is also placed on the <input>
itself, but that ref
is used for very different purposes. With your code, only one of those refs was getting used.
Below is a working example (based on the Combo Box example since your sandbox has a lot of other customizations that aren't directly related to this question) that uses <input>
instead of TextField
:
import React from "react";
import Autocomplete from "@material-ui/lab/Autocomplete";
export default function ComboBox() {
return (
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={option => option.title}
style={{ width: 300 }}
renderInput={params => (
<div ref={params.InputProps.ref}>
<label {...params.InputLabelProps}>My Label </label>
<input {...params.inputProps} autoFocus />
</div>
)}
/>
);
}