eslint-plugin-smarthr 0.2.1 → 0.2.4
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.
- package/CHANGELOG.md +21 -0
- package/libs/common.js +1 -1
- package/libs/format_styled_components.js +47 -30
- package/package.json +1 -1
- package/rules/a11y-clickable-element-has-text/index.js +12 -17
- package/rules/a11y-trigger-has-button/index.js +16 -2
- package/rules/redundant-name/index.js +22 -14
- package/rules/require-barrel-import/index.js +1 -1
- package/test/a11y-clickable-element-has-text.js +13 -0
- package/test/a11y-trigger-has-button.js +15 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.2.4](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.2.3...v0.2.4) (2022-08-30)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* ruleを更新する ([#27](https://github.com/kufu/eslint-plugin-smarthr/issues/27)) ([1ec7783](https://github.com/kufu/eslint-plugin-smarthr/commit/1ec7783395c9dafa547c453724f3671df489997b))
|
|
11
|
+
|
|
12
|
+
### [0.2.3](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.2.2...v0.2.3) (2022-08-26)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* a11y-xxxx: styled(Hoge)の実行結果を変数に代入しないパターンに対応する ([#26](https://github.com/kufu/eslint-plugin-smarthr/issues/26)) ([0bb0259](https://github.com/kufu/eslint-plugin-smarthr/commit/0bb02595a3be35802c1fe8bc41011fd1e55bf319))
|
|
18
|
+
|
|
19
|
+
### [0.2.2](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.2.1...v0.2.2) (2022-08-18)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* redundant-name rule の allowedNames オプションが適用されないバグがあったため修正する ([#23](https://github.com/kufu/eslint-plugin-smarthr/issues/23)) ([86a7bc5](https://github.com/kufu/eslint-plugin-smarthr/commit/86a7bc548398261885f31c75b56d8edffe5017c3))
|
|
25
|
+
|
|
5
26
|
### [0.2.1](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.2.0...v0.2.1) (2022-08-15)
|
|
6
27
|
|
|
7
28
|
|
package/libs/common.js
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
const getExtendedComponentName = (node) => {
|
|
2
|
+
if (!node.parent) {
|
|
3
|
+
return null
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
return node.parent.id?.name || getExtendedComponentName(node.parent)
|
|
7
|
+
}
|
|
8
|
+
const getBaseComponentName = (node) => {
|
|
9
|
+
if (!node) {
|
|
10
|
+
return null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (node.type === 'CallExpression') {
|
|
14
|
+
if (node.callee.name === 'styled') {
|
|
15
|
+
return node.arguments[0].name
|
|
16
|
+
}
|
|
17
|
+
if (node.callee.object?.name === 'styled') {
|
|
18
|
+
return node.callee.property.name
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (node?.object?.name === 'styled') {
|
|
23
|
+
return node.property.name
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return getBaseComponentName(node.parent)
|
|
27
|
+
}
|
|
28
|
+
|
|
1
29
|
const generateTagFormatter = ({ context, EXPECTED_NAMES }) => ({
|
|
2
30
|
ImportDeclaration: (node) => {
|
|
3
31
|
if (node.source.value !== 'styled-components') {
|
|
@@ -17,40 +45,29 @@ const generateTagFormatter = ({ context, EXPECTED_NAMES }) => ({
|
|
|
17
45
|
}
|
|
18
46
|
},
|
|
19
47
|
TaggedTemplateExpression: (node) => {
|
|
20
|
-
const
|
|
21
|
-
const base = (() => {
|
|
22
|
-
if (tag.type === 'CallExpression' && tag.callee.name === 'styled') {
|
|
23
|
-
return tag.arguments[0].name
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (tag?.object?.name === 'styled') {
|
|
27
|
-
return tag.property.name
|
|
28
|
-
}
|
|
48
|
+
const extended = getExtendedComponentName(node)
|
|
29
49
|
|
|
30
|
-
|
|
31
|
-
|
|
50
|
+
if (extended) {
|
|
51
|
+
const base = getBaseComponentName(node.tag)
|
|
32
52
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
53
|
+
if (base) {
|
|
54
|
+
Object.entries(EXPECTED_NAMES).forEach(([b, e]) => {
|
|
55
|
+
if (base.match(new RegExp(b))) {
|
|
56
|
+
const extendedregex = new RegExp(e)
|
|
36
57
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
message: `${extended}を正規表現 "${extendedregex.toString()}" がmatchする名称に変更してください`,
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
}
|
|
58
|
+
if (!extended.match(extendedregex)) {
|
|
59
|
+
context.report({
|
|
60
|
+
node: node.parent,
|
|
61
|
+
messageId: 'format-styled-components',
|
|
62
|
+
data: {
|
|
63
|
+
message: `${extended}を正規表現 "${extendedregex.toString()}" がmatchする名称に変更してください`,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
})
|
|
52
69
|
}
|
|
53
|
-
}
|
|
70
|
+
}
|
|
54
71
|
},
|
|
55
72
|
})
|
|
56
73
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { generateTagFormatter } = require('../../libs/format_styled_components')
|
|
2
2
|
|
|
3
3
|
const EXPECTED_NAMES = {
|
|
4
|
+
'SmartHRLogo$': 'SmartHRLogo$',
|
|
4
5
|
'(b|B)utton$': 'Button$',
|
|
5
6
|
'Anchor$': 'Anchor$',
|
|
6
7
|
'Link$': 'Link$',
|
|
@@ -35,23 +36,17 @@ module.exports = {
|
|
|
35
36
|
return
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
const recursiveSearch = (c) =>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return true
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return false
|
|
54
|
-
}
|
|
39
|
+
const recursiveSearch = (c) => (
|
|
40
|
+
['JSXText', 'JSXExpressionContainer'].includes(c.type) ||
|
|
41
|
+
(
|
|
42
|
+
c.type === 'JSXElement' && (
|
|
43
|
+
// HINT: SmartHRLogo コンポーネントは内部でaltを持っているため対象外にする
|
|
44
|
+
c.openingElement.name.name.match(/SmartHRLogo$/) ||
|
|
45
|
+
c.openingElement.attributes.some((a) => (['visuallyHiddenText', 'alt'].includes(a.name.name) && !!a.value.value)) ||
|
|
46
|
+
(c.children && filterFalsyJSXText(c.children).some(recursiveSearch))
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
)
|
|
55
50
|
|
|
56
51
|
const child = filterFalsyJSXText(parentNode.children).find(recursiveSearch)
|
|
57
52
|
|
|
@@ -47,7 +47,21 @@ module.exports = {
|
|
|
47
47
|
return
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
filterFalsyJSXText(parentNode.children)
|
|
50
|
+
const children = filterFalsyJSXText(parentNode.children)
|
|
51
|
+
|
|
52
|
+
if (children.length > 1) {
|
|
53
|
+
context.report({
|
|
54
|
+
node,
|
|
55
|
+
messageId: 'a11y-trigger-has-button',
|
|
56
|
+
data: {
|
|
57
|
+
message: `${match[1]}Trigger の直下には複数のコンポーネントを設置することは出来ません。buttonコンポーネントが一つだけ設置されている状態にしてください`,
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
children.forEach((c) => {
|
|
51
65
|
// `<DialogTrigger>{button}</DialogTrigger>` のような場合は許可する
|
|
52
66
|
if (c.type === 'JSXExpressionContainer') {
|
|
53
67
|
return false
|
|
@@ -56,7 +70,7 @@ module.exports = {
|
|
|
56
70
|
if (
|
|
57
71
|
c.type !== 'JSXElement' ||
|
|
58
72
|
!c.openingElement.name.name.match(/(b|B)utton$/) ||
|
|
59
|
-
c.openingElement.name.name.match(/AnchorButton
|
|
73
|
+
c.openingElement.name.name.match(/AnchorButton$/)
|
|
60
74
|
) {
|
|
61
75
|
context.report({
|
|
62
76
|
node: c,
|
|
@@ -16,7 +16,6 @@ const DEFAULT_CONFIG = {
|
|
|
16
16
|
],
|
|
17
17
|
SUFFIX: ['Props', 'Type'],
|
|
18
18
|
},
|
|
19
|
-
typeProperty: COMMON_DEFAULT_CONFIG,
|
|
20
19
|
file: COMMON_DEFAULT_CONFIG,
|
|
21
20
|
property: COMMON_DEFAULT_CONFIG,
|
|
22
21
|
function: COMMON_DEFAULT_CONFIG,
|
|
@@ -62,7 +61,6 @@ const SCHEMA = [
|
|
|
62
61
|
...DEFAULT_SCHEMA_PROPERTY,
|
|
63
62
|
suffix: { type: 'array', items: { type: 'string' } },
|
|
64
63
|
},
|
|
65
|
-
typeProperty: DEFAULT_SCHEMA_PROPERTY,
|
|
66
64
|
file: DEFAULT_SCHEMA_PROPERTY,
|
|
67
65
|
property: DEFAULT_SCHEMA_PROPERTY,
|
|
68
66
|
function: DEFAULT_SCHEMA_PROPERTY,
|
|
@@ -89,7 +87,6 @@ const generateRedundantKeywords = ({ args, key, terminalImportName }) => {
|
|
|
89
87
|
const option = args.option[key] || {}
|
|
90
88
|
const ignoreKeywords = option.ignoreKeywords || DEFAULT_CONFIG[key].IGNORE_KEYWORDS
|
|
91
89
|
const terminalImportKeyword = terminalImportName ? terminalImportName.toLowerCase() : ''
|
|
92
|
-
|
|
93
90
|
return args.keywords.reduce((prev, keyword) => {
|
|
94
91
|
if (keyword === terminalImportKeyword || ignoreKeywords.includes(keyword)) {
|
|
95
92
|
return prev
|
|
@@ -203,7 +200,7 @@ const handleReportBetterName = ({
|
|
|
203
200
|
}
|
|
204
201
|
|
|
205
202
|
const generateTypeRedundant = (args) => {
|
|
206
|
-
const { context } = args
|
|
203
|
+
const { context, filename } = args
|
|
207
204
|
const key = 'type'
|
|
208
205
|
const redundantKeywords = generateRedundantKeywords({ args, key })
|
|
209
206
|
const option = args.option[key]
|
|
@@ -211,6 +208,14 @@ const generateTypeRedundant = (args) => {
|
|
|
211
208
|
|
|
212
209
|
return (node) => {
|
|
213
210
|
const typeName = node.id.name
|
|
211
|
+
|
|
212
|
+
if (
|
|
213
|
+
option.allowedNames &&
|
|
214
|
+
Object.entries(option.allowedNames).find(([regex, calcs]) => filename.match(new RegExp(regex)) && calcs.find((c) => c === typeName))
|
|
215
|
+
) {
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
|
|
214
219
|
const suffix = option.suffix || defaultConfig.SUFFIX
|
|
215
220
|
|
|
216
221
|
let SuffixedName = typeName
|
|
@@ -254,8 +259,7 @@ const generateTypeRedundant = (args) => {
|
|
|
254
259
|
}
|
|
255
260
|
|
|
256
261
|
const generateTypePropertyRedundant = (args) => {
|
|
257
|
-
const key = '
|
|
258
|
-
|
|
262
|
+
const key = 'property'
|
|
259
263
|
return handleReportBetterName({
|
|
260
264
|
...args,
|
|
261
265
|
key,
|
|
@@ -266,7 +270,7 @@ const generateTypePropertyRedundant = (args) => {
|
|
|
266
270
|
})
|
|
267
271
|
}
|
|
268
272
|
const generateTypePropertyFunctionParamsRedundant = (args) => {
|
|
269
|
-
const key = '
|
|
273
|
+
const key = 'property'
|
|
270
274
|
const redundant = handleReportBetterName({
|
|
271
275
|
...args,
|
|
272
276
|
key,
|
|
@@ -290,7 +294,15 @@ const generatePropertyRedundant = (args) => {
|
|
|
290
294
|
option: args.option[key],
|
|
291
295
|
redundantKeywords: generateRedundantKeywords({ args, key }),
|
|
292
296
|
defaultBetterName: 'item',
|
|
293
|
-
fetchName: (node) =>
|
|
297
|
+
fetchName: (node) => {
|
|
298
|
+
// argumentsとしてわたされたobjectの展開などの場合は許可する
|
|
299
|
+
// このファイル内で修正すべき場合などは冗長な名前を修正するべき場合はtype propertyなどで判断出来る
|
|
300
|
+
if (node.parent.type === 'ObjectPattern') {
|
|
301
|
+
return null
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return node.key.name
|
|
305
|
+
},
|
|
294
306
|
})
|
|
295
307
|
}
|
|
296
308
|
|
|
@@ -383,7 +395,6 @@ module.exports = {
|
|
|
383
395
|
'file-name': ' {{ message }}',
|
|
384
396
|
'type-name': '{{ message }}',
|
|
385
397
|
'type-name/invalid-suffix': '{{ message }}',
|
|
386
|
-
'typeProperty-name': '{{ message }}',
|
|
387
398
|
'property-name': ' {{ message }}',
|
|
388
399
|
'function-name': ' {{ message }}',
|
|
389
400
|
'functionParams-name': ' {{ message }}',
|
|
@@ -441,9 +452,10 @@ module.exports = {
|
|
|
441
452
|
addRule('TSTypeAliasDeclaration', generateTypeRedundant(args))
|
|
442
453
|
// addRule('TSInterfaceDeclaration', generateTypeRedundant(args)) // 必要になったら実装する
|
|
443
454
|
}
|
|
444
|
-
if (option.
|
|
455
|
+
if (option.property) {
|
|
445
456
|
const typePropRedundant = generateTypePropertyRedundant(args)
|
|
446
457
|
const typeFuncParamRedundant = generateTypePropertyFunctionParamsRedundant(args)
|
|
458
|
+
const redundant = generatePropertyRedundant(args)
|
|
447
459
|
|
|
448
460
|
addRule('TSPropertySignature', (node) => {
|
|
449
461
|
typePropRedundant(node)
|
|
@@ -452,10 +464,6 @@ module.exports = {
|
|
|
452
464
|
typeFuncParamRedundant(node.typeAnnotation.typeAnnotation)
|
|
453
465
|
}
|
|
454
466
|
})
|
|
455
|
-
}
|
|
456
|
-
if (option.property) {
|
|
457
|
-
const redundant = generatePropertyRedundant(args)
|
|
458
|
-
|
|
459
467
|
addRule('Property', redundant)
|
|
460
468
|
addRule('PropertyDefinition', redundant)
|
|
461
469
|
}
|
|
@@ -26,6 +26,7 @@ ruleTester.run('a11y-clickable-element-has-text', rule, {
|
|
|
26
26
|
{ code: 'const HogeLink = styled(Link)``' },
|
|
27
27
|
{ code: 'const HogeButton = styled(Button)``' },
|
|
28
28
|
{ code: 'const FugaAnchor = styled(HogeAnchor)``' },
|
|
29
|
+
{ code: 'const FugaSmartHRLogo = styled(SmartHRLogo)``' },
|
|
29
30
|
{
|
|
30
31
|
code: `<a>ほげ</a>`,
|
|
31
32
|
},
|
|
@@ -89,6 +90,12 @@ ruleTester.run('a11y-clickable-element-has-text', rule, {
|
|
|
89
90
|
{
|
|
90
91
|
code: `<a><span>{any}</span></a>`,
|
|
91
92
|
},
|
|
93
|
+
{
|
|
94
|
+
code: `<a><SmartHRLogo /></a>`,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
code: `<a><PrefixSmartHRLogo /></a>`,
|
|
98
|
+
},
|
|
92
99
|
],
|
|
93
100
|
invalid: [
|
|
94
101
|
{ code: `import hoge from 'styled-components'`, errors: [ { message: "styled-components をimportする際は、名称が`styled` となるようにしてください。例: `import styled from 'styled-components'`" } ] },
|
|
@@ -98,6 +105,8 @@ ruleTester.run('a11y-clickable-element-has-text', rule, {
|
|
|
98
105
|
{ code: 'const Hoge = styled(Link)``', errors: [ { message: `Hogeを正規表現 "/Link$/" がmatchする名称に変更してください` } ] },
|
|
99
106
|
{ code: 'const Hoge = styled(Button)``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` } ] },
|
|
100
107
|
{ code: 'const Fuga = styled(HogeAnchor)``', errors: [ { message: `Fugaを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ] },
|
|
108
|
+
{ code: 'const Fuga = styled(HogeAnchor)``', errors: [ { message: `Fugaを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ] },
|
|
109
|
+
{ code: 'const Fuga = styled(SmartHRLogo)``', errors: [ { message: `Fugaを正規表現 "/SmartHRLogo$/" がmatchする名称に変更してください` } ] },
|
|
101
110
|
{
|
|
102
111
|
code: `<a><img src="hoge.jpg" /></a>`,
|
|
103
112
|
errors: [{ message: defaultErrorMessage }]
|
|
@@ -138,5 +147,9 @@ ruleTester.run('a11y-clickable-element-has-text', rule, {
|
|
|
138
147
|
code: `<button><AnyComponent><Icon visuallyHiddenText="" /></AnyComponent></button>`,
|
|
139
148
|
errors: [{ message: defaultErrorMessage }]
|
|
140
149
|
},
|
|
150
|
+
{
|
|
151
|
+
code: `<button><SmartHRLogoSuffix /></button>`,
|
|
152
|
+
errors: [{ message: defaultErrorMessage }]
|
|
153
|
+
},
|
|
141
154
|
]
|
|
142
155
|
})
|
|
@@ -33,18 +33,20 @@ ruleTester.run('a11y-trigger-has-button', rule, {
|
|
|
33
33
|
],
|
|
34
34
|
invalid: [
|
|
35
35
|
{ code: `import hoge from 'styled-components'`, errors: [ { message: "styled-components をimportする際は、名称が`styled` となるようにしてください。例: `import styled from 'styled-components'`" } ] },
|
|
36
|
-
{ code: 'const Hoge = styled.button``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` } ]
|
|
37
|
-
{ code: 'const Hoge = styled.a``', errors: [ { message: `Hogeを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください` } ]
|
|
38
|
-
{ code: 'const Hoge = styled(Button)``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` } ]
|
|
39
|
-
{ code: 'const Hoge = styled(AnchorButton)``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` },{ message: `Hogeを正規表現 "/AnchorButton$/" がmatchする名称に変更してください` } ]
|
|
40
|
-
{ code: 'const Hoge = styled(ButtonAnchor)``', errors: [ { message: `Hogeを正規表現 "/ButtonAnchor$/" がmatchする名称に変更してください` }, { message: `Hogeを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ]
|
|
41
|
-
{ code: 'const Hoge = styled(Anchor)``', errors: [ { message: `Hogeを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ]
|
|
42
|
-
{ code: 'const Hoge = styled(Link)``', errors: [ { message: `Hogeを正規表現 "/Link$/" がmatchする名称に変更してください` } ]
|
|
43
|
-
{ code: 'const Hoge = styled(DropdownTrigger)``', errors: [ { message: `Hogeを正規表現 "/DropdownTrigger$/" がmatchする名称に変更してください` } ]
|
|
44
|
-
{ code: 'const Hoge = styled(DialogTrigger)``', errors: [ { message: `Hogeを正規表現 "/DialogTrigger$/" がmatchする名称に変更してください` } ]
|
|
45
|
-
{ code: '<DropdownTrigger>ほげ</DropdownTrigger>', errors: [ { message: 'DropdownTrigger の直下にはbuttonコンポーネントのみ設置してください' } ]
|
|
46
|
-
{ code: '<DialogTrigger><span><Button>ほげ</Button></span></DialogTrigger>', errors: [ { message: 'DialogTrigger の直下にはbuttonコンポーネントのみ設置してください' } ]
|
|
47
|
-
{ code: '<DropdownTrigger><AnchorButton>ほげ</AnchorButton></DropdownTrigger>', errors: [ { message: 'DropdownTrigger の直下にはbuttonコンポーネントのみ設置してください' } ]
|
|
48
|
-
{ code: '<DropdownTrigger><ButtonAnchor>ほげ</ButtonAnchor></DropdownTrigger>', errors: [ { message: 'DropdownTrigger の直下にはbuttonコンポーネントのみ設置してください' } ]
|
|
36
|
+
{ code: 'const Hoge = styled.button``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` } ] },
|
|
37
|
+
{ code: 'const Hoge = styled.a``', errors: [ { message: `Hogeを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください` } ] },
|
|
38
|
+
{ code: 'const Hoge = styled(Button)``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` } ] },
|
|
39
|
+
{ code: 'const Hoge = styled(AnchorButton)``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` },{ message: `Hogeを正規表現 "/AnchorButton$/" がmatchする名称に変更してください` } ] },
|
|
40
|
+
{ code: 'const Hoge = styled(ButtonAnchor)``', errors: [ { message: `Hogeを正規表現 "/ButtonAnchor$/" がmatchする名称に変更してください` }, { message: `Hogeを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ] },
|
|
41
|
+
{ code: 'const Hoge = styled(Anchor)``', errors: [ { message: `Hogeを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ] },
|
|
42
|
+
{ code: 'const Hoge = styled(Link)``', errors: [ { message: `Hogeを正規表現 "/Link$/" がmatchする名称に変更してください` } ] },
|
|
43
|
+
{ code: 'const Hoge = styled(DropdownTrigger)``', errors: [ { message: `Hogeを正規表現 "/DropdownTrigger$/" がmatchする名称に変更してください` } ] },
|
|
44
|
+
{ code: 'const Hoge = styled(DialogTrigger)``', errors: [ { message: `Hogeを正規表現 "/DialogTrigger$/" がmatchする名称に変更してください` } ] },
|
|
45
|
+
{ code: '<DropdownTrigger>ほげ</DropdownTrigger>', errors: [ { message: 'DropdownTrigger の直下にはbuttonコンポーネントのみ設置してください' } ] },
|
|
46
|
+
{ code: '<DialogTrigger><span><Button>ほげ</Button></span></DialogTrigger>', errors: [ { message: 'DialogTrigger の直下にはbuttonコンポーネントのみ設置してください' } ] },
|
|
47
|
+
{ code: '<DropdownTrigger><AnchorButton>ほげ</AnchorButton></DropdownTrigger>', errors: [ { message: 'DropdownTrigger の直下にはbuttonコンポーネントのみ設置してください' } ] },
|
|
48
|
+
{ code: '<DropdownTrigger><ButtonAnchor>ほげ</ButtonAnchor></DropdownTrigger>', errors: [ { message: 'DropdownTrigger の直下にはbuttonコンポーネントのみ設置してください' } ] },
|
|
49
|
+
{ code: '<DialogTrigger><button>{hoge}</button>{hoge}</DialogTrigger>', errors: [ { message: 'DialogTrigger の直下には複数のコンポーネントを設置することは出来ません。buttonコンポーネントが一つだけ設置されている状態にしてください' } ] },
|
|
50
|
+
{ code: '<DropdownTrigger>{hoge}<span>text</span></DropdownTrigger>', errors: [ { message: 'DropdownTrigger の直下には複数のコンポーネントを設置することは出来ません。buttonコンポーネントが一つだけ設置されている状態にしてください' } ] },
|
|
49
51
|
]
|
|
50
52
|
})
|