MUI TextField sx props does not apply styles - html

I'm trying to style a TextField component in a one-off fashion using the sx prop:
<TextField
size="small"
sx={{
padding: '1px 3px',
fontSize: '0.875rem',
lineHeight: '1.25rem',
}}
{...params}
/>
I'm using MUI v5. If I inspect the input element, the styles are not applied. What am I missing?
UPDATE: it seems the styles are actually added to the wrapper element via its generated class. But I need to style the input element.
I've also tried using inputProps, but that did nothing at all.

You can style the constituent components by targeting their classes directly through sx. For example:
<TextField
label="My Label"
defaultValue="My Value"
size="small"
sx={{
".MuiInputBase-input": {
padding: '1px 3px',
fontSize: '0.875rem',
lineHeight: '1.25rem',
}
}}
/>
Working CodeSandbox: https://codesandbox.io/s/customizedinputs-material-demo-forked-jog26e?file=/demo.js

What you can use is the inputProps prop. This lets you pass the sx prop as a regular object down to the input component. For example:
<TextField
size="small"
inputProps={{
sx: {
padding: '1px 3px',
fontSize: '0.875rem',
lineHeight: '1.25rem'
}
}}
/>
Docs here: https://mui.com/material-ui/api/text-field/#props

Related

Why are properties in Material UI CSS classes overriding properties in custom CSS?

I was trying to use a npm package which has a Typography element from Material UI. This is written by me.
When I try to use it in a project, the typography css class properties override the custom css properties. An example is margin which is present in both the CSS classes but in some scenarios I see the margin of "MuiTypography-h1" overriding the custom css. How do I prevent this?
My general idea is custom CSS properties should always take precedence over MUI default CSS class properties. How can I make this happen ?
<Typography
variant="h1"
sx={{
width: '235px',
height: '96px',
fontSize: '20px',
fontWeight: 500,
lineHeight: '1.2',
color: 'primary',
textOverflow: 'ellipses',
overflow: 'hidden',
display: '-webkit-box',
WebkitLineClamp: 4,
WebkitBoxOrient: 'vertical',
marginTop: '11px',
}}
>
Title
</Typography>
Straight forward way to do: 🚀
you can directly override the MUI component with your custom CSS properties using the class name in your CSS file, for example in if you want to change the Button component's style, you can do this by applying your required CSS properties to "css-element-class-name" class on your "CSS" file as follows
.css-elemet-class-name{
color: yellow;
height: 25px;
padding: 15px;
}
I've found that, MUI theme should be created in order to override MUI--root properties with your css styles, so try somethins like this:
add your custome styles inside overrides:{}
const theme = createTheme({
overrides: {
MuiTypography: {
h1: {
'&.MuiTypography-gutterBottom': {
marginBottom: 7,
},
},
h2: {
marginBottom: props => (props.gutterBottom ? 20 : null),
},
},
},
});
and for the imports
import createtheme from '#material-ui/core/styles'
if you are using this version:
"#material-ui/styles": "^4.11.2",

How to make select list appear over another element?

I am building a project based on this React Template.
In one of the componenets I have a Select List and under it there's a Card element.
The problem is that when I click on the list the items appear under the card element as you see below:
I had a feeling this was caused by the CSS code of the template itself that configures the card to appear over all other elements.
So what I did is I created a new react project with:
npx create-react-app
And my suspicion was right.
I copied basically the same code:
const selectStyles = {
control: (styles) => ({ ...styles, backgroundColor: "white" }),
option: (styles) => {
return {
...styles,
backgroundColor: "green",
"z-index": -5,
};
},
};
export default class App extends Component {
render() {
return (
<Fragment>
<Select
className="basic-single"
classNamePrefix="select"
defaultValue={colourOptions[0]}
name="color"
options={colourOptions}
styles={selectStyles}
/>
<Card
style={{
position: "absolute",
"background-color": "red",
"z-index": 5,
}}
>
<CardImg
top
width="100%"
src="/assets/318x180.svg"
alt="Card image cap"
/>
<CardBody>
<CardTitle tag="h5">Card title</CardTitle>
<CardSubtitle tag="h6" className="mb-2 text-muted">
Card subtitle
</CardSubtitle>
<CardText>
Some quick example text to build on the card title and make up the
bulk of the card's content.
</CardText>
<Button>Button</Button>
</CardBody>
</Card>
</Fragment>
);
}
}
And the select items appear ABOVE the card:
The card is colored in red.
CONCLUSION: The problem is caused by the card css code of the template.
As you see, I tried with different configurations with the z-index attribute, but to no avail.
Any idea how to fix this?
The problem is with the z-index and position, whichever content you want to show in the top should have higher z-index value.
Try giving the select dropdown the high values compared to card.
Try removing both css attributes position: absolute and z-index if it is not needed. Position absolute is only used when to need to move the content to wherever you want to the respective relative parent container. So if you are just practicing and not doing design try to remove both.

How can I change the position of this React component to fixed?

I am using the react-particles-webgl npm package to render this webgl canvas:
I want the canvas to take up the entire screen. When I change the position of this element to "fixed" in the Chrome Developer tools it takes up the entire screen. So I went and changed the inline style of the particle field element to <ParticleField style={{ position: "fixed" }} /> But it still says the position is relative in the chrome developer tools. How do I change this?
This means ParticleField may not have style prop. You can either add style as prop for ParticleField, or wrap ParticleField with a div then use style={{position:fixed}} for that div
<div style={{ position: "fixed" }}><ParticleField /></div>
Look at the source of the library you're using. The key part would be the return statement in the component, which is effectively your render:
return (
<scene>
<group ref={group}>
{/* Bounding box that particles exist inside of */}
{showCube && (
<boxHelper>
<mesh name="object">
<meshBasicMaterial
attach="material"
color="white"
blending={AdditiveBlending}
wireframe
transparent
/>
<boxBufferGeometry attach="geometry" args={[r, r, r]} />
</mesh>
</boxHelper>
)}
{/* Lines connecting particles */}
{lines.visible && (
<lineSegments
geometry={lineMeshGeometry}
material={lineMeshMaterial}
/>
)}
{/* Particles */}
{particles.visible && (
<points geometry={pointCloudGeometry} material={pointMaterial} />
)}
</group>
</scene>
);
I would target <scene style={{ position:fixed; }}> based on what I see here. Another option might be to feed it through something like styled-components as an HOC.

How to align horizontal icon and text in MUI

I am a newbie in MUI, now my icon and text are not aligned:
My desired results:
My code is:
<div style={{
display: 'inline-flex',
VerticalAlign: 'text-bottom',
BoxSizing: 'inherit',
textAlign: 'center',
AlignItems: 'center'
}}>
<LinkIcon className={classes.linkIcon} />
revolve
</div>
I tried grid and row, but not work. Can anyone help me?
This works perfectly!
<div style={{
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
}}>
<LinkIcon />
<span>revolve</span>
</div>
You need to use Grid.
Something like that should works:
<Grid container direction="row" alignItems="center">
<Grid item>
<LinkIcon className={classes.linkIcon} />
</Grid>
<Grid item>
revolve
</Grid>
</Grid>
This can be easily achieved in MUI v5 by using a Stack and set alignItems prop to center:
import Stack from '#mui/material/Stack';
import Typography from '#mui/material/Typography';
import AddCircleIcon from '#mui/icons-material/AddCircle';
<Stack direction="row" alignItems="center" gap={1}>
<AddCircleIcon />
<Typography variant="body1">text</Typography>
</Stack>
Try the below code. You can use variant as per your requirement.
const useStyles = makeStyles(theme => ({
wrapIcon: {
verticalAlign: 'middle',
display: 'inline-flex'
}
}));
<Typography variant="subtitle1" className={classes.wrapIcon}>
<LinkIcon className={classes.linkIcon} /> revolve
</Typography>
alternative simple solution
<Grid container direction="row" alignItems="center">
<SearchIcon /> example
</Grid>
styles
const styles = theme => ({
icon: {
position: "relative",
top: theme.spacing.unit,
width: theme.typography.display1.fontSize,
height: theme.typography.display1.fontSize
}
});
JSX
<Typography variant="display1">
<Icon className={this.props.classes.icon}/>Your Text
</Typography>
you could replace display1 with display3 or another typography variant in all 3 places to choose your text size. The ensures that your text doesn't break between words when it wraps.
For me this can render to look like this
with display3 and a few other styles added for color.
Having ListItemIcon and ListItemText wrapped inside a ListItem will keep it in one line and prevent breaking:
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
<ListItem >
<ListItemIcon><AccessAlarmIcon color="secondary" /></ListItemIcon>
<ListItemText>Updated 1 hour ago</ListItemText>
</ListItem>
Demo image:
You can also use Material UI's Flexbox component.
For example:
// ...
import { Box } from '#material-ui/core';
// ...
<Box alignItems="center" display="flex">
<Box>
<LinkIcon className={classes.linkIcon} />
</Box>
<Box>
revolve
</Box>
</Box>
The alignItems: center attribute will vertically align the inner items.
This will add some additional markup. However, if you look at the component's API there's a lot of additional flexibility. Such as
for example a method to use margin or padding that's consistent with the rest of your Material UI implementation. Also it's really easy to align the items differently if the use-case should occur.
You can import these on top
import { Grid, Typography } from "#material-ui/core";
import LinkIcon from "#material-ui/icons/Link";
You can use
<Grid style={{ display: "flex" }}>
<LinkIcon />
<Typography>Revolve</Typography>
</Grid>
Sample Sandbox Example Here
If you are trying to vertical align text and icon within MUI's Typography without using variant, you can simply add a display setting to Typography as follows:
<Typography display="flex">
Welcome!
<Icon />
</Typography>
This is what worked for me.
Same problem here, this is what I did.
import LinkIcon from '#material-ui/icons/Link';
import styled from 'styled-components';
...
const Resolve = styled.div`
display: flex;
vertical-align: middle,
`;
<Resolve>
<LinkIcon style={{ marginRight: '5px' }} />
<p>resolve</p>
</Resolve>
If you aren't happy with mUI default link icon you can always DIY:
{/* this is the same chained icon used in the own material-ui,
idk why this ins't avaiable yet */}
function CustomLinkIcon(props) {
return (
<SvgIcon {...props}>
<path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" />
</SvgIcon>
);
}
...
<Resolve>
<CustomLinkIcon
{/* adjust margin top if needed */}
style={{ marginRight: '3px', marginTop: '3px' }} {
/>
<p>resolve</p>
</Resolve>
the best option is to use it like that :
import {Box, Typography} from '#material-ui/core'
import LinkIcon from '#material-ui/icons/LinkIcon';
........
<Box display='flex' alignItems='center'>
<LinkIcon className={classes.linkIcon} />
<Typography variant='h5'>
resolve
</Typography>
</Box>
With this solution the icon will inherit your typography, it prevents having to re-write the style when changin
<Typography component={Stack} direction="row" alignItems="center" color="secondary">
<EditIcon fontSize="inherit" sx={{ marginRight: 1 }} />
Edit
</Typography>
We can use Typography to make align horizontal spacing with icon
const styles = theme => ({
icon: {
fontSize: '1rem',
position: 'relative',
right: theme.spacing(0.5),
top: theme.spacing(0.5),
},
});
<Typography><CheckCircleIcon className={className={this.props.classes.icon}}/>Home</Typography>
I have seen all the solutions. But here is the simplest I believe :-):
<Typography><LinkIcon sx={{verticalAlign:"middle"}}/> RESOLVE</Topography>
It also works with inline image when you want the image align with the text.

