@atlaskit/eslint-plugin-design-system 13.8.0 → 13.10.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +2 -0
  3. package/dist/cjs/presets/all-flat.codegen.js +3 -1
  4. package/dist/cjs/presets/all.codegen.js +3 -1
  5. package/dist/cjs/presets/recommended-flat.codegen.js +3 -1
  6. package/dist/cjs/presets/recommended.codegen.js +3 -1
  7. package/dist/cjs/rules/index.codegen.js +5 -1
  8. package/dist/cjs/rules/no-html-heading/index.js +40 -0
  9. package/dist/cjs/rules/no-html-heading/node-types/index.js +19 -0
  10. package/dist/cjs/rules/no-html-heading/node-types/jsx-element/index.js +136 -0
  11. package/dist/cjs/rules/no-html-heading/node-types/styled-component/index.js +42 -0
  12. package/dist/cjs/rules/no-html-heading/node-types/supported.js +82 -0
  13. package/dist/cjs/rules/no-html-select/index.js +40 -0
  14. package/dist/cjs/rules/no-html-select/node-types/index.js +19 -0
  15. package/dist/cjs/rules/no-html-select/node-types/jsx-element/index.js +27 -0
  16. package/dist/cjs/rules/no-html-select/node-types/styled-component/index.js +42 -0
  17. package/dist/cjs/rules/no-html-select/node-types/supported.js +66 -0
  18. package/dist/es2019/presets/all-flat.codegen.js +3 -1
  19. package/dist/es2019/presets/all.codegen.js +3 -1
  20. package/dist/es2019/presets/recommended-flat.codegen.js +3 -1
  21. package/dist/es2019/presets/recommended.codegen.js +3 -1
  22. package/dist/es2019/rules/index.codegen.js +5 -1
  23. package/dist/es2019/rules/no-html-heading/index.js +34 -0
  24. package/dist/es2019/rules/no-html-heading/node-types/index.js +2 -0
  25. package/dist/es2019/rules/no-html-heading/node-types/jsx-element/index.js +99 -0
  26. package/dist/es2019/rules/no-html-heading/node-types/styled-component/index.js +37 -0
  27. package/dist/es2019/rules/no-html-heading/node-types/supported.js +72 -0
  28. package/dist/es2019/rules/no-html-select/index.js +34 -0
  29. package/dist/es2019/rules/no-html-select/node-types/index.js +2 -0
  30. package/dist/es2019/rules/no-html-select/node-types/jsx-element/index.js +19 -0
  31. package/dist/es2019/rules/no-html-select/node-types/styled-component/index.js +37 -0
  32. package/dist/es2019/rules/no-html-select/node-types/supported.js +56 -0
  33. package/dist/esm/presets/all-flat.codegen.js +3 -1
  34. package/dist/esm/presets/all.codegen.js +3 -1
  35. package/dist/esm/presets/recommended-flat.codegen.js +3 -1
  36. package/dist/esm/presets/recommended.codegen.js +3 -1
  37. package/dist/esm/rules/index.codegen.js +5 -1
  38. package/dist/esm/rules/no-html-heading/index.js +34 -0
  39. package/dist/esm/rules/no-html-heading/node-types/index.js +2 -0
  40. package/dist/esm/rules/no-html-heading/node-types/jsx-element/index.js +127 -0
  41. package/dist/esm/rules/no-html-heading/node-types/styled-component/index.js +36 -0
  42. package/dist/esm/rules/no-html-heading/node-types/supported.js +73 -0
  43. package/dist/esm/rules/no-html-select/index.js +34 -0
  44. package/dist/esm/rules/no-html-select/node-types/index.js +2 -0
  45. package/dist/esm/rules/no-html-select/node-types/jsx-element/index.js +18 -0
  46. package/dist/esm/rules/no-html-select/node-types/styled-component/index.js +36 -0
  47. package/dist/esm/rules/no-html-select/node-types/supported.js +57 -0
  48. package/dist/types/index.codegen.d.ts +18 -0
  49. package/dist/types/presets/all-flat.codegen.d.ts +2 -0
  50. package/dist/types/presets/all.codegen.d.ts +2 -0
  51. package/dist/types/presets/recommended-flat.codegen.d.ts +2 -0
  52. package/dist/types/presets/recommended.codegen.d.ts +2 -0
  53. package/dist/types/rules/index.codegen.d.ts +2 -0
  54. package/dist/types/rules/no-html-heading/index.d.ts +3 -0
  55. package/dist/types/rules/no-html-heading/node-types/index.d.ts +2 -0
  56. package/dist/types/rules/no-html-heading/node-types/jsx-element/index.d.ts +8 -0
  57. package/dist/types/rules/no-html-heading/node-types/styled-component/index.d.ts +8 -0
  58. package/dist/types/rules/no-html-heading/node-types/supported.d.ts +7 -0
  59. package/dist/types/rules/no-html-select/index.d.ts +3 -0
  60. package/dist/types/rules/no-html-select/node-types/index.d.ts +2 -0
  61. package/dist/types/rules/no-html-select/node-types/jsx-element/index.d.ts +8 -0
  62. package/dist/types/rules/no-html-select/node-types/styled-component/index.d.ts +8 -0
  63. package/dist/types/rules/no-html-select/node-types/supported.d.ts +7 -0
  64. package/dist/types-ts4.5/index.codegen.d.ts +18 -0
  65. package/dist/types-ts4.5/presets/all-flat.codegen.d.ts +2 -0
  66. package/dist/types-ts4.5/presets/all.codegen.d.ts +2 -0
  67. package/dist/types-ts4.5/presets/recommended-flat.codegen.d.ts +2 -0
  68. package/dist/types-ts4.5/presets/recommended.codegen.d.ts +2 -0
  69. package/dist/types-ts4.5/rules/index.codegen.d.ts +2 -0
  70. package/dist/types-ts4.5/rules/no-html-heading/index.d.ts +3 -0
  71. package/dist/types-ts4.5/rules/no-html-heading/node-types/index.d.ts +2 -0
  72. package/dist/types-ts4.5/rules/no-html-heading/node-types/jsx-element/index.d.ts +8 -0
  73. package/dist/types-ts4.5/rules/no-html-heading/node-types/styled-component/index.d.ts +8 -0
  74. package/dist/types-ts4.5/rules/no-html-heading/node-types/supported.d.ts +7 -0
  75. package/dist/types-ts4.5/rules/no-html-select/index.d.ts +3 -0
  76. package/dist/types-ts4.5/rules/no-html-select/node-types/index.d.ts +2 -0
  77. package/dist/types-ts4.5/rules/no-html-select/node-types/jsx-element/index.d.ts +8 -0
  78. package/dist/types-ts4.5/rules/no-html-select/node-types/styled-component/index.d.ts +8 -0
  79. package/dist/types-ts4.5/rules/no-html-select/node-types/supported.d.ts +7 -0
  80. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
- * @codegen <<SignedSource::5945e51ebc0b2c3553b51162f07dbd63>>
3
+ * @codegen <<SignedSource::19fc297469c40b1fa9fd64c9f9313ba7>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import consistentCssPropUsage from './consistent-css-prop-usage';
@@ -23,8 +23,10 @@ import noExportedKeyframes from './no-exported-keyframes';
23
23
  import noHtmlAnchor from './no-html-anchor';
24
24
  import noHtmlButton from './no-html-button';
25
25
  import noHtmlCheckbox from './no-html-checkbox';
26
+ import noHtmlHeading from './no-html-heading';
26
27
  import noHtmlImage from './no-html-image';
27
28
  import noHtmlRange from './no-html-range';
29
+ import noHtmlSelect from './no-html-select';
28
30
  import noInvalidCssMap from './no-invalid-css-map';
29
31
  import noKeyframesTaggedTemplateExpression from './no-keyframes-tagged-template-expression';
30
32
  import noLegacyIcons from './no-legacy-icons';
@@ -78,8 +80,10 @@ export var rules = {
78
80
  'no-html-anchor': noHtmlAnchor,
79
81
  'no-html-button': noHtmlButton,
80
82
  'no-html-checkbox': noHtmlCheckbox,
83
+ 'no-html-heading': noHtmlHeading,
81
84
  'no-html-image': noHtmlImage,
82
85
  'no-html-range': noHtmlRange,
86
+ 'no-html-select': noHtmlSelect,
83
87
  'no-invalid-css-map': noInvalidCssMap,
84
88
  'no-keyframes-tagged-template-expression': noKeyframesTaggedTemplateExpression,
85
89
  'no-legacy-icons': noLegacyIcons,
@@ -0,0 +1,34 @@
1
+ import { createLintRule } from '../utils/create-rule';
2
+ import { JSXElement as _JSXElement, StyledComponent } from './node-types';
3
+ var rule = createLintRule({
4
+ meta: {
5
+ name: 'no-html-heading',
6
+ type: 'suggestion',
7
+ hasSuggestions: true,
8
+ docs: {
9
+ description: 'Discourage direct usage of HTML heading elements in favor of Atlassian Design System heading components.',
10
+ recommended: true,
11
+ severity: 'warn'
12
+ },
13
+ messages: {
14
+ noHtmlHeading: "This <{{ name }}> should be replaced with a heading component from the Atlassian Design System. ADS headings include ensure accessible implementations and provide access to ADS styling features like design tokens."
15
+ }
16
+ },
17
+ create: function create(context) {
18
+ return {
19
+ // transforms styled.<heading>(...) usages
20
+ CallExpression: function CallExpression(node) {
21
+ StyledComponent.lint(node, {
22
+ context: context
23
+ });
24
+ },
25
+ // transforms <heading css={...}> usages
26
+ JSXElement: function JSXElement(node) {
27
+ _JSXElement.lint(node, {
28
+ context: context
29
+ });
30
+ }
31
+ };
32
+ }
33
+ });
34
+ export default rule;
@@ -0,0 +1,2 @@
1
+ export { StyledComponent } from './styled-component';
2
+ export { JSXElement } from './jsx-element';
@@ -0,0 +1,127 @@
1
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
2
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
3
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
+ import { isNodeOfType } from 'eslint-codemod-utils';
5
+ import { getSourceCode } from '@atlaskit/eslint-utils/context-compat';
6
+ import * as ast from '../../../../ast-nodes';
7
+ import { isSupportedForLint } from '../supported';
8
+ function isImportDeclaration(node) {
9
+ return node.type === 'ImportDeclaration';
10
+ }
11
+ export var JSXElement = {
12
+ lint: function lint(node, _ref) {
13
+ var context = _ref.context;
14
+ if (!isSupportedForLint(node)) {
15
+ return;
16
+ }
17
+ var nodeName = ast.JSXElement.getName(node);
18
+ var sourceCode = getSourceCode(context);
19
+ var importDeclarations = sourceCode.ast.body.filter(isImportDeclaration);
20
+ var existingHeadingName = null;
21
+ var usedNames = new Set();
22
+
23
+ // Check for existing imports
24
+ var _iterator = _createForOfIteratorHelper(importDeclarations),
25
+ _step;
26
+ try {
27
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
28
+ var declaration = _step.value;
29
+ var _iterator2 = _createForOfIteratorHelper(declaration.specifiers),
30
+ _step2;
31
+ try {
32
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
33
+ var specifier = _step2.value;
34
+ usedNames.add(specifier.local.name);
35
+ }
36
+ } catch (err) {
37
+ _iterator2.e(err);
38
+ } finally {
39
+ _iterator2.f();
40
+ }
41
+ if (declaration.source.value === '@atlaskit/heading') {
42
+ var defaultSpecifier = declaration.specifiers.find(function (specifier) {
43
+ return specifier.type === 'ImportDefaultSpecifier';
44
+ });
45
+ if (defaultSpecifier) {
46
+ existingHeadingName = defaultSpecifier.local.name;
47
+ }
48
+ }
49
+ }
50
+ } catch (err) {
51
+ _iterator.e(err);
52
+ } finally {
53
+ _iterator.f();
54
+ }
55
+ var generateUniqueName = function generateUniqueName(baseName) {
56
+ var index = 1;
57
+ var newName = baseName;
58
+ while (usedNames.has(newName)) {
59
+ newName = "".concat(baseName).concat(index);
60
+ index++;
61
+ }
62
+ return newName;
63
+ };
64
+ var headingName = existingHeadingName || generateUniqueName('Heading');
65
+ context.report({
66
+ node: node.openingElement,
67
+ messageId: 'noHtmlHeading',
68
+ data: {
69
+ name: nodeName
70
+ },
71
+ suggest: [{
72
+ desc: 'Replace with Heading component from @atlaskit/heading',
73
+ fix: function fix(fixer) {
74
+ var _node$closingElement;
75
+ var openingTagRange = node.openingElement.range;
76
+ var closingTagRange = (_node$closingElement = node.closingElement) === null || _node$closingElement === void 0 ? void 0 : _node$closingElement.range;
77
+ var elementName = isNodeOfType(node.openingElement.name, 'JSXIdentifier') ? node.openingElement.name.name : '';
78
+ var attributesText = node.openingElement.attributes
79
+ // Don't bring in the "role" or the "aria-level" because it's not needed
80
+ .filter(function (attr) {
81
+ return !isNodeOfType(attr, 'JSXAttribute') || typeof attr.name.name === 'string' && !['role', 'aria-level'].includes(attr.name.name);
82
+ }).map(function (attr) {
83
+ return sourceCode.getText(attr);
84
+ }).join(' ');
85
+
86
+ // Get the heading level
87
+ var headingLevel = '';
88
+ var ariaLevel = node.openingElement.attributes.find(function (attr) {
89
+ return isNodeOfType(attr, 'JSXAttribute') && attr.name.name === 'aria-level';
90
+ });
91
+ if (ariaLevel && isNodeOfType(ariaLevel, 'JSXAttribute')) {
92
+ var _ariaLevel$value, _ariaLevel$value2;
93
+ // If it's a string
94
+ if (((_ariaLevel$value = ariaLevel.value) === null || _ariaLevel$value === void 0 ? void 0 : _ariaLevel$value.type) === 'Literal' && ariaLevel.value.value) {
95
+ headingLevel = "h".concat(ariaLevel.value.value);
96
+ // If it's a number or some other literal in an expression container
97
+ } else if (((_ariaLevel$value2 = ariaLevel.value) === null || _ariaLevel$value2 === void 0 ? void 0 : _ariaLevel$value2.type) === 'JSXExpressionContainer' && ariaLevel.value.expression.type === 'Literal' && ariaLevel.value.expression.value) {
98
+ headingLevel = "h".concat(ariaLevel.value.expression.value);
99
+ }
100
+ } else if (elementName.match(/h[1-6]/)) {
101
+ headingLevel = elementName;
102
+ }
103
+ var fixers = [];
104
+
105
+ // Replace <a> with <Heading> and retain attributes
106
+ if (openingTagRange) {
107
+ if (node.openingElement.selfClosing) {
108
+ fixers.push(fixer.replaceTextRange([openingTagRange[0] + 1, openingTagRange[1] - 1], "".concat(headingName).concat(headingLevel ? " as=\"".concat(headingLevel, "\"") : '').concat(attributesText ? " ".concat(attributesText) : '', " /")));
109
+ } else {
110
+ fixers.push(fixer.replaceTextRange([openingTagRange[0] + 1, openingTagRange[1] - 1], "".concat(headingName).concat(headingLevel ? " as=\"".concat(headingLevel, "\"") : '').concat(attributesText ? " ".concat(attributesText) : '')));
111
+ }
112
+ }
113
+ if (closingTagRange && !node.openingElement.selfClosing) {
114
+ fixers.push(fixer.replaceTextRange([closingTagRange[0] + 2, closingTagRange[1] - 1], headingName));
115
+ }
116
+
117
+ // Add import if not present
118
+ if (!existingHeadingName) {
119
+ var importStatement = "import ".concat(headingName, " from '@atlaskit/heading';\n");
120
+ fixers.push(fixer.insertTextBefore(sourceCode.ast, importStatement));
121
+ }
122
+ return fixers;
123
+ }
124
+ }]
125
+ });
126
+ }
127
+ };
@@ -0,0 +1,36 @@
1
+ /* eslint-disable @repo/internal/react/require-jsdoc */
2
+
3
+ import { isNodeOfType } from 'eslint-codemod-utils';
4
+ import { getScope } from '@atlaskit/eslint-utils/context-compat';
5
+ import { getJsxElementByName } from '../../../utils/get-jsx-element-by-name';
6
+ import { getStyledComponentCall } from '../../../utils/get-styled-component-call';
7
+ import { isSupportedForLint } from '../supported';
8
+ export var StyledComponent = {
9
+ lint: function lint(node, _ref) {
10
+ var _getJsxElementByName;
11
+ var context = _ref.context;
12
+ if (!isNodeOfType(node, 'CallExpression') || !isNodeOfType(node.callee, 'MemberExpression') || !isNodeOfType(node.callee.object, 'Identifier') || !isNodeOfType(node.callee.property, 'Identifier')) {
13
+ return;
14
+ }
15
+ var styles = getStyledComponentCall(node);
16
+ var elementName = node.callee.property.name;
17
+ if (!styles || !isNodeOfType(styles.id, 'Identifier')) {
18
+ return;
19
+ }
20
+ var jsxElement = (_getJsxElementByName = getJsxElementByName(styles.id.name, getScope(context, node))) === null || _getJsxElementByName === void 0 ? void 0 : _getJsxElementByName.parent;
21
+ if (!jsxElement) {
22
+ // If there's no JSX element, we can't determine if it's being used as an heading or not
23
+ return;
24
+ }
25
+ if (jsxElement && !isSupportedForLint(jsxElement, elementName)) {
26
+ return;
27
+ }
28
+ context.report({
29
+ node: styles,
30
+ messageId: 'noHtmlHeading',
31
+ data: {
32
+ name: node.callee.property.name
33
+ }
34
+ });
35
+ }
36
+ };
@@ -0,0 +1,73 @@
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import * as ast from '../../../ast-nodes';
3
+ var supportedElements = [{
4
+ name: 'h1'
5
+ }, {
6
+ name: 'h2'
7
+ }, {
8
+ name: 'h3'
9
+ }, {
10
+ name: 'h4'
11
+ }, {
12
+ name: 'h5'
13
+ }, {
14
+ name: 'h6'
15
+ }, {
16
+ name: '*',
17
+ attributes: [{
18
+ name: 'role',
19
+ values: ['heading']
20
+ }]
21
+ }];
22
+
23
+ /**
24
+ * Determines if the given JSX element is a supported element to lint with this rule.
25
+ */
26
+ export function isSupportedForLint(jsxNode, elementName) {
27
+ if (!isNodeOfType(jsxNode, 'JSXElement')) {
28
+ return false;
29
+ }
30
+
31
+ // Allow passing in the element name because the jsxNode doesn't
32
+ // represent the element name with styled components
33
+ var elName = elementName || ast.JSXElement.getName(jsxNode);
34
+ if (!elName) {
35
+ return false;
36
+ }
37
+
38
+ // Only check native HTML elements, not components
39
+ if (elName[0] !== elName[0].toLowerCase()) {
40
+ return false;
41
+ }
42
+ var supportedElement = supportedElements.find(function (_ref) {
43
+ var name = _ref.name;
44
+ return name === elName;
45
+ });
46
+ if (!supportedElement) {
47
+ supportedElement = supportedElements.find(function (_ref2) {
48
+ var name = _ref2.name;
49
+ return name === '*';
50
+ });
51
+ }
52
+ if (!supportedElement) {
53
+ return false;
54
+ }
55
+
56
+ // Check if the element has any attributes that are not supported
57
+ var attributes = ast.JSXElement.getAttributes(jsxNode);
58
+ if (supportedElement.attributes && !supportedElement.attributes.every(function (_ref3) {
59
+ var name = _ref3.name,
60
+ values = _ref3.values;
61
+ return attributes.some(function (attribute) {
62
+ if (attribute.type === 'JSXSpreadAttribute') {
63
+ return false;
64
+ }
65
+ var isMatchingName = attribute.name.name === name;
66
+ var isMatchingValues = values && attribute.value && attribute.value.type === 'Literal' && typeof attribute.value.value === 'string' && (values === null || values === void 0 ? void 0 : values.includes(attribute.value.value));
67
+ return isMatchingName && isMatchingValues;
68
+ });
69
+ })) {
70
+ return false;
71
+ }
72
+ return true;
73
+ }
@@ -0,0 +1,34 @@
1
+ import { createLintRule } from '../utils/create-rule';
2
+ import { JSXElement as _JSXElement, StyledComponent } from './node-types';
3
+ var rule = createLintRule({
4
+ meta: {
5
+ name: 'no-html-select',
6
+ type: 'suggestion',
7
+ hasSuggestions: true,
8
+ docs: {
9
+ description: 'Discourage direct usage of HTML select elements in favor of the Atlassian Design System select component.',
10
+ recommended: true,
11
+ severity: 'warn'
12
+ },
13
+ messages: {
14
+ noHtmlSelect: "This <{{ name }}> should be replaced with the select component from the Atlassian Design System. ADS select components have event tracking, ensure accessible implementations, and provide access to ADS styling features like design tokens."
15
+ }
16
+ },
17
+ create: function create(context) {
18
+ return {
19
+ // transforms styled.<anchor>(...) usages
20
+ CallExpression: function CallExpression(node) {
21
+ StyledComponent.lint(node, {
22
+ context: context
23
+ });
24
+ },
25
+ // transforms <anchor css={...}> usages
26
+ JSXElement: function JSXElement(node) {
27
+ _JSXElement.lint(node, {
28
+ context: context
29
+ });
30
+ }
31
+ };
32
+ }
33
+ });
34
+ export default rule;
@@ -0,0 +1,2 @@
1
+ export { StyledComponent } from './styled-component';
2
+ export { JSXElement } from './jsx-element';
@@ -0,0 +1,18 @@
1
+ import * as ast from '../../../../ast-nodes';
2
+ import { isSupportedForLint } from '../supported';
3
+ export var JSXElement = {
4
+ lint: function lint(node, _ref) {
5
+ var context = _ref.context;
6
+ if (!isSupportedForLint(node)) {
7
+ return;
8
+ }
9
+ var nodeName = ast.JSXElement.getName(node);
10
+ context.report({
11
+ node: node.openingElement,
12
+ messageId: 'noHtmlSelect',
13
+ data: {
14
+ name: nodeName
15
+ }
16
+ });
17
+ }
18
+ };
@@ -0,0 +1,36 @@
1
+ /* eslint-disable @repo/internal/react/require-jsdoc */
2
+
3
+ import { isNodeOfType } from 'eslint-codemod-utils';
4
+ import { getScope } from '@atlaskit/eslint-utils/context-compat';
5
+ import { getJsxElementByName } from '../../../utils/get-jsx-element-by-name';
6
+ import { getStyledComponentCall } from '../../../utils/get-styled-component-call';
7
+ import { isSupportedForLint } from '../supported';
8
+ export var StyledComponent = {
9
+ lint: function lint(node, _ref) {
10
+ var _getJsxElementByName;
11
+ var context = _ref.context;
12
+ if (!isNodeOfType(node, 'CallExpression') || !isNodeOfType(node.callee, 'MemberExpression') || !isNodeOfType(node.callee.object, 'Identifier') || !isNodeOfType(node.callee.property, 'Identifier')) {
13
+ return;
14
+ }
15
+ var styles = getStyledComponentCall(node);
16
+ var elementName = node.callee.property.name;
17
+ if (!styles || !isNodeOfType(styles.id, 'Identifier')) {
18
+ return;
19
+ }
20
+ var jsxElement = (_getJsxElementByName = getJsxElementByName(styles.id.name, getScope(context, node))) === null || _getJsxElementByName === void 0 ? void 0 : _getJsxElementByName.parent;
21
+ if (!jsxElement) {
22
+ // If there's no JSX element, we can't determine if it's being used as an select or not
23
+ return;
24
+ }
25
+ if (jsxElement && !isSupportedForLint(jsxElement, elementName)) {
26
+ return;
27
+ }
28
+ context.report({
29
+ node: styles,
30
+ messageId: 'noHtmlSelect',
31
+ data: {
32
+ name: node.callee.property.name
33
+ }
34
+ });
35
+ }
36
+ };
@@ -0,0 +1,57 @@
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import * as ast from '../../../ast-nodes';
3
+ var supportedElements = [{
4
+ name: 'select'
5
+ }];
6
+
7
+ /**
8
+ * Determines if the given JSX element is a supported element to lint with this rule.
9
+ */
10
+ export function isSupportedForLint(jsxNode, elementName) {
11
+ if (!isNodeOfType(jsxNode, 'JSXElement')) {
12
+ return false;
13
+ }
14
+
15
+ // Allow passing in the element name because the jsxNode doesn't
16
+ // represent the element name with styled components
17
+ var elName = elementName || ast.JSXElement.getName(jsxNode);
18
+ if (!elName) {
19
+ return false;
20
+ }
21
+
22
+ // Only check native HTML elements, not components
23
+ if (elName[0] !== elName[0].toLowerCase()) {
24
+ return false;
25
+ }
26
+ var supportedElement = supportedElements.find(function (_ref) {
27
+ var name = _ref.name;
28
+ return name === elName;
29
+ });
30
+ if (!supportedElement) {
31
+ supportedElement = supportedElements.find(function (_ref2) {
32
+ var name = _ref2.name;
33
+ return name === '*';
34
+ });
35
+ }
36
+ if (!supportedElement) {
37
+ return false;
38
+ }
39
+
40
+ // Check if the element has any attributes that are not supported
41
+ var attributes = ast.JSXElement.getAttributes(jsxNode);
42
+ if (supportedElement.attributes && !supportedElement.attributes.every(function (_ref3) {
43
+ var name = _ref3.name,
44
+ values = _ref3.values;
45
+ return attributes.some(function (attribute) {
46
+ if (attribute.type === 'JSXSpreadAttribute') {
47
+ return false;
48
+ }
49
+ var isMatchingName = attribute.name.name === name;
50
+ var isMatchingValues = values && attribute.value && attribute.value.type === 'Literal' && typeof attribute.value.value === 'string' && (values === null || values === void 0 ? void 0 : values.includes(attribute.value.value));
51
+ return isMatchingName && isMatchingValues;
52
+ });
53
+ })) {
54
+ return false;
55
+ }
56
+ return true;
57
+ }
@@ -35,8 +35,10 @@ export declare const plugin: {
35
35
  'no-html-anchor': import("eslint").Rule.RuleModule;
36
36
  'no-html-button': import("eslint").Rule.RuleModule;
37
37
  'no-html-checkbox': import("eslint").Rule.RuleModule;
38
+ 'no-html-heading': import("eslint").Rule.RuleModule;
38
39
  'no-html-image': import("eslint").Rule.RuleModule;
39
40
  'no-html-range': import("eslint").Rule.RuleModule;
41
+ 'no-html-select': import("eslint").Rule.RuleModule;
40
42
  'no-invalid-css-map': import("eslint").Rule.RuleModule;
41
43
  'no-keyframes-tagged-template-expression': import("eslint").Rule.RuleModule;
42
44
  'no-legacy-icons': import("eslint").Rule.RuleModule;
@@ -91,8 +93,10 @@ export declare const plugin: {
91
93
  '@atlaskit/design-system/no-html-anchor': "warn";
92
94
  '@atlaskit/design-system/no-html-button': "warn";
93
95
  '@atlaskit/design-system/no-html-checkbox': "warn";
96
+ '@atlaskit/design-system/no-html-heading': "warn";
94
97
  '@atlaskit/design-system/no-html-image': "warn";
95
98
  '@atlaskit/design-system/no-html-range': "warn";
99
+ '@atlaskit/design-system/no-html-select': "warn";
96
100
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
97
101
  allowedFunctionCalls: string[][];
98
102
  }];
