How can i change TextField border-radius in Mui - javascript

I am trying to change mui TextField border radius but it's not working. Can anyone help me to solve this problem.
Here is my code:
<TextField variant="outlined" sx={{ borderRadius: 5 }} />
Can anyone fix it this?

override MuiOutlinedInput-root clasee
sx={{
".MuiOutlinedInput-root": {
borderRadius: 5
}
}}

Try this
<TextField
className="inputRounded"
placeholder="Search"
variant="outlined"
size="small"
/>
</div>

If you are looking for a more generic solution for all the textfields you can set the borderRadius for the Textfield in yourr theme. So you don't have to add and repeat the sx property on each one.
Here is the code in your theme file:
export const theme = createTheme({
components: {
MuiTextField: {
styleOverrides: {
root: {
'& .MuiOutlinedInput-root': {
borderRadius: 5,
},
},
},
}
}
});
Or you can create a styled component like this:
import styled from "styled-components";
import { TextField } from "#mui/material";
export const InputStyled = styled(TextField)`
& .MuiOutlinedInput-root {
border-radius: 10px;
}
`;
//Use it like this:
<InputStyled label="email" variant="standard" />

Related

Adding an endAdornment to the #mui/material TextField component breaks its custom styling

I used the CSS Validation Style TextField from this example https://mui.com/material-ui/react-text-field/#customization and simply added an endAdornment to it. Now the custom styling is completely ignored. Do I have to add something in addition or is this just broken?
import * as React from "react";
import { styled } from "#mui/material/styles";
import Box from "#mui/material/Box";
import TextField from "#mui/material/TextField";
import { IconButton } from "#mui/material";
import ClearIcon from "#mui/icons-material/Clear";
const ValidationTextField = styled(TextField)({
"& input:valid + fieldset": {
borderColor: "green",
borderWidth: 2
},
"& input:invalid + fieldset": {
borderColor: "red",
borderWidth: 2
},
"& input:valid:focus + fieldset": {
borderLeftWidth: 6,
padding: "4px !important" // override inline-style
}
});
export default function CustomizedInputs() {
return (
<Box
component="form"
noValidate
sx={{
display: "grid",
gridTemplateColumns: { sm: "1fr 1fr" },
gap: 2
}}
>
<ValidationTextField
label="CSS validation style"
required
variant="outlined"
defaultValue="Success"
id="validation-outlined-input"
/>
<ValidationTextField
label="CSS validation style"
required
variant="outlined"
defaultValue="Success"
id="validation-outlined-input"
InputProps={{
endAdornment: (
<>
<IconButton>
<ClearIcon />
</IconButton>
</>
)
}}
/>
</Box>
);
}
I did experiment with what exactly breaks it and I found that I can add normal HTML Elements in the endAdornment and it works fine, but when I add a mui component like the IconButton it breaks.

How to override MUI 5 input label background color for custom component

