Giter VIP home page Giter VIP logo

stylelint-processor-styled-components's Introduction

stylelint-processor-styled-components

Lint your styled components with stylelint!

Build Status Coverage Status Join the community on Spectrum Greenkeeper

Video of project in use

Setup

You need:

(npm install --save-dev \
  stylelint \
  stylelint-processor-styled-components \
  stylelint-config-styled-components \
  stylelint-config-recommended)

Now use those in your .stylelintrc and run stylelint with your JavaScript files!

{
  "processors": ["stylelint-processor-styled-components"],
  "extends": [
    "stylelint-config-recommended",
    "stylelint-config-styled-components"
  ]
}

NOTE: The processor works with Flow- and TypeScript-typed files too! (we'll assume TypeScript usage if your files end in .ts or .tsx)

And it also has some options. Their default values are,

{
  "processors": [["stylelint-processor-styled-components", {
    "moduleName": "styled-components",
    "importName": "default",
    "strict": false,
    "ignoreFiles": [],
    "parserPlugins": [
      "jsx",
      ["decorators", { "decoratorsBeforeExport": true }],
      "classProperties",
      "exportExtensions",
      "functionBind",
      "functionSent"
    ]
  }]]
}
  • Combining with moduleName, importName and strict, you can tell the processor what kinds of tagged template literals to lint.
import styled, { css, keyframes } from 'styled-components';

// `importName` from `moduleName`, which means where `styled` comes from
styled(Component)``;
styled('div')``;
styled.div``;

// any other imports from `moduleName` (if `strict` is true, they will not be linted)
css``;
keyframes``;

// special extend calls, which have been deprecated in styled-components v4
Component.extend``;

  • ignoreFiles is passed to micromatch as the second parameter, which means one or more glob patterns for matching.

  • parserPlugins is used to make the processor's parser be able to parse new syntaxes. All available babel parser plugins and related options can be found in Babel's website.

Further documentation for this processor lives on the styled-components website!

F.A.Q.

Why does it throw Unexpected token? Even thought the file didn't import styled-components.

You can custom babel plugins by option.parserPlugins now. An API example is our test. But if someone can implement #231, that will be much better.

If your project includes yarn.lock or package-lock.json, an alternative cause can be that babel related dependencies, i.e. @babel/parser and @babel/traverse, are outdated, especially when linting files with new TypeScript syntaxes. You can upgrade them by removing their entries in the lockfile and reinstall dependencies.

Why does it throw unexpected lint errors?

The processor can not always parse interpolations with right things. But you can use interpolation-tagging to help it. If you have ideas to make it more intelligent, feel free to send a PR or share your solution by an new issue.

What's more, if set syntax: css-in-js in stylelint@10, it can extract styles from styled-components without this processor. Even though there are still lots of differences with this processor, we hope this processor's abilities can be migrated to stylelint totally in the future.

I don't want specified tagged template literal to be parsed, i.e. css.

You can set option.strict. More examples are in #258.

License

Licensed under the MIT License, Copyright © 2017 Maximilian Stoiber. See LICENSE.md for more information!

Based on Mapbox' excellent stylelint-processor-markdown, thanks to @davidtheclark!

stylelint-processor-styled-components's People

Contributors

43081j avatar asvetliakov avatar benkeen avatar brettjurgens avatar chinesedfan avatar chrishelgert avatar davidtheclark avatar eliihen avatar emilgoldsmith avatar enoahnetzach avatar evilebottnawi avatar fabb avatar gcazaciuc avatar geniusgordon avatar greenkeeper[bot] avatar greenkeeperio-bot avatar jeddy3 avatar jmeyering avatar jpeer264 avatar karfau avatar kubajastrz avatar mxstbr avatar quantizor avatar rainydio avatar saravieira avatar sergioramos avatar stevenlangbroek avatar taneba avatar wickynilliams avatar wmertens avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stylelint-processor-styled-components's Issues

Expected empty line between multiple components

I'm getting a rule-non-nested-empty-line-before error when I have multiple components in one file

I've got a file like this

import styled from 'styled-component';

const TextA = styled.span`
  color: blue;
`

const TextB = styled.span`
  color: red;
`

and got this error

7:1  ✖  Expected empty line before non-nested rule   rule-non-nested-empty-line-before

I've console.log the extractedCSS and it looks like this

.selector {
  color: blue;
}  /* <----- missing a newline here */
.selector {
  color: red;
}

I'm using:

Integration with webpack?

Hey, are there any good solutions for integration with webpack yet? Can't find anything suitable online as it's all meant for scss etc.

Otherwise I might build one.

Doesn't handle one-line css interpolations

As I was checking the new merged code from #52 an edge case just popped into my mind. I already wrote breakings tests for it, just also wanted an issue to reference so I'll reference this issue as I push the new PR.

stylelint fail in typescript file containing generic type for function

This is a minimal example of a TypeScript file that caused stylelint to fail:

const someFunction = <T>(input: T) => input;

Linting succeeds after the generic type T is removed:

const someFunction = (input: number) => input;

stylelint config used to lint that file:

module.exports = {
  processors: ['stylelint-processor-styled-components'],
  extends: [
    'stylelint-config-standard',
  ],
  syntax: 'scss',
  rules: {
    'declaration-block-semicolon-newline-after': null,
    'rule-empty-line-before': null,
    'declaration-block-trailing-semicolon': null,
  },
}

Versions of relevant packages:

  • typescript: 2.4.0
  • stylelint-processor-styled-components: 0.2.2.
  • typescript-eslint-parser: 5.0.1
  • stylelint: 8.0.0

Versioning plan

The README currently says

NOTE: This is currently in alpha. While unit-tested, it doesn't yet have a lot of real world project exposure, so there'll be some edge cases we haven't covered. Please try it out and submit bug reports!

I think this is not true anymore with the recent work by @emilgoldsmith and @ismay and all the bugs that've been fixed.

Let's make 0.3.0 the first "beta" version and announce it as such? I'd love to publish an article on Medium about the recent improvements we've made, does one of you want to kick that off? If you just start writing a draft and send that over to me I can add you to the styled-components publication and we'll make it official.


Also, what do you think about going for a 1.0 after #70?

Add external stylelint config

Which can be extended by users of this processor. It'll mean that we won't have to modify the stylelint result anymore, and that people can still override any of the rules we define (should they want to do so).

It'll need to be a separate library, but still needs to be linked to a particular release of this lib, so specifying the config as a peerDependency would probably be best.

Ref #9

One line style considered as error

This snipped

export const A = styled.a`color: ${({ theme }) => theme.colors.main};` 

throws error

app/components/Theme.js
  8:13  ✖  Expected single space after "{" of a single-line block                                      block-opening-brace-space-after
           (block-opening-backtick-space-after)
  8:31  ✖  Expected single space before "}" of a single-line block                                     block-closing-brace-space-before
           (block-closing-backtick-space-before)

The fact is that Im using prettier and prettier formats to this form automatically

Linting .css files

Seems stylelint-processor-styled-components will cause stylelint fail in .css file

SyntaxError: Unexpected token, expected ( (1:8) at Parser.pp$5.raise (c:\Users\onetwo\Desktop\repo\itonnote\node_modules\babylon\lib\index.js:4443:13) at Parser.pp.unexpected (c:\Users\onetwo\Desktop\repo\itonnote\node_modules\babylon\lib\index.js:1755:8) at Parser.pp$3.parseExprAtom (c:\Users\onetwo

WebStorm 2016.3 .styleLintrc... works?

WebStorm recently released a version which support styleLint, and then I do the same step as mentioned on the homepage styleLint, but it is not working, here's the error:

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:374:25)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at C:\WebstormProjects\webroot\node_modules\stylelint\dist\augmentConfig.js:300:23
    at Array.forEach (native)
    at addProcessorFunctions (C:\WebstormProjects\webroot\node_modules\stylelint\dist\augmentConfig.js:290:58)

So, is someone working on intellij/webstorm plugin for that?

Expected indentation of 2 spaces

Note

I originally opened this as an issue for stylelint, but they directed me over here. I have reproduced the issue below. I am using stylelint-processor-styled-components v0.1.2.

Issue

Describe the issue. Is it a bug or a feature request (new rule, new option, etc.)?

I believe this is a bug. When linting styled-components styles inside a helper function, indentation is reported incorrectly.

Which rule, if any, is this issue related to?

indentation

What CSS is needed to reproduce this issue?

import { css } from 'styled-components';

const helper = (condition) => {
  if (condition) {
    return css`
      color: red;

      &:hover {
        color: blue;
      }
    `;
  }
  return null;
};

What stylelint configuration is needed to reproduce this issue?

{
  "processors": ["stylelint-processor-styled-components"],
  "extends": "stylelint-config-standard",
  "syntax": "scss"
}

Which version of stylelint are you using?

7.11.1

How are you running stylelint: CLI, PostCSS plugin, Node API?

yarn run lint which calls stylelint 'src/**/*.js?(x)'

Does your issue relate to non-standard syntax (e.g. SCSS, nesting, etc.)?

Yes. Both styled-components and SCSS look for & as a placeholder when expanding nested rules.

What did you expect to happen?

No errors to be reported. An error only gets reported when both the color: red; style and the &:hover block is present. Removing either does not trigger an indentation error to be reported.

What actually happened (e.g. what warnings or errors you are getting)?

The following errors were flagged:

Button.jsx
 36:5  ✖  Expected indentation of 2 spaces   indentation
 38:5  ✖  Expected indentation of 2 spaces   indentation
 39:7  ✖  Expected indentation of 4 spaces   indentation
 40:5  ✖  Expected indentation of 2 spaces   indentation
 41:3  ✖  Expected indentation of 0 spaces   indentation

Stylelint v3+ requires plugins to expose a ruleName

Just set up stylelint for my project, very basic setup with one file using styles currently.

Upon running stylelint against my project, I received the following error:

Error: stylelint v3+ requires plugins to expose a ruleName. 
The plugin "/Users/will/Development/main-site/node_modules/stylelint-processor-styled-components/lib/index.js" is not doing this, so will not work with stylelint v3+. 
Please file an issue with the plugin.

Not sure if this is an issue with my config, or that I'm using a too-new version of stylelint?

Atom support

Quick question:

Is it possible to enable this package when using the linter-stylelint plugin for atom?

Installing this package allows me to run a command from the terminal, and it properly picks up styling in .js files, but it does not work with [https://atom.io/packages/linter-stylelint](Atom linter-stylelint plugin). Any ideas how to get this working?

If it's easy, it might be nice to include in the documentation.

Unknown word - CssSyntaxError on comment

I just installed the stylelint for styled-component and run it.

I checked the documentation to see what's wrong with my code but can't figure it out.

This is the code I have in my project :

package.json

    "lint:css": "stylelint app/**/*.js",

...

    "stylelint": "^7.9.0",
    "stylelint-config-standard": "^16.0.0",
    "stylelint-processor-styled-components": "0.0.4",

.stylelintrc

{
  "processors": ["stylelint-processor-styled-components"],
  "extends": "stylelint-config-standard",
  "syntax": "scss",
  "rules": {
      "color-hex-case": "lower",
      "color-hex-length": "short",
      "color-no-invalid-hex": true
  }
}

style.js

import { css } from 'styled-components';

/* STYLEGUIDE v.0.1 */ <= The error is coming from this line

/* FONT-SIZE */

const fontSize = {
  default: '1.2rem',
  medium: '1.4rem',
  big: '2rem',
  bigger: '2.4rem',
};


/* COLORS */

/* Internal color variable */

webpack

{
      test: /\.css$/,
      include: /node_modules/,
      loaders: ['style-loader', 'css-loader'],
}

The comment looks like the one from the Stylelint documentation. Is it coming from this Github repo or from Styleling himself? Did you had this issue before?

Thanks a lot!

Support ignoring rules outside of TTL

I know we closed #56, but I thought about it a bit and I think I could add support for it pretty simply.

You just use the already implemented babylon parser and then every time you hit a comment outside a TTL you check if it fits /stylelint-(?:enable|disable)/ if it does you add it to an array, and every time you encounter a TTL you inject all the comments you pushed to the array to the top of the TTL to be parsed, in that way it will also support someone later using stylelint-enable. This should handle all cases from the docs as we of course could just ignore stylelint-disable-(?:next-)?line as those should only be used within.

I think it would be quite a nice intuitive addition. I of course think so because I thought it would intuitively work like eslint, and I could see why others would think the same.

I'll probably submit a PR in the near future adding this in.

Unexpected unknown property (property-no-unknown)

Not sure if this is related to #6 (please close if so) but it breaks with the following complex interpolation:

  const Button = styled.button`
    margin-${props => ((props.theme.dir === 'rtl') ? 'left' : 'right') }: 12.5px;
  `;

This is used for providing RTL support where the dir property can be set in ThemeProvider like so:

<ThemeProvider theme={{ dir: 'rtl' }}>
  <Button>Hello, World!</Button>
</ThemeProvider>

Stylelint throws the following error: Unexpected unknown property "margin-$undefined" (property-no-unknown).

$dummyValue placeholder conflict with stylelint rules

When writing styled-components looking like this:

const Row = styled.div`
    background: #ccc;
`;

const Cell = styled.div`
    ${Row}:hover {
        color: red;
    }
`;

Stylelint will report two issues:

34:5 ✖ Unexpected unknown type selector "$dummyValue" selector-type-no-unknown
34:5 ✖ Expected "$dummyValue" to be "$dummyvalue" selector-type-case

The selector-type-no-unknown error is easily fixable by fixing our config:

{
    'selector-type-no-unknown': [true, { ignoreTypes: ['$dummyValue'] }]
}

But the selector-type-case doesn't have "easy" workaround: https://stylelint.io/user-guide/rules/selector-type-case/ (apart from turning the rule off).

I'm wondering is maybe we could replace $dummyValue with $dummyvalue?

Don't prefix injectGlobal with a selector

This code...

injectGlobal`
  html {
    color: blue;
  }
`;

... with selector-max-compound-selectors rule set to 1 returns this validation issue

Expected ".selector html" to have no more than 1 compound selectors

stylelint --fix removing content of all js files

minimal example

Used command:
"lint:css": "stylelint '**/*.js'",

What I do

 ~/projects/ran   beta  yr lint:css -- --fix
yarn run v0.28.4
$ stylelint '**/*.js' "--fix"

app/components/Theme.js
  8:13  ✖  Expected single space after "{" of a single-line block                                      block-opening-brace-space-after
           (block-opening-backtick-space-after)
  8:31  ✖  Expected single space before "}" of a single-line block                                     block-closing-brace-space-before
           (block-closing-backtick-space-before)
 29:34  ✖  Expected a leading zero                                                                     number-leading-zero

app/containers/Header/styles.js
 4:13  ✖  Expected single space after "{" of a single-line block (block-opening-backtick-space-after)  block-opening-brace-space-after
 4:32  ✖  Expected single space before "}" of a single-line block                                      block-closing-brace-space-before
          (block-closing-backtick-space-before)

app/containers/PostList/styles.js
 4:14  ✖  Expected single space after "{" of a single-line block (block-opening-backtick-space-after)  block-opening-brace-space-after
 4:34  ✖  Expected single space before "}" of a single-line block                                      block-closing-brace-space-before
          (block-closing-backtick-space-before)

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

File before (app/Theme.js)

import styled from 'styled-components'

export const App = styled.div`
  background-color: ${({ theme }) => theme.colors.background};
  color: ${({ theme }) => theme.colors.text};
`

export const A = styled.a`color: ${({ theme }) => theme.colors.main};`

export const P = styled.p`
  font-size: ${({ theme }) => theme.font.sizes.normal};
  line-height: ${({ theme }) => theme.font.sizes.bigger};
`

export const Article = styled.article`
  margin: ${({ theme }) => theme.alignment.horizontalcenter};
  max-width: 650px;
`

export const Button = styled.button`
  align-items: center;
  background-color: ${({ theme }) => theme.colors.main};
  border: 0;
  color: ${({ theme }) => theme.colors.textAlt};
  display: flex;
  padding: ${({ theme }) => theme.spacing.smaller};
  &:active {
    background-color: ${({ theme }) =>
      theme.helper(theme.colors.main).darken(0.2).string()};
    transition: background-color .3s;
  }
  &:focus {
    outline: none;
  }
`

After

.selector1 {
  background-color: $dummyValue;
  color: $dummyValue;
}

.selector2 {color: $dummyValue;}

.selector3 {
  font-size: $dummyValue;
  line-height: $dummyValue;
}

.selector4 {
  margin: $dummyValue;
  max-width: 650px;
}

.selector5 {
  align-items: center;
  background-color: $dummyValue;
  border: 0;
  color: $dummyValue;
  display: flex;
  padding: $dummyValue;

  &:active {
    background-color: $dummyValue;
    transition: background-color .3s;
  }

  &:focus {
    outline: none;
  }
}l

and all js files without styled are empty

related brumbrum-it/styled-components-stylefmt#1

Incorrectly exits with exit code 2 for only warnings

Stylelint cli exits with exit code 2 for a run with only warnings (see this build) when using stylelint-processor-styled-components. After removing stylelint-processor-styled-components from the build chain, the process exits with 0, as expected.

Since removing the processing fixes the issue I'm suspecting that this lib is the cause, but I'm unsure where exactly it's going wrong. Is it possible that this processor somehow could cause the process to exit with an error code of 2 instead of 0?

Breaks stylelint if no file name given

If you either use the Node API code option without using codeFilename, or if you lint through stdin this will currently make stylelint throw an error with our processor as we require codeFilename to be specified for (I believe this is the reason without having looked much more into it anyway) source maps.

We should probably just quickly handle that case.

Selector-class-pattern error everywhere since 0.1.2

After bumping from v0.1.0 to v0.1.2, stylelint got mad and give us over 9000 errors like these:

 10:1  ✖  Expected class selector ".selector97" to match specified pattern    selector-class-pattern
 16:3  ✖  Expected class selector ".selector97" to match specified pattern    selector-class-pattern
 27:1  ✖  Unexpected empty line before rule                                   rule-empty-line-before
 27:1  ✖  Expected class selector ".selector98" to match specified pattern    selector-class-pattern
 31:1  ✖  Unexpected empty line before rule                                   rule-empty-line-before
 31:1  ✖  Expected class selector ".selector99" to match specified pattern    selector-class-pattern
 36:1  ✖  Unexpected empty line before rule                                   rule-empty-line-before
 36:1  ✖  Expected class selector ".selector100" to match specified pattern   selector-class-pattern
 44:1  ✖  Unexpected empty line before rule                                   rule-empty-line-before
 44:1  ✖  Expected class selector ".selector101" to match specified pattern   selector-class-pattern
 50:1  ✖  Unexpected empty line before rule                                   rule-empty-line-before
 50:1  ✖  Expected class selector ".selector102" to match specified pattern   selector-class-pattern

I didn't find any changelog --> have you any information about this?

Typescript support

I don't know how feasible it is but thought that I should put it out here.
It would be awesome with Typescript support.

Update travis config

Run version independent tests like linting, prettier etc. only on latest. Run unit tests on 6, 7 and 8.

Interpolations mess with source map

This will (incorrectly) report the indentation error to be on line 2 instead of 3.

const Button = styled.button`
  color: ${constants.color};
background: red;
`;

This is because we remove lines with interpolations, but don't account for them in the source maps fixing. This might need significant restructuring of the internals to fix. 😕

Process comments in template literal

When writing styles which go beyond 10 or so lines, you may want to add in comments. Or you may just want to write a comment to explain to your team why you wrote a specific line. As far as I know the only way to do that inside a template literal is to do ${/* comment */''}.

Using this processor, the comment will be processed as undefined, so when you have multiple comments in your style you will get the stylelint error Unexpected duplicate "undefined" declaration-block-no-duplicate-properties.

Example:

${/* My comment */''}

.something {
    color: red;
}

My guess would be that the solution to try and process these as normal CSS comments?

Error declaration-block-no-duplicate-properties from rules with mixins only

My code:

import styled from 'styled-components';
import { ellipsis } from 'polished';
import { TYPOGRAPHY } from 'style-constants';

const NameLink = styled.span`
  ${ellipsis('110px')}
  ${TYPOGRAPHY.bodyBold}
`;

export default NameLink;

7:3 ✖ Unexpected duplicate "undefined" declaration-block-no-duplicate-properties

Interoperate with SublimeLinter?

Does anyone know how to get this to operate with SublimeLinter-contrib-styelint? My guess is that it doesn't work out of the box because that package is only scanning CSS files, not JS/JSX.

Unknown word - CssSyntaxError

Hi!
Not sure if this is bug since I wasn't the one who set up our tooling.
But after upgrading to 0.2.0 yesterday I'm no longer able to use the css helper in nested rules.
Since I don't know how to properly set up a fresh environment I can't really prove it's a problem with the stylelint processor. But this was the only package I updated yesterday besides postcss.

const css = css`
  color: #FFF;
`

const div = styled(div)`
  span {
    ${css}
  } 
`

Feel free to close if you don't think it's a bug.

Strange errors with refering to other components

import styled from 'styled-components';
import { div } from 'react-dom';

const IconWrapper = styled.span`
  display: inline-block;
  ${div} & {
    color: #fff;
  }
`;

export default IconWrapper;
app/components/LeftMenu/IconWrapper.js
 6:22  ✖  Expected newline after ";" in a multi-line declaration block   declaration-block-semicolon-newline-after
 6:23  ✖  Expected empty line before rule                                rule-empty-line-before

How to fix all these interpolation edge cases?

(first of all, hope it's all good I added a discussion label)

So, there are obviously heaps of interpolation edge cases, I think all issues labeled with bug other than #26 are currently due to this, and I listed 4 cases (some of them overlapping with already existing issues) in the comments of #63. So I think we should have a bit of a discussion about how to fix this if you're up for it @styled-components/stylelint-processor.

I see the biggest issues with this as:

  • Many things will simply be unknowable before runtime such as what the props will be to a component etc.
  • If we were to try doing some smart stuff with interpreting Javascript to figure out the parts we could from pre-runtime it would probably take a lot of man-hours and could also potentially really damage our performance in quite a few cases.
  • Currently we are enumerating cases based on assumptions of use, and it's always a difficult path to for a proof (yep, I think like a mathematician 😛), and therefore for finding a bug-free missed-edge-case-free approach as well.

An idea came to me while pondering about the different things I've been working on in this repo recently, that should definitely work, and not be too hard to implement. I also don't think it would hinder UX too badly, but that's definitely up for discussion. It's definitely not a dream-worthy perfect solution as the user would have to do a bit of work, but let's see what you think, and otherwise that's also why the discussion tag is here!

So my approach would:

  • Ditch any attempts at trying to interpret JS, and continue on the path of inserting dummy values that will stop Stylelint from complaining, and then interpolations will either be linted where it was defined if defined with a styled-components helper, or not at all. It will hopefully do it in a much more comprehensive and correct way though, so we could close all those bug labeled issues all at once 😀
  • Make the user declare what kind of output this interpolation will have at the start of every interpolation in a comment, and we can then easily substitute the right dummy value
  • In case the user doesn't declare the type we can keep defaults such as something what we're using now, and also of course let that be known, so you would only have to declare in special cases and we can hopefully guess for the rest like we are doing now.

So implementation wise I would do something like this:

  • I would plan on using something like this css vocabulary list and not needing people to type it all out, but maybe make some shortcuts and if a substring has a unique match then use it etc. maybe store it as a trie or something. This would make sure we covered basically all edge cases, and the few that would possibly arise after should not be so numerous that it would feel bad adding a few more special-cases.
  • For finding the comments I already checked this AST explorer where you can see we would be able to find the comments easily by looking at program.body[0].expression.quasi.expressions[0].leadingComments[0].value
  • I would maybe prefix the comment like other operational comments do such as stylelint-enable and eslint-enable, though I would try and make it shorter, maybe an abbreviation such as scp (Styled Components Processor)
  • An actual example that would for example fix #34 and #54 would be:
export const ButtonGroup = styled.div`
  white-space: nowrap;

  > ${/* scp-sel */ Button} {
    margin: 0;
    border-radius: 0;
    vertical-align: top;
  }
`

Or you could of course also in that case write out scp-selector if you wanted.

  • We could even handle custom values for tough edge cases like #13 so the user could always make sure stylelint would work without having to disable any rules:
  const Button = styled.button`
    margin-${/* scp-custom-right */ props => ((props.theme.dir === 'rtl') ? 'left' : 'right') }: 12.5px;
  `;

So that's my speech! I know it got a bit long. It could possibly use a bit of refining which is also why I'd love your feedback and thoughts, and maybe we'll end up going in a completely different direction, but let's try starting a discussion as this is definitely an important problem that needs a very solid solution.

Experiencing errors on valid CSS

I am experiencing error from stylelint that I am not expecting. It probably has something to do with my setup, but not sure what else to try. I've had the same issue on both Win10 and macOS both with node 6.6.0.

Linting seems to work well for basic styles, example:

const RedBox = styled.div`
  background-color: red;
`

But If I use something like interpolation it seems to break, example:

const stylesTest = css`
  font-size: large;
`;

const Intro = styled.p`
  ${stylesTest}
`;

OR

const logoSpin = keyframes`
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(-360deg);
  }
`;

const Img = styled.img`
  animation: ${logoSpin} infinite 3s linear;
  height: 80px;
`;

I have also experienced other errors like indentation ect which I see in your test fixtures, so I am not sure why it is failing for me. To help identify what or where I have gone wrong I have created a repo base on create-react-app.

Example repo: https://github.com/samit4me/create-react-app-with-styled-components

I was getting similar issues when trying to get this working with react-boilerplate in the Use styled-components PR.

"Unknown word CssSyntaxError" in interpolation after comment

When using these packages...

├─ [email protected]
├─ [email protected]
│  └─ stylelint-config-recommended@^1.0.0
├─ [email protected]
├─ [email protected]

...this code...

const ColumnWidthMixin = `
    min-width: 0;
`;
const StyledDraggableColumn = styled.div`
    flex: 1 1 0px;  /* stylelint-disable-line length-zero-no-unit */
    ${ColumnWidthMixin}
`;

...throws this error:

 3:5  ✖  Unknown word   CssSyntaxError

But these variations do not throw the error:

const var1 = styled.div`
    flex: 1 1 0px;  /* stylelint-disable-line length-zero-no-unit */
    min-width: 0;
`;

const var2 = styled.div`
    ${ColumnWidthMixin}
    flex: 1 1 0px;  /* stylelint-disable-line length-zero-no-unit */
`;

const var3 = styled.div`
    flex: 1 1 3px;
    ${ColumnWidthMixin}
`;

const var4 = styled.div`
    flex: 1 1 0px;  /* stylelint-disable-line length-zero-no-unit */
    border: 1px solid red;
    ${ColumnWidthMixin}
`;

So looks like the problem is using an interpolation right after a comment

Requires typescript in non typescript project

Running this plugin on a non typescript problem yielded the following error

Error: Cannot find module 'typescript'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/node_modules/typescript-eslint-parser/parser.js:11:10)

Installing typescript fixes the problem but it should not be required on a non typescript project.

Interpolation comment tagging API proposal

To take the next step for #70 that followed from #68 I thought I would just put my initial thoughts on an API for this new feature. I thought it would be better to keep it separate here instead of in comments in the PR or something for nice organization if it ends up becoming a longer discussion.

So first of all we of course need a prefix for the comments like there is in stylelint-enable, eslint-disable etc. where I would simply suggest scp for Styled Components Processor but still keeping it very short as one of my considerations for this API is that we want to keep it as short as possible as for a short interpolation such as color: ${props => props.theme.color} you don't want to add a comment that's longer than the interpolation itself making inline short interpolations inconvenient.

I'll keep using scp as the prefix for my following suggestions but that is of course also up for discussion.

Following is my current draft of the full api (all vocabulary taken from here):

  • scp-ref (I'm thinking this should work for cases like ${Button} { css.... }
  • scp-block
  • scp-sel (sel is short for selector)
  • scp-dec (dec short for declaration)
  • scp-prop (prop short for property)
  • scp-val (val short for value)
  • scp-custom PLACEHOLDER (PLACEHOLDER is what we will replace the interpolation with for linting purposes)

This is just my quick first thoughts, and it's of course also easy to extend this API or modify it later.

Some of my main considerations are:

  • Should the prefix be different (though I'm personally pretty happy with scp)
  • Should some of the API be shortened further / shortened less (such as using value instead of val or cust instead of custom etc.)
  • What should the exact API for scp-custom be? My initial thought is to give maximum customizeability to the user so to literally say we don't count the one space between scp-custom and PLACEHOLDER but after that we literally take whatever is left. The question is then should you trim one final space at the end? Should you trim completely the end? You could also trim the beginning though that is what I was thinking not to do to give max customizeability. One could of course also make scp-custom be trimmed in both ends of PLACEHOLDER while you could have like a super custom like scp-all-cust or w/e that didn't trim as the not trimming could of course also be a nuisance to users as a payoff for the customizeability.
  • How specific should we make the API? For example it is very likely that we would in the implementation use the same placeholder for scp-block and scp-dec as a block and a declaration seems the same, but I thought it might be nice UX and even coding style (as in if someone else is reading your code they know that whatever function you put in will be inputting a block?) if you could had the possibility to be more specific even if the actual implementation might not distinguish between some of them.

I may have forgotten something but that's what the discussion is for :). And I may do an edit to this post depending on how the discussion evolves below here with an updated API proposal as things change.

MOST UPDATED PROPOSAL:

  • sc-ref
  • sc-block
  • sc-selector
  • sc-declaration
  • sc-property
  • sc-value
  • sc-custom PLACEHOLDER

And allow unique prefixes to be used to give flexibility which in the current case would even mean that sc-b would mean sc-block, it would be at the developers discretion to make it readable.

/* stylelint-disable */ doesn't work

I am running the pure setup from the readme and due to #55 I want to temporarily disable the rule, but this doesn't seem to work either?

I admit this is also my first time using stylelint, but I have checked quite thoroughly and it seems that I'm doing everything right, and the most likely thing is that it's this parser causing trouble?

Here is my code that acts up with

 11:3  ✖  Unexpected duplicate "undefined"   declaration-block-no-duplicate-properties
 12:3  ✖  Unexpected duplicate "undefined"   declaration-block-no-duplicate-properties

:

/* stylelint-disable declaration-block-no-duplicate-properties */
import React from 'react';
import styled from 'styled-components';

import { media } from '/styles/functions';

const Wrapper = styled.div`
  color: ${props => props.theme.gnarlesGreen};
  background-color: blue;
  ${media.desktop`background-color: red;`}
  ${media.tablet`background-color: yellow;`}
  ${media.phone`background-color: purple;`}
`;

export default () => <Wrapper>Hello World!</Wrapper>;

Add autofix support

Currently running stylelint --fix doesn't effect styles defined in JS using styled-components. It would be awesome if this feature could be added :)

Thank you!

Doesn't properly handle contextual selectors

Causes errors to trigger when using contextual selectors like ${Button}

ie.

export const ButtonGroup = styled.div`
  white-space: nowrap;

  > ${Button} {
    margin: 0;
    border-radius: 0;
    vertical-align: top;
  }
`
149:28  ✖  Expected "$Button" to be "$button"     selector-type-case
 149:28  ✖  Unexpected unknown type selector       selector-type-no-unknown
            "$Button"

Changelog

We should probably have a changelog, yeah? Especially now that we're introducing some breaking changes here and there. Any preferences for how to manage it?

Breaks on complex interpolations

Currently, this breaks on a complex interpolation:

const background = 'background: red;';
const Button = styled.div`
  color: red;
  ${background}
`;

We represent this for stylelint like so:

.selector {
  color: red;
  $background
}

The problem is that, while stylelint ignores Sass variables, those cannot represent full strings, which means stylelint throws a "CssSyntaxError" on the above code eventhough it's not a syntax error at all. 😕

Any ideas what we could do here @davidtheclark?

(also related to #4)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.