@@ -151,8 +155,10 @@ export declare const plugin: {
151
155
  '@atlaskit/design-system/no-html-anchor': "warn";
152
156
  '@atlaskit/design-system/no-html-button': "warn";
153
157
  '@atlaskit/design-system/no-html-checkbox': "warn";
158
+ '@atlaskit/design-system/no-html-heading': "warn";
154
159
  '@atlaskit/design-system/no-html-image': "warn";
155
160
  '@atlaskit/design-system/no-html-range': "warn";
161
+ '@atlaskit/design-system/no-html-select': "warn";
156
162
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
157
163
  allowedFunctionCalls: string[][];
158
164
  }];
@@ -204,8 +210,10 @@ export declare const plugin: {
204
210
  '@atlaskit/design-system/no-html-anchor': "warn";
205
211
  '@atlaskit/design-system/no-html-button': "warn";
206
212
  '@atlaskit/design-system/no-html-checkbox': "warn";
213
+ '@atlaskit/design-system/no-html-heading': "warn";
207
214
  '@atlaskit/design-system/no-html-image': "warn";
208
215
  '@atlaskit/design-system/no-html-range': "warn";
216
+ '@atlaskit/design-system/no-html-select': "warn";
209
217
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
210
218
  allowedFunctionCalls: string[][];
211
219
  }];
