Skip to content

Commit

Permalink
Add button eslint rule for va-button and va-table (#984)
Browse files Browse the repository at this point in the history
* Add button eslint rule

* add check for input type button

* add table tests

* typo fix
  • Loading branch information
ataker committed Nov 3, 2023
1 parent 4767798 commit c1f4ec7
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 1 deletion.
2 changes: 2 additions & 0 deletions packages/eslint-plugin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ module.exports = {
'use-new-utility-classes': require('./lib/rules/use-new-utility-classes'),
'use-workspace-imports': require('./lib/rules/use-workspace-imports'),
'remove-expanding-group': require('./lib/rules/remove-expanding-group'),
'prefer-button-component': require('./lib/rules/prefer-button-component'),
'prefer-table-component': require('./lib/rules/prefer-table-component'),
},
configs: {
recommended: require('./lib/config/recommended'),
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/lib/config/recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,7 @@ module.exports = {
'@department-of-veterans-affairs/deprecated-classes': 1,
'@department-of-veterans-affairs/use-workspace-imports': 1,
'@department-of-veterans-affairs/remove-expanding-group': 1,
'@department-of-veterans-affairs/prefer-button-component': 1,
'@department-of-veterans-affairs/prefer-table-component': 1,
},
};
32 changes: 32 additions & 0 deletions packages/eslint-plugin/lib/rules/prefer-button-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const jsxAstUtils = require('jsx-ast-utils');

const { elementType, getProp, getLiteralPropValue } = jsxAstUtils;

const MESSAGE =
'The <va-button> Web Component should be used instead of the button HTML element.';

module.exports = {
meta: {
type: 'suggestion',
fixable: 'code',
},

create(context) {
return {
JSXElement(node) {
const anchorNode = node.openingElement;
const typeProp = getProp(anchorNode.attributes, 'type');

// Only display if we are on a button or input with type button
if (elementType(anchorNode) === 'button' ||
(elementType(anchorNode) === 'input' && getLiteralPropValue(typeProp) === 'button')){

context.report({
node,
message: MESSAGE,
})
}
},
};
},
};
30 changes: 30 additions & 0 deletions packages/eslint-plugin/lib/rules/prefer-table-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const jsxAstUtils = require('jsx-ast-utils');

const { elementType } = jsxAstUtils;

const MESSAGE =
'The <va-table> Web Component should be used to instead of the table HTML element.';

module.exports = {
meta: {
type: 'suggestion',
fixable: 'code',
},

create(context) {
return {
JSXElement(node) {
const anchorNode = node.openingElement;

// Only display if we are on a table element
if (elementType(anchorNode) === 'table'){

context.report({
node,
message: MESSAGE,
})
}
},
};
},
};
2 changes: 1 addition & 1 deletion packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@department-of-veterans-affairs/eslint-plugin",
"version": "1.12.0",
"version": "1.13.0",
"description": "ESLint plugin for va.gov projects",
"homepage": "https://github.com/department-of-veterans-affairs/veteran-facing-services-tools/tree/master/packages/eslint-plugin#readme",
"bugs": {
Expand Down
120 changes: 120 additions & 0 deletions packages/eslint-plugin/tests/lib/rules/prefer-button-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
'use strict';

const rule = require('../../../lib/rules/prefer-button-component');
const RuleTester = require('eslint').RuleTester;

const parserOptions = {
ecmaVersion: 2018,
// sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
};

const ruleTester = new RuleTester({ parserOptions });

ruleTester.run('prefer-button-component', rule, {
valid: [
{
code: `
const button = () => (<va-button
id="cancel"
onClick={handlers.onCancel}
text="Cancel"
/>)
`,
}
],
invalid: [
{
code: `
const button = () => (
<button
className="foo"
id="bar"
onClick={() => window.print()}
>
Print this page
</button>
)
`,
errors: [
{
message:
'The <va-button> Web Component should be used instead of the button HTML element.'
},
],
},
{
code: `
const button = () => (<button
onClick={() => window.print()}
>
{variable}
</button>)
`,
errors: [
{
message:
'The <va-button> Web Component should be used instead of the button HTML element.'
},
],
},
{
code: `
const button = () => (<button
onClick={() => window.print()}
>
Some plain text next to a {variable}
</button>)
`,
errors: [
{
message:
'The <va-button> Web Component should be used instead of the button HTML element.'
},
]
},
{
code: `
const button = () => (<button
onClick={() => window.print()}
>
<span>Button Text</span>
</button>)
`,
errors: [
{
message:
'The <va-button> Web Component should be used instead of the button HTML element.'
},
],
},
{
code: `
const button = () => (
<input type="button">Click me</input>
)
`,
errors: [
{
message:
'The <va-button> Web Component should be used instead of the button HTML element.'
},
],
},
{
code: `
const button = () => (
<input type="button" value="Click me" />
)
`,
errors: [
{
message:
'The <va-button> Web Component should be used instead of the button HTML element.'
},
],
},
],
});
73 changes: 73 additions & 0 deletions packages/eslint-plugin/tests/lib/rules/prefer-table-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
'use strict';

const rule = require('../../../lib/rules/prefer-table-component');
const RuleTester = require('eslint').RuleTester;

const parserOptions = {
ecmaVersion: 2018,
// sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
};

const ruleTester = new RuleTester({ parserOptions });

ruleTester.run('prefer-table-component', rule, {
valid: [
{
code: `
const table = () => (<va-table
id="cancel"
onClick={handlers.onCancel}
text="Cancel"
/>)
`,
}
],
invalid: [
{
code: `
const table = () => (
<table>
<thead>
<tr>
<th>Date</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>Nov 9</td>
<td>Kelly</td>
</tr>
<tr>
<td>Dec 19</td>
<td>Franklin</td>
</tr>
</tbody>
</table>
)
`,
errors: [
{
message:
'The <va-table> Web Component should be used to instead of the table HTML element.'
},
],
},
{
code: `
const table = () => (
<table></table>
)
`,
errors: [
{
message:
'The <va-table> Web Component should be used to instead of the table HTML element.'
},
],
}
],
});

0 comments on commit c1f4ec7

Please sign in to comment.