@gitlab/eslint-plugin 20.3.0 → 20.4.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 +7 -0
- package/docs/rules/{tailwind.md → tailwind-no-interpolation.md} +2 -8
- package/docs/rules/tailwind-no-max-width-media-queries.md +30 -0
- package/docs/rules/{vue-tailwind.md → vue-tailwind-no-interpolation.md} +3 -13
- package/docs/rules/vue-tailwind-no-max-width-media-queries.md +33 -0
- package/lib/rules/{tailwind.js → tailwind-no-interpolation.js} +3 -9
- package/lib/rules/tailwind-no-max-width-media-queries.js +30 -0
- package/lib/rules/{vue-tailwind.js → vue-tailwind-no-interpolation.js} +3 -13
- package/lib/rules/vue-tailwind-no-max-width-media-queries.js +34 -0
- package/lib/utils/tailwind-utils.js +11 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [20.4.0](https://gitlab.com/gitlab-org/frontend/eslint-plugin/compare/v20.3.0...v20.4.0) (2024-10-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **Tailwind:** split up Tailwind rules into separate rules ([e581cee](https://gitlab.com/gitlab-org/frontend/eslint-plugin/commit/e581ceede5a4637deab52a204555be4ea43724b4))
|
|
7
|
+
|
|
1
8
|
# [20.3.0](https://gitlab.com/gitlab-org/frontend/eslint-plugin/compare/v20.2.1...v20.3.0) (2024-10-02)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @gitlab/tailwind
|
|
1
|
+
# @gitlab/tailwind-no-interpolation
|
|
2
2
|
|
|
3
3
|
This rule lints against string interpolation being used to build CSS utility class
|
|
4
4
|
names as that would prevent Tailwind from parsing those classes and adding them to the bundle.
|
|
@@ -13,9 +13,6 @@ const cssUtilsStringLiteral = 'gl-bg-red-' + variant;
|
|
|
13
13
|
|
|
14
14
|
// Using interpolation to build a utility in a template literal
|
|
15
15
|
const cssUtilsTemplateLiteral = `gl-border-top gl-bg-red-${color} gl-text-gray-400`;
|
|
16
|
-
|
|
17
|
-
// Using max-width media query utility classes
|
|
18
|
-
const cssClasses = ['gl-mt-5', 'max-md:gl-mt-3'];
|
|
19
16
|
```
|
|
20
17
|
|
|
21
18
|
### Examples of **correct** code for this rule
|
|
@@ -26,9 +23,6 @@ const cssUtilsStringLiteral = 'gl-bg-red-800';
|
|
|
26
23
|
|
|
27
24
|
// Utilities declared as a template literal without interpolation
|
|
28
25
|
const cssUtils = `gl-border-top gl-bg-red-800 gl-text-gray-400`;
|
|
29
|
-
|
|
30
|
-
// Using max-width media query utility classes
|
|
31
|
-
const cssClasses = ['gl-mt-3', 'md:gl-mt-5'];
|
|
32
26
|
```
|
|
33
27
|
|
|
34
28
|
## Options
|
|
@@ -37,7 +31,7 @@ No options.
|
|
|
37
31
|
|
|
38
32
|
## Related rules
|
|
39
33
|
|
|
40
|
-
- [vue-tailwind](./vue-tailwind.md)
|
|
34
|
+
- [vue-tailwind-no-interpolation](./vue-tailwind-no-interpolation.md)
|
|
41
35
|
|
|
42
36
|
## When Not To Use It
|
|
43
37
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @gitlab/tailwind-no-max-width-media-queries
|
|
2
|
+
|
|
3
|
+
This rule lints against using max-width media query Tailwind classes.
|
|
4
|
+
Min-width media query Tailwind classes should be used instead.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
### Examples of **incorrect** code for this rule
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
const cssClasses = ['gl-mt-5', 'max-md:gl-mt-3'];
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Examples of **correct** code for this rule
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
const cssClasses = ['gl-mt-3', 'md:gl-mt-5'];
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Options
|
|
21
|
+
|
|
22
|
+
No options.
|
|
23
|
+
|
|
24
|
+
## Related rules
|
|
25
|
+
|
|
26
|
+
- [vue-tailwind-no-max-width-media-queries](./vue-tailwind-no-max-width-media-queries.md)
|
|
27
|
+
|
|
28
|
+
## When Not To Use It
|
|
29
|
+
|
|
30
|
+
If the codebase doesn't leverage Tailwind CSS, keep this rule disabled.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# @gitlab/vue-tailwind
|
|
1
|
+
# @gitlab/vue-tailwind-no-interpolation
|
|
2
2
|
|
|
3
|
-
This rule enforces the same conventions as [tailwind](./tailwind.md) in Vue templates.
|
|
3
|
+
This rule enforces the same conventions as [tailwind-no-interpolation](./tailwind-no-interpolation.md) in Vue templates.
|
|
4
4
|
|
|
5
5
|
## Rule Details
|
|
6
6
|
|
|
@@ -16,11 +16,6 @@ This rule enforces the same conventions as [tailwind](./tailwind.md) in Vue temp
|
|
|
16
16
|
<template>
|
|
17
17
|
<span :class="`gl-border-top gl-bg-red-${color} gl-text-gray-400`"></span>
|
|
18
18
|
</template>
|
|
19
|
-
|
|
20
|
-
<!-- Using max-width media query utility classes -->
|
|
21
|
-
<template>
|
|
22
|
-
<span class="gl-mt-5 max-md:gl-mt-3"></span>
|
|
23
|
-
</template>
|
|
24
19
|
```
|
|
25
20
|
|
|
26
21
|
### Examples of **correct** code for this rule
|
|
@@ -35,11 +30,6 @@ This rule enforces the same conventions as [tailwind](./tailwind.md) in Vue temp
|
|
|
35
30
|
<template>
|
|
36
31
|
<span :class="`gl-bg-red-800`"></span>
|
|
37
32
|
</template>
|
|
38
|
-
|
|
39
|
-
<!-- Using max-width media query utility classes -->
|
|
40
|
-
<template>
|
|
41
|
-
<span class="gl-mt-3 md:gl-mt-5"></span>
|
|
42
|
-
</template>
|
|
43
33
|
```
|
|
44
34
|
|
|
45
35
|
## Options
|
|
@@ -48,7 +38,7 @@ No options.
|
|
|
48
38
|
|
|
49
39
|
## Related rules
|
|
50
40
|
|
|
51
|
-
- [tailwind](./tailwind.md)
|
|
41
|
+
- [tailwind-no-interpolation](./tailwind-no-interpolation.md)
|
|
52
42
|
|
|
53
43
|
## When Not To Use It
|
|
54
44
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @gitlab/vue-tailwind-no-max-width-media-queries
|
|
2
|
+
|
|
3
|
+
This rule enforces the same conventions as [tailwind-no-max-width-media-queries](./tailwind-no-max-width-media-queries.md) in Vue templates.
|
|
4
|
+
|
|
5
|
+
## Rule Details
|
|
6
|
+
|
|
7
|
+
### Examples of **incorrect** code for this rule
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<template>
|
|
11
|
+
<span class="gl-mt-5 max-md:gl-mt-3"></span>
|
|
12
|
+
</template>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Examples of **correct** code for this rule
|
|
16
|
+
|
|
17
|
+
```html
|
|
18
|
+
<template>
|
|
19
|
+
<span class="gl-mt-3 md:gl-mt-5"></span>
|
|
20
|
+
</template>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Options
|
|
24
|
+
|
|
25
|
+
No options.
|
|
26
|
+
|
|
27
|
+
## Related rules
|
|
28
|
+
|
|
29
|
+
- [tailwind-no-max-width-media-queries](./tailwind-no-max-width-media-queries.md)
|
|
30
|
+
|
|
31
|
+
## When Not To Use It
|
|
32
|
+
|
|
33
|
+
If the codebase doesn't leverage Tailwind CSS, keep this rule disabled.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Requirements
|
|
3
3
|
// ------------------------------------------------------------------------------
|
|
4
4
|
const { DOCS_BASE_URL } = require('../constants');
|
|
5
|
-
const { validateInterpolatedUtils
|
|
5
|
+
const { validateInterpolatedUtils } = require('../utils/tailwind-utils');
|
|
6
6
|
|
|
7
7
|
// ------------------------------------------------------------------------------
|
|
8
8
|
// Rule Definition
|
|
@@ -12,9 +12,9 @@ module.exports = {
|
|
|
12
12
|
meta: {
|
|
13
13
|
type: 'error',
|
|
14
14
|
docs: {
|
|
15
|
-
description: '
|
|
15
|
+
description: 'Prevents building Tailwind CSS utility classes with string interpolation.',
|
|
16
16
|
category: 'css',
|
|
17
|
-
url: DOCS_BASE_URL + '/tailwind.md',
|
|
17
|
+
url: DOCS_BASE_URL + '/tailwind-no-interpolation.md',
|
|
18
18
|
},
|
|
19
19
|
},
|
|
20
20
|
create(context) {
|
|
@@ -25,12 +25,6 @@ module.exports = {
|
|
|
25
25
|
TemplateLiteral(node) {
|
|
26
26
|
validateInterpolatedUtils(context, node);
|
|
27
27
|
},
|
|
28
|
-
TemplateElement(node) {
|
|
29
|
-
validateMaxWidthUtils(context, node);
|
|
30
|
-
},
|
|
31
|
-
Literal(node) {
|
|
32
|
-
validateMaxWidthUtils(context, node);
|
|
33
|
-
},
|
|
34
28
|
};
|
|
35
29
|
},
|
|
36
30
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// ------------------------------------------------------------------------------
|
|
2
|
+
// Requirements
|
|
3
|
+
// ------------------------------------------------------------------------------
|
|
4
|
+
const { DOCS_BASE_URL } = require('../constants');
|
|
5
|
+
const { validateMaxWidthMediaQueryUtils } = require('../utils/tailwind-utils');
|
|
6
|
+
|
|
7
|
+
// ------------------------------------------------------------------------------
|
|
8
|
+
// Rule Definition
|
|
9
|
+
// ------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
meta: {
|
|
13
|
+
type: 'error',
|
|
14
|
+
docs: {
|
|
15
|
+
description: 'Prevents the usage of max-width media query Tailwind CSS utility classes.',
|
|
16
|
+
category: 'css',
|
|
17
|
+
url: DOCS_BASE_URL + '/tailwind-no-max-width-media-queries.md',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
return {
|
|
22
|
+
TemplateElement(node) {
|
|
23
|
+
validateMaxWidthMediaQueryUtils(context, node);
|
|
24
|
+
},
|
|
25
|
+
Literal(node) {
|
|
26
|
+
validateMaxWidthMediaQueryUtils(context, node);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// ------------------------------------------------------------------------------
|
|
4
4
|
const { DOCS_BASE_URL } = require('../constants');
|
|
5
5
|
const { defineTemplateBodyVisitor } = require('../utils/index');
|
|
6
|
-
const { validateInterpolatedUtils
|
|
6
|
+
const { validateInterpolatedUtils } = require('../utils/tailwind-utils');
|
|
7
7
|
|
|
8
8
|
// ------------------------------------------------------------------------------
|
|
9
9
|
// Rule Definition
|
|
@@ -13,10 +13,9 @@ module.exports = {
|
|
|
13
13
|
meta: {
|
|
14
14
|
type: 'error',
|
|
15
15
|
docs: {
|
|
16
|
-
description:
|
|
17
|
-
'Ensures Tailwind CSS is used according to our internal guidelines in Vue templates.',
|
|
16
|
+
description: 'Prevents building Tailwind CSS utility classes with string interpolation.',
|
|
18
17
|
category: 'css',
|
|
19
|
-
url: DOCS_BASE_URL + '/vue-tailwind.md',
|
|
18
|
+
url: DOCS_BASE_URL + '/vue-tailwind-no-interpolation.md',
|
|
20
19
|
},
|
|
21
20
|
},
|
|
22
21
|
create(context) {
|
|
@@ -27,15 +26,6 @@ module.exports = {
|
|
|
27
26
|
TemplateLiteral(node) {
|
|
28
27
|
validateInterpolatedUtils(context, node);
|
|
29
28
|
},
|
|
30
|
-
VLiteral(node) {
|
|
31
|
-
validateMaxWidthUtils(context, node);
|
|
32
|
-
},
|
|
33
|
-
Literal(node) {
|
|
34
|
-
validateMaxWidthUtils(context, node);
|
|
35
|
-
},
|
|
36
|
-
TemplateElement(node) {
|
|
37
|
-
validateMaxWidthUtils(context, node);
|
|
38
|
-
},
|
|
39
29
|
});
|
|
40
30
|
},
|
|
41
31
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// ------------------------------------------------------------------------------
|
|
2
|
+
// Requirements
|
|
3
|
+
// ------------------------------------------------------------------------------
|
|
4
|
+
const { DOCS_BASE_URL } = require('../constants');
|
|
5
|
+
const { defineTemplateBodyVisitor } = require('../utils/index');
|
|
6
|
+
const { validateMaxWidthMediaQueryUtils } = require('../utils/tailwind-utils');
|
|
7
|
+
|
|
8
|
+
// ------------------------------------------------------------------------------
|
|
9
|
+
// Rule Definition
|
|
10
|
+
// ------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
meta: {
|
|
14
|
+
type: 'error',
|
|
15
|
+
docs: {
|
|
16
|
+
description: 'Prevents the usage of max-width media query Tailwind CSS utility classes.',
|
|
17
|
+
category: 'css',
|
|
18
|
+
url: DOCS_BASE_URL + '/vue-tailwind-no-max-width-media-queries.md',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
create(context) {
|
|
22
|
+
return defineTemplateBodyVisitor(context, {
|
|
23
|
+
VLiteral(node) {
|
|
24
|
+
validateMaxWidthMediaQueryUtils(context, node);
|
|
25
|
+
},
|
|
26
|
+
Literal(node) {
|
|
27
|
+
validateMaxWidthMediaQueryUtils(context, node);
|
|
28
|
+
},
|
|
29
|
+
TemplateElement(node) {
|
|
30
|
+
validateMaxWidthMediaQueryUtils(context, node);
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
};
|
|
@@ -6,10 +6,10 @@ const INTERPOLATED_UTILS_VALIDATORS = {
|
|
|
6
6
|
TemplateLiteral: templateLiteralHasInterpolatedUtils,
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const MAX_WIDTH_MEDIA_QUERY_PATTERN = /max-(sm|md|lg|xl):gl-/;
|
|
10
|
+
const MAX_WIDTH_MEDIA_QUERY_UTIL_ERROR =
|
|
11
11
|
'Do not use max-width media query utility classes unless absolutely necessary. Use min-width media query utility classes instead.';
|
|
12
|
-
const
|
|
12
|
+
const MAX_WIDTH_MEDIA_QUERY_UTIL_VALIDATORS = {
|
|
13
13
|
Literal: literalHasMaxWidthUtils,
|
|
14
14
|
VLiteral: literalHasMaxWidthUtils,
|
|
15
15
|
TemplateElement: templateElementHasMaxWidthUtils,
|
|
@@ -39,29 +39,29 @@ function validateInterpolatedUtils(context, node) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function literalHasMaxWidthUtils(node) {
|
|
42
|
-
return
|
|
42
|
+
return MAX_WIDTH_MEDIA_QUERY_PATTERN.test(node.value);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
function templateElementHasMaxWidthUtils(node) {
|
|
46
|
-
return
|
|
46
|
+
return MAX_WIDTH_MEDIA_QUERY_PATTERN.test(node.value.raw);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function
|
|
50
|
-
if (
|
|
49
|
+
function validateMaxWidthMediaQueryUtils(context, node) {
|
|
50
|
+
if (MAX_WIDTH_MEDIA_QUERY_UTIL_VALIDATORS[node.type] === undefined) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
if (
|
|
54
|
+
if (MAX_WIDTH_MEDIA_QUERY_UTIL_VALIDATORS[node.type](node)) {
|
|
55
55
|
context.report({
|
|
56
56
|
node,
|
|
57
|
-
message:
|
|
57
|
+
message: MAX_WIDTH_MEDIA_QUERY_UTIL_ERROR,
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
module.exports = {
|
|
63
63
|
validateInterpolatedUtils,
|
|
64
|
-
|
|
64
|
+
validateMaxWidthMediaQueryUtils,
|
|
65
65
|
INTERPOLATED_UTIL_ERROR,
|
|
66
|
-
|
|
66
|
+
MAX_WIDTH_MEDIA_QUERY_UTIL_ERROR,
|
|
67
67
|
};
|