eslint-plugin-smarthr 2.3.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.
Files changed (79) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/package.json +2 -2
  3. package/rules/a11y-anchor-has-href-attribute/index.js +1 -0
  4. package/rules/a11y-clickable-element-has-text/index.js +1 -0
  5. package/rules/a11y-delegate-element-has-role-presentation/index.js +2 -0
  6. package/rules/a11y-form-control-in-form/index.js +1 -0
  7. package/rules/a11y-heading-in-sectioning-content/README.md +16 -1
  8. package/rules/a11y-heading-in-sectioning-content/index.js +7 -2
  9. package/rules/a11y-help-link-with-support-href/index.js +2 -1
  10. package/rules/a11y-image-has-alt-attribute/index.js +2 -0
  11. package/rules/a11y-input-has-name-attribute/index.js +6 -3
  12. package/rules/a11y-input-in-form-control/index.js +11 -4
  13. package/rules/a11y-numbered-text-within-ol/index.js +5 -0
  14. package/rules/a11y-prohibit-checkbox-or-radio-in-table-cell/index.js +5 -23
  15. package/rules/a11y-prohibit-input-maxlength-attribute/index.js +5 -4
  16. package/rules/a11y-prohibit-input-placeholder/index.js +7 -3
  17. package/rules/a11y-prohibit-sectioning-content-in-form/index.js +2 -0
  18. package/rules/a11y-prohibit-useless-sectioning-fragment/index.js +2 -1
  19. package/rules/a11y-trigger-has-button/index.js +4 -2
  20. package/rules/best-practice-for-async-current-target/index.js +2 -2
  21. package/rules/best-practice-for-button-element/index.js +1 -0
  22. package/rules/best-practice-for-data-test-attribute/index.js +1 -0
  23. package/rules/best-practice-for-date/index.js +2 -0
  24. package/rules/best-practice-for-layouts/index.js +22 -10
  25. package/rules/best-practice-for-nested-attributes-array-index/index.js +1 -0
  26. package/rules/best-practice-for-remote-trigger-dialog/index.js +2 -1
  27. package/rules/best-practice-for-tailwind-prohibit-root-margin/index.js +2 -1
  28. package/rules/best-practice-for-tailwind-variants/index.js +6 -3
  29. package/rules/component-name/README.md +11 -3
  30. package/rules/component-name/index.js +135 -2
  31. package/rules/design-system-guideline-prohibit-double-icons/index.js +1 -0
  32. package/rules/format-import-path/index.js +2 -1
  33. package/rules/jsx-start-with-spread-attributes/index.js +2 -1
  34. package/rules/no-import-other-domain/index.js +2 -1
  35. package/rules/prohibit-export-array-type/index.js +1 -0
  36. package/rules/prohibit-file-name/index.js +2 -1
  37. package/rules/prohibit-import/index.js +4 -2
  38. package/rules/prohibit-path-within-template-literal/index.js +2 -1
  39. package/rules/require-barrel-import/index.js +2 -1
  40. package/rules/require-declaration/index.js +4 -2
  41. package/rules/require-export/index.js +2 -1
  42. package/rules/require-i18n-text/index.js +4 -2
  43. package/rules/require-import/index.js +2 -1
  44. package/rules/trim-props/index.js +24 -12
  45. package/test/a11y-anchor-has-href-attribute.js +1 -0
  46. package/test/a11y-clickable-element-has-text.js +1 -0
  47. package/test/a11y-delegate-element-has-role-presentation.js +2 -0
  48. package/test/a11y-form-control-in-form.js +1 -0
  49. package/test/a11y-heading-in-sectioning-content.js +7 -2
  50. package/test/a11y-help-link-with-support-href.js +2 -1
  51. package/test/a11y-image-has-alt-attribute.js +2 -0
  52. package/test/a11y-input-has-name-attribute.js +30 -15
  53. package/test/a11y-input-in-form-control.js +15 -1
  54. package/test/a11y-numbered-text-within-ol.js +29 -0
  55. package/test/a11y-prohhibit-input-placeholder.js +19 -9
  56. package/test/a11y-prohibit-checkbox-or-radio-in-table-cell.js +35 -15
  57. package/test/a11y-prohibit-input-maxlength-attribute.js +5 -4
  58. package/test/a11y-prohibit-useless-sectioning-fragment.js +2 -1
  59. package/test/a11y-trigger-has-button.js +12 -6
  60. package/test/best-practice-for-async-current-target.js +2 -2
  61. package/test/best-practice-for-button-element.js +2 -0
  62. package/test/best-practice-for-data-test-attribute.js +1 -0
  63. package/test/best-practice-for-date.js +2 -0
  64. package/test/best-practice-for-layouts.js +26 -12
  65. package/test/best-practice-for-nested-attributes-array-index.js +1 -0
  66. package/test/best-practice-for-remote-trigger-dialog.js +6 -3
  67. package/test/best-practice-for-tailwind-prohibit-root-margin.js +2 -2
  68. package/test/best-practice-for-tailwind-variants.js +8 -4
  69. package/test/component-name.js +11 -2
  70. package/test/design-system-guideline-prohibit-double-icons.js +1 -0
  71. package/test/prohibit-file-name.js +4 -2
  72. package/test/prohibit-import.js +14 -7
  73. package/test/prohibit-path-within-template-literal.js +4 -2
  74. package/test/require-declaration.js +11 -5
  75. package/test/require-export.js +6 -3
  76. package/test/require-i18n-text.js +4 -3
  77. package/test/require-import.js +13 -7
  78. package/test/trim-props.js +23 -14
  79. package/libs/format_styled_components.js +0 -126
