Skip to content
This repository was archived by the owner on May 14, 2021. It is now read-only.

Commit 0bc8560

Browse files
authored
Merge pull request #111 from styled-components/1.0
Merge 1.0 branch into master
2 parents f67b192 + add5e35 commit 0bc8560

13 files changed

+1459
-71
lines changed

README.md

+125-41
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# `stylelint-processor-styled-components`
22

3-
Lint the CSS in your [styled components](https://github.com/styled-components/styled-components) with [stylelint](http://stylelint.io/)!
3+
Lint your [styled components](https://github.com/styled-components/styled-components) with [stylelint](http://stylelint.io/)!
44

55
[![Build Status][build-badge]][build-url]
66
[![Coverage Status][coverage-badge]][coverage-url]
@@ -9,20 +9,23 @@ Lint the CSS in your [styled components](https://github.com/styled-components/st
99

1010
![Video of project in use](http://imgur.com/br9zdHb.gif)
1111

12-
**NOTE**: This is currently in beta. We're getting close to being fully production ready, and have now covered most normal use cases. There are still some edge cases though, but we are working hard on getting them fixed for a v1.0 release in the near future. Please keep using it and submit bug reports!
13-
1412
## Usage
1513

1614
### Installation
1715

1816
You need:
1917

2018
- `stylelint` (duh)
21-
- This processor (to add `styled-components` support)
22-
- The standard config for stylelint (or any config you like)
19+
- This processor, to extract styles from `styled-components`
20+
- The [`stylelint-config-styled-components-processor`](https://github.com/styled-components/stylelint-config-styled-components-processor) to disable stylelint rules that clash with `styled-components`
21+
- Your favorite `stylelint` config! (for example [`stylelint-config-standard`](https://github.com/stylelint/stylelint-config-standard))
2322

2423
```
25-
npm install --save-dev stylelint-processor-styled-components stylelint stylelint-config-standard
24+
(npm install --save-dev
25+
stylelint
26+
stylelint-processor-styled-components
27+
stylelint-config-styled-components-processor
28+
stylelint-config-standard)
2629
```
2730

2831
### Setup
@@ -32,82 +35,162 @@ Add a `.stylelintrc` file to the root of your project:
3235
```JSON
3336
{
3437
"processors": ["stylelint-processor-styled-components"],
35-
"extends": "stylelint-config-standard",
38+
"extends": [
39+
"stylelint-config-standard",
40+
"stylelint-config-styled-components-processor"
41+
],
3642
"syntax": "scss"
3743
}
3844
```
3945

40-
> Setting the `syntax` to `scss` is needed for nesting and interpolation support!
41-
42-
Then you need to actually run `stylelint`.
46+
> **NOTE:** Setting the `syntax` to `scss` is needed for nesting and interpolation support!
4347
44-
Add a `lint:css` script to your `package.json`. This script will run `stylelint` with a path to all of your files containing `styled-components` code:
48+
Then you need to run `stylelint`. Add a `lint:css` script to your `package.json` which runs `stylelint` with a glob to all of your styled components:
4549

4650
```JSON
4751
{
4852
"scripts": {
49-
"lint:css": "stylelint './components/**/*.js'"
53+
"lint:css": "stylelint './src/**/*.js'"
5054
}
5155
}
5256
```
5357

54-
> **NOTE:** Don't worry about passing in files that don't contain any styled-components code – we take care of that.
58+
> **NOTE:** The processor ignores javascript files that don't contain any `styled-components`, so don't worry about being too broad as long as you restrict it to javascript (or TypeScript).
5559
56-
Now you can lint your CSS by running this script! 🎉
60+
Now you can lint your CSS by running the script! 🎉
5761

5862
```
5963
npm run lint:css
6064
```
6165

62-
### Webpack
66+
#### Webpack
6367

64-
For use with Webpack you can use the [`stylelint-custom-processor-loader`](https://github.com/emilgoldsmith/stylelint-custom-processor-loader).
68+
If you want to lint on build, rather than as a separate command, you can use the [`stylelint-custom-processor-loader`](https://github.com/emilgoldsmith/stylelint-custom-processor-loader) for webpack.
6569

66-
### Syntax notes
67-
#### Turning rules off from within your CSS
70+
### Processor specific stylelint rules
71+
72+
When using this processor a couple of stylelint rules throw errors that cannot be prevented, like [`no-empty-source`](https://stylelint.io/user-guide/rules/no-empty-source) or [`no-missing-end-of-source-newline`](https://stylelint.io/user-guide/rules/no-missing-end-of-source-newline). There's also a couple rules which we need to enforce, like [`no-vendor-prefix` rules](https://stylelint.io/user-guide/rules/property-no-vendor-prefix). (`styled-components` automatically vendor prefixes your code, so you don't need to do it manually)
73+
74+
The [`stylelint-config-styled-components-processor`](https://github.com/styled-components/stylelint-config-styled-components-processor) will automatically disable rules that cause conflicts.
6875

69-
Turning off rules with `stylelint-disable`-like comments (see the [stylelint documentation](https://stylelint.io/user-guide/configuration/#turning-rules-off-from-within-your-css) for all allowed syntax) is fully supported inside and outside of the tagged template literals, do note though that what actually happens behind the scene is that all `stylelint-(disable|enable)` comments are moved into the compiled css that is actually linted, so something like this:
76+
> **NOTE:** You can override rules defined in shared configs in your custom `.stylelintrc`.
7077
78+
### Interpolation tagging
79+
80+
Sometimes `stylelint` can throw an error (e.g. `CssSyntaxError`) even though nothing is wrong with your CSS. This is often due to an interpolation, more specifically the fact that the processor doesn't know what you're interpolating.
81+
82+
A simplified example:
7183

7284
```js
73-
/* stylelint-disable */
74-
import React from 'react';
75-
import styled from 'styled-components';
85+
const something = 'background';
7686

77-
const Wrapper = styled.div`
78-
/* stylelint-disable */
79-
background-color: red;
80-
`;
87+
const Button = styled.div`
88+
${something}: papayawhip;
89+
`
8190
```
82-
or even
91+
92+
When you have interpolations in your styles the processor can't know what they are, so it makes a good guess and replaces them with a syntactically equivalent placeholder value. Since `stylelint` is not a code flow analysis tool this doesn't cover all edge cases and the processor will get it wrong every now and then.
93+
94+
Interpolation tagging allows you to tell the processor what an interpolation is in case it guesses wrong; it can then replace the interpolation with a syntactically correct value based on your tag.
95+
96+
For example:
97+
8398
```js
84-
/* stylelint-disable */
85-
import React from 'react';
86-
import styled from 'styled-components';
99+
const something = 'background';
100+
101+
const Button = styled.div`
102+
// Tell the processor that "something" is a property
103+
${/* sc-prop */ something}: papayawhip;
104+
`
105+
```
106+
107+
Now the processor knows that the `something` interpolation is a property, and it can replace the interpolation with a property for linting.
108+
109+
To tag an interpolation add a comment at either the start or the end of the interpolation. (`${/* sc-tag */ foo}` or `${bar /* sc-tag */}`) Tags start with `sc-` and, if specified, a tag overrides the processors guess about what the interpolation is.
110+
111+
#### Tags
87112

113+
The full list of supported tags:
114+
115+
- `sc-block`
116+
- `sc-selector`
117+
- `sc-declaration`
118+
- `sc-property`
119+
- `sc-value`
120+
121+
> **NOTE:** If you are in doubt of the vocabulary you can refer to [this CSS vocabulary list](http://apps.workflower.fi/vocabs/css/en) with examples.
122+
123+
For example, when you interpolate another styled component, what you really interpolate is its unique selector. Since the processor doesn't know that, you can tell it to replace it with a selector when linting:
124+
125+
```js
88126
const Wrapper = styled.div`
89-
/* stylelint-disable-next-line */
90-
background-color: red;
127+
${/* sc-selector */ Button} {
128+
color: red;
129+
}
91130
`;
92131
```
93132

94-
would throw a stylelint error similar to `All rules have already been disabled (CssSyntaxError)`.
133+
You can also use shorthand tags to avoid cluttering the code. For example:
134+
135+
```js
136+
const Wrapper = styled.div`
137+
${/* sc-sel */ Button} {
138+
color: red;
139+
}
140+
`;
141+
```
95142

96-
#### Interpolation linting
143+
##### `sc-custom`
97144

98-
We do not currently support linting interpolations as it could be a big performance hit though we aspire to have at least partial support in the future. You can of course lint your own mixins in their separate files, but it won't be linted in context, the implementation currently just inserts relevant dummy values. This, we are afraid, means you won't be able to lint cases such as `declaration-block-no-duplicate-properties` etc. and won't be able to lint outside mixins such as [polished](https://github.com/styled-components/polished).
145+
**`sc-custom` is meant to be used as a last resort escape hatch. Prefer to use the standard tags if possible!**
99146

100-
#### Template literal style and indentation
147+
On top of the above standard tags the processor also has the `sc-custom` tag to allow you to cover more unique and uncommon edge cases. With the `sc-custom` tag you can decide yourself what the placeholder value will be.
101148

102-
In order to have stylelint correctly apply indentation rules we need to do a bit of opinionated preprocessing on the `styled-components` styles, which results in us only officially supporting one coding style when it comes to `styled-components` tagged template literals. This style consists of always placing the closing backtick on the base level of indentation as follows:
149+
For example:
103150

104-
**Right**
105151
```js
152+
// Switch between left and right based on language settings passed through via the theme
153+
const rtlSwitch = props => props.theme.dir === 'rtl' ? 'left' : 'right';
154+
106155
const Button = styled.button`
107-
color: red;
108-
`
156+
background: green;
157+
// Tell the processor to replace the interpolation with "left"
158+
// when linting
159+
margin-${/* sc-custom 'left' */ rtlSwitch}: 12.5px;
160+
`;
109161
```
110162

163+
### Syntax notes
164+
165+
#### Turning rules off from within your JS/CSS
166+
167+
Turn off rules with `stylelint-disable` comments (see the [stylelint documentation](https://stylelint.io/user-guide/configuration/#turning-rules-off-from-within-your-css) for all allowed syntax) both inside and outside of the tagged template literals.
168+
169+
```js
170+
import React from 'react';
171+
import styled from 'styled-components';
172+
173+
// Disable stylelint from within the tagged template literal
174+
const Wrapper = styled.div`
175+
/* stylelint-disable */
176+
background-color: 123;
177+
`;
178+
179+
// Or from the JavaScript around the tagged template literal
180+
/* stylelint-disable */
181+
const Wrapper = styled.div`
182+
background-color: 123;
183+
`;
184+
```
185+
186+
#### Template literal style and indentation
187+
188+
In order to have stylelint correctly apply indentation rules the processor needs to do a bit of opinionated preprocessing on the styles, which results in us only officially supporting one indentation style. (the supported style is the "default" one as shown in all the documentation)
189+
190+
The important thing is that you put the closing backtick on the base level of indentation as follows:
191+
192+
**Right**
193+
111194
```js
112195
if (condition) {
113196
const Button = styled.button`
@@ -117,6 +200,7 @@ if (condition) {
117200
```
118201

119202
**Wrong**
203+
120204
```js
121205
if (condition) {
122206
const Button = styled.button`
@@ -136,7 +220,7 @@ It may be that other tagged template literal styles are coincidentally supported
136220

137221
## License
138222

139-
Licensed under the MIT License, Copyright © 2016 Maximilian Stoiber. See [LICENSE.md](./LICENSE.md) for more information!
223+
Licensed under the MIT License, Copyright © 2017 Maximilian Stoiber. See [LICENSE.md](./LICENSE.md) for more information!
140224

141225
Based on Mapbox' excellent [`stylelint-processor-markdown`](https://github.com/mapbox/stylelint-processor-markdown), thanks to @davidtheclark!
142226

0 commit comments

Comments
 (0)