@atlaskit/eslint-plugin-design-system 9.7.0 → 10.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.
Files changed (144) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +6 -5
  3. package/constellation/consistent-css-prop-usage/usage.mdx +44 -30
  4. package/constellation/ensure-design-token-usage/usage.mdx +12 -7
  5. package/constellation/ensure-design-token-usage-preview/usage.mdx +2 -1
  6. package/constellation/icon-label/usage.mdx +5 -3
  7. package/constellation/index/usage.mdx +4 -2
  8. package/constellation/no-banned-imports/usage.mdx +3 -1
  9. package/constellation/no-css-tagged-template-expression/usage.mdx +22 -17
  10. package/constellation/no-deprecated-apis/usage.mdx +33 -27
  11. package/constellation/no-deprecated-design-token-usage/usage.mdx +7 -4
  12. package/constellation/no-deprecated-imports/usage.mdx +31 -27
  13. package/constellation/no-direct-use-of-web-platform-drag-and-drop/usage.mdx +19 -10
  14. package/constellation/no-empty-styled-expression/usage.mdx +19 -14
  15. package/constellation/no-exported-css/usage.mdx +15 -10
  16. package/constellation/no-exported-keyframes/usage.mdx +15 -10
  17. package/constellation/no-html-anchor/usage.mdx +40 -0
  18. package/constellation/no-html-button/usage.mdx +52 -0
  19. package/constellation/no-invalid-css-map/usage.mdx +69 -58
  20. package/constellation/no-keyframes-tagged-template-expression/usage.mdx +24 -18
  21. package/constellation/no-margin/usage.mdx +3 -2
  22. package/constellation/no-nested-styles/usage.mdx +16 -16
  23. package/constellation/no-physical-properties/usage.mdx +13 -13
  24. package/constellation/no-styled-tagged-template-expression/usage.mdx +39 -34
  25. package/constellation/no-unsafe-design-token-usage/usage.mdx +8 -7
  26. package/constellation/no-unsafe-style-overrides/usage.mdx +10 -7
  27. package/constellation/no-unsupported-drag-and-drop-libraries/usage.mdx +8 -2
  28. package/constellation/prefer-primitives/usage.mdx +3 -2
  29. package/constellation/use-button-group-label/usage.mdx +4 -2
  30. package/constellation/use-drawer-label/usage.mdx +4 -2
  31. package/constellation/use-heading/usage.mdx +7 -4
  32. package/constellation/use-heading-level-in-spotlight-card/usage.mdx +3 -2
  33. package/constellation/use-href-in-link-item/usage.mdx +2 -1
  34. package/constellation/use-popup-label/usage.mdx +5 -2
  35. package/constellation/use-primitives/usage.mdx +40 -39
  36. package/constellation/use-primitives-text/usage.mdx +7 -3
  37. package/constellation/use-tokens-space/usage.mdx +7 -3
  38. package/constellation/use-tokens-typography/usage.mdx +15 -6
  39. package/constellation/use-visually-hidden/usage.mdx +2 -1
  40. package/dist/cjs/common/token-maps.partial.js +49 -0
  41. package/dist/cjs/index.codegen.js +1 -1
  42. package/dist/cjs/presets/all.codegen.js +3 -2
  43. package/dist/cjs/presets/recommended.codegen.js +1 -1
  44. package/dist/cjs/rules/index.codegen.js +5 -3
  45. package/dist/cjs/rules/no-html-anchor/index.js +39 -0
  46. package/dist/cjs/rules/no-html-anchor/node-types/index.js +19 -0
  47. package/dist/cjs/rules/no-html-anchor/node-types/jsx-element/index.js +28 -0
  48. package/dist/cjs/rules/no-html-anchor/node-types/styled-component/get-styled-component-call.js +47 -0
  49. package/dist/cjs/rules/no-html-anchor/node-types/styled-component/index.js +37 -0
  50. package/dist/cjs/rules/no-html-anchor/node-types/supported.js +66 -0
  51. package/dist/cjs/rules/no-html-anchor/utils/get-jsx-element-by-name.js +53 -0
  52. package/dist/cjs/rules/no-html-button/index.js +39 -0
  53. package/dist/cjs/rules/no-html-button/node-types/index.js +19 -0
  54. package/dist/cjs/rules/no-html-button/node-types/jsx-element/index.js +28 -0
  55. package/dist/cjs/rules/no-html-button/node-types/styled-component/get-styled-component-call.js +47 -0
  56. package/dist/cjs/rules/no-html-button/node-types/styled-component/index.js +37 -0
  57. package/dist/cjs/rules/no-html-button/node-types/supported.js +79 -0
  58. package/dist/cjs/rules/no-html-button/utils/get-jsx-element-by-name.js +53 -0
  59. package/dist/es2019/common/token-maps.partial.js +42 -0
  60. package/dist/es2019/index.codegen.js +1 -1
  61. package/dist/es2019/presets/all.codegen.js +3 -2
  62. package/dist/es2019/presets/recommended.codegen.js +1 -1
  63. package/dist/es2019/rules/index.codegen.js +5 -3
  64. package/dist/es2019/rules/no-html-anchor/index.js +33 -0
  65. package/dist/es2019/rules/no-html-anchor/node-types/index.js +2 -0
  66. package/dist/es2019/rules/no-html-anchor/node-types/jsx-element/index.js +20 -0
  67. package/dist/es2019/rules/no-html-anchor/node-types/styled-component/get-styled-component-call.js +42 -0
  68. package/dist/es2019/rules/no-html-anchor/node-types/styled-component/index.js +32 -0
  69. package/dist/es2019/rules/no-html-anchor/node-types/supported.js +56 -0
  70. package/dist/es2019/rules/no-html-anchor/utils/get-jsx-element-by-name.js +39 -0
  71. package/dist/es2019/rules/no-html-button/index.js +33 -0
  72. package/dist/es2019/rules/no-html-button/node-types/index.js +2 -0
  73. package/dist/es2019/rules/no-html-button/node-types/jsx-element/index.js +20 -0
  74. package/dist/es2019/rules/no-html-button/node-types/styled-component/get-styled-component-call.js +42 -0
  75. package/dist/es2019/rules/no-html-button/node-types/styled-component/index.js +32 -0
  76. package/dist/es2019/rules/no-html-button/node-types/supported.js +69 -0
  77. package/dist/es2019/rules/no-html-button/utils/get-jsx-element-by-name.js +39 -0
  78. package/dist/esm/common/token-maps.partial.js +42 -0
  79. package/dist/esm/index.codegen.js +1 -1
  80. package/dist/esm/presets/all.codegen.js +3 -2
  81. package/dist/esm/presets/recommended.codegen.js +1 -1
  82. package/dist/esm/rules/index.codegen.js +5 -3
  83. package/dist/esm/rules/no-html-anchor/index.js +33 -0
  84. package/dist/esm/rules/no-html-anchor/node-types/index.js +2 -0
  85. package/dist/esm/rules/no-html-anchor/node-types/jsx-element/index.js +19 -0
  86. package/dist/esm/rules/no-html-anchor/node-types/styled-component/get-styled-component-call.js +42 -0
  87. package/dist/esm/rules/no-html-anchor/node-types/styled-component/index.js +31 -0
  88. package/dist/esm/rules/no-html-anchor/node-types/supported.js +57 -0
  89. package/dist/esm/rules/no-html-anchor/utils/get-jsx-element-by-name.js +47 -0
  90. package/dist/esm/rules/no-html-button/index.js +33 -0
  91. package/dist/esm/rules/no-html-button/node-types/index.js +2 -0
  92. package/dist/esm/rules/no-html-button/node-types/jsx-element/index.js +19 -0
  93. package/dist/esm/rules/no-html-button/node-types/styled-component/get-styled-component-call.js +42 -0
  94. package/dist/esm/rules/no-html-button/node-types/styled-component/index.js +31 -0
  95. package/dist/esm/rules/no-html-button/node-types/supported.js +70 -0
  96. package/dist/esm/rules/no-html-button/utils/get-jsx-element-by-name.js +47 -0
  97. package/dist/types/common/token-maps.partial.d.ts +65 -0
  98. package/dist/types/index.codegen.d.ts +2 -1
  99. package/dist/types/presets/all.codegen.d.ts +3 -2
  100. package/dist/types/presets/recommended.codegen.d.ts +1 -1
  101. package/dist/types/rules/index.codegen.d.ts +2 -1
  102. package/dist/types/rules/no-html-anchor/index.d.ts +3 -0
  103. package/dist/types/rules/no-html-anchor/node-types/index.d.ts +2 -0
  104. package/dist/types/rules/no-html-anchor/node-types/jsx-element/index.d.ts +8 -0
  105. package/dist/types/rules/no-html-anchor/node-types/styled-component/get-styled-component-call.d.ts +6 -0
  106. package/dist/types/rules/no-html-anchor/node-types/styled-component/index.d.ts +8 -0
  107. package/dist/types/rules/no-html-anchor/node-types/supported.d.ts +7 -0
  108. package/dist/types/rules/no-html-anchor/utils/get-jsx-element-by-name.d.ts +6 -0
  109. package/dist/types/rules/no-html-button/index.d.ts +3 -0
  110. package/dist/types/rules/no-html-button/node-types/index.d.ts +2 -0
  111. package/dist/types/rules/no-html-button/node-types/jsx-element/index.d.ts +8 -0
  112. package/dist/types/rules/no-html-button/node-types/styled-component/get-styled-component-call.d.ts +6 -0
  113. package/dist/types/rules/no-html-button/node-types/styled-component/index.d.ts +8 -0
  114. package/dist/types/rules/no-html-button/node-types/supported.d.ts +7 -0
  115. package/dist/types/rules/no-html-button/utils/get-jsx-element-by-name.d.ts +6 -0
  116. package/dist/types-ts4.5/common/token-maps.partial.d.ts +65 -0
  117. package/dist/types-ts4.5/index.codegen.d.ts +2 -1
  118. package/dist/types-ts4.5/presets/all.codegen.d.ts +3 -2
  119. package/dist/types-ts4.5/presets/recommended.codegen.d.ts +1 -1
  120. package/dist/types-ts4.5/rules/index.codegen.d.ts +2 -1
  121. package/dist/types-ts4.5/rules/no-html-anchor/node-types/index.d.ts +2 -0
  122. package/dist/types-ts4.5/rules/no-html-anchor/node-types/jsx-element/index.d.ts +8 -0
  123. package/dist/types-ts4.5/rules/no-html-anchor/node-types/styled-component/get-styled-component-call.d.ts +6 -0
  124. package/dist/types-ts4.5/rules/no-html-anchor/node-types/styled-component/index.d.ts +8 -0
  125. package/dist/types-ts4.5/rules/no-html-anchor/node-types/supported.d.ts +7 -0
  126. package/dist/types-ts4.5/rules/no-html-anchor/utils/get-jsx-element-by-name.d.ts +6 -0
  127. package/dist/types-ts4.5/rules/no-html-button/node-types/index.d.ts +2 -0
  128. package/dist/types-ts4.5/rules/no-html-button/node-types/jsx-element/index.d.ts +8 -0
  129. package/dist/types-ts4.5/rules/no-html-button/node-types/styled-component/get-styled-component-call.d.ts +6 -0
  130. package/dist/types-ts4.5/rules/no-html-button/node-types/styled-component/index.d.ts +8 -0
  131. package/dist/types-ts4.5/rules/no-html-button/node-types/supported.d.ts +7 -0
  132. package/dist/types-ts4.5/rules/no-html-button/utils/get-jsx-element-by-name.d.ts +6 -0
  133. package/package.json +3 -2
  134. package/constellation/no-html-button-element/usage.mdx +0 -26
  135. package/dist/cjs/rules/no-html-button-element/index.js +0 -107
  136. package/dist/cjs/rules/no-html-button-element/utils.js +0 -18
  137. package/dist/es2019/rules/no-html-button-element/index.js +0 -101
  138. package/dist/es2019/rules/no-html-button-element/utils.js +0 -12
  139. package/dist/esm/rules/no-html-button-element/index.js +0 -101
  140. package/dist/esm/rules/no-html-button-element/utils.js +0 -12
  141. package/dist/types/rules/no-html-button-element/utils.d.ts +0 -2
  142. package/dist/types-ts4.5/rules/no-html-button-element/utils.d.ts +0 -2
  143. /package/dist/types-ts4.5/rules/{no-html-button-element → no-html-anchor}/index.d.ts +0 -0
  144. /package/dist/{types/rules/no-html-button-element → types-ts4.5/rules/no-html-button}/index.d.ts +0 -0
