@readme/stylelint-config 3.2.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [4.0.0](https://github.com/readmeio/standards/compare/@readme/stylelint-config@3.2.2...@readme/stylelint-config@4.0.0) (2023-08-03)
7
+
8
+ **Note:** Version bump only for package @readme/stylelint-config
9
+
10
+
11
+
12
+
13
+
14
+ ## [3.2.2](https://github.com/readmeio/standards/compare/@readme/stylelint-config@3.2.1...@readme/stylelint-config@3.2.2) (2023-07-05)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **stylelint-config:** disable media-query-no-invalid rule ([#700](https://github.com/readmeio/standards/issues/700)) ([c6cfebd](https://github.com/readmeio/standards/commit/c6cfebdacf63b5f8cc73ee06d79dcac8a66d945c))
20
+
21
+
22
+
23
+
24
+
6
25
  ## [3.2.1](https://github.com/readmeio/standards/compare/@readme/stylelint-config@3.2.0...@readme/stylelint-config@3.2.1) (2023-07-05)
7
26
 
8
27
  **Note:** Version bump only for package @readme/stylelint-config
@@ -1,8 +1,16 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`stylelint-config prettier rules matches snapshot with all formatting errors fixed 1`] = `
4
+ "$prettier: 'should be single quotes';
5
+ "
6
+ `;
7
+
3
8
  exports[`stylelint-config with an invalid file and auto-fix enabled matches the auto-fixed snapshot 1`] = `
4
- "@import "x.css";
5
- @import "y.css";
9
+ "@import 'x.css';
10
+ @import 'y.css';
11
+
12
+ $one: 'one';
13
+ $twoCamelCase: 'two';
6
14
 
7
15
  /**
8
16
  * Multi-line comment
@@ -30,11 +38,11 @@ exports[`stylelint-config with an invalid file and auto-fix enabled matches the
30
38
 
31
39
  .selector-1,
32
40
  .selector-2,