Material-ui v1 tabs label wrap bug

Using Material UI #next v1.0.0 beta 32:
Tabs labels wrap as expected on smaller devices.
But the wrapping makes them change font-size, which in turn, in some screen width removes the need for the text to wrap.
So I end up with this: tabs with non-wrapped labels and different font sizes.
sandbox example: https://codesandbox.io/s/o7worrr32q
In order to see the described result make the window narrow enough for at least 1 tab label to wrap, but not all.
I' have overriddeen the wrapped styles this way:
<Tab
value={value}
label='my label'
classes={{
root: classes.tab,
rootPrimarySelected: classes.selected,
labelWrapped: classes.labelWrapped
}}
/>
and my style:
labelWrapped: {
fontSize: '0.875rem'
},
The problem as illustrated in this gif animation, is that as you click on other tabs, the text wraps and unwraps alternatively, seemingly without reason.
My guess is that a padding changes somewhere, but I can't figure it out.
It was easier than I thought in the end:
I only had to use the MUI provided css override labelWrapped, as documented in the MUI API:
<Tab
aria-label="aria description"
label="Wrapping Label"
icon={<Icon />}
value={x}
classes={{
root: classes.root,
labelContainer: classes.labelContainer,
rootInheritSelected: classes.rootInheritSelected,
labelWrapped: classes.labelWrapped,
}}
component={Link}
to={{
pathname: '/my/router/url',
search: this.props.location.search,
}}
/>
and my overriding styles:
const styles = theme => ({
root: {
minWidth: 60,
height: '100%',
color: 'rgba(255,255,255,0.5)',
alignItems: 'flex-start',
paddingBottom: 5,
wordWrap: 'break-word',
flex: 1,
overflowWrap: 'break-word',
textAlign: 'center',
},
labelContainer: {
paddingLeft: 0,
paddingRight: 0,
},
rootInheritSelected: {
color: '#FFF',
},
labelWrapped: {
fontSize: '0.875rem',
},
})