package/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
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
+
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)
13
+
14
+
15
+ ### Features
16
+
17
+ * Modalというコンポーネントの作成を禁止し、Dialogという名称に統一させる ([#915](https://github.com/kufu/tamatebako/issues/915)) ([208c2a0](https://github.com/kufu/tamatebako/commit/208c2a06034bcf24bfe1a3dd0d8633b0c546db11))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * a11y-prohibit-checkbox-or-radio-in-table-cellのautofixを削除 & childrenを持つ場合に警告されないよう修正 ([#914](https://github.com/kufu/tamatebako/issues/914)) ([3962fda](https://github.com/kufu/tamatebako/commit/3962fda01a1966c9624d5cd7056d807f86ccb5bc))
23
+ * trim-props でTemplateLiteralがネストしている場合のチェックを修正 ([#912](https://github.com/kufu/tamatebako/issues/912)) ([2d090c4](https://github.com/kufu/tamatebako/commit/2d090c4ef6d1ac4c9537fdb13a0198552456c10c))
24
+
5
25
  ## [2.3.0](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v2.2.1...eslint-plugin-smarthr-v2.3.0) (2025-12-01)
6
26
 
7
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-smarthr",
3
- "version": "2.3.0",
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": "18f89a924a8920722a1e71982a4d117db0c6a073"
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 = 'smarthr-ui/PageHeading が同一ファイル内に複数存在しています。PageHeadingはh1タグを出力するため最も重要な見出しにのみ利用してください。'
22
- const pageHeadingInSectionMessage = 'smarthr-ui/PageHeadingはsmarthr-uiのArticle, Aside, Nav, Sectionで囲まないでください。囲んでしまうとページ全体の見出しではなくなってしまいます。'
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 に変更し、正しくグルーピングされるように修正してください。${isRadio ? `
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
  })
@@ -1,12 +1,3 @@
1
- const findClosestThFromAncestor = (node) => {
2
- if (node.type === 'JSXElement' && node.openingElement.name.name === 'Th') {
3
- return node
4
- }
5
- if (node.parent) {
6
- return findClosestThFromAncestor(node.parent)
7
- }
8
- }
9
-
10
1
  /**
11
2
  * @type {import('@typescript-eslint/utils').TSESLint.RuleModule<''>}
12
3
  */
@@ -16,14 +7,13 @@ module.exports = {
16
7
  fixable: 'code',
17
8
  schema: [],
18
9
  messages: {
19
- default: '{{cell}} の子孫に {{component}} を置くことはできません。代わりに {{preferred}} を使用してください。',
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`,
20
12
  },
21
13
  },
22
14
  create(context) {
23
- const sourceCode = context.sourceCode
24
-
25
15
  return {
26
- 'JSXElement[openingElement.name.name=/Td$/] JSXElement[openingElement.name.name=/Check(b|B)ox$/]': (node) => {
16
+ 'JSXElement[openingElement.name.name=/Td$/] JSXElement[openingElement.name.name=/Check(b|B)ox$/][children.length=0]': (node) => {
27
17
  context.report({
28
18
  node,
29
19
  messageId: 'default',
@@ -34,7 +24,7 @@ module.exports = {
34
24
  },
35
25
  })
36
26
  },
37
- 'JSXElement[openingElement.name.name=/Td$/] JSXElement[openingElement.name.name=/RadioButton$/]': (node) => {
27
+ 'JSXElement[openingElement.name.name=/Td$/] JSXElement[openingElement.name.name=/RadioButton$/][children.length=0]': (node) => {
38
28
  context.report({
39
29
  node,
40
30
  messageId: 'default',
@@ -45,7 +35,7 @@ module.exports = {
45
35
  },
46
36
  })
47
37
  },
48
- 'JSXElement[openingElement.name.name=/Th$/] JSXElement[openingElement.name.name=/Check(b|B)ox$/]': (node) => {
38
+ 'JSXElement[openingElement.name.name=/Th$/] JSXElement[openingElement.name.name=/Check(b|B)ox$/][children.length=0]': (node) => {
49
39
  context.report({
50
40
  node,
51
41
  messageId: 'default',
@@ -54,14 +44,6 @@ module.exports = {
54
44
  component: 'Checkbox',
55
45
  preferred: 'ThCheckbox',
56
46
  },
57
- *fix(fixer) {
58
- const th = findClosestThFromAncestor(node)
59
- if (th) {
60
- const thCheckbox = sourceCode.getText(node).replace(/<Check(b|B)ox/, '<ThCheckbox')
61
- yield fixer.insertTextAfter(th, thCheckbox)
62
- yield fixer.remove(th)
63
- }
64
- },
65
47
  })
66
48
  },
67
49
  }
@@ -14,10 +14,11 @@ module.exports = {
14
14
  context.report({
15
15
  node,
16
16
  message: `${node.name.name}にmaxLength属性を設定しないでください。
17
- - maxLength属性がついた要素に、テキストをペーストすると、maxLength属性の値を超えた範囲が意図せず切り捨てられてしまう場合があります
18
- - 以下のいずれかの方法で修正をおこなってください
19
- - 方法1: pattern属性とtitle属性を組み合わせ、form要素でラップする
20
- - 方法2: JavaScriptを用いたバリデーションを実装する`,
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
- - 参考: https://developer.mozilla.org/ja/docs/Web/API/Event/currentTarget
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
- - 参考: https://developer.mozilla.org/ja/docs/Web/API/Event/currentTarget
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()'),