eslint-plugin-smarthr 6.21.1 → 6.22.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 +16 -0
- package/README.md +3 -2
- package/package.json +1 -1
- package/rules/autofixer-smarthr-ui-migration/DEVELOPER.md +4 -4
- package/rules/autofixer-smarthr-ui-migration/README.md +2 -0
- package/rules/autofixer-smarthr-ui-migration/index.js +21 -0
- package/rules/autofixer-smarthr-ui-migration/versions/v95-to-v96/README.md +47 -0
- package/rules/autofixer-smarthr-ui-migration/versions/v95-to-v96/REFERENCE.md +132 -0
- package/rules/autofixer-smarthr-ui-migration/versions/v95-to-v96/index.js +54 -0
- package/rules/autofixer-smarthr-ui-migration/versions/v95-to-v96/test.js +142 -0
- package/rules/autofixer-smarthr-ui-migration/versions/v96-to-v97/README.md +96 -0
- package/rules/autofixer-smarthr-ui-migration/versions/v96-to-v97/index.js +56 -0
- package/rules/autofixer-smarthr-ui-migration/versions/v96-to-v97/test.js +137 -0
- package/rules/best-practice-for-reduce-redundant-calls/README.md +460 -0
- package/rules/best-practice-for-reduce-redundant-calls/index.js +623 -0
- package/rules/best-practice-for-unstable-dependencies/README.md +74 -0
- package/rules/best-practice-for-unstable-dependencies/index.js +64 -12
- package/rules/require-i18n-translation-sync/README.md +19 -0
- package/rules/require-i18n-translation-sync/index.js +24 -0
- package/test/autofixer-smarthr-ui-migration.js +20 -6
- package/test/best-practice-for-reduce-redundant-calls.js +1195 -0
- package/test/best-practice-for-unstable-dependencies.js +125 -0
- package/test/require-i18n-translation-sync.js +35 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
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
|
+
## [6.22.0](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v6.21.2...eslint-plugin-smarthr-v6.22.0) (2026-07-02)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* autofixer-smarthr-ui-migration v95-to-v96, v96-to-v97 対応 ([#1442](https://github.com/kufu/tamatebako/issues/1442)) ([d70787b](https://github.com/kufu/tamatebako/commit/d70787bc6961b0f65b6cc78506fab92707ce3f90))
|
|
11
|
+
* best-practice-for-reduce-redundant-calls ルールを追加 ([#1440](https://github.com/kufu/tamatebako/issues/1440)) ([0564d24](https://github.com/kufu/tamatebako/commit/0564d24fa5de3b9f812d23c7396411e064604234))
|
|
12
|
+
* best-practice-for-unstable-dependenciesに正規表現パターンとカスタムメッセージを追加 ([#1424](https://github.com/kufu/tamatebako/issues/1424)) ([9ed3f1f](https://github.com/kufu/tamatebako/commit/9ed3f1fac878b7f0f37c5a1f3db1b66d30d507c9))
|
|
13
|
+
|
|
14
|
+
## [6.21.2](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v6.21.1...eslint-plugin-smarthr-v6.21.2) (2026-06-30)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* require-i18n-translation-syncでsatisfies演算子に対応 ([#1415](https://github.com/kufu/tamatebako/issues/1415)) ([d0eb87a](https://github.com/kufu/tamatebako/commit/d0eb87a1616c63145499b8adc9fc20d5f6f8c5b9))
|
|
20
|
+
|
|
5
21
|
## [6.21.1](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v6.21.0...eslint-plugin-smarthr-v6.21.1) (2026-06-22)
|
|
6
22
|
|
|
7
23
|
|
package/README.md
CHANGED
|
@@ -26,12 +26,13 @@
|
|
|
26
26
|
- [best-practice-for-date](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-date)
|
|
27
27
|
- [best-practice-for-default-props](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-default-props)
|
|
28
28
|
- [best-practice-for-interactive-element](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-interactive-element)
|
|
29
|
-
- [best-practice-for-lazy-variable](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-lazy-variable)
|
|
30
|
-
- [best-practice-for-no-unnecessary-variable](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-no-unnecessary-variable)
|
|
31
29
|
- [best-practice-for-layouts](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-layouts)
|
|
30
|
+
- [best-practice-for-lazy-variable](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-lazy-variable)
|
|
32
31
|
- [best-practice-for-nested-attributes-array-index](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-nested-attributes-array-index)
|
|
32
|
+
- [best-practice-for-no-unnecessary-variable](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-no-unnecessary-variable)
|
|
33
33
|
- [best-practice-for-optional-chaining](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-optional-chaining)
|
|
34
34
|
- [best-practice-for-prohibit-import-smarthr-ui-local](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-prohibit-import-smarthr-ui-local)
|
|
35
|
+
- [best-practice-for-reduce-redundant-calls](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-reduce-redundant-calls)
|
|
35
36
|
- [best-practice-for-remote-trigger-dialog](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-remote-trigger-dialog)
|
|
36
37
|
- [best-practice-for-response-message](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-response-message)
|
|
37
38
|
- [best-practice-for-rest-parameters](https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-rest-parameters)
|
package/package.json
CHANGED
|
@@ -66,10 +66,10 @@ autofixer-smarthr-ui-migrationルールに新しいバージョン(v[XX]→v[Y
|
|
|
66
66
|
## 参考にするファイル
|
|
67
67
|
|
|
68
68
|
必ず以下のファイルを読んで、実装パターンを踏襲してください(最新のversionディレクトリを参照):
|
|
69
|
-
- rules/autofixer-smarthr-ui-migration/versions/
|
|
70
|
-
- rules/autofixer-smarthr-ui-migration/versions/
|
|
71
|
-
- rules/autofixer-smarthr-ui-migration/versions/
|
|
72
|
-
- rules/autofixer-smarthr-ui-migration/versions/
|
|
69
|
+
- rules/autofixer-smarthr-ui-migration/versions/v95-to-v96/REFERENCE.md(実装パターンの詳細説明)
|
|
70
|
+
- rules/autofixer-smarthr-ui-migration/versions/v95-to-v96/index.js(実装例)
|
|
71
|
+
- rules/autofixer-smarthr-ui-migration/versions/v95-to-v96/README.md(ユーザー向け移行ガイド)
|
|
72
|
+
- rules/autofixer-smarthr-ui-migration/versions/v95-to-v96/test.js(テストケース)
|
|
73
73
|
- test/autofixer-smarthr-ui-migration.js(メインテスト)
|
|
74
74
|
- libs/common.js(rootPathの取得、tsconfig.jsonのpaths設定読み込み)
|
|
75
75
|
|
|
@@ -196,6 +196,8 @@ export const ActionDialog = (props) => <div>{props.children}</div>
|
|
|
196
196
|
| `92` → `93` | [移行ガイド](./versions/v92-to-v93/README.md) |
|
|
197
197
|
| `93` → `94` | [移行ガイド](./versions/v93-to-v94/README.md) |
|
|
198
198
|
| `94` → `95` | [移行ガイド](./versions/v94-to-v95/README.md) |
|
|
199
|
+
| `95` → `96` | [移行ガイド](./versions/v95-to-v96/README.md) |
|
|
200
|
+
| `96` → `97` | [移行ガイド](./versions/v96-to-v97/README.md)(検出のみ) |
|
|
199
201
|
|
|
200
202
|
## 使用方法
|
|
201
203
|
|
|
@@ -20,6 +20,8 @@ const v91ToV92 = require('./versions/v91-to-v92/index')
|
|
|
20
20
|
const v92ToV93 = require('./versions/v92-to-v93/index')
|
|
21
21
|
const v93ToV94 = require('./versions/v93-to-v94/index')
|
|
22
22
|
const v94ToV95 = require('./versions/v94-to-v95/index')
|
|
23
|
+
const v95ToV96 = require('./versions/v95-to-v96/index')
|
|
24
|
+
const v96ToV97 = require('./versions/v96-to-v97/index')
|
|
23
25
|
|
|
24
26
|
// サポートしているバージョン間の移行モジュール
|
|
25
27
|
const VERSION_MODULES = {
|
|
@@ -28,6 +30,8 @@ const VERSION_MODULES = {
|
|
|
28
30
|
'v92-v93': v92ToV93,
|
|
29
31
|
'v93-v94': v93ToV94,
|
|
30
32
|
'v94-v95': v94ToV95,
|
|
33
|
+
'v95-v96': v95ToV96,
|
|
34
|
+
'v96-v97': v96ToV97,
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
module.exports = {
|
|
@@ -64,6 +68,8 @@ module.exports = {
|
|
|
64
68
|
...v92ToV93.messages,
|
|
65
69
|
...v93ToV94.messages,
|
|
66
70
|
...v94ToV95.messages,
|
|
71
|
+
...v95ToV96.messages,
|
|
72
|
+
...v96ToV97.messages,
|
|
67
73
|
},
|
|
68
74
|
},
|
|
69
75
|
create(context) {
|
|
@@ -200,6 +206,21 @@ function getMigrationPath(from, to) {
|
|
|
200
206
|
}
|
|
201
207
|
}
|
|
202
208
|
|
|
209
|
+
// v96→v97は検出のみのルール(手動対応必須)のため、他のバージョンとの一気実行を禁止
|
|
210
|
+
// v95→v96(自動修正)とv96→v97(検出のみ)を混在させると、エラーが消えず混乱する
|
|
211
|
+
if (path.includes('v95-v96') && path.includes('v96-v97')) {
|
|
212
|
+
return {
|
|
213
|
+
path,
|
|
214
|
+
skipped,
|
|
215
|
+
conflict: true,
|
|
216
|
+
conflictData: {
|
|
217
|
+
from,
|
|
218
|
+
to,
|
|
219
|
+
middle: '96',
|
|
220
|
+
},
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
203
224
|
return { path, skipped }
|
|
204
225
|
}
|
|
205
226
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# smarthr-ui v95 → v96 移行ガイド
|
|
2
|
+
|
|
3
|
+
このドキュメントは、smarthr-ui を v95 から v96 にアップグレードする際の破壊的変更と対処方法を説明します。
|
|
4
|
+
|
|
5
|
+
## 破壊的変更
|
|
6
|
+
|
|
7
|
+
### Chip: size 属性の値が "s" から "S" に変更
|
|
8
|
+
|
|
9
|
+
**変更内容:**
|
|
10
|
+
`Chip` コンポーネントの `size` 属性の値が小文字の `"s"` から大文字の `"S"` に変更されました。
|
|
11
|
+
|
|
12
|
+
**Before (v95):**
|
|
13
|
+
```jsx
|
|
14
|
+
<Chip size="s">label</Chip>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**After (v96):**
|
|
18
|
+
```jsx
|
|
19
|
+
<Chip size="S">label</Chip>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**自動修正:**
|
|
23
|
+
このルールは自動修正に対応しています。ESLintの`--fix`オプションを使用することで、自動的に変換されます。
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
eslint --fix .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**対象:**
|
|
30
|
+
- 文字列リテラル `"s"` のみが対象です
|
|
31
|
+
- 動的な値(変数など)は検出されません
|
|
32
|
+
- `Chip` で終わるコンポーネント名(例: `CustomChip`, `MyChip`)も対象です
|
|
33
|
+
|
|
34
|
+
```jsx
|
|
35
|
+
// 自動修正される
|
|
36
|
+
<Chip size="s">label</Chip>
|
|
37
|
+
<CustomChip size="s">label</CustomChip> // ラップコンポーネントも対象
|
|
38
|
+
|
|
39
|
+
// 検出されない(手動で対応が必要)
|
|
40
|
+
<Chip size={dynamicSize}>label</Chip>
|
|
41
|
+
<Chip size={SIZES.SMALL}>label</Chip>
|
|
42
|
+
<ChipContainer size="s" /> // "Chip"で終わらない
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 参考リンク
|
|
46
|
+
|
|
47
|
+
- [smarthr-ui v96.0.0 Release Notes](https://github.com/kufu/smarthr-ui/releases/tag/smarthr-ui-v96.0.0)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# v95-to-v96 実装リファレンス
|
|
2
|
+
|
|
3
|
+
このドキュメントは、v95-to-v96移行ルールの実装パターンとトラブルシューティングをまとめた開発者向けリファレンスです。
|
|
4
|
+
|
|
5
|
+
## 実装パターン
|
|
6
|
+
|
|
7
|
+
### 1. JSX属性値の文字列置換
|
|
8
|
+
|
|
9
|
+
**ユースケース:** Chip の size 属性を "s" から "S" に変更
|
|
10
|
+
|
|
11
|
+
**実装例:**
|
|
12
|
+
```javascript
|
|
13
|
+
'JSXOpeningElement[name.name=/Chip$/] > JSXAttribute[name.name="size"][value.type="Literal"][value.value="s"]'(node) {
|
|
14
|
+
context.report({
|
|
15
|
+
node,
|
|
16
|
+
messageId: 'migrateChipSize',
|
|
17
|
+
data: { to: TARGET_VERSION },
|
|
18
|
+
fix(fixer) {
|
|
19
|
+
// "s" → "S" に置換
|
|
20
|
+
return fixer.replaceText(node.value, '"S"')
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**ポイント:**
|
|
27
|
+
- セレクタで条件をすべて絞り込む(関数内チェック不要)
|
|
28
|
+
- `name.name=/Chip$/`: Chipで終わるコンポーネント名(CustomChip等も対象)
|
|
29
|
+
- `[value.type="Literal"][value.value="s"]`: 文字列リテラル "s" のみ
|
|
30
|
+
- `fixer.replaceText()` で値全体を置換する
|
|
31
|
+
|
|
32
|
+
**検出対象:**
|
|
33
|
+
```jsx
|
|
34
|
+
<Chip size="s">label</Chip> // ✅ 検出される
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**検出対象外:**
|
|
38
|
+
```jsx
|
|
39
|
+
<Chip size={dynamicSize}>label</Chip> // ❌ 動的な値
|
|
40
|
+
<Chip size={"s"}>label</Chip> // ❌ JSX式
|
|
41
|
+
<OtherComponent size="s" /> // ❌ 他のコンポーネント
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## テストパターン
|
|
45
|
+
|
|
46
|
+
### 基本的なテスト構成
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
const v95ToV96Options = [{ from: '95', to: '96' }]
|
|
50
|
+
|
|
51
|
+
const valid = [
|
|
52
|
+
// 既に正しい値
|
|
53
|
+
{ code: '<Chip size="S">label</Chip>', options: v95ToV96Options },
|
|
54
|
+
|
|
55
|
+
// 動的な値(検出対象外)
|
|
56
|
+
{ code: '<Chip size={dynamicSize}>label</Chip>', options: v95ToV96Options },
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
const invalid = [
|
|
60
|
+
{
|
|
61
|
+
code: '<Chip size="s">label</Chip>',
|
|
62
|
+
output: '<Chip size="S">label</Chip>',
|
|
63
|
+
options: v95ToV96Options,
|
|
64
|
+
errors: [
|
|
65
|
+
{
|
|
66
|
+
messageId: 'migrateChipSize',
|
|
67
|
+
data: { to: 'v96' },
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## トラブルシューティング
|
|
75
|
+
|
|
76
|
+
### JSX式内の文字列が検出されない
|
|
77
|
+
|
|
78
|
+
**問題:**
|
|
79
|
+
```jsx
|
|
80
|
+
<Chip size={"s"}>label</Chip> // 検出されない
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**原因:**
|
|
84
|
+
JSX式(`{}`)内の文字列は `JSXExpressionContainer > Literal` という構造になる。
|
|
85
|
+
|
|
86
|
+
**対処:**
|
|
87
|
+
現在の実装では文字列リテラル(`size="s"`)のみを対象としています。JSX式内の文字列も対象にする場合は、以下のように拡張できます:
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
'JSXOpeningElement[name.name="Chip"] > JSXAttribute[name.name="size"]'(node) {
|
|
91
|
+
const value = node.value
|
|
92
|
+
|
|
93
|
+
// 文字列リテラル: size="s"
|
|
94
|
+
if (value && value.type === 'Literal' && value.value === 's') {
|
|
95
|
+
// 修正処理
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// JSX式: size={"s"}
|
|
99
|
+
if (value && value.type === 'JSXExpressionContainer') {
|
|
100
|
+
const expr = value.expression
|
|
101
|
+
if (expr.type === 'Literal' && expr.value === 's') {
|
|
102
|
+
// 修正処理
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
ただし、実用上は文字列リテラルのみで十分なケースが多いです。
|
|
109
|
+
|
|
110
|
+
## 参考情報
|
|
111
|
+
|
|
112
|
+
### AST構造
|
|
113
|
+
|
|
114
|
+
**文字列リテラル:** `size="s"`
|
|
115
|
+
```
|
|
116
|
+
JSXAttribute
|
|
117
|
+
├── name: JSXIdentifier (name: "size")
|
|
118
|
+
└── value: Literal (value: "s")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**JSX式:** `size={"s"}`
|
|
122
|
+
```
|
|
123
|
+
JSXAttribute
|
|
124
|
+
├── name: JSXIdentifier (name: "size")
|
|
125
|
+
└── value: JSXExpressionContainer
|
|
126
|
+
└── expression: Literal (value: "s")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 関連ドキュメント
|
|
130
|
+
|
|
131
|
+
- [ESLint AST Explorer](https://astexplorer.net/)
|
|
132
|
+
- [smarthr-ui v96.0.0 Release Notes](https://github.com/kufu/smarthr-ui/releases/tag/smarthr-ui-v96.0.0)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* smarthr-ui v95 → v96 移行ルール
|
|
3
|
+
*
|
|
4
|
+
* v96での破壊的変更に対応する自動修正を提供します。
|
|
5
|
+
*
|
|
6
|
+
* 対応する破壊的変更:
|
|
7
|
+
* 1. Chip の size 属性: "s" → "S"
|
|
8
|
+
*
|
|
9
|
+
* 参考: https://github.com/kufu/smarthr-ui/releases/tag/smarthr-ui-v96.0.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const { setupSmarthrUiAliasOptions } = require('../../helpers')
|
|
13
|
+
|
|
14
|
+
// ============================================================
|
|
15
|
+
// 定数定義
|
|
16
|
+
// ============================================================
|
|
17
|
+
|
|
18
|
+
// v96を示す定数(メッセージで使用)
|
|
19
|
+
const TARGET_VERSION = 'v96'
|
|
20
|
+
|
|
21
|
+
// ============================================================
|
|
22
|
+
// モジュールエクスポート
|
|
23
|
+
// ============================================================
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
messages: {
|
|
27
|
+
migrateChipSize: 'smarthr-ui {{to}} では Chip の size 属性が "s" から "S" に変更されました',
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
createCheckers(context, sourceCode, options = {}) {
|
|
31
|
+
const { validSources, isAliasFile, filename } = setupSmarthrUiAliasOptions(context, options)
|
|
32
|
+
|
|
33
|
+
const checkers = {
|
|
34
|
+
// ============================================================
|
|
35
|
+
// 1. Chip の size 属性: "s" → "S"
|
|
36
|
+
// Chipで終わるコンポーネント(CustomChip等のラップコンポーネント)も対象
|
|
37
|
+
// ============================================================
|
|
38
|
+
|
|
39
|
+
'JSXOpeningElement[name.name=/Chip$/] > JSXAttribute[name.name="size"][value.type="Literal"][value.value="s"]'(node) {
|
|
40
|
+
context.report({
|
|
41
|
+
node,
|
|
42
|
+
messageId: 'migrateChipSize',
|
|
43
|
+
data: { to: TARGET_VERSION },
|
|
44
|
+
fix(fixer) {
|
|
45
|
+
// "s" → "S" に置換
|
|
46
|
+
return fixer.replaceText(node.value, '"S"')
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return checkers
|
|
53
|
+
},
|
|
54
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* smarthr-ui v95 → v96 移行ルール テストケース
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const v95ToV96Options = [{ from: '95', to: '96' }]
|
|
6
|
+
|
|
7
|
+
// ============================================================
|
|
8
|
+
// validテストケース(エラーにならないコード)
|
|
9
|
+
// ============================================================
|
|
10
|
+
|
|
11
|
+
const valid = [
|
|
12
|
+
// size属性なし
|
|
13
|
+
{ code: '<Chip>label</Chip>', options: v95ToV96Options },
|
|
14
|
+
|
|
15
|
+
// 既に "S" を使用
|
|
16
|
+
{ code: '<Chip size="S">label</Chip>', options: v95ToV96Options },
|
|
17
|
+
|
|
18
|
+
// 他のサイズ値
|
|
19
|
+
{ code: '<Chip size="m">label</Chip>', options: v95ToV96Options },
|
|
20
|
+
|
|
21
|
+
// 動的な値
|
|
22
|
+
{ code: '<Chip size={dynamicSize}>label</Chip>', options: v95ToV96Options },
|
|
23
|
+
{ code: '<Chip size={SIZES.SMALL}>label</Chip>', options: v95ToV96Options },
|
|
24
|
+
|
|
25
|
+
// JSX式での "s"(文字列リテラルではない)
|
|
26
|
+
{ code: '<Chip size={"s"}>label</Chip>', options: v95ToV96Options },
|
|
27
|
+
|
|
28
|
+
// 対象外のコンポーネント(Chipで終わらない)
|
|
29
|
+
{ code: '<OtherComponent size="s" />', options: v95ToV96Options },
|
|
30
|
+
{ code: '<ChipContainer size="s" />', options: v95ToV96Options },
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
// ============================================================
|
|
34
|
+
// invalidテストケース(エラーになり、自動修正されるコード)
|
|
35
|
+
// ============================================================
|
|
36
|
+
|
|
37
|
+
const invalid = [
|
|
38
|
+
// ============================================================
|
|
39
|
+
// Chip の size 属性: "s" → "S"
|
|
40
|
+
// ============================================================
|
|
41
|
+
|
|
42
|
+
// 基本的な使用例
|
|
43
|
+
{
|
|
44
|
+
code: '<Chip size="s">label</Chip>',
|
|
45
|
+
output: '<Chip size="S">label</Chip>',
|
|
46
|
+
options: v95ToV96Options,
|
|
47
|
+
errors: [
|
|
48
|
+
{
|
|
49
|
+
messageId: 'migrateChipSize',
|
|
50
|
+
data: { to: 'v96' },
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
// セルフクロージングタグ
|
|
56
|
+
{
|
|
57
|
+
code: '<Chip size="s" />',
|
|
58
|
+
output: '<Chip size="S" />',
|
|
59
|
+
options: v95ToV96Options,
|
|
60
|
+
errors: [
|
|
61
|
+
{
|
|
62
|
+
messageId: 'migrateChipSize',
|
|
63
|
+
data: { to: 'v96' },
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
// 複数の属性がある場合
|
|
69
|
+
{
|
|
70
|
+
code: '<Chip size="s" disabled>label</Chip>',
|
|
71
|
+
output: '<Chip size="S" disabled>label</Chip>',
|
|
72
|
+
options: v95ToV96Options,
|
|
73
|
+
errors: [
|
|
74
|
+
{
|
|
75
|
+
messageId: 'migrateChipSize',
|
|
76
|
+
data: { to: 'v96' },
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
// spread属性と組み合わせ
|
|
82
|
+
{
|
|
83
|
+
code: '<Chip {...props} size="s">label</Chip>',
|
|
84
|
+
output: '<Chip {...props} size="S">label</Chip>',
|
|
85
|
+
options: v95ToV96Options,
|
|
86
|
+
errors: [
|
|
87
|
+
{
|
|
88
|
+
messageId: 'migrateChipSize',
|
|
89
|
+
data: { to: 'v96' },
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// 複数行
|
|
95
|
+
{
|
|
96
|
+
code: `<Chip
|
|
97
|
+
size="s"
|
|
98
|
+
disabled
|
|
99
|
+
>
|
|
100
|
+
label
|
|
101
|
+
</Chip>`,
|
|
102
|
+
output: `<Chip
|
|
103
|
+
size="S"
|
|
104
|
+
disabled
|
|
105
|
+
>
|
|
106
|
+
label
|
|
107
|
+
</Chip>`,
|
|
108
|
+
options: v95ToV96Options,
|
|
109
|
+
errors: [
|
|
110
|
+
{
|
|
111
|
+
messageId: 'migrateChipSize',
|
|
112
|
+
data: { to: 'v96' },
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// ラップコンポーネント(Chipで終わる名前)
|
|
118
|
+
{
|
|
119
|
+
code: '<CustomChip size="s">label</CustomChip>',
|
|
120
|
+
output: '<CustomChip size="S">label</CustomChip>',
|
|
121
|
+
options: v95ToV96Options,
|
|
122
|
+
errors: [
|
|
123
|
+
{
|
|
124
|
+
messageId: 'migrateChipSize',
|
|
125
|
+
data: { to: 'v96' },
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
code: '<MyChip size="s" />',
|
|
131
|
+
output: '<MyChip size="S" />',
|
|
132
|
+
options: v95ToV96Options,
|
|
133
|
+
errors: [
|
|
134
|
+
{
|
|
135
|
+
messageId: 'migrateChipSize',
|
|
136
|
+
data: { to: 'v96' },
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
module.exports = { valid, invalid }
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# smarthr-ui v96 → v97 移行ガイド
|
|
2
|
+
|
|
3
|
+
このドキュメントは、smarthr-ui を v96 から v97 にアップグレードする際の破壊的変更と対処方法を説明します。
|
|
4
|
+
|
|
5
|
+
## 破壊的変更
|
|
6
|
+
|
|
7
|
+
### TabItem: onClick の型が変更
|
|
8
|
+
|
|
9
|
+
**変更内容:**
|
|
10
|
+
`TabItem` コンポーネントの `onClick` プロパティの型が、カスタムハンドラから標準的なイベントハンドラに変更されました。
|
|
11
|
+
|
|
12
|
+
**Before (v96):**
|
|
13
|
+
```tsx
|
|
14
|
+
<TabItem onClick={(tabId: string) => console.log(tabId)} />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**After (v97):**
|
|
18
|
+
```tsx
|
|
19
|
+
<TabItem onClick={(e: MouseEvent<HTMLButtonElement>) => console.log(e.currentTarget.value)} />
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**変更の理由:**
|
|
23
|
+
- より標準的なイベントハンドラの型に統一
|
|
24
|
+
- ESLint ルール `smarthr/best-practice-for-unstable-dependencies` との互換性向上
|
|
25
|
+
- `useCallback` の依存配列を安定化
|
|
26
|
+
|
|
27
|
+
**自動修正について:**
|
|
28
|
+
この変更は**自動修正に対応していません**。以下の理由により、手動での対応が必要です:
|
|
29
|
+
|
|
30
|
+
- 引数名が可変(`tabId`, `id`, `value` など)
|
|
31
|
+
- 関数本体内での使用箇所の特定が複雑
|
|
32
|
+
- 変数代入、関数呼び出し、オブジェクトプロパティなど多様な使用パターン
|
|
33
|
+
|
|
34
|
+
**手動対応の手順:**
|
|
35
|
+
|
|
36
|
+
1. **引数を `e` に変更**
|
|
37
|
+
```tsx
|
|
38
|
+
// Before
|
|
39
|
+
onClick={(tabId) => handleClick(tabId)}
|
|
40
|
+
|
|
41
|
+
// After
|
|
42
|
+
onClick={(e) => handleClick(e.currentTarget.value)}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. **引数の使用箇所を `e.currentTarget.value` に置き換え**
|
|
46
|
+
```tsx
|
|
47
|
+
// Before
|
|
48
|
+
onClick={(id) => {
|
|
49
|
+
console.log(id)
|
|
50
|
+
setActiveTab(id)
|
|
51
|
+
}}
|
|
52
|
+
|
|
53
|
+
// After
|
|
54
|
+
onClick={(e) => {
|
|
55
|
+
const id = e.currentTarget.value
|
|
56
|
+
console.log(id)
|
|
57
|
+
setActiveTab(id)
|
|
58
|
+
}}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
3. **TypeScript の型エラーを確認**
|
|
62
|
+
```tsx
|
|
63
|
+
// 型定義を明示的に指定する場合
|
|
64
|
+
onClick={(e: MouseEvent<HTMLButtonElement>) => {
|
|
65
|
+
// 処理
|
|
66
|
+
}}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 検出方法
|
|
70
|
+
|
|
71
|
+
このルールは `TabItem` コンポーネントに `onClick` プロパティがある箇所を検出し、手動対応を促すエラーを表示します。
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# ESLintでエラーを確認
|
|
75
|
+
eslint .
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**重要な注意事項:**
|
|
79
|
+
- `--fix` オプションを使用しても自動修正されません。エラーメッセージに従って手動で修正してください。
|
|
80
|
+
- **このエラーは手動で修正しても消えません**。`TabItem` に `onClick` がある限り検出され続けます。
|
|
81
|
+
- すべての対応が完了したら、ESLint設定から `{ from: "96", to: "97" }` の設定を削除してください。
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
// .eslintrc.js または eslint.config.js
|
|
85
|
+
{
|
|
86
|
+
rules: {
|
|
87
|
+
// 対応完了後は削除またはコメントアウト
|
|
88
|
+
// 'smarthr/autofixer-smarthr-ui-migration': ['error', { from: '96', to: '97' }],
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 参考リンク
|
|
94
|
+
|
|
95
|
+
- [smarthr-ui v97.0.0 Release Notes](https://github.com/kufu/smarthr-ui/releases/tag/smarthr-ui-v97.0.0)
|
|
96
|
+
- [PR #6421: onClickの型をイベントハンドラに変更](https://github.com/kufu/smarthr-ui/pull/6421)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* smarthr-ui v96 → v97 移行ルール
|
|
3
|
+
*
|
|
4
|
+
* v97での破壊的変更を検出します(自動修正なし)。
|
|
5
|
+
*
|
|
6
|
+
* 対応する破壊的変更:
|
|
7
|
+
* 1. TabItem の onClick 型変更: (tabId: string) => void → (e: MouseEvent) => void
|
|
8
|
+
*
|
|
9
|
+
* 参考: https://github.com/kufu/smarthr-ui/releases/tag/smarthr-ui-v97.0.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const { setupSmarthrUiAliasOptions } = require('../../helpers')
|
|
13
|
+
|
|
14
|
+
// ============================================================
|
|
15
|
+
// 定数定義
|
|
16
|
+
// ============================================================
|
|
17
|
+
|
|
18
|
+
// v97を示す定数(メッセージで使用)
|
|
19
|
+
const TARGET_VERSION = 'v97'
|
|
20
|
+
|
|
21
|
+
// README.mdへのGitHubリンク(エラーメッセージで使用)
|
|
22
|
+
const README_URL =
|
|
23
|
+
'https://github.com/kufu/tamatebako/blob/master/packages/eslint-plugin-smarthr/rules/autofixer-smarthr-ui-migration/versions/v96-to-v97/README.md'
|
|
24
|
+
|
|
25
|
+
// ============================================================
|
|
26
|
+
// モジュールエクスポート
|
|
27
|
+
// ============================================================
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
messages: {
|
|
31
|
+
migrateTabItemOnClick:
|
|
32
|
+
'smarthr-ui {{to}} では TabItem の onClick の型が変更されました。引数を (tabId: string) から (e: MouseEvent<HTMLButtonElement>) に変更し、tabId の使用箇所を e.currentTarget.value に置き換えてください。注意: このエラーは手動修正後も消えません。対応完了後は { from: "96", to: "97" } 設定を削除してください。詳細: {{readmeUrl}}',
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
createCheckers(context, sourceCode, options = {}) {
|
|
36
|
+
const { validSources, isAliasFile, filename } = setupSmarthrUiAliasOptions(context, options)
|
|
37
|
+
|
|
38
|
+
const checkers = {
|
|
39
|
+
// ============================================================
|
|
40
|
+
// 1. TabItem の onClick 型変更(検出のみ、自動修正なし)
|
|
41
|
+
// TabItemで終わるコンポーネント(CustomTabItem等のラップコンポーネント)も対象
|
|
42
|
+
// ============================================================
|
|
43
|
+
|
|
44
|
+
'JSXOpeningElement[name.name=/TabItem$/] > JSXAttribute[name.name="onClick"]'(node) {
|
|
45
|
+
context.report({
|
|
46
|
+
node,
|
|
47
|
+
messageId: 'migrateTabItemOnClick',
|
|
48
|
+
data: { to: TARGET_VERSION, readmeUrl: README_URL },
|
|
49
|
+
// fix関数を提供しない = 自動修正不可
|
|
50
|
+
})
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return checkers
|
|
55
|
+
},
|
|
56
|
+
}
|