33
- .selector-3[type="text"] {
41
+ .selector-3[type='text'] {
34
42
  background: linear-gradient(#fff, rgb(0 0 0 / 0.8));
35
43
  box-sizing: border-box;
36
- display: block;
37
44
  color: var(--brand-red);
45
+ display: block;
38
46
  }
39
47
 
40
48
  .selector-a,
@@ -67,7 +75,7 @@ exports[`stylelint-config with an invalid file and auto-fix enabled matches the
67
75
  @media (orientation: portrait), projection and (color) {
68
76
  .selector-i + .selector-ii {
69
77
  background: hsl(20deg 25% 33%);
70
- font-family: Helvetica, "Arial Black", sans-serif;
78
+ font-family: Helvetica, 'Arial Black', sans-serif;
71
79
  }
72
80
  }
73
81
 
@@ -75,22 +83,20 @@ exports[`stylelint-config with an invalid file and auto-fix enabled matches the
75
83
  @media screen and (min-resolution: 192dpi), screen and (min-resolution: 2dppx) {
76
84
  .selector {
77
85
  animation: 3s none fade-in;
78
- background-image: repeating-linear-gradient(
79
- -45deg,
80
- transparent,
81
- #fff 25px,
82
- rgb(255 255 255 / 1) 50px
83
- );
86
+ background-image: repeating-linear-gradient(-45deg, transparent, #fff 25px, rgb(255 255 255 / 1) 50px);
87
+ box-shadow:
88
+ 0 1px 1px #000,
89
+ 0 1px 0 #fff,
90
+ 2px 2px 1px 1px #ccc inset;
91
+ height: 10rem;
84
92
  margin: 10px;
85
93
  margin-bottom: 5px;
86
- box-shadow: 0 1px 1px #000, 0 1px 0 #fff, 2px 2px 1px 1px #ccc inset;
87
- height: 10rem;
88
94
  }
89
95
 
90
96
  /* Flush nested single line comment */
91
97
  .selector::after {
92
- content: "→";
93
- background-image: url("x.svg");
98
+ background-image: url('x.svg');
99
+ content: '→';
94
100
  }
95
101
  }
96
102
 
@@ -0,0 +1,110 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const stylelint = require('stylelint');
5
+
6
+ const config = require('..');
7
+
8
+ const invalidScss = fs.readFileSync(path.join(__dirname, './invalid.scss'), 'utf-8');
9
+ const validScss = fs.readFileSync(path.join(__dirname, './valid.scss'), 'utf-8');
10
+
11
+ describe('stylelint-config', () => {
12
+ let data;
13
+ let warnings;
14
+
15
+ describe('with a valid file', () => {
16
+ beforeEach(async () => {
17
+ data = await stylelint.lint({
18
+ code: validScss,
19
+ config,
20
+ });
21
+ ({ warnings } = data.results[0]);
22
+ });
23
+
24
+ it('has no errors', () => {
25
+ expect(data.errored).toBeFalsy();
26
+ });
27
+
28
+ it('flags no warnings', () => {
29
+ expect(warnings).toHaveLength(0);
30
+ });
31
+ });
32
+
33
+ describe('with an invalid file and auto-fix enabled', () => {
34
+ beforeEach(async () => {
35
+ data = await stylelint.lint({
36
+ code: invalidScss,
37
+ config,
38
+ fix: true,
39
+ });
40
+ ({ warnings } = data.results[0]);
41
+ });
42
+
43
+ it('matches the auto-fixed snapshot', () => {
44
+ expect(data.output).toMatchSnapshot();
45
+ });
46
+
47
+ it('has errors', () => {
48
+ expect(data.errored).toBeTruthy();
49
+ });
50
+
51
+ it('flags warnings', () => {
52
+ expect(warnings).toContainEqual(
53
+ expect.objectContaining({
54
+ text: expect.stringMatching(/scss\/dollar-variable-pattern/),
55
+ }),
56
+ );
57
+ expect(warnings).toContainEqual(
58
+ expect.objectContaining({
59
+ text: expect.stringMatching(/color-function-notation/),
60
+ }),
61
+ );
62
+ expect(warnings).toContainEqual(
63
+ expect.objectContaining({
64
+ text: expect.stringMatching(/selector-id-pattern/),
65
+ }),
66
+ );
67
+ expect(warnings).toContainEqual(
68
+ expect.objectContaining({
69
+ text: expect.stringMatching(/selector-max-id/),
70
+ }),
71
+ );
72
+ });
73
+
74
+ it('expects no more than 1 id selector', () => {
75
+ expect(warnings.some(w => w.rule === 'selector-max-id')).toBeTruthy();
76
+ });
77
+
78
+ it('expects id pattern to be either kebab-case or TitleCase', () => {
79
+ expect(warnings.some(w => w.rule === 'selector-id-pattern')).toBeTruthy();
80
+ });
81
+
82
+ it('auto-fixes "selector-not-notation" to "simple" pattern', () => {
83
+ expect(data.output).toContain('&:not(.one):not(.two):not(.three)');
84
+ });
85
+ });
86
+
87
+ describe('prettier rules', () => {
88
+ it('matches snapshot with all formatting errors fixed', async () => {
89
+ data = await stylelint.lint({
90
+ code: `
91
+ $prettier: "should be single quotes";
92
+ `,
93
+ config,
94
+ fix: true,
95
+ });
96
+ ({ warnings } = data.results[0]);
97
+ expect(data.output).toMatchSnapshot();
98
+ });
99
+
100
+ it('flags double quotes as an error', async () => {
101
+ data = await stylelint.lint({
102
+ code: '$prettier: "should be single quotes"',
103
+ config,
104
+ });
105
+ ({ warnings } = data.results[0]);
106
+ expect(warnings).toHaveLength(1);
107
+ expect(warnings[0].rule).toBe('prettier/prettier');
108
+ });
109
+ });
110
+ });
@@ -1,5 +1,8 @@
1
- @import url("x.css");
2
- @import url("y.css");
1
+ @import url('x.css');
2
+ @import url('y.css');
3
+
4
+ $one: 'one';
5
+ $twoCamelCase: 'two';
3
6
 
4
7
  /**
5
8
  * Multi-line comment
@@ -27,7 +30,7 @@
27
30
 
28
31
  .selector-1,
29
32
  .selector-2,
30
- .selector-3[type="text"] {
33
+ .selector-3[type='text'] {
31
34
  background: linear-gradient(#fff, rgb(0 0 0 / 80%));
32
35
  box-sizing: border-box;
33
36
  display: block;
@@ -40,9 +43,15 @@
40
43
  top: calc(100% - 2rem);
41
44
  }
42
45
 
43
- .selector-x { width: 10%; }
44
- .selector-y { width: 20%; }
45
- .selector-z { width: 30%; }
46
+ .selector-x {
47
+ width: 10%;
48
+ }
49
+ .selector-y {
50
+ width: 20%;
51
+ }
52
+ .selector-z {
53
+ width: 30%;
54
+ }
46
55
 
47
56
  /* Single-line comment */
48
57
 
@@ -56,23 +65,15 @@
56
65
  @media (orientation: portrait), projection and (color) {
57
66
  .selector-i + .selector-ii {
58
67
  background: hsl(20deg 25% 33%);
59
- font-family: Helvetica, "Arial Black", sans-serif;
68
+ font-family: Helvetica, 'Arial Black', sans-serif;
60
69
  }
61
70
  }
62
71
 
63
72
  /* Flush single line comment */
64
- @media
65
- screen and (min-resolution: 192dpi),
66
- screen and (min-resolution: 2dppx) {
73
+ @media screen and (min-resolution: 192dpi), screen and (min-resolution: 2dppx) {
67
74
  .selector {
68
75
  animation: 3s none fade-in;
69
- background-image:
70
- repeating-linear-gradient(
71
- -45deg,
72
- transparent,
73
- #fff 25px,
74
- rgb(255 255 255 / 100%) 50px
75
- );
76
+ background-image: repeating-linear-gradient(-45deg, transparent, #fff 25px, rgb(255 255 255 / 100%) 50px);
76
77
  margin: 10px;
77
78
  margin-bottom: 5px;
78
79
  box-shadow:
@@ -84,14 +85,18 @@
84
85
 
85
86
  /* Flush nested single line comment */
86
87
  .selector::after {
87
- content: "";
88
- background-image: url("x.svg");
88
+ content: '';
89
+ background-image: url('x.svg');
89
90
  }
90
91
  }
91
92
 
92
93
  @keyframes fade-in {
93
- from { opacity: 0; }
94
- to { opacity: 1; }
94
+ from {
95
+ opacity: 0;
96
+ }
97
+ to {
98
+ opacity: 1;
99
+ }
95
100
  }
96
101
 
97
102
  // Prefer "simple" selector-not-notation
@@ -1,5 +1,9 @@
1
- @import "x.css";
2
- @import "y.css";
1
+ @import 'x.css';
2
+ @import 'y.css';
3
+
4
+ $one: 'one';
5
+ $two-kebab-case: 'two';
6
+ $media-query-width: 300px;
3
7
 
4
8
  /**
5
9
  * Multi-line comment
@@ -19,7 +23,7 @@
19
23
 
20
24
  .selector-1,
21
25
  .selector-2,
22
- .selector-3[type="text"] {
26
+ .selector-3[type='text'] {
23
27
  background: linear-gradient(#fff, rgba(0, 0, 0, 0.8));
24
28
  box-sizing: border-box;
25
29
  color: var(--brand-red);
@@ -46,6 +50,10 @@
46
50
 
47
51
  /* Single-line comment */
48
52
 
53
+ @media (min-width: $media-query-width) {
54
+ border: 1px solid black;
55
+ }
56
+
49
57
  @media (width >= 60em) {
50
58
  .selector {
51
59
  /* Flush to parent comment */
@@ -56,7 +64,7 @@
56
64
  @media (orientation: portrait), projection and (color) {
57
65
  .selector-i + .selector-ii {
58
66
  background: rgb(105, 77, 63);
59
- font-family: Helvetica, "Arial Black", sans-serif;
67
+ font-family: Helvetica, 'Arial Black', sans-serif;
60
68
  }
61
69
  }
62
70
 
@@ -64,13 +72,11 @@
64
72
  @media screen and (min-resolution: 192dpi), screen and (min-resolution: 2dppx) {
65
73
  .selector {
66
74
  animation: 3s none fade-in;
67
- background-image: repeating-linear-gradient(
68
- -45deg,
69
- transparent,
70
- #fff 25px,
71
- rgb(255, 255, 255, 1) 50px
72
- );
73
- box-shadow: 0 1px 1px #000, 0 1px 0 #fff, 2px 2px 1px 1px #ccc inset;
75
+ background-image: repeating-linear-gradient(-45deg, transparent, #fff 25px, rgb(255, 255, 255, 1) 50px);
76
+ box-shadow:
77
+ 0 1px 1px #000,
78
+ 0 1px 0 #fff,
79
+ 2px 2px 1px 1px #ccc inset;
74
80
  height: 10rem;
75
81
  margin: 10px;
76
82
  margin-bottom: 5px;
@@ -78,8 +84,8 @@
78
84
 
79
85
  /* Flush nested single line comment */
80
86
  .selector::after {
81
- background-image: url("x.svg");
82
- content: "";
87
+ background-image: url('x.svg');
88
+ content: '';
83
89
  }
84
90
  }
85
91
 
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@readme/stylelint-config",
3
- "version": "3.2.1",
3
+ "version": "4.0.0",
4
4
  "description": "ReadMe coding standards for styles",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
7
7
  "lint": "eslint .",
8
- "test": "jest"
8
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest"
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",
@@ -18,20 +18,20 @@
18
18
  },
19
19
  "homepage": "https://github.com/readmeio/standards",
20
20
  "dependencies": {
21
- "stylelint": "^15.10.0",
21
+ "stylelint": "^15.10.2",
22
22
  "stylelint-config-css-modules": "^4.2.0",
23
23
  "stylelint-config-sass-guidelines": "^10.0.0",
24
24
  "stylelint-config-standard": "^34.0.0",
25
25
  "stylelint-config-standard-scss": "^10.0.0",
26
26
  "stylelint-order": "^6.0.3",
27
- "stylelint-prettier": "^3.0.0"
27
+ "stylelint-prettier": "^4.0.2"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "postcss": "^8.4.12"
31
31
  },
32
32
  "devDependencies": {
33
- "@readme/eslint-config": "^10.6.2",
33
+ "@readme/eslint-config": "^11.0.0",
34
34
  "jest": "^29.4.3"
35
35
  },
36
- "gitHead": "88d8d9d48d4194b68b5fede311c052b4c2828161"
36
+ "gitHead": "2d4b64f7fe85193bf65bf549605e3a65b1cb09a1"
37
37
  }
package/src/index.js CHANGED
@@ -59,6 +59,11 @@ module.exports = {
59
59
  // https://stylelint.io/user-guide/rules/media-feature-range-notation/
60
60
  'media-feature-range-notation': null,
61
61
 
62
+ // Rule is not appropriate when using SCSS variables with media queries.
63
+ // e.g. @media (max-width: $container-lg)
64
+ // https://stylelint.io/user-guide/rules/media-query-no-invalid/
65
+ 'media-query-no-invalid': null,
66
+
62
67
  // Allows us to write duplicate selectors in groups
63
68
  // https://github.com/stylelint/stylelint/issues/3196
64
69
  'no-descending-specificity': [
@@ -130,7 +135,7 @@ module.exports = {
130
135
  'selector-id-pattern': [
131
136
  '^(([a-z][a-z0-9]*(-[a-z0-9]+)*)|([A-Z][a-z0-9]*)+)$',
132
137
  {
133
- message: 'Expected id selector to be kebab-case or TitleCase',
138
+ message: 'Expected id selector to be kebab-case or TitleCase (selector-id-pattern)',
134
139
  },
135
140
  ],
136
141
 
@@ -1,66 +0,0 @@
1
- const fs = require('fs');
2
-
3
- const stylelint = require('stylelint');
4
-
5
- const config = require('..');
6
-
7
- const invalidScss = fs.readFileSync('./__tests__/invalid.scss', 'utf-8');
8
- const validScss = fs.readFileSync('./__tests__/valid.scss', 'utf-8');
9
-
10
- describe('stylelint-config', () => {
11
- let data;
12
- let warnings;
13
-
14
- describe('with a valid file', () => {
15
- beforeEach(async () => {
16
- data = await stylelint.lint({
17
- code: validScss,
18
- config,
19
- });
20
- ({ warnings } = data.results[0]);
21
- });
22
-
23
- it('has no errors', () => {
24
- expect(data.errored).toBeFalsy();
25
- });
26
-
27
- it('flags no warnings', () => {
28
- expect(warnings).toHaveLength(0);
29
- });
30
- });
31
-
32
- describe('with an invalid file and auto-fix enabled', () => {
33
- beforeEach(async () => {
34
- data = await stylelint.lint({
35
- code: invalidScss,
36
- config,
37
- fix: true,
38
- });
39
- ({ warnings } = data.results[0]);
40
- });
41
-
42
- it('matches the auto-fixed snapshot', () => {
43
- expect(data.output).toMatchSnapshot();
44
- });
45
-
46
- it('has errors', () => {
47
- expect(data.errored).toBeTruthy();
48
- });
49
-
50
- it('flags warnings', () => {
51
- expect(warnings).toHaveLength(6);
52
- });
53
-
54
- it('expects no more than 1 id selector', () => {
55
- expect(warnings.some(w => w.rule === 'selector-max-id')).toBeTruthy();
56
- });
57
-
58
- it('expects id pattern to be either kebab-case or TitleCase', () => {
59
- expect(warnings.some(w => w.rule === 'selector-id-pattern')).toBeTruthy();
60
- });
61
-
62
- it('auto-fixes "selector-not-notation" to "simple" pattern', () => {
63
- expect(data.output).toContain('&:not(.one):not(.two):not(.three)');
64
- });
65
- });
66
- });
File without changes