Skip to content
This repository is currently being migrated. It's locked while the migration is in progress.

Commit c1f4ec7

Browse files
authored
Add button eslint rule for va-button and va-table (#984)
* Add button eslint rule * add check for input type button * add table tests * typo fix
1 parent 4767798 commit c1f4ec7

7 files changed

Lines changed: 260 additions & 1 deletion

File tree

packages/eslint-plugin/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ module.exports = {
1515
'use-new-utility-classes': require('./lib/rules/use-new-utility-classes'),
1616
'use-workspace-imports': require('./lib/rules/use-workspace-imports'),
1717
'remove-expanding-group': require('./lib/rules/remove-expanding-group'),
18+
'prefer-button-component': require('./lib/rules/prefer-button-component'),
19+
'prefer-table-component': require('./lib/rules/prefer-table-component'),
1820
},
1921
configs: {
2022
recommended: require('./lib/config/recommended'),

packages/eslint-plugin/lib/config/recommended.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,5 +187,7 @@ module.exports = {
187187
'@department-of-veterans-affairs/deprecated-classes': 1,
188188
'@department-of-veterans-affairs/use-workspace-imports': 1,
189189
'@department-of-veterans-affairs/remove-expanding-group': 1,
190+
'@department-of-veterans-affairs/prefer-button-component': 1,
191+
'@department-of-veterans-affairs/prefer-table-component': 1,
190192
},
191193
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const jsxAstUtils = require('jsx-ast-utils');
2+
3+
const { elementType, getProp, getLiteralPropValue } = jsxAstUtils;
4+
5+
const MESSAGE =
6+
'The <va-button> Web Component should be used instead of the button HTML element.';
7+
8+
module.exports = {
9+
meta: {
10+
type: 'suggestion',
11+
fixable: 'code',
12+
},
13+
14+
create(context) {
15+
return {
16+
JSXElement(node) {
17+
const anchorNode = node.openingElement;
18+
const typeProp = getProp(anchorNode.attributes, 'type');
19+
20+
// Only display if we are on a button or input with type button
21+
if (elementType(anchorNode) === 'button' ||
22+
(elementType(anchorNode) === 'input' && getLiteralPropValue(typeProp) === 'button')){
23+
24+
context.report({
25+
node,
26+
message: MESSAGE,
27+
})
28+
}
29+
},
30+
};
31+
},
32+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const jsxAstUtils = require('jsx-ast-utils');
2+
3+
const { elementType } = jsxAstUtils;
4+
5+
const MESSAGE =
6+
'The <va-table> Web Component should be used to instead of the table HTML element.';
7+
8+
module.exports = {
9+
meta: {
10+
type: 'suggestion',
11+
fixable: 'code',
12+
},
13+
14+
create(context) {
15+
return {
16+
JSXElement(node) {
17+
const anchorNode = node.openingElement;
18+
19+
// Only display if we are on a table element
20+
if (elementType(anchorNode) === 'table'){
21+
22+
context.report({
23+
node,
24+
message: MESSAGE,
25+
})
26+
}
27+
},
28+
};
29+
},
30+
};

packages/eslint-plugin/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@department-of-veterans-affairs/eslint-plugin",
3-
"version": "1.12.0",
3+
"version": "1.13.0",
44
"description": "ESLint plugin for va.gov projects",
55
"homepage": "https://github.com/department-of-veterans-affairs/veteran-facing-services-tools/tree/master/packages/eslint-plugin#readme",
66
"bugs": {
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
'use strict';
2+
3+
const rule = require('../../../lib/rules/prefer-button-component');
4+
const RuleTester = require('eslint').RuleTester;
5+
6+
const parserOptions = {
7+
ecmaVersion: 2018,
8+
// sourceType: 'module',
9+
ecmaFeatures: {
10+
jsx: true,
11+
},
12+
};
13+
14+
const ruleTester = new RuleTester({ parserOptions });
15+
16+
ruleTester.run('prefer-button-component', rule, {
17+
valid: [
18+
{
19+
code: `
20+
const button = () => (<va-button
21+
id="cancel"
22+
onClick={handlers.onCancel}
23+
text="Cancel"
24+
/>)
25+
`,
26+
}
27+
],
28+
invalid: [
29+
{
30+
code: `
31+
const button = () => (
32+
<button
33+
className="foo"
34+
id="bar"
35+
onClick={() => window.print()}
36+
>
37+
Print this page
38+
</button>
39+
)
40+
`,
41+
errors: [
42+
{
43+
message:
44+
'The <va-button> Web Component should be used instead of the button HTML element.'
45+
},
46+
],
47+
},
48+
{
49+
code: `
50+
const button = () => (<button
51+
onClick={() => window.print()}
52+
>
53+
{variable}
54+
</button>)
55+
`,
56+
errors: [
57+
{
58+
message:
59+
'The <va-button> Web Component should be used instead of the button HTML element.'
60+
},
61+
],
62+
},
63+
{
64+
code: `
65+
const button = () => (<button
66+
onClick={() => window.print()}
67+
>
68+
Some plain text next to a {variable}
69+
</button>)
70+
`,
71+
errors: [
72+
{
73+
message:
74+
'The <va-button> Web Component should be used instead of the button HTML element.'
75+
},
76+
]
77+
},
78+
{
79+
code: `
80+
const button = () => (<button
81+
onClick={() => window.print()}
82+
>
83+
<span>Button Text</span>
84+
</button>)
85+
`,
86+
errors: [
87+
{
88+
message:
89+
'The <va-button> Web Component should be used instead of the button HTML element.'
90+
},
91+
],
92+
},
93+
{
94+
code: `
95+
const button = () => (
96+
<input type="button">Click me</input>
97+
)
98+
`,
99+
errors: [
100+
{
101+
message:
102+
'The <va-button> Web Component should be used instead of the button HTML element.'
103+
},
104+
],
105+
},
106+
{
107+
code: `
108+
const button = () => (
109+
<input type="button" value="Click me" />
110+
)
111+
`,
112+
errors: [
113+
{
114+
message:
115+
'The <va-button> Web Component should be used instead of the button HTML element.'
116+
},
117+
],
118+
},
119+
],
120+
});
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'use strict';
2+
3+
const rule = require('../../../lib/rules/prefer-table-component');
4+
const RuleTester = require('eslint').RuleTester;
5+
6+
const parserOptions = {
7+
ecmaVersion: 2018,
8+
// sourceType: 'module',
9+
ecmaFeatures: {
10+
jsx: true,
11+
},
12+
};
13+
14+
const ruleTester = new RuleTester({ parserOptions });
15+
16+
ruleTester.run('prefer-table-component', rule, {
17+
valid: [
18+
{
19+
code: `
20+
const table = () => (<va-table
21+
id="cancel"
22+
onClick={handlers.onCancel}
23+
text="Cancel"
24+
/>)
25+
`,
26+
}
27+
],
28+
invalid: [
29+
{
30+
code: `
31+
const table = () => (
32+
<table>
33+
<thead>
34+
<tr>
35+
<th>Date</th>
36+
<th>Name</th>
37+
</tr>
38+
</thead>
39+
<tbody>
40+
<tr>
41+
<td>Nov 9</td>
42+
<td>Kelly</td>
43+
</tr>
44+
<tr>
45+
<td>Dec 19</td>
46+
<td>Franklin</td>
47+
</tr>
48+
</tbody>
49+
</table>
50+
)
51+
`,
52+
errors: [
53+
{
54+
message:
55+
'The <va-table> Web Component should be used to instead of the table HTML element.'
56+
},
57+
],
58+
},
59+
{
60+
code: `
61+
const table = () => (
62+
<table></table>
63+
)
64+
`,
65+
errors: [
66+
{
67+
message:
68+
'The <va-table> Web Component should be used to instead of the table HTML element.'
69+
},
70+
],
71+
}
72+
],
73+
});

0 commit comments

Comments
 (0)