@gitlab/eslint-plugin 20.2.1 → 20.3.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
@@ -1,3 +1,10 @@
1
+ # [20.3.0](https://gitlab.com/gitlab-org/frontend/eslint-plugin/compare/v20.2.1...v20.3.0) (2024-10-02)
2
+
3
+
4
+ ### Features
5
+
6
+ * **tailwind:** add check for max-width CSS utils ([ec8026a](https://gitlab.com/gitlab-org/frontend/eslint-plugin/commit/ec8026a4bf1961b90808cdfc7984640ab16fdc40))
7
+
1
8
  ## [20.2.1](https://gitlab.com/gitlab-org/frontend/eslint-plugin/compare/v20.2.0...v20.2.1) (2024-09-06)
2
9
 
3
10
 
@@ -13,6 +13,9 @@ 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'];
16
19
  ```
17
20
 
18
21
  ### Examples of **correct** code for this rule
@@ -23,6 +26,9 @@ const cssUtilsStringLiteral = 'gl-bg-red-800';
23
26
 
24
27
  // Utilities declared as a template literal without interpolation
25
28
  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'];
26
32
  ```
27
33
 
28
34
  ## Options
@@ -16,6 +16,11 @@ 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>
19
24
  ```
20
25
 
21
26
  ### Examples of **correct** code for this rule
@@ -30,6 +35,11 @@ This rule enforces the same conventions as [tailwind](./tailwind.md) in Vue temp
30
35
  <template>
31
36
  <span :class="`gl-bg-red-800`"></span>
32
37
  </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>
33
43
  ```
34
44
 
35
45
  ## Options
@@ -48,6 +48,12 @@ const tsConfig = {
48
48
  '@typescript-eslint/no-shadow': 'error',
49
49
  '@typescript-eslint/return-await': 'error',
50
50
  '@typescript-eslint/no-floating-promises': 'error',
51
+ '@typescript-eslint/explicit-member-accessibility': [
52
+ 'error',
53
+ {
54
+ accessibility: 'no-public',
55
+ },
56
+ ],
51
57
  'class-methods-use-this': 'off',
52
58
  'import/no-cycle': 'error',
53
59
  'promise/param-names': 'off',
@@ -2,7 +2,7 @@
2
2
  // Requirements
3
3
  // ------------------------------------------------------------------------------
4
4
  const { DOCS_BASE_URL } = require('../constants');
5
- const { validateInterpolatedUtils } = require('../utils/tailwind-utils');
5
+ const { validateInterpolatedUtils, validateMaxWidthUtils } = require('../utils/tailwind-utils');
6
6
 
7
7
  // ------------------------------------------------------------------------------
8
8
  // Rule Definition
@@ -25,6 +25,12 @@ 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
+ },
28
34
  };
29
35
  },
30
36
  };
@@ -1,10 +1,9 @@
1
-
2
1
  // ------------------------------------------------------------------------------
3
2
  // Requirements
4
3
  // ------------------------------------------------------------------------------
5
4
  const { DOCS_BASE_URL } = require('../constants');
6
5
  const { defineTemplateBodyVisitor } = require('../utils/index');
7
- const { validateInterpolatedUtils } = require('../utils/tailwind-utils');
6
+ const { validateInterpolatedUtils, validateMaxWidthUtils } = require('../utils/tailwind-utils');
8
7
 
9
8
  // ------------------------------------------------------------------------------
10
9
  // Rule Definition
@@ -14,7 +13,8 @@ module.exports = {
14
13
  meta: {
15
14
  type: 'error',
16
15
  docs: {
17
- description: 'Ensures Tailwind CSS is used according to our internal guidelines in Vue templates.',
16
+ description:
17
+ 'Ensures Tailwind CSS is used according to our internal guidelines in Vue templates.',
18
18
  category: 'css',
19
19
  url: DOCS_BASE_URL + '/vue-tailwind.md',
20
20
  },
@@ -22,10 +22,19 @@ module.exports = {
22
22
  create(context) {
23
23
  return defineTemplateBodyVisitor(context, {
24
24
  BinaryExpression(node) {
25
- validateInterpolatedUtils(context, node)
25
+ validateInterpolatedUtils(context, node);
26
26
  },
27
27
  TemplateLiteral(node) {
28
- validateInterpolatedUtils(context, node)
28
+ validateInterpolatedUtils(context, node);
29
+ },
30
+ VLiteral(node) {
31
+ validateMaxWidthUtils(context, node);
32
+ },
33
+ Literal(node) {
34
+ validateMaxWidthUtils(context, node);
35
+ },
36
+ TemplateElement(node) {
37
+ validateMaxWidthUtils(context, node);
29
38
  },
30
39
  });
31
40
  },
@@ -6,6 +6,15 @@ const INTERPOLATED_UTILS_VALIDATORS = {
6
6
  TemplateLiteral: templateLiteralHasInterpolatedUtils,
7
7
  };
8
8
 
9
+ const MAX_WIDTH_PATTERN = /max-(sm|md|lg|xl):gl-/;
10
+ const MAX_WIDTH_UTIL_ERROR =
11
+ 'Do not use max-width media query utility classes unless absolutely necessary. Use min-width media query utility classes instead.';
12
+ const MAX_WIDTH_UTILS_VALIDATORS = {
13
+ Literal: literalHasMaxWidthUtils,
14
+ VLiteral: literalHasMaxWidthUtils,
15
+ TemplateElement: templateElementHasMaxWidthUtils,
16
+ };
17
+
9
18
  function binaryExpressionHasInterpolatedUtils(node) {
10
19
  return node.operator === '+' && INTERPOLATION_PATTERN.test(node.left.value);
11
20
  }
@@ -29,7 +38,30 @@ function validateInterpolatedUtils(context, node) {
29
38
  }
30
39
  }
31
40
 
41
+ function literalHasMaxWidthUtils(node) {
42
+ return MAX_WIDTH_PATTERN.test(node.value);
43
+ }
44
+
45
+ function templateElementHasMaxWidthUtils(node) {
46
+ return MAX_WIDTH_PATTERN.test(node.value.raw);
47
+ }
48
+
49
+ function validateMaxWidthUtils(context, node) {
50
+ if (MAX_WIDTH_UTILS_VALIDATORS[node.type] === undefined) {
51
+ return;
52
+ }
53
+
54
+ if (MAX_WIDTH_UTILS_VALIDATORS[node.type](node)) {
55
+ context.report({
56
+ node,
57
+ message: MAX_WIDTH_UTIL_ERROR,
58
+ });
59
+ }
60
+ }
61
+
32
62
  module.exports = {
33
63
  validateInterpolatedUtils,
64
+ validateMaxWidthUtils,
34
65
  INTERPOLATED_UTIL_ERROR,
66
+ MAX_WIDTH_UTIL_ERROR,
35
67
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/eslint-plugin",
3
- "version": "20.2.1",
3
+ "version": "20.3.0",
4
4
  "description": "GitLab package for our custom eslint rules",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {