Implement inputRef prop with Material UI TextField custom component - reactjs

I'm trying to hook up Material UI TextField with an input component of my own. The code utilizing the TextField looks like this:
<Autocomplete
id="inputData"
options={inputData}
getOptionLabel={option => option.text}
renderInput={params => (
<TextField
{...params}
label="inputData"
InputProps={{
inputComponent: () => <Input name="inputData" />
}}
/>
)}
/>
and the Input component code is simple:
const Input = () => <input />
It will become more complicated but for now I'd like to get this simple code to work. The error I get is that inputRef.current is null which is probably caused by the lack of InputElement interface implementation in the Input component. Please see the Material UI docs below the code snippet for the info on InputElement interface. In other words my Input component doesn't handle the inputRef prop Material UI needs.
How do I properly integrate a custom Input component with Material UI TextField ?
Here's a Sandbox: https://codesandbox.io/s/fervent-bash-pxqq0.

Related

Change the clock svg to another svg in Material UI X Timepicker

I am using the Material UI x time-picker component in my app. I would like to change the clock SVG in the component to a custom SVG (a Chevron). I read that I need to use the props components. But what is the component called? I tried with the testid ClockIcon but that was not successful.
I believe what you are looking for is this:
<TimePicker
label="Time"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} />}
components={{
OpenPickerIcon: SearchIcon // Replace with your icon
}}
/>
For example I have imported the SearchIcon to use it as an example to replace the default one.

How to add custom handler on close icon in Material UI TextField component?

I'm using Material UI in a Reactjs/Typescript project where I render a search input component using TextField.
The "x" icon is built into the component and clears the value on the input. However, I would like to create my own custom handler to make an api call when the search value is deleted.
I looked at the component and component API docs but haven't come across anything useful. There was another answer that used the browser api to grab the x element and add an event listener, but I would like to avoid directly manipulating the DOM if possible.
<TextField
id="outlined-search"
label="Search users"
type="search"
variant="outlined"
style={{ width: '40ch' }}
value={searchValue}
inputRef={textRef}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => event.target.value !== " " &&
setSearchValue(event.target.value)}
onKeyPress={() => {}}
/>
I think something like below might help. It will call a business logic/API function when input is empty.
const handleChange = async (event) => {
setSearchValue(event.target.value)
// API calls here
if(!event.target.value) {
const response = await api.get();
}
}
<TextField
id="outlined-search"
label="Search users"
type="search"
variant="outlined"
style={{ width: '40ch' }}
value={searchValue}
inputRef={textRef}
onChange={handleChange}
/>

React Material UI Color Picker with Formik

I'm trying to use material-ui-color picker with Formik. I'm using React Material UI FormControl. Here's what I've tried for the color picker:
<FormControl
variant="outlined"
error={Boolean(touched.color_code && errors.color_code)}>
<ColorPicker
id="color_code"
defaultValue="#03a9f4"
onChange={handleChange}
value={values.color_code}
aria-describedby="color_code-error-text"
name="color_code"
/>
{touched.color_code && errors.color_code ? (
<FormHelperText id="color_code-error-text">
{errors.color_code}
</FormHelperText>
) : null
}
</FormControl>
Now, the issue is that, the selected color code is not being populated inside formik form values when I'm submitting the form.
Any help would be highly appreciated. Thanks in advance.
The onChange function provides the hex code directly. You can use the setFieldValue function provided from useFormik hook. So try doing the following:
<ColorPicker
id="color_code"
defaultValue="#03a9f4"
onChange={(value) => setFieldValue("color_code", value)}
value={values.color_code}
aria-describedby="color_code-error-text"
name="color_code"/>
I hope this helps!

Material UI Autocomplete custom renderInput

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>
)}
/>
);
}

React material-UI custom input for TextField

I'm trying to integrate the material-UI TextField with react-payment-inputs library.
For example I use this library like this:
import {usePaymentInputs} from 'react-payment-inputs';
const { getCardNumberProps} = usePaymentInputs();
<input {...getCardNumberProps({
onChange: handleCardChange('number'),
onFocus: handleFocus('number'),
placeholder: ''
})}/>
I need to pass all input props using the react-payment-inputs library
I want to wrap this input with the nice TextField label effect.
I cannot see how can I send custom input element with custom props to TextField.
This is for example also not working:
<TextField label="First name"
InputProps={{
input: <input type="text" value={cardInfo.name}
onChange={handleFirstNameChange} onFocus={handleFocus('name')}/>
}}
/>
Here is the codesandbox

Resources