How to disable stylelint for all non-string values - styled-components

Is it possible to turn off stylelint linting in interpolations globally with the styled-components processor enabled? My eslint config should apply for this cases and I don't want my stylelint config to interfere with it. Are there any ways to approach this?
For example, this piece of code will generate an error, because of the CSS value-keyword-case rule of stylelint. But because it's inside the interpolation (so it's just JS and no CSS), I would like to turn off linting for places like this.
const MyStyling = styled.div`
color: ${props => props.colors.darkPink};
`
What I use:
{
"stylelint": "^9.10.1",
"stylelint-config-standard": "^16.0.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-processor-styled-components": "^1.5.2"
}

I'm having this same problem.
After not finding anything specific to disable stylelint rules applying to non-string values in javascript, I have decided to disable the value-keyword-case rule on the few lines where I need it using:
/* stylelint-disable-line value-keyword-case */
Example in my code:
const buttonStyles = css<Props>`
/* CSS property: value pairs removed for simplicity */
`
const DecoyButton = styled.div`
${buttonStyles} /* stylelint-disable-line value-keyword-case */
`
const Button = styled('button').attrs(({ type = 'button' }: Attrs) => ({
type,
}))`
${buttonStyles} /* stylelint-disable-line value-keyword-case */
`

Related

${StyledComponent}:hover & {...} Not triggering on hover

Below are two styled-components as and the JSX how they are used in a Gatsby project. I am using gatsby's specific styled-components plugin.
const PhotoWrapper = styled(Card)`
{...styles}
&:hover {
{...hoverStyles}
}
`
const CardTitle = styled.h3`
{...styles}
${PhotoWrapper}:hover & {
{...titleHoverStyles}
}
`
return (
<Slide>
<PhotoWrapper>
<GatsbyImage
image={projectPhoto}
alt={`Screenshot of ${project.name}`}
/>
</PhotoWrapper>
<CardSection>
<CardTitle>{project.name}</CardTitle>
<DetailsWrapper>
{frontEndContainer}
{backEndContainer}
</DetailsWrapper>
</CardSection>
</Slide>
);
The PhotoWrapper hover styles work, but the Title hover styles do not take effect when the PhotoWrapper is hovered over. Is it a prerequisite that the Title component be a child of the PhotoWrapper or is there a better selector to use?
One more thing to note {...styles} is used only in this code snippet. In my project, I list each style instead of deconstructing an object.
I have also tried this format with little luck but I believe this is specifically a 'children of' selector:
const PhotoWrapper = styled(Card)`
{...styles}
&:hover {
{...hoverStyles}
}
&:hover ${CardTitle} {
{...titleHoverStyles}
}
`

Background: url() using .attrs() function

I'm trying to display a different background depending on props with .attrs();
I have the following;
const Heart = styled.div.attrs(props => ({
background: `url(${props => props.filled ? "./media/heart-filled.png" : "./media/heart-empty.png"})`
}))`
//rest of styles here.
`;
However, it doesn't display anything. How exactly does this function work?
I don't know why you're trying to use .attrs here, but it's used to attache some props to a styled component.
https://styled-components.com/docs/api#attrs
To make your code work, you could try:
const Heart = styled.div.attrs(props => ({/* Some aditional props here ! */}))`
background: url(${props => (props.filled ? "./media/heart-filled.png" : "./media/heart-empty.png")}); /* props that you pass into your component can be used here */
/* rest of styles here. */
`;
https://codesandbox.io/s/condescending-brown-lx0lf?file=/src/App.js

Extending styled components

