Search code examples
javascriptreactjstypescriptmaterial-uireact-tsx

How to render a material-ui input control instead a textfield for materials-ui-datepicker


In my React (v16.3) app I am rendering date-picker controls using material-ui-pickers library's DatePicker component. This component renders a Material-UI TextField component. I like to change this so it renders only a Material-UI Input without the chrome rendered by TextField.

As I understood one can to this with the DatePickers TextFieldComponent field (here at the bottom) but I couldn't figure out how to use this field.

 <DatePicker 
     id={name}
     TextFieldComponent={...<HOW_TO> ...}
     value={value} 
     onChange={this.handleChange}
     disabled={isReadOnly} />

Any ideas how to do this?

Update: Got one step further by finding the right syntax to use and not its rendering without the chrome (FormControl, InputLabel, etc.). But also no DatePicker is opened anymore. Do I have to open it programmatically?

<DatePicker 
    id={name}
    TextFieldComponent={(props) => this.renderInput(props)}
    value={value} 
    onChange={this.handleChange}
    disabled={isReadOnly} />

And here is renderInput():

renderInput(props: TextFieldProps): any {
   return ( <Input
     id={props.id}
     value={props.value}
     onChange={this.handleChange}
     type={'text'}
     disabled={props.disabled}
   /> );
 }

Solution

  • Updated October 2020

    @material-ui/pickers v3.x (latest)

    To render an Input instead of a TextField component, you can pass a custom component to the TextFieldComponent prop on DatePicker.

    You will need to pass along the following props to the Input: value, onChange, and onClick.

    import React, { useState } from "react";
    import { Input, TextFieldProps } from "@material-ui/core";
    import { DatePicker } from "@material-ui/pickers";
    import { MaterialUiPickersDate } from "@material-ui/pickers/typings/date";
    
    export default function Demo() {
      const [selectedDate, setSelectedDate] = useState<MaterialUiPickersDate>(
        new Date()
      );
    
      const renderInput = (props: TextFieldProps): any => (
        <Input
          type="text"
          onClick={props.onClick}
          value={props.value}
          onChange={props.onChange}
        />
      );
    
      return (
        <DatePicker
          label="Basic example"
          value={selectedDate}
          onChange={setSelectedDate}
          TextFieldComponent={renderInput}
        />
      );
    }
    

    Edit Material UI Pickers Example

    @material-ui/pickers v4.0.0-alpha12 (next)

    NOTE: v4 is currently in alpha, so the API might change in the future.

    In V4, you use the renderInput prop on DatePicker to customize the input (see docs). The following example renders a material ui Input instead of a TextField.

    import React, { useState } from "react";
    import { Input, TextFieldProps } from "@material-ui/core";
    import { DatePicker } from "@material-ui/pickers";
    
    export default function Demo() {
      const [selectedDate, setSelectedDate] = useState<Date | null>(new Date());
    
      const renderInput = (props: TextFieldProps): any => (
        <Input
          type="text"
          inputRef={props.inputRef}
          inputProps={props.inputProps}
          value={props.value}
          onClick={props.onClick}
          onChange={props.onChange}
          endAdornment={props.InputProps?.endAdornment}
        />
      );
    
      return (
        <DatePicker
          label="Basic example"
          value={selectedDate}
          onChange={setSelectedDate}
          renderInput={renderInput}
        />
      );
    }
    

    Edit Material UI Pickers v4 Example