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

Merge 1.0 branch into master #111

Merged
merged 33 commits into from
Aug 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d6582ad
Update package.lock
Aug 17, 2017
cf988ad
Add stylelint-config-styled-components-processor as peer dependency
Aug 17, 2017
15093e0
Remove ignoring of stylelint rules
Aug 17, 2017
9f85932
Update typescript to supress warnings during testing
Aug 17, 2017
09f9578
Remove todo comment
Aug 17, 2017
24d6a1f
Don't mutate stylelintResult
Aug 17, 2017
e152b93
Update readme
Aug 17, 2017
1331c92
Update readme
Aug 17, 2017
6b71c0f
Fix readme wording
Aug 17, 2017
2d655a9
Revert Typescript to 2.3.2 for updating in different PR
emilgoldsmith Aug 17, 2017
d7d0122
Merge pull request #49 from styled-components/move-to-shared-config
emilgoldsmith Aug 17, 2017
9e79304
Initial implementation efforts for interpolation tags
emilgoldsmith Jul 14, 2017
23dacc7
Initial tests for interpolation tags
emilgoldsmith Aug 13, 2017
1d96a49
Implemented extrapolateShortenedCommand
emilgoldsmith Aug 17, 2017
5ae6913
Added tests for extrapolateShortenedCommand
emilgoldsmith Aug 17, 2017
c91bbc3
Implemented and tested extractScpTagInformation
emilgoldsmith Aug 17, 2017
61c8f4c
Implemented basic current interpolation tag API spec and basic tests
emilgoldsmith Aug 21, 2017
e813aad
Renamed Scp to Sc
emilgoldsmith Aug 25, 2017
d42f3a1
Add error throwing to invalid sc- tags
emilgoldsmith Aug 25, 2017
46743cb
Implemented and added tests for quotes for custom placeholder
emilgoldsmith Aug 26, 2017
18c89f1
Edited a few comments
emilgoldsmith Aug 26, 2017
4732a2a
Completed tests
emilgoldsmith Aug 26, 2017
65aae8e
Rewording of turning off rules in README
emilgoldsmith Aug 26, 2017
de0da57
first draft of interpolation tagging README section
emilgoldsmith Aug 26, 2017
f013644
README overhaul
mxstbr Aug 27, 2017
86b660f
Removed ref from the interpolation tagging API
emilgoldsmith Aug 27, 2017
c971fde
Merge pull request #70 from styled-components/feature/label-interpola…
emilgoldsmith Aug 28, 2017
da1c593
Merge branch 'master' into 1.0
mxstbr Aug 28, 2017
736b435
Fix linting issue
mxstbr Aug 28, 2017
1040c67
Fix linting issue
mxstbr Aug 28, 2017
891a8fb
Empty commit to trigger build
mxstbr Aug 28, 2017
7296373
Update package-lock
Aug 28, 2017
add5e35
Fix prettier error
Aug 28, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 125 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `stylelint-processor-styled-components`

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

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

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

**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!

## Usage

### Installation

You need:

- `stylelint` (duh)
- This processor (to add `styled-components` support)
- The standard config for stylelint (or any config you like)
- This processor, to extract styles from `styled-components`
- 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`
- Your favorite `stylelint` config! (for example [`stylelint-config-standard`](https://github.com/stylelint/stylelint-config-standard))

```
npm install --save-dev stylelint-processor-styled-components stylelint stylelint-config-standard
(npm install --save-dev
stylelint
stylelint-processor-styled-components
stylelint-config-styled-components-processor
stylelint-config-standard)
```

### Setup
Expand All @@ -32,82 +35,162 @@ Add a `.stylelintrc` file to the root of your project:
```JSON
{
"processors": ["stylelint-processor-styled-components"],
"extends": "stylelint-config-standard",
"extends": [
"stylelint-config-standard",
"stylelint-config-styled-components-processor"
],
"syntax": "scss"
}
```

> Setting the `syntax` to `scss` is needed for nesting and interpolation support!

Then you need to actually run `stylelint`.
> **NOTE:** Setting the `syntax` to `scss` is needed for nesting and interpolation support!

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:
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:

```JSON
{
"scripts": {
"lint:css": "stylelint './components/**/*.js'"
"lint:css": "stylelint './src/**/*.js'"
}
}
```

> **NOTE:** Don't worry about passing in files that don't contain any styled-components code – we take care of that.
> **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).

Now you can lint your CSS by running this script! 🎉
Now you can lint your CSS by running the script! 🎉

```
npm run lint:css
```

### Webpack
#### Webpack

For use with Webpack you can use the [`stylelint-custom-processor-loader`](https://github.com/emilgoldsmith/stylelint-custom-processor-loader).
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.

### Syntax notes
#### Turning rules off from within your CSS
### Processor specific stylelint rules

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)

The [`stylelint-config-styled-components-processor`](https://github.com/styled-components/stylelint-config-styled-components-processor) will automatically disable rules that cause conflicts.

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:
> **NOTE:** You can override rules defined in shared configs in your custom `.stylelintrc`.

### Interpolation tagging

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.

A simplified example:

```js
/* stylelint-disable */
import React from 'react';
import styled from 'styled-components';
const something = 'background';

const Wrapper = styled.div`
/* stylelint-disable */
background-color: red;
`;
const Button = styled.div`
${something}: papayawhip;
`
```
or even

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.

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.

For example:

```js
/* stylelint-disable */
import React from 'react';
import styled from 'styled-components';
const something = 'background';

const Button = styled.div`
// Tell the processor that "something" is a property
${/* sc-prop */ something}: papayawhip;
`
```

Now the processor knows that the `something` interpolation is a property, and it can replace the interpolation with a property for linting.

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.

#### Tags

The full list of supported tags:

- `sc-block`
- `sc-selector`
- `sc-declaration`
- `sc-property`
- `sc-value`

> **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.

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:

```js
const Wrapper = styled.div`
/* stylelint-disable-next-line */
background-color: red;
${/* sc-selector */ Button} {
color: red;
}
`;
```

would throw a stylelint error similar to `All rules have already been disabled (CssSyntaxError)`.
You can also use shorthand tags to avoid cluttering the code. For example:

```js
const Wrapper = styled.div`
${/* sc-sel */ Button} {
color: red;
}
`;
```

#### Interpolation linting
##### `sc-custom`

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).
**`sc-custom` is meant to be used as a last resort escape hatch. Prefer to use the standard tags if possible!**

#### Template literal style and indentation
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.

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:
For example:

**Right**
```js
// Switch between left and right based on language settings passed through via the theme
const rtlSwitch = props => props.theme.dir === 'rtl' ? 'left' : 'right';

const Button = styled.button`
color: red;
`
background: green;
// Tell the processor to replace the interpolation with "left"
// when linting
margin-${/* sc-custom 'left' */ rtlSwitch}: 12.5px;
`;
```

### Syntax notes

#### Turning rules off from within your JS/CSS

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.

```js
import React from 'react';
import styled from 'styled-components';

// Disable stylelint from within the tagged template literal
const Wrapper = styled.div`
/* stylelint-disable */
background-color: 123;
`;

// Or from the JavaScript around the tagged template literal
/* stylelint-disable */
const Wrapper = styled.div`
background-color: 123;
`;
```

#### Template literal style and indentation

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)

The important thing is that you put the closing backtick on the base level of indentation as follows:

**Right**

```js
if (condition) {
const Button = styled.button`
Expand All @@ -117,6 +200,7 @@ if (condition) {
```

**Wrong**

```js
if (condition) {
const Button = styled.button`
Expand All @@ -136,7 +220,7 @@ It may be that other tagged template literal styles are coincidentally supported

## License

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

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

Expand Down
Loading