How can I set the value of my MaterialUI TextField to uppercase? - reactjs

I have a Material UI TextField as an input and I need to force the entered text as uppercase. I have tried using textTransform: "uppercase" as part of the style attribute but this does not seem to work. All of the other styling in my component is applied correctly however the textTransform is not.
I have also tried using the standard style method of passing my style as a prop to the component but I get the same result.
My component:
const MenuInput = (props) => {
const useStyles = makeStyles((theme) => ({
input: {
textTransform: "uppercase",
marginTop: "10px",
width: "100%",
borderRadius: 4,
backgroundColor: "#FFFFFF",
},
}));
const classes = useStyles();
return (
<TextField
className={classes.input}
id={props.id}
color="primary"
label={props.label}
variant="filled"
onChange={(e) => props.onChange(e)}
error={props.isError}
helperText={props.error}
/>
);
};
The output:

You could try applying styles through the inputProps like the following:
<TextField
className={classes.input}
id={props.id}
color="primary"
label={props.label}
variant="filled"
onChange={(e) => props.onChange(e)}
error={props.isError}
helperText={props.error}
inputProps={{ style: { textTransform: "uppercase" } }}
/>
I'll leave a link with a sandbox where I tested that solution.

try adding important
textTransform: "uppercase !important"
Or add inline style
<Textfield style={{textTransform:"uppercase"}} />

Related

How to apply maxWidth to TextField component from mui?

I'm trying to apply maxWidth to the TextField from material-ui but it seems like I can't.
import * as React from "react";
import Box from "#mui/material/Box";
import TextField from "#mui/material/TextField";
export default function BasicTextFields() {
const messages = [
{ id: 1, message: "short message" },
{
id: 2,
message: " It comes with three variants: outlined."
},
{
id: 3,
message:
"The TextField wrapper component is a complete form control including a label, input, and help text."
}
];
return (
<Box
component="form"
sx={{
"& > :not(style)": { m: 1, width: "25ch" }
}}
noValidate
autoComplete="off"
style={{ display: "flex", flexDirection: "column" }}
>
{messages.map((e) => (
<TextField
id="outlined-basic"
key={e.id}
value={e.message}
label="Outlined"
variant="outlined"
multiline={true}
style={{ maxWidth: "350px" }}
/>
))}
</Box>
);
}
Currently, the max-width for TextField seems not applying correctly. If I look at TextField with the inspect, it says 200px
I know I can apply regular width like this.
<TextField
id="outlined-basic"
key={e.id}
value={e.message}
label="Outlined"
variant="outlined"
multiline={true}
style={{ width: "350px" }}
/>
But what I want here is maxWidth.
Ideally, I like to have the width of text input based on the message length which I pass to the value property like this value={e.message}.
So before the width hits 350px, width needs to be kind of auto like the width is depends on the message, but once it hits 350px, it will keep being 350px.
Is that possible with the TextField component?
Attampts
I used InputProps proptery.
{messages.map((e) => (
<TextField
id="outlined-basic"
key={e.id}
value={e.message}
label="Outlined"
variant="outlined"
multiline={true}
InputProps={{
style: { maxWidth: "350px" }
}}
/>
))}
But I got width 200px.
if you wrap in an div?
<div style: { width: "400px" }>
<TextField
id="outlined-basic"
key={e.id}
value={e.message}
label="Outlined"
variant="outlined"
multiline={true}
InputProps={{
style: { maxWidth: "350px" }
}}
/>
</div>

How to know height of react material textfield in other component?

I wrote code below to switch TextField and my custom component. But I can't set the height of the custom component with same height as TextField.
What can I do for this situation?
<Grid item xs={12}>
<FormControlLabel
control={<Switch value={toggleView} onChange={e => setToggleView(e.target.checked)} />}
label="view"
style={{position: 'absolute', top: `-4%`, right:'0', zIndex: '9999'}}/>
{
toggleView? <CustomComponent/> :
<TextField
rows="10"
multiline
fullWidth={true}
value={content}
onChange={e => setContent(e.target.value)}
label="content"
/>
}
</Grid>
you can change textFiled height and other properties in various ways like:
the sx prop:
<TextField
sx={{ '& .MuiOutlinedInput-root': { height: '50px' } }} // change height form here
variant="outlined"
/>
Mui styled component way(using emotion)
import { styled } from '#mui/material/styles'
import TextField from '#mui/material/TextField'
export const StyledTextField = styled(TextField)(() => ({
'& .MuiInputBase-root': {
height: 50
}
}))

