bbrinck
bbrinck

Reputation: 1103

React Material <Select> with regular HTML <input> or <select>

Is it possible to use regular HTML or with React Material ?

I want to use the Material Select, but that it uses my or .

I know you have the input property, but I don't get it to work.

<Select
            labelId="demo-customized-select-label"
            id="demo-customized-select"
            variant="outlined"
            className="form-control"
            input={<input />} // or <select>
          >
            {clientAppContext.currentProfile?.profiles?.map((profile: Profile) => (
              <MenuItem key={profile.number} value={profile.number}>
                <div className="flex flex-col">
                  <span className="text-gray-900 text-sm">{profile.name}</span>
                  <span className="font-light text-gray-700 text-xs">{profile.name} - {profile.number}</span>
                </div>
              </MenuItem>
            ))}
          </Select>

Upvotes: 0

Views: 151

Answers (1)

Terminat
Terminat

Reputation: 1237

I checked it, and the only way to make it work out of a box is to use Input provided by Material UI. With native HTML input element it's not possible, because it doesn't know what to do with the props that the Select is providing.

However, you can create a wrapper around this native input. The Select component will inject all the props you need to create your own custom dropdown.

Check this example I created. Sorry for not styling it properly, but I wanted to focus on making it work.

Remember to set native prop to false. Otherwise, it will not allow you to control if it's open or not.

App.js

import React, { useState } from 'react';

import Select from '@material-ui/core/Select';
import MenuItem from '@material-ui/core/MenuItem';
import Input from './Input';

function App() {
  const [age, setAge] = useState(10);
  const [isOpen, setIsOpen] = useState(false);
  console.log(isOpen);

  const handleChange = (event) => {
    setAge(event.target.value);
  }
  return (
    <div className="App">
      <Select
        labelId="demo-simple-select-label"
        id="demo-simple-select"
        value={age}
        onChange={handleChange}
        style={{ width: 500 }}
        native={false}
        open={isOpen}
        inputComponent="input"
        inputProps={{ onClick: () => setIsOpen(true), onBlur: () => setIsOpen(false) }}
        input={<Input />}
      >
        <MenuItem value={50}>
          <div className="flex flex-col">
            <span className="text-gray-900 text-sm">My name</span>
            <span className="font-light text-gray-700 text-xs">My name - 12</span>
          </div>
        </MenuItem>
        <MenuItem value={50}>
          <div className="flex flex-col">
            <span className="text-gray-900 text-sm">My name</span>
            <span className="font-light text-gray-700 text-xs">My name - 13</span>
          </div>
        </MenuItem>
        <MenuItem value={50}>
          <div className="flex flex-col">
            <span className="text-gray-900 text-sm">My name</span>
            <span className="font-light text-gray-700 text-xs">My name - 14</span>
          </div>
        </MenuItem>
      </Select>
    </div>
  );
}

export default App;

Custom Input Element - Wrapper around native HTML element

import React, { useState } from 'react';


function Input(props) {
  console.log(props);

  return (
    <>
      <input value={props.inputProps.value} onClick={props.inputProps.onClick} onBlur={props.inputProps.onBlur} />
      {props.inputProps.open ? props.inputProps.children : null}
    </>

  );
}

export default Input;

Upvotes: 1

Related Questions