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

Commit 4e40a29

Browse files
committed
Add importName option
Closes #109
1 parent 736b435 commit 4e40a29

File tree

6 files changed

+116
-8
lines changed

6 files changed

+116
-8
lines changed

README.md

+24
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,30 @@ if (condition) {
218218

219219
It may be that other tagged template literal styles are coincidentally supported, but no issues will be handled regarding indentation unless the above style was used.
220220

221+
### Usage with other libraries
222+
223+
Some other libraries also implement the `styled.x` pattern with tagged template literals. This processor will lint the CSS in those tagged template literals too.
224+
225+
If you want to avoid edge cases when you assing the default import to a variable not called "styled" set the `importName` option to the library name. (set to `styled-components` by default)
226+
227+
```js
228+
import cool from 'other-library';
229+
230+
const Button = cool.button`
231+
color: blue;
232+
`
233+
```
234+
235+
```json
236+
{
237+
"processors": [["stylelint-processor-styled-components", {
238+
"importName": "other-library"
239+
}]]
240+
}
241+
```
242+
243+
> **NOTE:** That double array is on purpose but only necessary if you set options, see the [processors configuration docs](https://stylelint.io/user-guide/configuration/#processors).
244+
221245
## License
222246

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

src/index.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@ const path = require('path')
22
const parse = require('./parsers/index')
33

44
const sourceMapsCorrections = {}
5+
const DEFAULT_OPTIONS = {
6+
importName: 'styled-components'
7+
}
58

6-
module.exports = (/* options */) => ({
9+
module.exports = options => ({
710
// Get string for stylelint to lint
811
code(input, filepath) {
912
const absolutePath = path.resolve(process.cwd(), filepath)
1013
sourceMapsCorrections[absolutePath] = {}
11-
const { extractedCSS, sourceMap } = parse(input, absolutePath)
14+
const { extractedCSS, sourceMap } = parse(
15+
input,
16+
absolutePath,
17+
Object.assign({}, DEFAULT_OPTIONS, options)
18+
)
1219
// Save source location, merging existing corrections with current corrections
1320
sourceMapsCorrections[absolutePath] = Object.assign(
1421
sourceMapsCorrections[absolutePath],

src/parsers/index.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const getTTLContent = require('../utils/tagged-template-literal.js').getTaggedTe
1717
const parseImports = require('../utils/parse').parseImports
1818
const getSourceMap = require('../utils/parse').getSourceMap
1919

20-
const processStyledComponentsFile = (ast, absolutePath) => {
20+
const processStyledComponentsFile = (ast, absolutePath, options) => {
2121
const extractedCSS = []
2222
let ignoreRuleComments = []
2323
let importedNames = {
@@ -37,7 +37,7 @@ const processStyledComponentsFile = (ast, absolutePath) => {
3737
}
3838
})
3939
}
40-
if (isStyledImport(node)) {
40+
if (isStyledImport(node, options.importName)) {
4141
importedNames = parseImports(node)
4242
return
4343
}
@@ -76,7 +76,7 @@ const processStyledComponentsFile = (ast, absolutePath) => {
7676
}
7777
}
7878

79-
module.exports = (input, absolutePath) => {
79+
module.exports = (input, absolutePath, options) => {
8080
let ast = null
8181
if (absolutePath.endsWith('.ts') || absolutePath.endsWith('.tsx')) {
8282
// We import it dynamically in order to be able to not include typescript as a dependency
@@ -87,5 +87,5 @@ module.exports = (input, absolutePath) => {
8787
} else {
8888
ast = estreeParse(input)
8989
}
90-
return processStyledComponentsFile(ast, absolutePath)
90+
return processStyledComponentsFile(ast, absolutePath, options)
9191
}

src/utils/styled.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ const isTaggedTemplateLiteral = require('./tagged-template-literal').isTaggedTem
33
/**
44
* Check if something is a styled-components import declaration
55
*/
6-
const isStyledImport = node =>
7-
node.type === 'ImportDeclaration' && node.source.value === 'styled-components'
6+
const isStyledImport = (node, importName) =>
7+
node.type === 'ImportDeclaration' && node.source.value === importName
88

99
/**
1010
* Check if something is a styled shorthand call

test/fixtures/options/import-name.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import emotion from 'emotion'
2+
3+
// ⚠️ EMPTY BLOCK ⚠️
4+
const Button = emotion.div`
5+
6+
`

test/options.test.js

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
const stylelint = require('stylelint')
2+
const path = require('path')
3+
4+
const processor = path.join(__dirname, '../src/index.js')
5+
const rules = {
6+
'block-no-empty': true,
7+
indentation: 2,
8+
'rule-empty-line-before': [
9+
'always-multi-line',
10+
{
11+
except: ['first-nested'],
12+
ignore: ['after-comment']
13+
}
14+
],
15+
'selector-type-no-unknown': true
16+
}
17+
18+
describe('options', () => {
19+
let fixture
20+
let data
21+
22+
// NOTE beforeEach() runs _after_ the beforeAll() hooks of the describe() blocks, so `fixture`
23+
// will have the right path
24+
beforeEach(done => {
25+
stylelint
26+
.lint({
27+
files: [fixture],
28+
syntax: 'scss',
29+
config: {
30+
// Set importName option to "emotion"
31+
processors: [[processor, { importName: 'emotion' }]],
32+
rules
33+
}
34+
})
35+
.then(result => {
36+
data = result
37+
done()
38+
})
39+
.catch(err => {
40+
console.log(err)
41+
data = err
42+
done()
43+
})
44+
})
45+
46+
describe('importName', () => {
47+
beforeAll(() => {
48+
fixture = path.join(__dirname, './fixtures/options/import-name.js')
49+
})
50+
51+
it('should have one result', () => {
52+
expect(data.results.length).toEqual(1)
53+
})
54+
55+
it('should use the right file', () => {
56+
expect(data.results[0].source).toEqual(fixture)
57+
})
58+
59+
it('should have errored', () => {
60+
expect(data.results[0].errored).toEqual(true)
61+
})
62+
63+
it('should have one warning (i.e. wrong lines of code)', () => {
64+
expect(data.results[0].warnings.length).toEqual(1)
65+
})
66+
67+
it('should have a block-no-empty as the first warning', () => {
68+
expect(data.results[0].warnings[0].rule).toEqual('block-no-empty')
69+
})
70+
})
71+
})

0 commit comments

Comments
 (0)