@@ -16,7 +16,7 @@ var _recommended = _interopRequireDefault(require("./presets/recommended.codegen
16
16
  var _index = _interopRequireDefault(require("./rules/index.codegen"));
17
17
  /**
18
18
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
19
- * @codegen <<SignedSource::11fe367c1ab4107f7418a84fa435cc23>>
19
+ * @codegen <<SignedSource::a1bb0f17560603fa4895326b1d50744e>>
20
20
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
21
21
  */
22
22
 
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  /**
8
8
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
9
- * @codegen <<SignedSource::5a5b0ed8cf86631274d7d30df4199e5d>>
9
+ * @codegen <<SignedSource::0be7639a95bf4c9bbfe00154d8193477>>
10
10
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
11
11
  */
12
12
  var _default = exports.default = {
@@ -25,7 +25,8 @@ var _default = exports.default = {
25
25
  '@atlaskit/design-system/no-empty-styled-expression': 'warn',
26
26
  '@atlaskit/design-system/no-exported-css': 'warn',
27
27
  '@atlaskit/design-system/no-exported-keyframes': 'warn',
28
- '@atlaskit/design-system/no-html-button-element': 'warn',
28
+ '@atlaskit/design-system/no-html-anchor': 'warn',
29
+ '@atlaskit/design-system/no-html-button': 'warn',
29
30
  '@atlaskit/design-system/no-invalid-css-map': 'error',
30
31
  '@atlaskit/design-system/no-keyframes-tagged-template-expression': 'error',
31
32
  '@atlaskit/design-system/no-margin': 'warn',
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  /**
8
8
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
9
- * @codegen <<SignedSource::af55c21605e3b8ee7836cb8950a9f713>>
9
+ * @codegen <<SignedSource::73a3666b244b58cc221eebcda071161d>>
10
10
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
11
11
  */
12
12
  var _default = exports.default = {
@@ -18,7 +18,8 @@ var _noDirectUseOfWebPlatformDragAndDrop = _interopRequireDefault(require("./no-
18
18
  var _noEmptyStyledExpression = _interopRequireDefault(require("./no-empty-styled-expression"));
19
19
  var _noExportedCss = _interopRequireDefault(require("./no-exported-css"));
20
20
  var _noExportedKeyframes = _interopRequireDefault(require("./no-exported-keyframes"));
21
- var _noHtmlButtonElement = _interopRequireDefault(require("./no-html-button-element"));
21
+ var _noHtmlAnchor = _interopRequireDefault(require("./no-html-anchor"));
22
+ var _noHtmlButton = _interopRequireDefault(require("./no-html-button"));
22
23
  var _noInvalidCssMap = _interopRequireDefault(require("./no-invalid-css-map"));
23
24
  var _noKeyframesTaggedTemplateExpression = _interopRequireDefault(require("./no-keyframes-tagged-template-expression"));
24
25
  var _noMargin = _interopRequireDefault(require("./no-margin"));
@@ -42,7 +43,7 @@ var _useTokensTypography = _interopRequireDefault(require("./use-tokens-typograp
42
43
  var _useVisuallyHidden = _interopRequireDefault(require("./use-visually-hidden"));
43
44
  /**
44
45
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
45
- * @codegen <<SignedSource::5e5b4678175cdf8209b7e2443bc4abb4>>
46
+ * @codegen <<SignedSource::9b934590b0ff7880e962fa4dd73bdb0b>>
46
47
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
47
48
  */
48
49
  var _default = exports.default = {
@@ -59,7 +60,8 @@ var _default = exports.default = {
59
60
  'no-empty-styled-expression': _noEmptyStyledExpression.default,
60
61
  'no-exported-css': _noExportedCss.default,
61
62
  'no-exported-keyframes': _noExportedKeyframes.default,
62
- 'no-html-button-element': _noHtmlButtonElement.default,
63
+ 'no-html-anchor': _noHtmlAnchor.default,
64
+ 'no-html-button': _noHtmlButton.default,
63
65
  'no-invalid-css-map': _noInvalidCssMap.default,
64
66
  'no-keyframes-tagged-template-expression': _noKeyframesTaggedTemplateExpression.default,
65
67
  'no-margin': _noMargin.default,
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _createRule = require("../utils/create-rule");
8
+ var _nodeTypes = require("./node-types");
9
+ var rule = (0, _createRule.createLintRule)({
10
+ meta: {
11
+ name: 'no-html-anchor',
12
+ type: 'suggestion',
13
+ docs: {
14
+ description: 'Discourage direct usage of HTML anchor elements in favor of Atlassian Design System link components.',
15
+ recommended: false,
16
+ severity: 'warn'
17
+ },
18
+ messages: {
19
+ noHtmlAnchor: "This <{{ name }}> should be replaced with a link component from the Atlassian Design System, such as the \"Link\" or \"LinkButton\" component when suitable. For custom links use the \"Anchor\" primitive. ADS links include event tracking, automatic router configuration, ensure accessible implementations, and provide access to ADS styling features like design tokens."
20
+ }
21
+ },
22
+ create: function create(context) {
23
+ return {
24
+ // transforms styled.<anchor>(...) usages
25
+ CallExpression: function CallExpression(node) {
26
+ _nodeTypes.StyledComponent.lint(node, {
27
+ context: context
28
+ });
29
+ },
30
+ // transforms <anchor css={...}> usages
31
+ JSXElement: function JSXElement(node) {
32
+ _nodeTypes.JSXElement.lint(node, {
33
+ context: context
34
+ });
35
+ }
36
+ };
37
+ }
38
+ });
39
+ var _default = exports.default = rule;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "JSXElement", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _jsxElement.JSXElement;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "StyledComponent", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _styledComponent.StyledComponent;
16
+ }
17
+ });
18
+ var _styledComponent = require("./styled-component");
19
+ var _jsxElement = require("./jsx-element");
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.JSXElement = void 0;
8
+ var ast = _interopRequireWildcard(require("../../../../ast-nodes"));
9
+ var _supported = require("../supported");
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ /* eslint-disable @repo/internal/react/require-jsdoc */
13
+
14
+ var JSXElement = exports.JSXElement = {
15
+ lint: function lint(node, _ref) {
16
+ var context = _ref.context;
17
+ if (!(0, _supported.isSupportedForLint)(node)) {
18
+ return;
19
+ }
20
+ context.report({
21
+ node: node.openingElement,
22
+ messageId: 'noHtmlAnchor',
23
+ data: {
24
+ name: ast.JSXElement.getName(node)
25
+ }
26
+ });
27
+ }
28
+ };
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getStyledComponentCall = void 0;
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
8
+ /**
9
+ * Returns a styled component
10
+ */
11
+
12
+ var getStyledComponentCall = exports.getStyledComponentCall = function getStyledComponentCall(node) {
13
+ // halts unless we are dealing with a styled component
14
+ if (!isStyledCallExpression(node)) {
15
+ return;
16
+ }
17
+ // halts if the component is being exported directly
18
+ if ((0, _eslintCodemodUtils.closestOfType)(node, 'ExportNamedDeclaration')) {
19
+ return;
20
+ }
21
+ var styledComponentVariableRef = node.parent;
22
+ // halts if the styled component is not assigned to a variable immediately
23
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(styledComponentVariableRef, 'VariableDeclarator')) {
24
+ return;
25
+ }
26
+ return styledComponentVariableRef;
27
+ };
28
+
29
+ /**
30
+ * Some verbose precondition checks but all it does is check
31
+ * a call expression is of form `styled.a` or `styled2.a`
32
+ */
33
+ var isStyledCallExpression = function isStyledCallExpression(call) {
34
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(call, 'CallExpression')) {
35
+ return false;
36
+ }
37
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(call.callee, 'MemberExpression')) {
38
+ return false;
39
+ }
40
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(call.callee.object, 'Identifier') || !(0, _eslintCodemodUtils.isNodeOfType)(call.callee.property, 'Identifier')) {
41
+ return false;
42
+ }
43
+ if (/^styled2?$/.test(call.callee.object.name)) {
44
+ return true;
45
+ }
46
+ return false;
47
+ };
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.StyledComponent = void 0;
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
8
+ var _getJsxElementByName2 = require("../../utils/get-jsx-element-by-name");
9
+ var _supported = require("../supported");
10
+ var _getStyledComponentCall = require("./get-styled-component-call");
11
+ /* eslint-disable @repo/internal/react/require-jsdoc */
12
+
13
+ var StyledComponent = exports.StyledComponent = {
14
+ lint: function lint(node, _ref) {
15
+ var _getJsxElementByName;
16
+ var context = _ref.context;
17
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') || !(0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'MemberExpression') || !(0, _eslintCodemodUtils.isNodeOfType)(node.callee.object, 'Identifier') || !(0, _eslintCodemodUtils.isNodeOfType)(node.callee.property, 'Identifier')) {
18
+ return;
19
+ }
20
+ var styles = (0, _getStyledComponentCall.getStyledComponentCall)(node);
21
+ var elementName = node.callee.property.name;
22
+ if (!styles || !(0, _eslintCodemodUtils.isNodeOfType)(styles.id, 'Identifier')) {
23
+ return;
24
+ }
25
+ var jsxElement = (_getJsxElementByName = (0, _getJsxElementByName2.getJsxElementByName)(styles.id.name, context.getScope())) === null || _getJsxElementByName === void 0 ? void 0 : _getJsxElementByName.parent;
26
+ if (jsxElement && !(0, _supported.isSupportedForLint)(jsxElement, elementName)) {
27
+ return;
28
+ }
29
+ context.report({
30
+ node: styles,
31
+ messageId: 'noHtmlAnchor',
32
+ data: {
33
+ name: node.callee.property.name
34
+ }
35
+ });
36
+ }
37
+ };
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.isSupportedForLint = isSupportedForLint;
8
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
9
+ var ast = _interopRequireWildcard(require("../../../ast-nodes"));
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ var supportedElements = [{
13
+ name: 'a'
14
+ }];
15
+
16
+ /**
17
+ * Determines if the given JSX element is a supported element to lint with this rule.
18
+ */
19
+ function isSupportedForLint(jsxNode, elementName) {
20
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(jsxNode, 'JSXElement')) {
21
+ return false;
22
+ }
23
+
24
+ // Allow passing in the element name because the jsxNode doesn't
25
+ // represent the element name with styled components
26
+ var elName = elementName || ast.JSXElement.getName(jsxNode);
27
+ if (!elName) {
28
+ return false;
29
+ }
30
+
31
+ // Only check native HTML elements, not components
32
+ if (elName[0] !== elName[0].toLowerCase()) {
33
+ return false;
34
+ }
35
+ var supportedElement = supportedElements.find(function (_ref) {
36
+ var name = _ref.name;
37
+ return name === elName;
38
+ });
39
+ if (!supportedElement) {
40
+ supportedElement = supportedElements.find(function (_ref2) {
41
+ var name = _ref2.name;
42
+ return name === '*';
43
+ });
44
+ }
45
+ if (!supportedElement) {
46
+ return false;
47
+ }
48
+
49
+ // Check if the element has any attributes that are not supported
50
+ var attributes = ast.JSXElement.getAttributes(jsxNode);
51
+ if (supportedElement.attributes && !supportedElement.attributes.every(function (_ref3) {
52
+ var name = _ref3.name,
53
+ values = _ref3.values;
54
+ return attributes.some(function (attribute) {
55
+ if (attribute.type === 'JSXSpreadAttribute') {
56
+ return false;
57
+ }
58
+ var isMatchingName = attribute.name.name === name;
59
+ 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));
60
+ return isMatchingName && isMatchingValues;
61
+ });
62
+ })) {
63
+ return false;
64
+ }
65
+ return true;
66
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getJsxElementByName = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
10
+ /**
11
+ * Given a component name finds its JSX usage
12
+ */
13
+ var getJsxElementByName = exports.getJsxElementByName = function getJsxElementByName(componentName, scope) {
14
+ var _variableDeclaration$;
15
+ var variableDeclaration = scope.variables.find(function (v) {
16
+ return v.name === componentName;
17
+ });
18
+ if (!variableDeclaration) {
19
+ return;
20
+ }
21
+
22
+ // length here should be exactly 2 to indicate only two references:
23
+ // one being the variable declaration itself
24
+ // second being the JSX call site
25
+ // we might consider handling multiple local JSX call sites in the future
26
+ // but "this is good enough for now"™️
27
+ if (variableDeclaration.references.length !== 2) {
28
+ return;
29
+ }
30
+ var jsxUsage = (_variableDeclaration$ = variableDeclaration.references[1]) === null || _variableDeclaration$ === void 0 ? void 0 : _variableDeclaration$.identifier;
31
+ var _variableDeclaration$2 = variableDeclaration.references.map(function (ref) {
32
+ return ref === null || ref === void 0 ? void 0 : ref.identifier;
33
+ }),
34
+ _variableDeclaration$3 = (0, _slicedToArray2.default)(_variableDeclaration$2, 2),
35
+ firstIdentifier = _variableDeclaration$3[0],
36
+ secondIdentifier = _variableDeclaration$3[1];
37
+ // Check if the first reference is a JSXOpeningElement and the second is not or vice versa
38
+ if ((0, _eslintCodemodUtils.isNodeOfType)(firstIdentifier, 'JSXIdentifier') && !(0, _eslintCodemodUtils.isNodeOfType)(secondIdentifier, 'JSXIdentifier')) {
39
+ jsxUsage = firstIdentifier;
40
+ } else if ((0, _eslintCodemodUtils.isNodeOfType)(secondIdentifier, 'JSXIdentifier') && !(0, _eslintCodemodUtils.isNodeOfType)(firstIdentifier, 'JSXIdentifier')) {
41
+ jsxUsage = secondIdentifier;
42
+ } else {
43
+ return;
44
+ }
45
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(jsxUsage, 'JSXIdentifier')) {
46
+ return;
47
+ }
48
+ var jsxOpeningElement = jsxUsage.parent;
49
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(jsxOpeningElement, 'JSXOpeningElement')) {
50
+ return;
51
+ }
52
+ return jsxOpeningElement;
53
+ };
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _createRule = require("../utils/create-rule");
8
+ var _nodeTypes = require("./node-types");
9
+ var rule = (0, _createRule.createLintRule)({
10
+ meta: {
11
+ name: 'no-html-button',
12
+ type: 'suggestion',
13
+ docs: {
14
+ description: 'Discourage direct usage of HTML button elements in favor of Atlassian Design System button components.',
15
+ recommended: false,
16
+ severity: 'warn'
17
+ },
18
+ messages: {
19
+ noHtmlButton: "This {{ name }} should be replaced with a button component from the Atlassian Design System, such as the \"Button\" component when suitable. For custom buttons use the \"Pressable\" primitive. ADS buttons include event tracking, ensure accessible implementations, and provide access to ADS styling features like design tokens."
20
+ }
21
+ },
22
+ create: function create(context) {
23
+ return {
24
+ // transforms styled.<button>(...) usages
25
+ CallExpression: function CallExpression(node) {
26
+ _nodeTypes.StyledComponent.lint(node, {
27
+ context: context
28
+ });
29
+ },
30
+ // transforms <button css={...}> usages
31
+ JSXElement: function JSXElement(node) {
32
+ _nodeTypes.JSXElement.lint(node, {
33
+ context: context
34
+ });
35
+ }
36
+ };
37
+ }
38
+ });
39
+ var _default = exports.default = rule;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "JSXElement", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _jsxElement.JSXElement;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "StyledComponent", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _styledComponent.StyledComponent;
16
+ }
17
+ });
18
+ var _styledComponent = require("./styled-component");
19
+ var _jsxElement = require("./jsx-element");
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.JSXElement = void 0;
8
+ var ast = _interopRequireWildcard(require("../../../../ast-nodes"));
9
+ var _supported = require("../supported");
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ /* eslint-disable @repo/internal/react/require-jsdoc */
13
+
14
+ var JSXElement = exports.JSXElement = {
15
+ lint: function lint(node, _ref) {
16
+ var context = _ref.context;
17
+ if (!(0, _supported.isSupportedForLint)(node)) {
18
+ return;
19
+ }
20
+ context.report({
21
+ node: node.openingElement,
22
+ messageId: 'noHtmlButton',
23
+ data: {
24
+ name: ast.JSXElement.getName(node)
25
+ }
26
+ });
27
+ }
28
+ };
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getStyledComponentCall = void 0;
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
8
+ /**
9
+ * Returns a styled component
10
+ */
11
+
12
+ var getStyledComponentCall = exports.getStyledComponentCall = function getStyledComponentCall(node) {
13
+ // halts unless we are dealing with a styled component
14
+ if (!isStyledCallExpression(node)) {
15
+ return;
16
+ }
17
+ // halts if the component is being exported directly
18
+ if ((0, _eslintCodemodUtils.closestOfType)(node, 'ExportNamedDeclaration')) {
19
+ return;
20
+ }
21
+ var styledComponentVariableRef = node.parent;
22
+ // halts if the styled component is not assigned to a variable immediately
23
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(styledComponentVariableRef, 'VariableDeclarator')) {
24
+ return;
25
+ }
26
+ return styledComponentVariableRef;
27
+ };
28
+
29
+ /**
30
+ * Some verbose precondition checks but all it does is check
31
+ * a call expression is of form `styled.button` or `styled2.button`
32
+ */
33
+ var isStyledCallExpression = function isStyledCallExpression(call) {
34
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(call, 'CallExpression')) {
35
+ return false;
36
+ }
37
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(call.callee, 'MemberExpression')) {
38
+ return false;
39
+ }
40
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(call.callee.object, 'Identifier') || !(0, _eslintCodemodUtils.isNodeOfType)(call.callee.property, 'Identifier')) {
41
+ return false;
42
+ }
43
+ if (/^styled2?$/.test(call.callee.object.name)) {
44
+ return true;
45
+ }
46
+ return false;
47
+ };
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.StyledComponent = void 0;
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
8
+ var _getJsxElementByName2 = require("../../utils/get-jsx-element-by-name");
9
+ var _supported = require("../supported");
10
+ var _getStyledComponentCall = require("./get-styled-component-call");
11
+ /* eslint-disable @repo/internal/react/require-jsdoc */
12
+
13
+ var StyledComponent = exports.StyledComponent = {
14
+ lint: function lint(node, _ref) {
15
+ var _getJsxElementByName;
16
+ var context = _ref.context;
17
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') || !(0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'MemberExpression') || !(0, _eslintCodemodUtils.isNodeOfType)(node.callee.object, 'Identifier') || !(0, _eslintCodemodUtils.isNodeOfType)(node.callee.property, 'Identifier')) {
18
+ return;
19
+ }
20
+ var styles = (0, _getStyledComponentCall.getStyledComponentCall)(node);
21
+ var elementName = node.callee.property.name;
22
+ if (!styles || !(0, _eslintCodemodUtils.isNodeOfType)(styles.id, 'Identifier')) {
23
+ return;
24
+ }
25
+ var jsxElement = (_getJsxElementByName = (0, _getJsxElementByName2.getJsxElementByName)(styles.id.name, context.getScope())) === null || _getJsxElementByName === void 0 ? void 0 : _getJsxElementByName.parent;
26
+ if (jsxElement && !(0, _supported.isSupportedForLint)(jsxElement, elementName)) {
27
+ return;
28
+ }
29
+ context.report({
30
+ node: styles,
31
+ messageId: 'noHtmlButton',
32
+ data: {
33
+ name: node.callee.property.name
34
+ }
35
+ });
36
+ }
37
+ };
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.isSupportedForLint = isSupportedForLint;
8
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
9
+ var ast = _interopRequireWildcard(require("../../../ast-nodes"));
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ var supportedElements = [{
13
+ name: 'button'
14
+ }, {
15
+ name: 'input',
16
+ attributes: [{
17
+ name: 'type',
18
+ // Values from https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role#best_practices
19
+ values: ['submit', 'reset', 'button', 'image']
20
+ }]
21
+ }, {
22
+ name: '*',
23
+ attributes: [{
24
+ name: 'role',
25
+ values: ['button']
26
+ }]
27
+ }];
28
+
29
+ /**
30
+ * Determines if the given JSX element is a supported element to lint with this rule.
31
+ */
32
+ function isSupportedForLint(jsxNode, elementName) {
33
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(jsxNode, 'JSXElement')) {
34
+ return false;
35
+ }
36
+
37
+ // Allow passing in the element name because the jsxNode doesn't
38
+ // represent the element name with styled components
39
+ var elName = elementName || ast.JSXElement.getName(jsxNode);
40
+ if (!elName) {
41
+ return false;
42
+ }
43
+
44
+ // Only check native HTML elements, not components
45
+ if (elName[0] !== elName[0].toLowerCase()) {
46
+ return false;
47
+ }
48
+ var supportedElement = supportedElements.find(function (_ref) {
49
+ var name = _ref.name;
50
+ return name === elName;
51
+ });
52
+ if (!supportedElement) {
53
+ supportedElement = supportedElements.find(function (_ref2) {
54
+ var name = _ref2.name;
55
+ return name === '*';
56
+ });
57
+ }
58
+ if (!supportedElement) {
59
+ return false;
60
+ }
61
+
62
+ // Check if the element has any attributes that are not supported
63
+ var attributes = ast.JSXElement.getAttributes(jsxNode);
64
+ if (supportedElement.attributes && !supportedElement.attributes.every(function (_ref3) {
65
+ var name = _ref3.name,
66
+ values = _ref3.values;
67
+ return attributes.some(function (attribute) {
68
+ if (attribute.type === 'JSXSpreadAttribute') {
69
+ return false;
70
+ }
71
+ var isMatchingName = attribute.name.name === name;
72
+ 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));
73
+ return isMatchingName && isMatchingValues;
74
+ });
75
+ })) {
76
+ return false;
77
+ }
78
+ return true;
79
+ }