diff --git a/.changeset/quick-donkeys-yawn.md b/.changeset/quick-donkeys-yawn.md new file mode 100644 index 0000000000..f6b6c23fb9 --- /dev/null +++ b/.changeset/quick-donkeys-yawn.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-components': patch +'@backstage/plugin-techdocs': patch +--- + +Add `react/forbid-elements` linter rule for button, suggest MUI `Button` diff --git a/.eslintrc.js b/.eslintrc.js index 675a834efb..cf01ffe3a6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -18,7 +18,7 @@ var path = require('path'); module.exports = { root: true, - plugins: ['notice', 'testing-library'], + plugins: ['@spotify', 'notice', 'react', 'testing-library'], rules: { 'notice/notice': [ 'error', @@ -237,4 +237,20 @@ module.exports = { }), ].flat(), }, + overrides: [ + { + files: ['**/*.[jt]s?(x)'], + excludedFiles: '**/*.{test,spec}.[jt]s?(x)', + rules: { + 'react/forbid-elements': [ + 1, + { + forbid: [ + { element: 'button', message: 'use MUI + ); } @@ -691,7 +692,8 @@ export const SidebarExpandButton = () => { }; return ( - + ); }; diff --git a/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx b/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx index fbe4496c72..5fdd29f203 100644 --- a/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx +++ b/packages/core-components/src/layout/Sidebar/SidebarSubmenuItem.tsx @@ -27,6 +27,7 @@ import ArrowDropUpIcon from '@material-ui/icons/ArrowDropUp'; import { SidebarItemWithSubmenuContext } from './config'; import { isLocationMatch } from './utils'; import Box from '@material-ui/core/Box'; +import Button from '@material-ui/core/Button'; const useStyles = makeStyles( theme => ({ @@ -158,7 +159,8 @@ export const SidebarSubmenuItem = (props: SidebarSubmenuItemProps) => { return ( - + {dropdownItems && showDropDown && ( diff --git a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.test.tsx b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.test.tsx index a8188ce358..54d5c27993 100644 --- a/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.test.tsx +++ b/plugins/catalog-import/src/components/StepPrepareCreatePullRequest/PreparePullRequestForm.test.tsx @@ -15,6 +15,7 @@ */ import { FormHelperText, TextField } from '@material-ui/core'; +import Button from '@material-ui/core/Button'; import { act, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; @@ -31,7 +32,7 @@ describe('', () => { render={({ register }) => ( <> - {' '} + {' '} )} onSubmit={onSubmitFn} @@ -59,7 +60,7 @@ describe('', () => { id="main" label="Main Field" /> - + )} onSubmit={onSubmitFn} @@ -93,7 +94,7 @@ describe('', () => { Error in required main field )} - {' '} + {' '} )} onSubmit={onSubmitFn} diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx index 6adb4252d3..a90c4ca116 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx @@ -23,6 +23,8 @@ import { SvgIcon, Tooltip, } from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import type { Transformer } from './transformer'; const CopyToClipboardTooltip = withStyles(theme => ({ tooltip: { @@ -65,15 +67,13 @@ const CopyToClipboardButton = ({ text }: CopyToClipboardButtonProps) => { onClose={handleClose} leaveDelay={1000} > - + ); }; -import type { Transformer } from './transformer'; - /** * Recreates copy-to-clipboard functionality attached to snippets that * is native to mkdocs-material theme. diff --git a/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx b/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx index 28d2346c61..05d26b87d8 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx @@ -16,6 +16,7 @@ import { ApiProvider } from '@backstage/core-app-api'; import { searchApiRef } from '@backstage/plugin-search-react'; import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils'; +import Button from '@material-ui/core/Button'; import { act, fireEvent, @@ -136,9 +137,9 @@ describe('', () => { const [entityName, setEntityName] = useState(entityId); return wrapInTestApp( - + , ); diff --git a/yarn.lock b/yarn.lock index 92082912e5..7dc311f37a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13180,6 +13180,16 @@ __metadata: languageName: node linkType: hard +"@spotify/eslint-plugin@npm:^14.1.3": + version: 14.1.3 + resolution: "@spotify/eslint-plugin@npm:14.1.3" + peerDependencies: + "@typescript-eslint/parser": ^5.13.0 + eslint: ^8.10.0 + checksum: 788f5d9aab6f7b6c0ad7e414ebd5f4504f058f26a769dc4bcd0088dd8e6d9e5334965c8f6fffcf5b7ed52dbe25de0dc7bba403bcffa79b6d94c7ba3094757b5f + languageName: node + linkType: hard + "@spotify/prettier-config@npm:^14.0.0": version: 14.0.1 resolution: "@spotify/prettier-config@npm:14.0.1" @@ -34435,6 +34445,7 @@ __metadata: "@changesets/cli": ^2.14.0 "@manypkg/get-packages": ^1.1.3 "@octokit/rest": ^19.0.3 + "@spotify/eslint-plugin": ^14.1.3 "@spotify/prettier-config": ^14.0.0 "@techdocs/cli": "workspace:*" "@types/node": ^16.11.26 @@ -34445,6 +34456,7 @@ __metadata: e2e-test: "workspace:*" eslint: ^8.6.0 eslint-plugin-notice: ^0.9.10 + eslint-plugin-react: ^7.28.0 eslint-plugin-testing-library: ^5.9.1 fs-extra: 10.1.0 husky: ^8.0.0