Reputation: 860
I am trying to use Material UI dropdown in my website, using react-select library. The problem is, when I'm using an option longer than the dropdown width, it compromises the UI.
Can anyone please help me out here.
Here is my react code:
import React, { useState } from "react";
import "./styles.css";
import SelectDropdown from "./EditableDropdown";
export default function App() {
const [description, setDesc] = useState("");
const options = [
{
label: "a11 b33 c88 o99 t66 j44 z99",
value: "a11 b33 c88 o99 t66 j44 z99"
},
{
label: "Switches",
value: "Switches"
}
];
return (
<div style={{ width: "25%" }}>
<SelectDropdown
label="Description"
value={description}
onChange={setDesc}
options={options}
/>
</div>
);
}
Here is the code for the Editable component
import React from "react";
import {
MuiThemeProvider,
createMuiTheme,
MenuItem,
Paper,
withStyles,
TextField
} from "@material-ui/core";
import Select from "react-select";
const styles = {
input: {
padding: 0,
marginSides: "8px",
minHeight: "inherit",
lineHeight: "22px",
fontWeight: 200
},
valueContainer: {
alignItems: "center",
fontFamily: "Helvetica Neue,Arial,Helvetica,sans-serif",
fontWeight: 400,
fontSize: "14px !important"
}
};
function inputComponent({ inputRef, ...props }) {
return <div ref={inputRef} {...props} />;
}
function Control(props) {
return (
<TextField
fullWidth
InputProps={{
inputComponent,
inputProps: {
className: props.selectProps.classes.input,
children: props.children,
...props.innerProps
}
}}
{...props.selectProps.textFieldProps}
/>
);
}
function Option(props) {
return (
<MenuItem
buttonRef={props.innerRef}
selected={props.isFocused}
component="div"
style={{
fontWeight: props.isSelected ? 500 : 400,
backgroundColor: props.isSelected
? "rgba(59,234,31,0.2)"
: props.isFocused
? "#F0F0F0"
: null,
fontFamily: "Helvetica Neue,Arial,Helvetica,sans-serif",
height: "34px",
color: "#343434"
}}
{...props.innerProps}
>
{props.children}
</MenuItem>
);
}
function SingleValue(props) {
return (
<div
className={props.selectProps.classes.singleValue}
{...props.innerProps}
>
{typeof props.children !== "object" ? props.children : ""}
</div>
);
}
function ValueContainer(props) {
let valueContainerClass = props.selectProps.classes.valueContainer;
return (
<div className={valueContainerClass} ref={props.inputRef}>
{props.children}
</div>
);
}
function Menu(props) {
return (
<Paper square {...props.innerProps}>
{props.children}
</Paper>
);
}
const dropDownStyle = {
overrides: {
MuiOutlinedInput: {
root: {
padding: "12px 12px 12px 16px !important"
}
},
MuiInputBase: {
root: {
cursor: "pointer"
}
}
}
};
class SelectDropdown extends React.Component {
state = {
focused: false
};
handleTextFieldChange = ({ target: { value } }) => {
this.props.onChange({
label: value,
value
});
};
components = {
Control,
Menu,
Option,
SingleValue,
ValueContainer,
IndicatorSeparator: () => null,
DropdownIndicator: () => null
};
render() {
const { classes, options, onChange, value } = this.props;
const selectStyles = {
clearIndicator: () => ({
display: "none"
}),
noOptionsMessage: () => ({
display: "none"
})
};
return (
<MuiThemeProvider theme={createMuiTheme(dropDownStyle)}>
<Select
styles={selectStyles}
isClearable={true}
classes={classes}
onChange={onChange}
backspaceRemovesValue={true}
textFieldProps={{
label: this.props.label,
variant: "outlined",
InputLabelProps: value ? { shrink: true } : {},
onChange: this.handleTextFieldChange
}}
value={value}
components={this.components}
isSearchable={true}
placeholder=""
options={options}
/>
</MuiThemeProvider>
);
}
}
export default withStyles(styles, { withTheme: true })(SelectDropdown);
and here is a link to same code in a sandbox: https://codesandbox.io/s/editable-dropdown-ckf1r
Upvotes: 1
Views: 1296
Reputation: 2093
I believe you are better off using material-ui
directly instead of EditableDropdown
. Since the latter has limitations.
Also you are better off using a newer version of Material-UI.
Here is a code in Material-UI (V4.9.5) that works just as you want it. If you want to add styling to it, you can always use CSS to
import React from 'react';
import TextField from '@material-ui/core/TextField';
import Autocomplete, { createFilterOptions } from '@material-ui/lab/Autocomplete';
const filter = createFilterOptions();
export default function FreeSoloCreateOption() {
const [value, setValue] = React.useState(null);
return (
<Autocomplete
value={value}
onChange={(event, newValue) => {
if (newValue && newValue.inputValue) {
setValue({
title: newValue.inputValue,
});
return;
}
setValue(newValue);
}}
filterOptions={(options, params) => {
const filtered = filter(options, params);
if (params.inputValue !== '') {
filtered.push({
inputValue: params.inputValue,
title: `Add "${params.inputValue}"`,
});
}
return filtered;
}}
id="free-solo-with-text-demo"
options={top100Films}
getOptionLabel={option => {
// e.g value selected with enter, right from the input
if (typeof option === 'string') {
return option;
}
if (option.inputValue) {
return option.inputValue;
}
return option.title;
}}
renderOption={option => option.title}
style={{ width: 300 }}
freeSolo
renderInput={params => (
<TextField {...params} label="Free solo with text demo" variant="outlined" />
)}
/>
);
}
// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top100Films = [
{ title: 'Raiders of the Lost Ark', year: 1981 },
{ title: 'Rear Window', year: 1954 },
{ title: 'The Pianist', year: 2002 },
{ title: 'The Departed', year: 2006 },
{ title: 'Terminator 2: Judgment Day', year: 1991 },
{ title: 'Back to the Future', year: 1985 },
{ title: 'Whiplash', year: 2014 },
{ title: 'Gladiator', year: 2000 },
{ title: 'Memento', year: 2000 },
{ title: 'The Prestige', year: 2006 },
{ title: 'The Lion King', year: 1994 },
{ title: 'Apocalypse Now', year: 1979 },
{ title: 'Alien', year: 1979 },
{ title: 'Sunset Boulevard', year: 1950 },
{
title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb',
year: 1964,
},
];
Reference: https://material-ui.com/components/autocomplete/ Link to code: https://codesandbox.io/s/gbljf
Let me know if this helps.
Upvotes: 1