@@ -248,8 +256,10 @@ export declare const plugin: {
248
256
  '@atlaskit/design-system/no-html-anchor': "warn";
249
257
  '@atlaskit/design-system/no-html-button': "warn";
250
258
  '@atlaskit/design-system/no-html-checkbox': "warn";
259
+ '@atlaskit/design-system/no-html-heading': "warn";
251
260
  '@atlaskit/design-system/no-html-image': "warn";
252
261
  '@atlaskit/design-system/no-html-range': "warn";
262
+ '@atlaskit/design-system/no-html-select': "warn";
253
263
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
254
264
  allowedFunctionCalls: string[][];
255
265
  }];
@@ -298,8 +308,10 @@ declare const configs: {
298
308
  '@atlaskit/design-system/no-html-anchor': "warn";
299
309
  '@atlaskit/design-system/no-html-button': "warn";
300
310
  '@atlaskit/design-system/no-html-checkbox': "warn";
311
+ '@atlaskit/design-system/no-html-heading': "warn";
301
312
  '@atlaskit/design-system/no-html-image': "warn";
302
313
  '@atlaskit/design-system/no-html-range': "warn";
314
+ '@atlaskit/design-system/no-html-select': "warn";
303
315
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
304
316
  allowedFunctionCalls: string[][];
305
317
  }];
@@ -358,8 +370,10 @@ declare const configs: {
358
370
  '@atlaskit/design-system/no-html-anchor': "warn";
359
371
  '@atlaskit/design-system/no-html-button': "warn";
360
372
  '@atlaskit/design-system/no-html-checkbox': "warn";
373
+ '@atlaskit/design-system/no-html-heading': "warn";
361
374
  '@atlaskit/design-system/no-html-image': "warn";
362
375
  '@atlaskit/design-system/no-html-range': "warn";
376
+ '@atlaskit/design-system/no-html-select': "warn";
363
377
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
364
378
  allowedFunctionCalls: string[][];
365
379
  }];
@@ -411,8 +425,10 @@ declare const configs: {
411
425
  '@atlaskit/design-system/no-html-anchor': "warn";
412
426
  '@atlaskit/design-system/no-html-button': "warn";
413
427
  '@atlaskit/design-system/no-html-checkbox': "warn";
428
+ '@atlaskit/design-system/no-html-heading': "warn";
414
429
  '@atlaskit/design-system/no-html-image': "warn";
415
430
  '@atlaskit/design-system/no-html-range': "warn";
431
+ '@atlaskit/design-system/no-html-select': "warn";
416
432
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
417
433
  allowedFunctionCalls: string[][];
418
434
  }];
@@ -455,8 +471,10 @@ declare const configs: {
455
471
  '@atlaskit/design-system/no-html-anchor': "warn";
456
472
  '@atlaskit/design-system/no-html-button': "warn";
457
473
  '@atlaskit/design-system/no-html-checkbox': "warn";
474
+ '@atlaskit/design-system/no-html-heading': "warn";
458
475
  '@atlaskit/design-system/no-html-image': "warn";
459
476
  '@atlaskit/design-system/no-html-range': "warn";
477
+ '@atlaskit/design-system/no-html-select': "warn";
460
478
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
461
479
  allowedFunctionCalls: string[][];
462
480
  }];
@@ -18,8 +18,10 @@ declare const _default: {
18
18
  '@atlaskit/design-system/no-html-anchor': "warn";
19
19
  '@atlaskit/design-system/no-html-button': "warn";
20
20
  '@atlaskit/design-system/no-html-checkbox': "warn";
21
+ '@atlaskit/design-system/no-html-heading': "warn";
21
22
  '@atlaskit/design-system/no-html-image': "warn";
22
23
  '@atlaskit/design-system/no-html-range': "warn";
24
+ '@atlaskit/design-system/no-html-select': "warn";
23
25
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
24
26
  allowedFunctionCalls: string[][];
25
27
  }];
@@ -18,8 +18,10 @@ declare const _default: {
18
18
  '@atlaskit/design-system/no-html-anchor': "warn";
19
19
  '@atlaskit/design-system/no-html-button': "warn";
20
20
  '@atlaskit/design-system/no-html-checkbox': "warn";
21
+ '@atlaskit/design-system/no-html-heading': "warn";
21
22
  '@atlaskit/design-system/no-html-image': "warn";
22
23
  '@atlaskit/design-system/no-html-range': "warn";
24
+ '@atlaskit/design-system/no-html-select': "warn";
23
25
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
24
26
  allowedFunctionCalls: string[][];
25
27
  }];
@@ -13,8 +13,10 @@ declare const _default: {
13
13
  '@atlaskit/design-system/no-html-anchor': "warn";
14
14
  '@atlaskit/design-system/no-html-button': "warn";
15
15
  '@atlaskit/design-system/no-html-checkbox': "warn";
16
+ '@atlaskit/design-system/no-html-heading': "warn";
16
17
  '@atlaskit/design-system/no-html-image': "warn";
17
18
  '@atlaskit/design-system/no-html-range': "warn";
19
+ '@atlaskit/design-system/no-html-select': "warn";
18
20
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
19
21
  allowedFunctionCalls: string[][];
20
22
  }];
@@ -13,8 +13,10 @@ declare const _default: {
13
13
  '@atlaskit/design-system/no-html-anchor': "warn";
14
14
  '@atlaskit/design-system/no-html-button': "warn";
15
15
  '@atlaskit/design-system/no-html-checkbox': "warn";
16
+ '@atlaskit/design-system/no-html-heading': "warn";
16
17
  '@atlaskit/design-system/no-html-image': "warn";
17
18
  '@atlaskit/design-system/no-html-range': "warn";
19
+ '@atlaskit/design-system/no-html-select': "warn";
18
20
  '@atlaskit/design-system/no-invalid-css-map': ["error", {
19
21
  allowedFunctionCalls: string[][];
20
22
  }];
@@ -19,8 +19,10 @@ export declare const rules: {
19
19
  'no-html-anchor': import("eslint").Rule.RuleModule;
20
20
  'no-html-button': import("eslint").Rule.RuleModule;
21
21
  'no-html-checkbox': import("eslint").Rule.RuleModule;
22
+ 'no-html-heading': import("eslint").Rule.RuleModule;
22
23
  'no-html-image': import("eslint").Rule.RuleModule;
23
24
  'no-html-range': import("eslint").Rule.RuleModule;
25
+ 'no-html-select': import("eslint").Rule.RuleModule;
24
26
  'no-invalid-css-map': import("eslint").Rule.RuleModule;
25
27
  'no-keyframes-tagged-template-expression': import("eslint").Rule.RuleModule;
26
28
  'no-legacy-icons': import("eslint").Rule.RuleModule;
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
@@ -0,0 +1,2 @@
1
+ export { StyledComponent } from './styled-component';
2
+ export { JSXElement } from './jsx-element';
@@ -0,0 +1,8 @@
1
+ import type { Rule } from 'eslint';
2
+ interface MetaData {
3
+ context: Rule.RuleContext;
4
+ }
5
+ export declare const JSXElement: {
6
+ lint(node: Rule.Node, { context }: MetaData): void;
7
+ };
8
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { Rule } from 'eslint';
2
+ interface MetaData {
3
+ context: Rule.RuleContext;
4
+ }
5
+ export declare const StyledComponent: {
6
+ lint(node: Rule.Node, { context }: MetaData): void;
7
+ };
8
+ export {};