I'm using MUI v5, together with Gatsby Image. I'm hoping to keep my styling syntax consistency across the application so I tried to add the sx
prop to GatsbyImage
.
This is what I've tried:
<Box
ponent={GatsbyImage}
sx={/* my sx styles */}
/>
This does what I want. Yet, I noticed the sx
prop somehow gets passed to the img
. This ends up getting a <img sx=[object Object]/>
in my HTML.
Although this doesn't really affect my application in anyways, I'm wondering are there better ways to achieve this?
I'm using MUI v5, together with Gatsby Image. I'm hoping to keep my styling syntax consistency across the application so I tried to add the sx
prop to GatsbyImage
.
This is what I've tried:
<Box
ponent={GatsbyImage}
sx={/* my sx styles */}
/>
This does what I want. Yet, I noticed the sx
prop somehow gets passed to the img
. This ends up getting a <img sx=[object Object]/>
in my HTML.
Although this doesn't really affect my application in anyways, I'm wondering are there better ways to achieve this?
Share Improve this question edited Oct 19, 2021 at 4:41 Ferran Buireu 29.3k7 gold badges46 silver badges72 bronze badges asked Oct 19, 2021 at 1:02 Matthew KwongMatthew Kwong 2,9572 gold badges15 silver badges25 bronze badges 1- Does my answer solve your problem? – NearHuscarl Commented Oct 28, 2021 at 16:29
3 Answers
Reset to default 7You can use the styled
function to add the sx
prop to your custom ponent like this:
import { styled } from "@mui/material/styles";
const ComponentWithSx = styled(YourCustomComponent)();
<ComponentWithSx
sx={{
width: 30,
height: 30,
backgroundColor: "primary.dark"
}}
/>
When you pass the GatsbyImage
to the ponent
prop of Box
, GatsbyImage
is used as the root ponent inside Box
, and the sx
object is passed to the DOM element:
function Box(props) {
const { ponent, ...other /* other includes sx prop */ } = props;
return <ponent {...other} />;
});
If you want to use Box
you need to create a wrapper ponent to filter the sx
prop:
function MyGatsbyImage({ sx, ...props }) {
return <GatsbyImage {...props} />;
}
For anyone trying to style a custom ponent, I did it this way:
Use the materialUI styled function, like so:
import { styled } from '@mui/material/styles';
import Star from '../ponents/Star'; //my custom ponent
[...]
const StarStyled = styled(Star)({ position: 'absolute', right: 5, bottom: 5 });
Then, in your render function, call your newly-styled ponent:
<StarStyled />
Now, your custom ponent (in this case, the ponent "Star") will receive a className prop, so you can use the prop like so:
const Star = ({className}) => {
return (
<span className={className}>
...whatever else you want your ponent to do
</span>
);
};
export default Star;
Thanks to @Garrett for pointing me in the right direction. I didn't want to have to call styled()
every time I used my ponent, though. So I encapsulated that detail in the ponent itself:
import Typography from '@mui/material/Typography';
import { styled } from "@mui/system";
function Para({ className, children, ...props }) {
return (
<Typography
variant='body1'
className={className}
sx={{ color: "red", ml: 5 }}
{...props}
>
{children}
</Typography>
)
}
const StyledPara = styled(Para)``;
export default StyledPara;
Now, using sx
to style my custom ponent is just as easy as it would be with one of the built-in MUI ponents:
import Para from './Para';
<Para sx={{ color: "rebeccapurple" }}>
Your mother was a hamster, and your father smelt of elderberries!
</Para>
I'm able to provide default sx
style inside the ponent which I want to be applied to every instance. Fortunately, this is overridden by style applied to an instance of the pmonent. In this case, I'll get a purple paragraph indented 40px (5 ✕ 8px) from the left. Any other props are passed through to Typography
.
Also, note that the empty ``
are required after the styled()
call. Interesting syntax, which you can learn more about in this SO answer.