I have a Field Formik's component, in order to apply custom CSS I do:
const Input = styled(Field)`
// CSS goes here
`
And use Input component, works fine. However I use exactly the same CSS in many places, so I've extracted those CSS to standalone styled-component called SuperInput
Now, how can extend style-componet? I need something like
const Input = styled(Field)`
// inlucde CSS from SuperInput component here
`
Example code.
import styled from 'styled-components'
const SuperInput = styled.input`
// CSS here
`
import { Field } from 'formik'
import { SuperInput } from 'styled_components/super_input'
const SomeFormComponent = () => (
<>
// How to use here <Field /> that has <SuperInput /> CSS applied?
</>
)
Basically you just need to spread or append inside the template literals to get it to work. you can keep the common CSS something like
import styled, { css } from "styled-components"
const commonCss = css`
background: red;
`
And can use it in your component like this:
const Input = styled(Field)`
// CSS goes here
${commonCss}
color: hotpink;
`;
const Input1 = styled(Field)`
${commonCss}
color: lightblue;
`;
This should allow you to use the common CSS in various styled components.
For more info, you can read through css styled component API
Edit:
Styled components create HOCs.
After the added superInput definition, I understand what you are trying to do. So your superInput is creating a button with the certain css properties which you are trying to reuse. In that case when you are using Field and trying to extend SuperInput which is a button doesnot make sense. Your Field component is by default a input element(text box), it can be checkbox, radio, file input also.Whatever CSS is written in superInput can be extracted the way I mentioned above and used at multiple places. The way you are trying to do is not the way styled component is designed. That's my understanding
Note : I may be wrong here about whether it is possible or not. But that's what i can say according to my awareness . Anyone Feel free to correct me if I am wrong.

How to change static css file on API response in ReactJS

In my project i want to change the background-color and font of text. Both the properties are written in css file.
Project structure is:
|-myProject
|--public
|--src
|--package.json
All my css is written in public directory, and i have an api which give response of background-color and font. Now i want to change the properties background-color and font in css files according to api response.
Instead of trying to modify the base stylesheets, why not set these particular properties using the elements’ style attributes:
const divStyle = {
backgroundColor: /* Some color */,
fontFamily: /* Some font stack */,
};
function HelloWorldComponent() {
return <div style={ divStyle }>Hello World!</div>;
}
(adapted from the React docs)
I think the best way to do this would be to use inline style on the elements you want to change.
On api response -> set
const yourVar={
backgroundColor:##,
fontFamily:##
};
I believe that the answer from MTCoster is the best approach. depending on the structure of your app you could use the new Context API to make some sort of theme provider, so that you could pass custom styles that could be stored on your application state and that is loaded from your backend API. there are some tools that could help you integrate this feature more easily, like Styled-Components.
with Styled components you culd write something like:
import styled from 'styled-components'
import { YourComponentJSX } from '../somewhere'
// Wrap the component where you need your custom styles
const YourStyledComponent = styled(YourComponentJSX)`
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
/* Color the border and text with theme.main */
// using the short-if to add a default color in case it is not connected to the ThemeProvider
color: ${props => props.theme.main ? props.theme.main : "palevioletred"};
border: 2px solid ${props => props.theme.main ? props.theme.main : "palevioletred"};
`;
// Define what props.theme will look like
const theme = {
main: "mediumseagreen"
};
render(
<div>
<ThemeProvider theme={theme}>
<App>
<YourStyledComponent>Themed</YourStyledComponent>
</App>
</ThemeProvider>
</div>
);
This way you could wrap your whole app and use custom styles saved on the app state that have been loaded from the backend and use them on really deeply nested ui components
*The code is a modification from the styled-component docs

Exclude color property from sass compilation

Is there a way to exclude color propertys from sass compilation in webpack sass compiler, to prevent the opacity problem in child elements.
At the moment it compile this:
div {
background: rgba(255, 255, 255, 1);
}
to:
div {
background: white;
}
Sorry for my bad english :)
You can't prevent it. Because it's a sass function that converts the color to hex.
But there are few ways to avoid it
you can create your own rgba function that will do the trick for you
#function rgba($r, $g, $b, $a) {
#return unquote('rgba(#{$r}, #{$g}, #{$b}, #{$a})');
}
But doing this means there are changes that, if some one is using rgba(hex, a) then it will fail, if there are some one using syntax like rgba(rgb(255,255,255), 1) then also it will fail. So you have to look in your project structure and see how the syntax is there in all the files. And you have to mention to the team to use rgba alone.
Or else you can create a simple mixin
#mixin mysuper-rgba($hexcolor, $opacity) {
background-color: $hexcolor;
background-color: rgba($hexcolor, $opacity);
}
body {
#include mysuper-rgba(#11111, 0.5);
}
What I suggest is create a mixin that will do the trick for you and ask all your developers to use the same.

Resources