I've been struggling on how to override the background color for a MUI 5 input label on focus for a specific component. I was able to override the background color and set it to blue in my _theme.js file but this change is global. Does anyone know how I would override this and make the background color red for my KeywordSearchTextField in my index.js file following MUI 5 best practice? Any help is greatly appreciated! Please see my sandbox at https://codesandbox.io/s/mui-5-styling-uqt9m?file=/pages/index.js . Code snippet below...
import Box from "#mui/material/Box";
import TextField from "#mui/material/TextField";
import Autocomplete from "#mui/material/Autocomplete";
import { styled, createTheme, useTheme } from "#mui/material/styles";
const styles = {
baseBoxStyle: {
maxWidth: "350px",
margin: "20px",
padding: "10px"
}
};
const KeywordSearchContainer = styled("div")(() => ({}));
const KeywordSearchTextField = styled(TextField)(() => ({}));
const keywordOptions = [
{ label: "Generic keyword 1", value: "Generic keyword 1" },
{ label: "Generic keyword 2", value: "Generic keyword 2" },
{ label: "Generic keyword 3", value: "Generic keyword 3" }
];
export default function Index() {
return (
<Box sx={{ ...styles.baseBoxStyle }}>
<KeywordSearchContainer>
<Autocomplete
id="free-solo-demo"
options={keywordOptions.map((option) => option.label)}
renderInput={(params) => (
<KeywordSearchTextField
{...params}
label="freeSolo"
InputLabelProps={{
classes: {
focused: "focused"
}
}}
/>
)}
/>
</KeywordSearchContainer>
</Box>
);
}```
Add your styles to a targeted nested class (componet-slot combo) like so:
See also my forked codesandbox
<KeywordSearchTextField
{...params}
sx={{
'& .MuiInputBase-input:focus': {
backgroundColor: 'red',
},
}}
label="freeSolo"
InputLabelProps={{
classes: {
focused: 'focused',
},
}}
/>

How to use multiple CSS classes with MUI 5 SX prop?

Does anyone know how to use multiple CSS classes with MUI 5 SX prop? I created a base class that I want to use with my Box components but use a second class specifically for the text inside of the Box. Applying base class, such as sx={styles.baseBoxStyle} works but sx={styles.baseBoxStyle styles.customBoxFontStyle} returns an error. Full code snippet and sandbox provided below. Any assistance is greatly appreciated!
Sandbox: https://codesandbox.io/s/mui-5-styling-uqt9m?file=/pages/index.js
import * as React from "react";
import Box from "#mui/material/Box";
const styles = {
baseBoxStyle: {
backgroundColor: "red",
borderRadius: "20px 20px 20px 20px",
border: "1px solid black",
maxWidth: "150px",
margin: "20px",
padding: "10px"
},
customBoxFontStyle: {
color: "yellow",
fontWeight: "bold"
}
};
export default function Index() {
return <Box sx={styles.baseBoxStyle styles.customBoxFontStyle}>This is a test</Box>;
}
I had a similar problem and came up with this solution.
<Box sx={[styles.baseBoxStyle, styles.customBoxFontStyle]}>
This is a test
</Box>
https://codesandbox.io/s/sweet-blackwell-oqp9ph?file=/src/App.js:416-517
For a simple solution, can deconstruct the style objects and compile into one object.
<Box sx={{...styles.baseBoxStyle,...styles.customBoxFontStyle}}>This is a test</Box>
If you want combine 2 calsses, and you get one of them as props you should work like this
const componnent = (styles) => {
return (
<ListItem
sx={[
{
width: 'auto',
textDecoration: 'underline',
},
...(Array.isArray(styles) ? styles : [styles]),
]}
/>
)
}
You cannot spread sx directly because SxProps (typeof sx) can be an array
You can try to use classnames as its commonly used library, or you can just make string from these styles that you pass into sx sx={styles.baseBoxStyle+' '+styles.customBoxFontStyle}
I think you cant use sx with classes. I have not seen any example in documentation.
To build on Aleksander's answer, there is a section about merging sx in MUI official documentation.
import * as React from 'react';
import ListItem from '#mui/material/ListItem';
import FormLabel from '#mui/material/FormLabel';
import { SxProps, Theme } from '#mui/material/styles';
interface ListHeaderProps {
children: React.ReactNode;
sx?: SxProps<Theme>;
}
function ListHeader({ sx = [], children }: ListHeaderProps) {
return (
<ListItem
sx={[
{
width: 'auto',
textDecoration: 'underline',
},
// You cannot spread `sx` directly because `SxProps` (typeof sx) can be an array.
...(Array.isArray(sx) ? sx : [sx]),
]}
>
<FormLabel sx={{ color: 'inherit' }}>{children}</FormLabel>
</ListItem>
);
}
export default function PassingSxProp() {
return (
<ListHeader
sx={(theme) => ({
color: 'info.main',
...theme.typography.overline,
})}
>
Header
</ListHeader>
);
}

Input text overlapping in TextField multiline area of Material-UI

The input text in a Material-UI Multiline TextField is overlapping each other (not the label).
See sample and code in CodeSandBox: https://codesandbox.io/s/keen-wu-yquk6
I suspect it may have something to do with the fact that I increased the Font-Sized to 30, but the line-height (or something else) remained configured for the default size font.
Samples screenshots:
import React from "react";
import styled from "styled-components";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
const useStyles = makeStyles(theme => ({
container: {
display: "flex",
flexWrap: "wrap"
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 350
}
}));
const StyledTextField = styled(TextField)`
.MuiInput-underline::before {
border-bottom-color: white;
}
.MuiInput-underline:hover:not(.Mui-disabled)::before {
border-bottom-color: white;
}
.MuiInput-underline::after {
border-bottom-color: #fdcd39;
}
`;
const StyledTextArea1 = ({ Label, fieldType, handleChange }) => {
const classes = useStyles();
return (
<StyledTextField
id="standard-basic"
className={classes.textField}
label="Test Label"
multiline
fullWidth
rows="5"
variant="outlined"
margin="normal"
// onChange={handleChange(fieldType)}
InputLabelProps={{
style: {
color: "black",
fontSize: 30,
borderBottom: "white",
fontFamily: "Akrobat"
}
}}
inputProps={{
style: {
fontSize: 30,
color: "#fdcd39",
fontFamily: "Akrobat",
fontWeight: 800
}
}}
/>
);
};
export { StyledTextArea1 };
Any assistance greatly appreciated.
Setting the font styles via inputProps defines those styles on the textarea element whereas Material-UI controls the font size on a div (with the MuiInputBase-root CSS class) that wraps the textarea. If you move where you control the font styles to target .MuiInputBase-root, it works as desired.
import React from "react";
import styled from "styled-components";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
const useStyles = makeStyles(theme => ({
container: {
display: "flex",
flexWrap: "wrap"
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 350
}
}));
const StyledTextField = styled(TextField)`
.MuiInputBase-root {
font-size: 30px;
color: #fdcd39;
font-family: Akrobat;
font-weight: 800;
}
.MuiInput-underline::before {
border-bottom-color: white;
}
.MuiInput-underline:hover:not(.Mui-disabled)::before {
border-bottom-color: white;
}
.MuiInput-underline::after {
border-bottom-color: #fdcd39;
}
`;
const StyledTextArea1 = ({ Label, fieldType, handleChange }) => {
const classes = useStyles();
return (
<StyledTextField
id="standard-basic"
className={classes.textField}
label="Test Label"
defaultValue="Default Value"
multiline
fullWidth
rows="5"
variant="outlined"
margin="normal"
// onChange={handleChange(fieldType)}
InputLabelProps={{
style: {
color: "black",
fontSize: 30,
borderBottom: "white",
fontFamily: "Akrobat"
}
}}
/>
);
};
export { StyledTextArea1 };
In my sandbox, I also added <StylesProvider injectFirst> around everything in index.js to ensure that the styled-components CSS classes are injected after the Material-UI CSS classes in the <head> so that your style overrides via styled-components will win in cases where specificity is the same.

Warning: Prop `className` did not match ~ Material UI css arbitrarily breaks on reload

Video reproducing the error/missing css
I know there are already dated versions of this question on stack overflow, like React + Material-UI - Warning: Prop className did not match.
However, when I attempt to google and research people's solutions, there is just no clear answer. Any answers I could find don't match my stack.
My stack:
Node JS
Next JS
Material UI
And from what I could glean from answers to questions like next.js & material-ui - getting them to work is that there is some measure of incompatibility when it comes to Next JS and Material UI.
Code-wise, here is my Appbar component. Initially I was not exporting my useStyles object, but I ended up doing it in a pitiful attempt to follow along with Material UI's express guide to "server rendering". There has to be a fix that doesn't involve changing like every file I have.
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import IconButton from '#material-ui/core/IconButton';
import Typography from '#material-ui/core/Typography';
import InputBase from '#material-ui/core/InputBase';
import { fade } from '#material-ui/core/styles/colorManipulator';
import { makeStyles } from '#material-ui/core/styles';
import MenuIcon from '#material-ui/icons/Menu';
import SearchIcon from '#material-ui/icons/Search';
import {connectSearchBox} from 'react-instantsearch-dom';
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
flexGrow: 1,
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block',
},
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(1),
width: 'auto',
},
},
searchIcon: {
width: theme.spacing(7),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
},
inputInput: {
padding: theme.spacing(1, 1, 1, 7),
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: 300,
'&:focus': {
width: 400,
},
},
}
}));
function SearchBox({currentRefinement, refine}){
const classes = useStyles();
return(
<InputBase
type="search"
value={currentRefinement}
onChange={event => refine(event.currentTarget.value)}
placeholder="Search by state, park name, keywords..."
classes = {{
root: classes.inputRoot,
input: classes.inputInput,
}}
/>
)
}
const CustomSearchBox = connectSearchBox(SearchBox);
function SearchAppBar() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="static" color="primary">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="Open drawer"
>
<MenuIcon />
</IconButton>
<Typography className={classes.title} variant="h6" noWrap>
Title
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<CustomSearchBox/>
</div>
</Toolbar>
</AppBar>
</div>
);
}
export {SearchAppBar, useStyles};
I was just digging around random parts of the internet looking for answers to this error, accidentally npm install'ed styled-components as part of this answer on a Github issue (because they have a very similar object to the counterpart in Material UI called ServerStyleSheet (vs Material UI's ServerStyleSheets), so obviously that didn't work.
BUT......... I ended up just using the ServerStyleSheet fix to try to make it agreeable with Material UI's ServerStyleSheets object, and ended up with this new _document.js.
I'm still dumbfounded I was able to refactor an entirely different fix to make this work but I tested it and it fixes the problem entirely, now reloads are fine.
import Document, { Html, Head, Main, NextScript } from 'next/document';
import {ServerStyleSheets} from "#material-ui/styles";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
try{
ctx.renderPage = () => originalRenderPage({
enhanceApp: App => props => sheet.collect(<App {...props}/>)
});
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
)
}
} finally {
ctx.renderPage(sheet)
}
}
render() {
return (
<Html>
<Head>
<link rel="shortcut icon" type="image/png" href="../static/favicon.ico"/>
<style>{`body { margin: 0 } /* custom! */`}</style>
<meta name="viewport"content="width=device-width, initial-scale=1.0" />
</Head>
<body className="custom_class">
<Main />
<NextScript />
</body>
</Html>
)}
}
export default MyDocument;
If you wanna see how crazy it was that it worked, here is the fix for the same error in styled-components:
export default MyDocument;
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
export default class MyDocument extends Document {
static async getInitialProps (ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
)
}
} finally {
sheet.seal()
}
}
}
I hope this helped someone with the mess that is Material-UI + Next.js
For my part, adding { name: "MuiExample_Component" } in the makeStyle hook works for some reason. I found this solution while digging on internet. I would appreciate if someone could tell me if it's a good solution or not, but here is the code :
const useStyles = makeStyles({
card: {
backgroundColor: "#f7f7f7",
width: "33%",
},
title: {
color: "#0ab5db",
fontWeight: "bold",
},
description: {
fontSize: "1em"
}
}, { name: "MuiExample_Component" });

Categories