React JS Material UI Select IconComponent (Dropdown Icon) avoid rotating

By default, in React JS Material UI's Select component, when we provide a custom IconComponent, it gets turned upside down when user has selected the dropdown / Select component.
Sample code:
<Select
multiple
variant="outlined"
MenuProps={CustomMenuProps}
IconComponent={Search}
renderValue={(selected) => (selected as string[]).join(', ')}
{...props}
>
...
I did a sneaky thing to remove "MuiSelect-iconOpen" from the className when calling IconComponent.
Sample Code after my fix:
<Select
multiple
variant="outlined"
MenuProps={CustomMenuProps}
IconComponent={({ className }) => {
className = className.replace("MuiSelect-iconOpen", "")
return <Search className={className} />
}}
renderValue={(selected) => (selected as string[]).join(', ')}
{...props}
>
....
Now is there a better way to do this without replacing the className?
My current solution is to overwrite the original iconOpen class provided by the Material-UI Select.
....
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
iconOpen: {
transform: 'rotate(0deg)',
},
}));
....
export const MyCompo: FC<> = () => {
const classes = useStyles();
return (
<Select
multiple
variant="outlined"
MenuProps={CustomMenuProps}
IconComponent={Search}
classes={{
iconOpen: classes.iconOpen,
}}
renderValue={(selected) => (selected as string[]).join(', ')}
{...props}
>
....
<Select
value={values.phoneCode}
onChange={handleChange("phoneCode")}
inputProps={{ "aria-label": "Without label" }}
IconComponent={(_props) => {
const rotate = _props.className.toString().includes("iconOpen");
return (
<div
style={{
position: "absolute",
cursor: "pointer",
pointerEvents: "none",
right: 10,
height: "15px",
width: "15px",
transform: rotate ? "rotate(180deg)" : "none",
}}
>
<ArrowDown />
</div>
);
}}
>
....
It does not rotate if you use arrow function: IconComponent={()=> <YourIcon/>}

How do I set a width for the TextAreaAutoSize component in Material-UI?

I can't find any info anywhere on how to change the default width of a TextAreaAutosize component in material-ui.
It seems the only choice is to have this little box. Does anyone know of a better text area auto size component I can use, or how to change the width of the TextAreaAutoSize component?
The API doesn't show any properties that have anything to do with 'className'. I tried to use it anyway and it was ignored. I also tried wrapping the component in a Box, and styling that, but it was ignored by the TextArea.
Any help would be greatly appreciated!
Resizing by the user is turned off (via resize: "none") for TextField here in InputBase: https://github.com/mui-org/material-ui/blob/v4.10.2/packages/material-ui/src/InputBase/InputBase.js#L140.
Below is an example of how to turn it back on:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
const useStyles = makeStyles(theme => ({
root: {
"& .MuiTextField-root": {
margin: theme.spacing(1)
}
},
textarea: {
resize: "both"
}
}));
export default function MultilineTextFields() {
const classes = useStyles();
return (
<form className={classes.root} noValidate autoComplete="off">
<div>
<TextField
id="outlined-textarea"
label="Multiline Placeholder"
placeholder="Placeholder"
multiline
variant="outlined"
inputProps={{ className: classes.textarea }}
/>
</div>
</form>
);
}
CSS documentation for resize: https://developer.mozilla.org/en-US/docs/Web/CSS/resize
Multiline TextField demos: https://material-ui.com/components/text-fields/#multiline
You can change the style prop of the TextareaAutosize check here
<TextareaAutosize
rowsMin={3}
placeholder=''
defaultValue=''
style={{ width: "100%" }}
/>
I was able to get it to work thanks to Ryan Cogswell. Stupid me, though I wrapped the textarea in a box and applied className to the box (which didn't work), I should have applied it to the textareaautosize directly.
There's a bug in VSCODE Intellisense where it shows 'classes' as a property but not 'className' so I assumed it didn't exist.
Here's the code:
const FormStyles = makeStyles((theme) => ({
root: {
width: '100%',
},
button: {
marginTop: '20px',
marginRight: theme.spacing(1),
},
buttons: {
display: 'flex',
justifyContent: 'flex-end'
},
textarea: {
width: '100%',
},
}));
<TextareaAutosize
rowsMin={3}
aria-label={info.label}
name={info.name}
placeholder=''
defaultValue=''
className={classes.textarea}
/>
I could not get the drag icon to show up in textfield, so didn't use it. But I would appreciate an example of textfield using multiline and resizing.
Thanks Ryan!
Here's the trick I used. I wrapped it in a flex container and used align-items to stretch the width to cover the size of that container.
<Stack
direction="column"
justifyContent="center"
alignItems="stretch"
spacing={2}
>
<TextareaAutosize
label='Title'
value={pub.title || ''}
onChange={(e) => pub.title = e.target.value}
variant='outlined'
sx={{m: 1}}
size='small'
/>
</Stack>

Material UI - Autocomplete Styling

I am trying to style the padding so that the icon is pushed to the far right side in an AutoComplete Material UI component which is currently being overridden by this style:
.MuiAutocomplete-hasPopupIcon.MuiAutocomplete-hasClearIcon .MuiAutocomplete-inputRoot[class*="MuiOutlinedInput-root"]
This is the code:
const useStyles = makeStyles(theme => ({
inputRoot: {
color: "blue",
fontFamily: "Roboto Mono",
backgroundColor: fade("#f2f2f2", 0.05),
"& .MuiOutlinedInput-notchedOutline": {
borderWidth: '2px',
borderColor: "blue"
},
"&:hover .MuiOutlinedInput-notchedOutline": {
borderWidth: "2px",
borderColor: "blue"
},
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderWidth: "2px",
borderColor: "blue"
}
}
}));
const textStyles = makeStyles({
formControlRoot: {
fontFamily: "Roboto Mono",
width: "50vw",
color: "#ffffff",
borderRadius: "7px",
position: "relative",
"& label.Mui-focused": {
color: "blue"
},
},
inputLabelRoot: {
color: "#ffffff",
fontFamily: "Roboto Mono",
"&.focused": {
color: "#ffffff"
}
},
});
export default function ComboBox() {
const classes = useStyles();
const textClasses = textStyles();
return (
<Autocomplete
id="combo-box-demo"
classes={classes}
// options={top100Films}
getOptionLabel={option => option.title}
renderInput={params => {
return (
<TextField
{...params}
label="Combo box"
variant="outlined"
classes={{ root: textClasses.formControlRoot }}
fullWidth
InputProps={{
...params.InputProps,
endAdornment: (
<InputAdornment position="end">
<SearchIcon />
</InputAdornment>
)
}}
InputLabelProps={{ classes: {root: textClasses.inputLabelRoot}}}
/>
);
}}
/>
);
}
And this is the result:
You are specifying the endAdornment for the Input, but Autocomplete also tries to specify the endAdornment. Your endAdornment is winning, but the Autocomplete is still trying to apply all of the CSS related to its end adornment (space for the popup icon and clear icon).
You can turn off the CSS related to the Autocomplete's end adornment by passing the props that turn off those features:
<Autocomplete
disableClearable
forcePopupIcon={false}
v4 CodeSandbox: https://codesandbox.io/s/autocomplete-with-custom-endadornment-86c87?file=/src/App.js
v5 CodeSandbox: https://codesandbox.io/s/autocomplete-with-custom-endadornment-euzor?file=/src/App.js
Alternatively, if you want to keep the clear icon and/or force-popup icon (arrow-drop-down icon), you can leverage cloneElement to add the search icon to the existing end adornment as shown below.
import React from "react";
import Autocomplete from "#mui/material/Autocomplete";
import TextField from "#mui/material/TextField";
import SearchIcon from "#mui/icons-material/Search";
import { styled } from "#mui/material/styles";
const StyledSearchIcon = styled(SearchIcon)`
vertical-align: middle;
`;
function addSearchIconToEndAdornment(endAdornment) {
const children = React.Children.toArray(endAdornment.props.children);
children.push(<StyledSearchIcon />);
return React.cloneElement(endAdornment, {}, children);
}
export default function ComboBox() {
return (
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={(option) => option.title}
renderInput={(params) => {
return (
<TextField
{...params}
label="Combo box"
variant="outlined"
fullWidth
InputProps={{
...params.InputProps,
endAdornment: addSearchIconToEndAdornment(
params.InputProps.endAdornment
)
}}
/>
);
}}
/>
);
}

Resources