Is there anything wrong with using classnames within styled components like so:
export const StyledNav = styled.nav`
background-color: ${({ theme }) => theme.backgroundSecondary};
.logo-container {
width: 201px;
img {
padding: 28px 24.47px 26.78px 24px;
}
}
`;
here I used the classname logo-container rather than making an entire new styled component for that.
You can use nesting and SCSS-like combinations
See their official doc page, and refer to Pseudoelements, pseudoselectors, and nesting section.
It shows an example where, just as your snippet, one component is declared which contains nested selectors and class names.
There's nothing wrong with this approach, and it might actually be more efficient than creating every single element as a styled component.
Related
I am working on a React project (react#18.2.0, styled-components#5.1.1) that has been set up to use styled-components so that commonly used components are exported from a common/styled.js file, but that causes a great amount of invalid hook call errors.
Right now, it looks something like this:
export const ExampleButton = styled.button`
color: white;
`;
And then those styled componets are imported where needed, like this:
import { ExampleButton, SomeComponent, AnotherComponent } from '../common.styled';
I know they invalid hook calls are caused by this export/import setup, because the error message for one particular styled component goes away when I remove it from common/styled.js and instead paste it locally everywhere it's needed, so that instead of this:
import { ExampleButton } from '../common.styled';
const ExampleComponent = () => {
return (
<div>
<ExampleButton>Hello</ExampleButton>
</div>
);
};
I do this:
import styled from 'styled-components';
const ExampleComponent = () => {
const ExampleButton = styled.button`
color: white;
`;
return (
<div>
<ExampleButton>Hello</ExampleButton>
</div>
);
};
So that works, but it's not really a viable solution, because I would have to paste the same code everywhere, not just ExampleComponent, and doing that for the whole project would result in a massive amount of code repetition.
What is the right way to create a solution similar to common/styled.js here in a way that doesn't break the Rules of Hooks?
It seems that there had been an issue between some older versions of styled-components and React 18 that have been solved in v5.3.1.
https://github.com/styled-components/styled-components/pull/3564
Maybe upgrading styled-components to v5.3.1 or higher would solve the issue.
I'm struggling with React error -> React does not recognize zIndex prop on a DOM element.
It happens when I'm using MUI component and Styled with props.
Code example:
styled:
import {Drawer as DrawerBase, styled} from '#material-ui/core'
interface DrawerProps {
zIndex: number
}
export const Drawer = styled(DrawerBase)<Theme, DrawerProps>(({zIndex}) => ({
zIndex
}))
implementation:
<Drawer zIndex={10} />
I'm using:
"#material-ui/core": "^4.12.3"
Is there any possibility to prevent passing props to DOM elements?
Material UI's 'styled' syntax is very confusing unfortunately. This should work though:
interface DrawerProps {
zIndex: number
}
export const Drawer = styled(DrawerBase, {
shouldForwardProp: (prop) => prop !== 'zIndex',
})<Theme, DrawerProps>(({zIndex}) => ({
zIndex
}))
'shouldForwardProp' is also an unfortunate name as it sounds like the property zIndex isn't forwarded, but it is actually accessible.
Hope it helps.
I've not used styled components within MUI before, so take what I'm saying with a grain of salt. But I have a few ideas:
You're importing styled from '#material-ui/core', but you're calling a style function (without the "d").
Looking at the MUI docs for using styled components, they're using it the way we traditionally use styled components, which is using CSS syntax. I'd expect your code to look like this:
const Drawer = styled(DrawerBase)`
z-index: ${props => props.zIndex};
`;
The DOM element needs "z-index", not "zIndex".
Your code snippet also has a typo with your const Drawer where you've left out the "s": cont.
Hopefully this helps.
Basicaly what I'm trying to do is create one single component that has a list of re-usable styled components that I can use instantly without having to redefine / extend said styled component.
For the component that has a list of re-usable styles I currently export an object that has all the re-usable styles like so:
import styled from 'styled-components';
const ReusableStyles = {
BgGreen : styled.div`
background-color: #50ccb7;
color: #FFF;
`,
TextLeft : styled.div`
text-align: left;
width: 50%;
`
}
export default ReusableStyles;
I'm currently using these re-usable styles like so
import React from 'react'
import styled from 'styled-components'
import ReusableStyles from './reusableStyles.js'
const TestWithBgGreen = styled(ReusableStyles.BgGreen)`
`;
class Test extends React.Component {
render() {
return (
<TestWithBgGreen>
Test Text with green background
</TestWithBgGreen>
);
}
}
export default Test;
Now my problem with this is that I have to re-define / extend ReusableStyles.BgGreen each time I use this, even though I'm not adding any style properties.
I'd prefer to use the styled component directly like so:
<ReusableStyles.BgGreen>
Test Text with green background
</ReusableStyles.BgGreen>
This obviously does not work.
Is there any way to create a single component that has a collection of re-usable styles that can be used without having to redefine / extend that styled component each time?
This is not working due to the way you're exporting and importing your components. Right now you're adding them to an object and then exporting that object. So you're forced to get to the styled-components through that ReusableStyles object.
This is what you want to do:
const BgGreen = styled.div`
background-color: #50ccb7;
color: #FFF;
`,
const TextLeft = styled.div`
text-align: left;
width: 50%;
`
export {
BgGreen,
TextLeft,
}
Then import them as:
import {BgGreen} from './reusableStyles.js'
And use them as any other component
<BgGreen>
My Text
</BgGreen>
Another way to export them if you want to keep your reusable object:
export { ... ReusableStyles }
And you can use default export in case you want to use the object for some reason like you're already doing.
I have a Styled-Component called Headline that I wish to extend with another component called SubHeadline. Now, Headline looks like this:
const Headline = styled.h2`
// Css styles go here
`
What I would like to do is to both extend the styles of Headline AND change the tag type to something else (say h3). Something like this:
const SubHeadline = styled(Headline).h3`
// Css styles go here
`
Now the above does NOT work, but it illustrates what I would like to do.
Any ideas on how to do this?
The way I know how to manage this is described in this Github Issue.
Put all your functionality out in variables and added it to your different child components:
import styled, { css } from 'styled-components'
const HeadlineStyles = css`
// Css for Headline here
`
const Headline = styled.h2`
${HeadlineStyles}
`
const SubHeadline = styled.h3`
${HeadlineStyles}
`
I'm trying to create a custom style for material textField and need a JSS selector that reaches a nondeterministic classname.
Style would look something like this:
const styles = {
'#media (min-width: 768px)': {
borderLabel: {
top: 2,
'&.MuiInputLabel-shrink':{
top: -2,
}
}
}
The issue is MuiInputLabel-shrink is also generated by jss and has a xxx number suffix. Is there any selector that work on generated classes?
Material-ui have a built in API where you can override mostly of the styling.
Assuming you are using material-ui in react, you can override shrink in the classes property in InputLabel component.
<InputLabel
classes={{
shrink: classes.shrinkStyle
}}
/>
Read the documentation to find the right component to override. There is also attached code to help you on the way. https://codesandbox.io/embed/l32qn5p18q
Link to similar problem in GitHub: https://github.com/mui-org/material-ui/issues/10468
Now then back to style through JSS
There is some possibilites to style with JSS through nesting. I've not researched huge lot on this, but I know that you can use nested JSS. Example:
const styles = {
'#media (min-width: 768px)': {
borderLabel: {
//styling
'&>div':{
//styling
}
'&>div>div>td':{
'& svg':{
//styling
}
}
}
}
}
You should also read JSS documentation