eslint-plugin-smarthr 2.4.0 → 2.5.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.
- package/CHANGELOG.md +7 -0
- package/package.json +2 -2
- package/rules/a11y-anchor-has-href-attribute/index.js +1 -0
- package/rules/a11y-clickable-element-has-text/index.js +1 -0
- package/rules/a11y-delegate-element-has-role-presentation/index.js +2 -0
- package/rules/a11y-form-control-in-form/index.js +1 -0
- package/rules/a11y-heading-in-sectioning-content/README.md +16 -1
- package/rules/a11y-heading-in-sectioning-content/index.js +7 -2
- package/rules/a11y-help-link-with-support-href/index.js +2 -1
- package/rules/a11y-image-has-alt-attribute/index.js +2 -0
- package/rules/a11y-input-has-name-attribute/index.js +6 -3
- package/rules/a11y-input-in-form-control/index.js +11 -4
- package/rules/a11y-numbered-text-within-ol/index.js +5 -0
- package/rules/a11y-prohibit-checkbox-or-radio-in-table-cell/index.js +2 -1
- package/rules/a11y-prohibit-input-maxlength-attribute/index.js +5 -4
- package/rules/a11y-prohibit-input-placeholder/index.js +7 -3
- package/rules/a11y-prohibit-sectioning-content-in-form/index.js +2 -0
- package/rules/a11y-prohibit-useless-sectioning-fragment/index.js +2 -1
- package/rules/a11y-trigger-has-button/index.js +4 -2
- package/rules/best-practice-for-async-current-target/index.js +2 -2
- package/rules/best-practice-for-button-element/index.js +1 -0
- package/rules/best-practice-for-data-test-attribute/index.js +1 -0
- package/rules/best-practice-for-date/index.js +2 -0
- package/rules/best-practice-for-layouts/index.js +22 -10
- package/rules/best-practice-for-nested-attributes-array-index/index.js +1 -0
- package/rules/best-practice-for-remote-trigger-dialog/index.js +2 -1
- package/rules/best-practice-for-tailwind-prohibit-root-margin/index.js +2 -1
- package/rules/best-practice-for-tailwind-variants/index.js +6 -3
- package/rules/component-name/README.md +11 -3
- package/rules/component-name/index.js +7 -2
- package/rules/design-system-guideline-prohibit-double-icons/index.js +1 -0
- package/rules/format-import-path/index.js +2 -1
- package/rules/jsx-start-with-spread-attributes/index.js +2 -1
- package/rules/no-import-other-domain/index.js +2 -1
- package/rules/prohibit-export-array-type/index.js +1 -0
- package/rules/prohibit-file-name/index.js +2 -1
- package/rules/prohibit-import/index.js +4 -2
- package/rules/prohibit-path-within-template-literal/index.js +2 -1
- package/rules/require-barrel-import/index.js +2 -1
- package/rules/require-declaration/index.js +4 -2
- package/rules/require-export/index.js +2 -1
- package/rules/require-i18n-text/index.js +4 -2
- package/rules/require-import/index.js +2 -1
- package/rules/trim-props/index.js +2 -1
- package/test/a11y-anchor-has-href-attribute.js +1 -0
- package/test/a11y-clickable-element-has-text.js +1 -0
- package/test/a11y-delegate-element-has-role-presentation.js +2 -0
- package/test/a11y-form-control-in-form.js +1 -0
- package/test/a11y-heading-in-sectioning-content.js +7 -2
- package/test/a11y-help-link-with-support-href.js +2 -1
- package/test/a11y-image-has-alt-attribute.js +2 -0
- package/test/a11y-input-has-name-attribute.js +30 -15
- package/test/a11y-input-in-form-control.js +15 -1
- package/test/a11y-numbered-text-within-ol.js +29 -0
- package/test/a11y-prohhibit-input-placeholder.js +19 -9
- package/test/a11y-prohibit-checkbox-or-radio-in-table-cell.js +21 -11
- package/test/a11y-prohibit-input-maxlength-attribute.js +5 -4
- package/test/a11y-prohibit-useless-sectioning-fragment.js +2 -1
- package/test/a11y-trigger-has-button.js +12 -6
- package/test/best-practice-for-async-current-target.js +2 -2
- package/test/best-practice-for-button-element.js +2 -0
- package/test/best-practice-for-data-test-attribute.js +1 -0
- package/test/best-practice-for-date.js +2 -0
- package/test/best-practice-for-layouts.js +26 -12
- package/test/best-practice-for-nested-attributes-array-index.js +1 -0
- package/test/best-practice-for-remote-trigger-dialog.js +6 -3
- package/test/best-practice-for-tailwind-prohibit-root-margin.js +2 -2
- package/test/best-practice-for-tailwind-variants.js +8 -4
- package/test/component-name.js +7 -2
- package/test/design-system-guideline-prohibit-double-icons.js +1 -0
- package/test/prohibit-file-name.js +4 -2
- package/test/prohibit-import.js +14 -7
- package/test/prohibit-path-within-template-literal.js +4 -2
- package/test/require-declaration.js +11 -5
- package/test/require-export.js +6 -3
- package/test/require-i18n-text.js +4 -3
- package/test/require-import.js +13 -7
- package/test/trim-props.js +18 -15
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
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
|
+
## [2.5.0](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v2.4.0...eslint-plugin-smarthr-v2.5.0) (2025-12-04)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* lintのエラーメッセージに仕様詳細へのリンクを追加 ([#918](https://github.com/kufu/tamatebako/issues/918)) ([4f6dd2f](https://github.com/kufu/tamatebako/commit/4f6dd2fdca759b7b04c885196fe2b2e2a05c0c96))
|
|
11
|
+
|
|
5
12
|
## [2.4.0](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v2.3.0...eslint-plugin-smarthr-v2.4.0) (2025-12-02)
|
|
6
13
|
|
|
7
14
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-smarthr",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"author": "SmartHR",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "A sharable ESLint plugin for SmartHR",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"eslintplugin",
|
|
38
38
|
"smarthr"
|
|
39
39
|
],
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "f066316ebb46360a61effed8bec040ba0dedd11a"
|
|
41
41
|
}
|
|
@@ -50,6 +50,7 @@ const NEXT_LINK_REGEX = /Link$/
|
|
|
50
50
|
const nextCheck = (node) => ((node.parent.parent.openingElement.name.name || '').test(NEXT_LINK_REGEX))
|
|
51
51
|
|
|
52
52
|
const MESSAGE_SUFFIX = ` に href${OPTION.react_router ? '、もしくはto' : ''} 属性を正しく設定してください
|
|
53
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-anchor-has-href-attribute
|
|
53
54
|
- onClickなどでページ遷移する場合でもhref属性に遷移先のURIを設定してください
|
|
54
55
|
- Cmd + clickなどのキーボードショートカットに対応出来ます
|
|
55
56
|
- onClickなどの動作がURLの変更を行わない場合、button要素でマークアップすることを検討してください
|
|
@@ -12,6 +12,7 @@ const CLICKABLE_ELEMENT = 'JSXElement[openingElement.name.name=/((^b|B)utton|Anc
|
|
|
12
12
|
const TEXT_LIKE_ATTRIBUTE = 'JSXAttribute[name.name=/^(text|alt|aria-label(ledby)?)$/]:not(:matches([value=null],[value.value=""])))'
|
|
13
13
|
|
|
14
14
|
const message = `a, buttonなどのクリッカブルな要素内にはテキストを設定してください
|
|
15
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-clickable-element-has-text
|
|
15
16
|
- 要素内にアイコン、画像のみを設置する場合はaltなどの代替テキスト用属性を指定してください
|
|
16
17
|
- SVG component の場合、altを属性として受け取れるようにした上で '<svg role="img" aria-label={alt}>' のように指定してください
|
|
17
18
|
- クリッカブルな要素内に設置しているコンポーネントがテキストを含んでいる場合、"XxxxText" のように末尾に "Text" もしくは "Message" という名称を設定してください`
|
|
@@ -33,6 +33,7 @@ const messageNonInteractiveEventHandler = (nodeName, interactiveComponentRegex,
|
|
|
33
33
|
const onAttrsText = onAttrs.join(', ')
|
|
34
34
|
|
|
35
35
|
return `${nodeName} に${onAttrsText}を設定するとブラウザが正しく解釈が行えず、ユーザーが利用することが出来ない場合があるため、以下のいずれかの対応をおこなってください。
|
|
36
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-delegate-element-has-role-presentation
|
|
36
37
|
- 方法1: ${nodeName}がinput、buttonやaなどのインタラクティブな要素の場合、コンポーネント名の末尾をインタラクティブなコンポーネントであることがわかる名称に変更してください
|
|
37
38
|
- "${interactiveComponentRegex}" の正規表現にmatchするコンポーネントに差し替える、もしくは名称を変更してください
|
|
38
39
|
- 方法2: ${onAttrsText} がコンポーネント内の特定のインタラクティブな要素に設定される場合、名称を具体的なものに変更してください
|
|
@@ -45,6 +46,7 @@ const messageNonInteractiveEventHandler = (nodeName, interactiveComponentRegex,
|
|
|
45
46
|
- 'role="presentation"' を設定する適切な要素が存在しない場合、div、またはspanでイベントが発生する要素を囲んだ上でrole属性を設定してください`
|
|
46
47
|
}
|
|
47
48
|
const messageRolePresentationNotHasInteractive = (nodeName, interactiveComponentRegex, onAttrs, roleMean) => `${nodeName}に 'role="${roleMean}"' が設定されているにも関わらず、子要素にinput、buttonやaなどのインタラクティブな要素が見つからないため、ブラウザが正しく解釈が行えず、ユーザーが利用することが出来ない場合があるため、以下のいずれかの対応をおこなってください。
|
|
49
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-delegate-element-has-role-presentation
|
|
48
50
|
- 方法1: 子要素にインタラクティブな要素が存在するにも関わらずこのエラーが表示されている場合、子要素の名称を変更してください
|
|
49
51
|
- "${interactiveComponentRegex}" の正規表現にmatchするよう、インタラクティブな子要素全てを差し替える、もしくは名称を変更してください
|
|
50
52
|
- 方法2: ${nodeName}自体がインタラクティブな要素の場合、'role="presentation"'を削除した上で名称を変更してください
|
|
@@ -58,6 +58,7 @@ module.exports = {
|
|
|
58
58
|
context.report({
|
|
59
59
|
node,
|
|
60
60
|
message: `${elementName}をform要素で囲むようにマークアップしてください。
|
|
61
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-form-control-in-form
|
|
61
62
|
- form要素で囲むことでスクリーンリーダーに入力フォームであることが正しく伝わる、入力要素にfocusした状態でEnterを押せばsubmitできる、inputのpattern属性を利用できるなどのメリットがあります
|
|
62
63
|
- 以下のいずれかの方法で修正をおこなってください
|
|
63
64
|
- 方法1: form要素で ${elementName} を囲んでください。smarthr-ui/ActionDialog、もしくはsmarthr-ui/RemoteTriggerActionDialogを利用している場合、smarthr-ui/FormDialog、smarthr-ui/RemoteTriggerFormDialogに置き換えてください
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
- Headingコンポーネントをsmarthr-ui/SectioningContent(Article, Aside, Nav, Section) のいずれかで囲むことを促すルールです
|
|
4
4
|
- article, aside, nav, section で Heading とHeadingの対象となる範囲を囲むとブラウザが正確に解釈できるようになるメリットがあります
|
|
5
5
|
- またsmarthr-ui/SectioningContentで smarthr-ui/Headingを囲むことで、Headingのレベル(h1~h6)を自動的に計算するメリットもあります
|
|
6
|
+
- このルールではSectiongContentがHeadingを内包しているかもチェックします
|
|
6
7
|
- Headingコンポーネントをsmarthr-ui/Layout(Center, Reel, Sidebar, Stack) のいずれかで囲んでおり、かつas, forwardedAsのいずれかの属性で 'section', 'article', 'aside', 'nav' が指定されている場合、SectioningContentで囲んでいるものとして扱われるようになります
|
|
7
8
|
|
|
8
9
|
## rules
|
|
@@ -40,6 +41,14 @@
|
|
|
40
41
|
</section>
|
|
41
42
|
```
|
|
42
43
|
|
|
44
|
+
```jsx
|
|
45
|
+
<Section>
|
|
46
|
+
<PageHeading> // PageHeadingはSectiongContentでラップするとoutlineが狂う可能性があるためNG
|
|
47
|
+
hoge
|
|
48
|
+
</PageHeading>
|
|
49
|
+
</Section>
|
|
50
|
+
```
|
|
51
|
+
|
|
43
52
|
```jsx
|
|
44
53
|
<>
|
|
45
54
|
<PageHeading> // 同じファイル内に複数のPageHeadingが存在するとNG
|
|
@@ -51,11 +60,17 @@
|
|
|
51
60
|
</>
|
|
52
61
|
```
|
|
53
62
|
|
|
63
|
+
```jsx
|
|
64
|
+
<Aside> // Headingに当たる要素がないためNG
|
|
65
|
+
<AnyContent />
|
|
66
|
+
</Aside>
|
|
67
|
+
```
|
|
68
|
+
|
|
54
69
|
## ✅ Correct
|
|
55
70
|
|
|
56
71
|
```jsx
|
|
57
72
|
<Section>
|
|
58
|
-
<Heading>hoge</Heading>
|
|
73
|
+
<Heading>hoge</Heading> // SectioningContentにはHeadingを含む必要がある
|
|
59
74
|
<Section>
|
|
60
75
|
<Heading>fuga</Heading>
|
|
61
76
|
</Section>
|
|
@@ -15,12 +15,16 @@ const ariaLabelRegex = /^aria-label(ledby)?$/
|
|
|
15
15
|
const includeSectioningAsAttr = (a) => asRegex.test(a.name?.name) && bareTagRegex.test(a.value.value)
|
|
16
16
|
|
|
17
17
|
const headingMessage = `smarthr-ui/Headingと紐づく内容の範囲(アウトライン)が曖昧になっています。
|
|
18
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-heading-in-sectioning-content
|
|
18
19
|
- smarthr-uiのArticle, Aside, Nav, SectionのいずれかでHeadingコンポーネントと内容をラップしてHeadingに対応する範囲を明確に指定してください。`
|
|
19
20
|
const rootHeadingMessage = `${headingMessage}
|
|
20
21
|
- Headingをh1にしたい場合(機能名、ページ名などこのページ内でもっとも重要な見出しの場合)、smarthr-ui/PageHeadingを利用してください。その場合はSectionなどでアウトラインを示す必要はありません。`
|
|
21
|
-
const pageHeadingMessage =
|
|
22
|
-
|
|
22
|
+
const pageHeadingMessage = `smarthr-ui/PageHeading が同一ファイル内に複数存在しています。PageHeadingはh1タグを出力するため最も重要な見出しにのみ利用してください。
|
|
23
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-heading-in-sectioning-content`
|
|
24
|
+
const pageHeadingInSectionMessage = `smarthr-ui/PageHeadingはsmarthr-uiのArticle, Aside, Nav, Sectionで囲まないでください。囲んでしまうとページ全体の見出しではなくなってしまいます。
|
|
25
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-heading-in-sectioning-content`
|
|
23
26
|
const noTagAttrMessage = `tag属性を指定せず、smarthr-uiのArticle, Aside, Nav, Sectionのいずれかの自動レベル計算に任せるよう、tag属性を削除してください。
|
|
27
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-heading-in-sectioning-content
|
|
24
28
|
- tag属性を指定することで意図しないレベルに固定されてしまう可能性があります。`
|
|
25
29
|
|
|
26
30
|
const VariableDeclaratorBareToSHR = (context, node) => {
|
|
@@ -281,6 +285,7 @@ module.exports = {
|
|
|
281
285
|
context.report({
|
|
282
286
|
node,
|
|
283
287
|
message: `${isSection ? elementName : `<${elementName} ${layoutSectionAsAttr.name.name}="${layoutSectionAsAttr.value.value}">`} はHeading要素を含んでいません。
|
|
288
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-heading-in-sectioning-content
|
|
284
289
|
- SectioningContentはHeadingを含むようにマークアップする必要があります
|
|
285
290
|
- ${elementName}に設定しているいずれかの属性がHeading,もしくはHeadingのテキストに該当する場合、その属性の名称を ${headingAttributeRegex.toString()} にマッチする名称に変更してください
|
|
286
291
|
- Headingにするべき適切な文字列が存在しない場合、 ${isSection ? `${elementName} は削除するか、SectioningContentではない要素に差し替えてください` : `${layoutSectionAsAttr.name.name}="${layoutSectionAsAttr.value.value}"を削除、もしくは別の要素に変更してください`}${isNav ? `
|
|
@@ -72,7 +72,8 @@ module.exports = {
|
|
|
72
72
|
if (node.name.name === 'href' && ANCHER_LIKE_REGEX.test(node.parent.name.name) && !HELP_LINK_REGEX.test(node.parent.name.name) && checkSupportURL(node.value, context)) {
|
|
73
73
|
context.report({
|
|
74
74
|
node,
|
|
75
|
-
message: `ヘルプページ用のリンクは smarthr-ui/HelpLink
|
|
75
|
+
message: `ヘルプページ用のリンクは smarthr-ui/HelpLink コンポーネントを利用してください
|
|
76
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-help-link-with-support-href`,
|
|
76
77
|
});
|
|
77
78
|
}
|
|
78
79
|
},
|
|
@@ -2,12 +2,14 @@ const IMG_ELEMENT = 'JSXOpeningElement[name.name=/((i|I)mg|Image)$/]'
|
|
|
2
2
|
const ALT_LIKE_ATTRIBUTE = 'JSXAttribute[name.name=/^(alt|aria-describedby)$/]'
|
|
3
3
|
|
|
4
4
|
const MESSAGE_NOT_EXIST_ALT = `画像にはalt属性を指定してください。
|
|
5
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-image-has-alt-attribute
|
|
5
6
|
- コンポーネントが画像ではない場合、img or image を末尾に持たない名称に変更してください。
|
|
6
7
|
- ボタンやリンクの先頭・末尾などに設置するアイコンとしての役割を持つ画像の場合、コンポーネント名の末尾を "Icon" に変更してください。
|
|
7
8
|
- SVG component の場合、altを属性として受け取れるようにした上で '<svg role="img" aria-label={alt}>' のように指定してください。
|
|
8
9
|
- 文字情報が多い場合や画像の前後の画像と同じ内容を設定したい場合などは aria-describedby属性を利用することもできます。
|
|
9
10
|
- aria-describedby属性を利用する場合でもalt属性を併用することができます。`
|
|
10
11
|
const MESSAGE_NULL_ALT = `画像の情報をテキストにした代替テキスト('alt')を設定してください。
|
|
12
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-image-has-alt-attribute
|
|
11
13
|
- 装飾目的の画像など、alt属性に指定すべき文字がない場合は背景画像にすることを検討してください。`
|
|
12
14
|
|
|
13
15
|
const SCHEMA = [
|
|
@@ -57,20 +57,23 @@ module.exports = {
|
|
|
57
57
|
[`${INPUT_ELEMENT_WITHOUT_RADIO}:not(:has(:matches(${NAME_ATTRIBUTE},JSXAttribute[name.name="type"][value.value="radio"])))${notHasSpreadAttribute}`]: (node) => {
|
|
58
58
|
context.report({
|
|
59
59
|
node,
|
|
60
|
-
message: `${node.name.name} にname属性を指定してください${MESSAGE_UNDEFINED_NAME_PART}
|
|
60
|
+
message: `${node.name.name} にname属性を指定してください${MESSAGE_UNDEFINED_NAME_PART}
|
|
61
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-has-name-attribute`,
|
|
61
62
|
})
|
|
62
63
|
},
|
|
63
64
|
[`${RADIO_ELEMENT}:not(:has(${NAME_ATTRIBUTE}))${notHasSpreadAttribute}`]: (node) => {
|
|
64
65
|
context.report({
|
|
65
66
|
node,
|
|
66
67
|
message: `${node.name.name} にグループとなる他のinput[radio]と同じname属性を指定してください
|
|
67
|
-
- 適切に指定することで同じname属性を指定したinput[radio]とグループが確立され、適切なキーボード操作を行えるようになります${MESSAGE_UNDEFINED_NAME_PART}
|
|
68
|
+
- 適切に指定することで同じname属性を指定したinput[radio]とグループが確立され、適切なキーボード操作を行えるようになります${MESSAGE_UNDEFINED_NAME_PART}
|
|
69
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-has-name-attribute`,
|
|
68
70
|
})
|
|
69
71
|
},
|
|
70
72
|
[`${INPUT_ELEMENT}${notHasSpreadAttribute} ${NAME_ATTRIBUTE}[value.value]:not([value.value=${INPUT_NAME_REGEX}])`]: (node) => {
|
|
71
73
|
context.report({
|
|
72
74
|
node,
|
|
73
|
-
message: `${node.parent.name.name} のname属性の値(${node.value.value})はブラウザの自動補完が適切に行えない可能性があるため${MESSAGE_PART_FORMAT}
|
|
75
|
+
message: `${node.parent.name.name} のname属性の値(${node.value.value})はブラウザの自動補完が適切に行えない可能性があるため${MESSAGE_PART_FORMAT}
|
|
76
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-has-name-attribute`,
|
|
74
77
|
})
|
|
75
78
|
},
|
|
76
79
|
}
|
|
@@ -145,7 +145,8 @@ module.exports = {
|
|
|
145
145
|
|
|
146
146
|
context.report({
|
|
147
147
|
node: n,
|
|
148
|
-
message: `${name} が ${nodeName} を含んでいます。smarthr-ui/${matcherFormControl[1]} を smarthr-ui/Fieldset
|
|
148
|
+
message: `${name} が ${nodeName} を含んでいます。smarthr-ui/${matcherFormControl[1]} を smarthr-ui/Fieldset に変更し、正しくグルーピングされるように修正してください。
|
|
149
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-in-form-control${isRadio ? `
|
|
149
150
|
- Fieldsetで同じname属性のラジオボタン全てを囲むことで正しくグループ化され、適切なタイトル・説明を追加出来ます` : ''}${isPureInput ? `
|
|
150
151
|
- 可能なら${nodeName}は${convertComp}への変更を検討してください。難しい場合は ${nodeName} と結びつくlabel要素が必ず存在するよう、マークアップする必要があることに注意してください。` : ''}`,
|
|
151
152
|
});
|
|
@@ -153,6 +154,7 @@ module.exports = {
|
|
|
153
154
|
context.report({
|
|
154
155
|
node: n,
|
|
155
156
|
message: `${name} が複数の入力要素を含んでいます。ラベルと入力要素の紐づけが正しく行われない可能性があるため、以下の方法のいずれかで修正してください。
|
|
157
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-in-form-control
|
|
156
158
|
- 方法1: 郵便番号や電話番号など、本来一つの概念の入力要素を分割して複数の入力要素にしている場合、一つの入力要素にまとめることを検討してください
|
|
157
159
|
- コピーアンドペーストがしやすくなる、ブラウザの自動補完などがより適切に反映されるなど多大なメリットがあります
|
|
158
160
|
- 方法2: ${name}をsmarthr-ui/Fieldset、もしくはそれを拡張したコンポーネントに変更した上で、入力要素を一つずつsmarthr-ui/FormControlで囲むようにマークアップを変更してください
|
|
@@ -168,6 +170,7 @@ module.exports = {
|
|
|
168
170
|
context.report({
|
|
169
171
|
node: n,
|
|
170
172
|
message: `${name} が ラベルを持たない入力要素(${nodeName})を含んでいます。入力要素が何であるかを正しく伝えるため、以下の方法のいずれかで修正してください。
|
|
173
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-in-form-control
|
|
171
174
|
- 方法1: ${name} を smarthr-ui/FormControl、もしくはそれを拡張したコンポーネントに変更してください
|
|
172
175
|
- 画面上に表示するラベルが存在しない場合でも、必ずその入力要素は何であるか、どんな値を入力すればいいのか?を伝えるため、ラベルの設定は必須です。
|
|
173
176
|
- この場合、FormControlのdangerouslyTitleHidden属性をtrueにして、ラベルを非表示にしてください(https://smarthr.design/products/components/form-control/)
|
|
@@ -195,6 +198,7 @@ module.exports = {
|
|
|
195
198
|
context.report({
|
|
196
199
|
node,
|
|
197
200
|
message: `${nodeName}は${actualName}より先に、smarthr-ui/${wrapComponentName}が入力要素を囲むようマークアップを以下のいずれかの方法で変更してください。
|
|
201
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-in-form-control
|
|
198
202
|
- 方法1: ${actualName} を${wrapComponentName}、もしくはそれを拡張したコンポーネントに変更してください
|
|
199
203
|
- ${actualName} 内のHeading要素は${wrapComponentName}のtitle属性に変更してください
|
|
200
204
|
- 方法2: ${actualName} と ${nodeName} の間に ${wrapComponentName} が存在するようにマークアップを変更してください
|
|
@@ -246,6 +250,7 @@ module.exports = {
|
|
|
246
250
|
context.report({
|
|
247
251
|
node,
|
|
248
252
|
message: `${nodeName} を、smarthr-ui/${wrapComponentName} もしくはそれを拡張したコンポーネントが囲むようマークアップを変更してください。
|
|
253
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-in-form-control
|
|
249
254
|
- ${wrapComponentName}で入力要素を囲むことでラベルと入力要素が適切に紐づき、操作性が高まります${isRadio ? `
|
|
250
255
|
- FieldsetでRadioButtonを囲むことでグループ化された入力要素に対して適切なタイトル・説明を追加出来ます` : `
|
|
251
256
|
- 画面上に表示するラベルが存在しない場合でも、必ずその入力要素は何であるか、どんな値を入力すればいいのか?を伝えるため、ラベルの設定は必須です。
|
|
@@ -280,11 +285,11 @@ module.exports = {
|
|
|
280
285
|
const component = formControlMatcher[1]
|
|
281
286
|
const actualComponent = az_REGEX.test(component[0]) ? component : `smarthr-ui/${component}`
|
|
282
287
|
|
|
283
|
-
const message = `${nodeName}に 'role="group" が設定されています。${actualComponent} をつかってマークアップする場合、'role="group"' は不要です
|
|
284
|
-
- ${nodeName} が ${actualComponent}、もしくはそれを拡張しているコンポーネントではない場合、名称を ${FROM_CONTROLS_REGEX} にマッチしないものに変更してください`
|
|
285
288
|
context.report({
|
|
286
289
|
node,
|
|
287
|
-
message
|
|
290
|
+
message: `${nodeName}に 'role="group" が設定されています。${actualComponent} をつかってマークアップする場合、'role="group"' は不要です
|
|
291
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-in-form-control
|
|
292
|
+
- ${nodeName} が ${actualComponent}、もしくはそれを拡張しているコンポーネントではない場合、名称を ${FROM_CONTROLS_REGEX} にマッチしないものに変更してください`,
|
|
288
293
|
});
|
|
289
294
|
|
|
290
295
|
return
|
|
@@ -308,6 +313,7 @@ module.exports = {
|
|
|
308
313
|
context.report({
|
|
309
314
|
node: n,
|
|
310
315
|
message: `${name} が、${nodeName} を子要素として持っており、マークアップとして正しくない状態になっています。以下のいずれかの方法で修正を試みてください。
|
|
316
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-in-form-control
|
|
311
317
|
- 方法1: 親要素である${name}をsmarthr-ui/${matcher[1]}、もしくはそれを拡張していないコンポーネントでマークアップしてください
|
|
312
318
|
- ${matcher[1]}ではなく、smarthr-ui/Fieldset、もしくはsmarthr-ui/Section + smarthr-ui/Heading などでのマークアップを検討してください
|
|
313
319
|
- 方法2: 親要素である${name}がsmarthr-ui/${matcher[1]}を拡張したコンポーネントではない場合、コンポーネント名を${FORM_CONTROL_REGEX}と一致しない名称に変更してください`,
|
|
@@ -432,6 +438,7 @@ module.exports = {
|
|
|
432
438
|
context.report({
|
|
433
439
|
node,
|
|
434
440
|
message: `${nodeName}内に入力要素が2個以上存在しないため、'role="group"'を削除してください。'role="group"'は複数の入力要素を一つのグループとして扱うための属性です。
|
|
441
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-input-in-form-control
|
|
435
442
|
- ${nodeName}内に2つ以上の入力要素が存在する場合、入力要素を含むコンポーネント名全てを${FORM_CONTROL_INPUTS_REGEX}、もしくは${FROM_CONTROLS_REGEX}にマッチする名称に変更してください`,
|
|
436
443
|
});
|
|
437
444
|
}
|
|
@@ -34,6 +34,7 @@ const checkNumberedTextInOl = (result, node, context) => {
|
|
|
34
34
|
context.report({
|
|
35
35
|
node,
|
|
36
36
|
message: `${result.name.name} 内で連番がテキストとして記述されています。連番はol要素で表現できるため、削除してください。
|
|
37
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-numbered-text-within-ol
|
|
37
38
|
- ol要素のデフォルトで表示される連番のフォーマット、スタイルから変更したい場合、counter-reset と counter-increment を利用してください
|
|
38
39
|
- 参考: [MDN CSS カウンターの使用](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_counter_styles/Using_CSS_counters)`,
|
|
39
40
|
})
|
|
@@ -76,6 +77,7 @@ module.exports = {
|
|
|
76
77
|
context.report({
|
|
77
78
|
node: firstNumberedNode,
|
|
78
79
|
message: `連番を含むテキストがol要素でマークアップされていません。ol要素でマークアップすることで関連する順番に意味のある要素を適切にマークアップできるため以下の方法で修正してください。
|
|
80
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-numbered-text-within-ol
|
|
79
81
|
- ${renderNode(firstNumberedNode, firstNumberedMatcher)} と ${renderNode(node, matcher)} が同じol要素内に存在するように修正してください
|
|
80
82
|
- 上記以外にも関連する連番をふくむ要素が存在する場合、それらも同じol内に存在する必要があります`,
|
|
81
83
|
})
|
|
@@ -83,6 +85,7 @@ module.exports = {
|
|
|
83
85
|
context.report({
|
|
84
86
|
node: firstNumberedNode,
|
|
85
87
|
message: `連番を含むテキストがol要素でマークアップされていません。ol要素でマークアップすることで関連する順番に意味のある要素を適切にマークアップできるため以下の方法で修正してください。
|
|
88
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-numbered-text-within-ol
|
|
86
89
|
- ${renderNode(firstNumberedNode, firstNumberedMatcher)} が ${renderNode(node, matcher)} を囲んでいるol要素内(<${result.name.name}>)に存在するように修正してください
|
|
87
90
|
- 上記以外にも関連する連番をふくむ要素が存在する場合、それらも同じol要素内(<${result.name.name}>)に存在する必要があります`,
|
|
88
91
|
})
|
|
@@ -92,6 +95,7 @@ module.exports = {
|
|
|
92
95
|
context.report({
|
|
93
96
|
node,
|
|
94
97
|
message: `連番を含むテキストがol要素でマークアップされていません。ol要素でマークアップすることで関連する順番に意味のある要素を適切にマークアップできるため以下の方法で修正してください。
|
|
98
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-numbered-text-within-ol
|
|
95
99
|
- ${renderNode(node, matcher)} が ${renderNode(firstNumberedNode, firstNumberedMatcher)} を囲んでいるol要素内(<${resultFirst.name.name}>)に存在するように修正してください
|
|
96
100
|
- 上記以外にも関連する連番をふくむ要素が存在する場合、それらも同じol要素内(<${resultFirst.name.name}>)に存在する必要があります`,
|
|
97
101
|
})
|
|
@@ -101,6 +105,7 @@ module.exports = {
|
|
|
101
105
|
context.report({
|
|
102
106
|
node,
|
|
103
107
|
message: `連番を含むテキストが同一のol要素でマークアップされていません。同一のol要素でマークアップすることでリスト内の要素関連性を正しく表せるためマークアップの修正を行ってください。
|
|
108
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-numbered-text-within-ol
|
|
104
109
|
- ${renderNode(firstNumberedNode, firstNumberedMatcher)} と ${renderNode(node, matcher)} が同じol要素内に存在するように修正してください
|
|
105
110
|
- 上記以外にも関連する連番をふくむ要素が存在する場合、それらも同じol内に存在する必要があります`,
|
|
106
111
|
})
|
|
@@ -7,7 +7,8 @@ module.exports = {
|
|
|
7
7
|
fixable: 'code',
|
|
8
8
|
schema: [],
|
|
9
9
|
messages: {
|
|
10
|
-
default:
|
|
10
|
+
default: `{{cell}} の子孫に {{component}} を置くことはできません。代わりに {{preferred}} を使用してください。
|
|
11
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-checkbox-or-radio-in-table-cell`,
|
|
11
12
|
},
|
|
12
13
|
},
|
|
13
14
|
create(context) {
|
|
@@ -14,10 +14,11 @@ module.exports = {
|
|
|
14
14
|
context.report({
|
|
15
15
|
node,
|
|
16
16
|
message: `${node.name.name}にmaxLength属性を設定しないでください。
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-input-maxlength-attribute
|
|
18
|
+
- maxLength属性がついた要素に、テキストをペーストすると、maxLength属性の値を超えた範囲が意図せず切り捨てられてしまう場合があります
|
|
19
|
+
- 以下のいずれかの方法で修正をおこなってください
|
|
20
|
+
- 方法1: pattern属性とtitle属性を組み合わせ、form要素でラップする
|
|
21
|
+
- 方法2: JavaScriptを用いたバリデーションを実装する`,
|
|
21
22
|
})
|
|
22
23
|
},
|
|
23
24
|
}
|
|
@@ -16,7 +16,8 @@ module.exports = {
|
|
|
16
16
|
[`${COMBOBOX_ELEMENT}:has(${DEFAULT_ITEM_ATTRIBUTE}) ${PLACEHOLDER_ATTRIBUTE}`]: (node) => {
|
|
17
17
|
context.report({
|
|
18
18
|
node,
|
|
19
|
-
message: `${node.parent.name.name} にはdefaultItemが設定されているため、placeholder
|
|
19
|
+
message: `${node.parent.name.name} にはdefaultItemが設定されているため、placeholder属性を閲覧出来ません。削除してください。
|
|
20
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-input-placeholder`,
|
|
20
21
|
})
|
|
21
22
|
},
|
|
22
23
|
[`${COMBOBOX_ELEMENT}:not(:has(${DEFAULT_ITEM_ATTRIBUTE}, JSXAttribute[name.name="dropdownHelpMessage"])) ${PLACEHOLDER_ATTRIBUTE}`]: (node) => {
|
|
@@ -25,6 +26,7 @@ module.exports = {
|
|
|
25
26
|
context.report({
|
|
26
27
|
node,
|
|
27
28
|
message: `${name} にはplaceholder属性は設定せず、以下のいずれか、もしくは組み合わせての対応を検討してください。
|
|
29
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-input-placeholder
|
|
28
30
|
- 選択肢をどんな値で絞り込めるかの説明をしたい場合は dropdownHelpMessage 属性に変更してください。
|
|
29
31
|
- 空の値の説明のためにplaceholderを利用している場合は defaultItem 属性に変更してください。
|
|
30
32
|
- 上記以外の説明を行いたい場合、ヒント用要素を設置してください。(例: '<div><${name} /><Hint>ヒント</Hint></div>')`,
|
|
@@ -34,7 +36,8 @@ module.exports = {
|
|
|
34
36
|
const inputName = node.parent.name.name
|
|
35
37
|
context.report({
|
|
36
38
|
node,
|
|
37
|
-
message: `${inputName} にはplaceholder属性を単独で利用せず、tooltipMessageオプションのみ、もしくはplaceholderとtooltipMessageの併用を検討してください。 (例: '<${inputName} tooltipMessage="ヒント" />', '<${inputName} tooltipMessage={hint} placeholder={hint} />')
|
|
39
|
+
message: `${inputName} にはplaceholder属性を単独で利用せず、tooltipMessageオプションのみ、もしくはplaceholderとtooltipMessageの併用を検討してください。 (例: '<${inputName} tooltipMessage="ヒント" />', '<${inputName} tooltipMessage={hint} placeholder={hint} />')
|
|
40
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-input-placeholder`,
|
|
38
41
|
})
|
|
39
42
|
},
|
|
40
43
|
[`JSXOpeningElement[name.name=/((I|^i)nput|(T|^t)extarea|FieldSet|(Date|Wareki|Time)Picker)$/]:not(${SEARCH_INPUT_NAME}) ${PLACEHOLDER_ATTRIBUTE}`]: (node) => {
|
|
@@ -42,7 +45,8 @@ module.exports = {
|
|
|
42
45
|
|
|
43
46
|
context.report({
|
|
44
47
|
node,
|
|
45
|
-
message: `${name} にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><${name} /><Hint>ヒント</Hint></div>')
|
|
48
|
+
message: `${name} にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><${name} /><Hint>ヒント</Hint></div>')
|
|
49
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-input-placeholder`,
|
|
46
50
|
})
|
|
47
51
|
},
|
|
48
52
|
}
|
|
@@ -134,6 +134,7 @@ module.exports = {
|
|
|
134
134
|
context.report({
|
|
135
135
|
node,
|
|
136
136
|
message: `${isSection ? elementName : `${asAttr.name.name}="${asAttr.value.value}"`}とその内部に存在するHeadingをsmarthr-ui/Fieldsetに置き換えてください
|
|
137
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-sectioning-content-in-form
|
|
137
138
|
- もしくはform要素を利用していない場合、フォームを構成する入力要素郡すべてを一つのform要素で囲んでください
|
|
138
139
|
- required属性、pattern属性など一部属性はform要素で囲まないと動作しません
|
|
139
140
|
- 送信用ボタンのonClickをform要素のonSubmitに移動し、送信用ボタンのtype属性に "submit" を指定することでより適切にマークアップ出来ます
|
|
@@ -153,6 +154,7 @@ module.exports = {
|
|
|
153
154
|
context.report({
|
|
154
155
|
node: sectioningContent.node,
|
|
155
156
|
message: `${sectioningContent.elementName}とその内部に存在するHeadingをsmarthr-ui/Fieldsetに置き換えてください
|
|
157
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-sectioning-content-in-form
|
|
156
158
|
- もしくはform要素を利用していない場合、フォームを構成する入力要素郡すべてを一つのform要素で囲んでください
|
|
157
159
|
- required属性、pattern属性など一部属性はform要素で囲まないと動作しません
|
|
158
160
|
- 送信用ボタンのonClickをform要素のonSubmitに移動し、送信用ボタンのtype属性に "submit" を指定することでより適切にマークアップ出来ます
|
|
@@ -17,7 +17,8 @@ module.exports = {
|
|
|
17
17
|
[`${SECTIONING_FRAGMENT_ELEMENT}:has(:matches(${SECTIONING_CONTENT_ELEMENT}, ${SECTIONING_LAYOUT_ELEMENT}))`]: (node) => {
|
|
18
18
|
context.report({
|
|
19
19
|
node,
|
|
20
|
-
message: `無意味なSectioningFragmentが記述されています。子要素で問題なくセクションは設定されているため、このSectioningFragment
|
|
20
|
+
message: `無意味なSectioningFragmentが記述されています。子要素で問題なくセクションは設定されているため、このSectioningFragmentは削除してください
|
|
21
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-prohibit-useless-sectioning-fragment`
|
|
21
22
|
})
|
|
22
23
|
},
|
|
23
24
|
}
|
|
@@ -26,7 +26,8 @@ module.exports = {
|
|
|
26
26
|
|
|
27
27
|
context.report({
|
|
28
28
|
node,
|
|
29
|
-
message: `${match[1]}Trigger の直下には複数のコンポーネントを設置することは出来ません。button
|
|
29
|
+
message: `${match[1]}Trigger の直下には複数のコンポーネントを設置することは出来ません。button要素が一つだけ設置されている状態にしてください
|
|
30
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-trigger-has-button`,
|
|
30
31
|
})
|
|
31
32
|
} else {
|
|
32
33
|
const c = children[0]
|
|
@@ -44,7 +45,8 @@ module.exports = {
|
|
|
44
45
|
|
|
45
46
|
context.report({
|
|
46
47
|
node: c,
|
|
47
|
-
message: `${match[1]}Trigger の直下にはbutton要素のみ設置してください(AnchorButtonはa要素のため設置できません)
|
|
48
|
+
message: `${match[1]}Trigger の直下にはbutton要素のみ設置してください(AnchorButtonはa要素のため設置できません)
|
|
49
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/a11y-trigger-has-button`,
|
|
48
50
|
})
|
|
49
51
|
}
|
|
50
52
|
}
|
|
@@ -39,7 +39,7 @@ module.exports = {
|
|
|
39
39
|
context.report({
|
|
40
40
|
node,
|
|
41
41
|
message: `currentTargetはイベント処理中以外に参照するとnullになる場合があります。awaitの宣言より前にcurrentTarget、もしくはcurrentTarget以下の属性を含む値を変数として宣言してください
|
|
42
|
-
-
|
|
42
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-async-current-target
|
|
43
43
|
- NG例:
|
|
44
44
|
const onChange = async (e) => {
|
|
45
45
|
await hoge()
|
|
@@ -58,7 +58,7 @@ module.exports = {
|
|
|
58
58
|
context.report({
|
|
59
59
|
node,
|
|
60
60
|
message: `currentTargetはイベント処理中以外に参照するとnullになる場合があります。イベントハンドラ用関数のスコープ直下でcurrentTarget、もしくはcurrentTarget以下の属性を含む値を変数として宣言してください
|
|
61
|
-
-
|
|
61
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-async-current-target
|
|
62
62
|
- React/useStateのsetterは第一引数に関数を渡すと非同期処理になるためこの問題が起きる可能性があります
|
|
63
63
|
- イベントハンドラ内で関数を定義すると参照タイミングがずれる可能性があるため、イベントハンドラ直下のスコープ内にcurrentTarget関連の参照を変数に残すことをオススメします
|
|
64
64
|
- NG例:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const ERRORMESSAGE_SUFFIX = `
|
|
2
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-button-element
|
|
2
3
|
- button要素のtype属性のデフォルトは "submit" のため、button要素がformでラップされていると意図しないsubmitを引き起こす可能性があります
|
|
3
4
|
- smarthr-ui/Button, smarthr-ui/UnstyledButtonのtype属性のデフォルトは "button" になっているため、buttonから置き換えることをおすすめします`
|
|
4
5
|
|
|
@@ -16,6 +16,7 @@ module.exports = {
|
|
|
16
16
|
context.report({
|
|
17
17
|
node,
|
|
18
18
|
message: `テストしたい要素を指定するためにテスト用の属性は利用せず、他の方法を検討してください
|
|
19
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-data-test-attribute
|
|
19
20
|
- 方法1: click_link, click_button等を利用することで、テスト環境に準じた方法で要素を指定することを検討してください
|
|
20
21
|
- 参考(Testing Library): https://testing-library.com/docs/queries/about
|
|
21
22
|
- 参考(Capybara): https://rubydoc.info/github/jnicklas/capybara/Capybara/Node/Finders
|
|
@@ -33,6 +33,7 @@ module.exports = {
|
|
|
33
33
|
context.report({
|
|
34
34
|
node,
|
|
35
35
|
message: `'new Date(arg)' のように引数を一つだけ指定したDate instanceの生成は実行環境によって結果が異なるため、以下のいずれかの方法に変更してください
|
|
36
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-date
|
|
36
37
|
- 'new Date(2022, 12 - 1, 31)' のように数値を個別に指定する
|
|
37
38
|
- dayjsなど、日付系ライブラリを利用する (例: 'dayjs(arg).toDate()')`,
|
|
38
39
|
fix: (fixer) => fixAction(fixer, node),
|
|
@@ -42,6 +43,7 @@ module.exports = {
|
|
|
42
43
|
context.report({
|
|
43
44
|
node,
|
|
44
45
|
message: `Date.parse は実行環境によって結果が異なるため、以下のいずれかの方法に変更してください
|
|
46
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-date
|
|
45
47
|
- 'new Date(2022, 12 - 1, 31).getTime()' のように数値を個別に指定する
|
|
46
48
|
- dayjsなど、日付系ライブラリを利用する (例: 'dayjs(arg).valueOf()')`,
|
|
47
49
|
fix: (fixer) => fixAction(fixer, node, '.getTime()'),
|
|
@@ -92,6 +92,7 @@ module.exports = {
|
|
|
92
92
|
context.report({
|
|
93
93
|
node,
|
|
94
94
|
message: `${nodeName} に "gap={0}" が指定されており、smarthr-ui/${layoutType} の利用方法として誤っている可能性があります。以下の修正方法を検討してください。
|
|
95
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts
|
|
95
96
|
- 方法1: 子要素を一つにまとめられないか検討してください
|
|
96
97
|
- 例: "<Stack gap={0}><p>hoge</p><p>fuga</p></Stack>" を "<p>hoge<br />fuga</p>" にするなど
|
|
97
98
|
- 方法2: 子要素のstyleを確認しgap属性を0以外にできないか検討してください
|
|
@@ -115,8 +116,10 @@ module.exports = {
|
|
|
115
116
|
node,
|
|
116
117
|
message:
|
|
117
118
|
(justifyAttr?.value.value === 'center' || alignAttr?.value.value === 'center')
|
|
118
|
-
? `${nodeName} は smarthr-ui/${layoutType} ではなく smarthr-ui/Center
|
|
119
|
+
? `${nodeName} は smarthr-ui/${layoutType} ではなく smarthr-ui/Center でマークアップしてください
|
|
120
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`
|
|
119
121
|
: `${nodeName}には子要素が一つしか無いため、${layoutType}でマークアップする意味がありません。
|
|
122
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts
|
|
120
123
|
- styleを確認し、div・spanなど、別要素でマークアップし直すか、${nodeName}を削除してください
|
|
121
124
|
- as, forwardedAsなどでSectioningContent系要素に変更している場合、対応するsmarthr-ui/Section, Aside, Nav, Article のいずれかに差し替えてください`
|
|
122
125
|
})
|
|
@@ -128,55 +131,64 @@ module.exports = {
|
|
|
128
131
|
|
|
129
132
|
context.report({
|
|
130
133
|
node,
|
|
131
|
-
message: `Headingの子孫に${component}を置くことはできません。Headingの外で${component}
|
|
134
|
+
message: `Headingの子孫に${component}を置くことはできません。Headingの外で${component}を使用するようにマークアップを修正してください。
|
|
135
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`
|
|
132
136
|
})
|
|
133
137
|
},
|
|
134
138
|
[`${HEADING_ELEMENT} ${STACK_ELEMENT_NOT_SPAN}`]: (node) => {
|
|
135
139
|
context.report({
|
|
136
140
|
node,
|
|
137
|
-
message:
|
|
141
|
+
message: `Headingの子孫にStackを置く場合、as属性、もしくはforwardedAs属性に \`span\` を指定してください
|
|
142
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`,
|
|
138
143
|
})
|
|
139
144
|
},
|
|
140
145
|
[`${HEADING_ELEMENT} :matches(${ICON_ELEMENT_WITH_TEXT},${TEXT_ELEMENT_WITH_PREFIX})`]: (node) => {
|
|
141
146
|
context.report({
|
|
142
147
|
node,
|
|
143
|
-
message:
|
|
148
|
+
message: `HeadingにIconを設定する場合 <Heading icon={<XxxIcon />}></Heading> のようにicon属性を利用してください
|
|
149
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`,
|
|
144
150
|
})
|
|
145
151
|
},
|
|
146
152
|
[`${FORM_CONTROL_LABEL_ATTRIBUTE} ${INVALID_ELEMENT}`]: (node) => {
|
|
147
153
|
context.report({
|
|
148
154
|
node,
|
|
149
|
-
message: `FormControlのlabel属性に${node.name.name.match(TARGET_INVALID_COMPONENT_REGEX)[1]}を置くことはできません。ラベル用テキスト以外をstatusLabels、subActionArea、もしくはlabel属性のObjectとして '{ text: テキスト, icon: <XxxIcon /> }'
|
|
155
|
+
message: `FormControlのlabel属性に${node.name.name.match(TARGET_INVALID_COMPONENT_REGEX)[1]}を置くことはできません。ラベル用テキスト以外をstatusLabels、subActionArea、もしくはlabel属性のObjectとして '{ text: テキスト, icon: <XxxIcon /> }'に置き換えてください。
|
|
156
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`,
|
|
150
157
|
})
|
|
151
158
|
},
|
|
152
159
|
[`${FORM_CONTROL_LABEL_ATTRIBUTE} ${STACK_ELEMENT_NOT_SPAN}`]: (node) => {
|
|
153
160
|
context.report({
|
|
154
161
|
node,
|
|
155
|
-
message:
|
|
162
|
+
message: `FormControlのlabel属性にStackを置く場合、as属性、もしくはforwardedAs属性に \`span\` を指定してください
|
|
163
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`,
|
|
156
164
|
})
|
|
157
165
|
},
|
|
158
166
|
[`${FORM_CONTROL_LABEL_ATTRIBUTE} :matches(${ICON_ELEMENT_WITH_TEXT},${TEXT_ELEMENT_WITH_PREFIX})`]: (node) => {
|
|
159
167
|
context.report({
|
|
160
168
|
node,
|
|
161
|
-
message:
|
|
169
|
+
message: `FormControlのlabel属性にアイコンを設定する場合 <FormControl label={{ text: 'テキスト', icon: <XxxIcon /> }} /> のようにlabel.icon属性を利用してください
|
|
170
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`,
|
|
162
171
|
})
|
|
163
172
|
},
|
|
164
173
|
[`${FIELDSET_LEGEND_ATTRIBUTE} ${INVALID_ELEMENT}`]: (node) => {
|
|
165
174
|
context.report({
|
|
166
175
|
node,
|
|
167
|
-
message: `Fieldsetのlegend属性に${node.name.name.match(TARGET_INVALID_COMPONENT_REGEX)[1]}を置くことはできません。ラベル用テキスト以外をstatusLabels、subActionArea、もしくはlabel属性のObjectとして '{ text: テキスト, icon: <XxxIcon /> }'
|
|
176
|
+
message: `Fieldsetのlegend属性に${node.name.name.match(TARGET_INVALID_COMPONENT_REGEX)[1]}を置くことはできません。ラベル用テキスト以外をstatusLabels、subActionArea、もしくはlabel属性のObjectとして '{ text: テキスト, icon: <XxxIcon /> }'に置き換えてください。
|
|
177
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`,
|
|
168
178
|
})
|
|
169
179
|
},
|
|
170
180
|
[`${FIELDSET_LEGEND_ATTRIBUTE} ${STACK_ELEMENT_NOT_SPAN}`]: (node) => {
|
|
171
181
|
context.report({
|
|
172
182
|
node,
|
|
173
|
-
message:
|
|
183
|
+
message: `Fieldsetのlegend属性にStackを置く場合、as属性、もしくはforwardedAs属性に \`span\` を指定してください
|
|
184
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`,
|
|
174
185
|
})
|
|
175
186
|
},
|
|
176
187
|
[`${FIELDSET_LEGEND_ATTRIBUTE} :matches(${ICON_ELEMENT_WITH_TEXT},${TEXT_ELEMENT_WITH_PREFIX})`]: (node) => {
|
|
177
188
|
context.report({
|
|
178
189
|
node,
|
|
179
|
-
message:
|
|
190
|
+
message: `Fieldsetのlegend属性にアイコンを設定する場合 <Fieldset legend={{ text: 'テキスト', icon: <XxxIcon /> }} /> のようにlegend.icon属性を利用してください
|
|
191
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts`,
|
|
180
192
|
})
|
|
181
193
|
},
|
|
182
194
|
}
|
|
@@ -13,6 +13,7 @@ module.exports = {
|
|
|
13
13
|
context.report({
|
|
14
14
|
node,
|
|
15
15
|
message: `入力要素のname属性に対して、配列に当たる部分の連番を指定しない場合(例: a[xxx][][yyy] )、配列内アイテムの属性が意図せず入れ替わってしまう場合がありえるため、常にindexを設定してください。
|
|
16
|
+
- 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-nested-attributes-array-index
|
|
16
17
|
- 例のyyyに当たる値が配列内の別アイテムに紐づいてしまう場合があります。
|
|
17
18
|
- 詳しくは https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-nested-attributes-array-index を参照してください`,
|
|
18
19
|
})
|