eslint-plugin-smarthr 6.9.0 → 6.9.1

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 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
+ ## [6.9.1](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v6.9.0...eslint-plugin-smarthr-v6.9.1) (2026-04-07)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **best-practice-for-text-component:** 変換不可能なshr-クラスのみの場合に不要なスペースが挿入される問題を修正 ([#1199](https://github.com/kufu/tamatebako/issues/1199)) ([ad942fc](https://github.com/kufu/tamatebako/commit/ad942fcfa2484013fe82fd1c9d9b94c097a0e27a))
11
+
5
12
  ## [6.9.0](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v6.8.0...eslint-plugin-smarthr-v6.9.0) (2026-04-05)
6
13
 
7
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-smarthr",
3
- "version": "6.9.0",
3
+ "version": "6.9.1",
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": "41bc1d6941b48121d18250aaecb83812f87955e1"
40
+ "gitHead": "5f958652e81f7a69a347489108ff88cb1b3e56dd"
41
41
  }
@@ -177,16 +177,37 @@ module.exports = {
177
177
  // パターン2-1: classNameのみ(asなし)、Text属性なし、shr-クラスあり
178
178
  [SELECTOR_CONVERTIBLE_SHR_TO_PROPS]: (classNameAttrNode) => {
179
179
  const { nonConvertible, propSuggestions, convertible } = categorizeClassNames(classNameAttrNode)
180
+ const openingElement = classNameAttrNode.parent
181
+ const jsxElement = openingElement.parent
182
+
183
+ // 変換可能なクラスが0個の場合、spanに変換(パターン1-3と同じ動作)
184
+ if (!propSuggestions) {
185
+ const classNameText = `className="${classNameAttrNode.value.value}"`
186
+ context.report({
187
+ node: openingElement,
188
+ message: `Textコンポーネントの機能を使用していないため、ネイティブHTML要素(<span>)に置き換えてください。
189
+ - 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-text-component
190
+ - 推奨: <span ${classNameText}>
191
+ - Textコンポーネントの機能(weight、size、color等)を使用しない場合は、直接HTML要素を使用することでシンプルになります`,
192
+ fix(fixer) {
193
+ return [
194
+ fixer.replaceText(openingElement.name, 'span'),
195
+ fixer.replaceText(jsxElement.closingElement.name, 'span')
196
+ ]
197
+ },
198
+ })
199
+ return
200
+ }
180
201
 
202
+ // 変換可能なクラスがある場合、属性に変換
181
203
  context.report({
182
- node: classNameAttrNode.parent,
204
+ node: openingElement,
183
205
  message: `classNameで指定されたshr-プレフィックスのクラスは、Textコンポーネントの属性に置き換えてください。
184
206
  - 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-text-component
185
207
  - 推奨: <Text ${propSuggestions}${nonConvertible ? ` className="${nonConvertible}"` : ''}>
186
208
  - 変換可能なクラス: ${convertible}
187
209
  - shr-プレフィックスのクラスをTextの属性に置き換えることで、型安全性が向上し、意図がより明確になります`,
188
210
  fix(fixer) {
189
- const openingElement = classNameAttrNode.parent
190
211
  const sourceCode = context.sourceCode || context.getSourceCode()
191
212
  const fixes = []
192
213
 
@@ -235,8 +256,39 @@ module.exports = {
235
256
  [SELECTOR_CONVERTIBLE_SHR_TO_PROPS_WITH_AS]: (classNameAttrNode) => {
236
257
  const { nonConvertible, propSuggestions, convertible } = categorizeClassNames(classNameAttrNode)
237
258
  const openingElement = classNameAttrNode.parent
259
+ const jsxElement = openingElement.parent
238
260
  const asValue = getAttributeLiteralValue(openingElement, 'as')
239
261
 
262
+ // 変換可能なクラスが0個の場合、as属性で指定されたタグに変換(パターン1-4と同じ動作)
263
+ if (!propSuggestions) {
264
+ const classNameValue = getAttributeLiteralValue(openingElement, 'className')
265
+ const classNameText = `className="${classNameValue}"`
266
+ context.report({
267
+ node: openingElement,
268
+ message: `Textコンポーネントの機能を使用していないため、ネイティブHTML要素に置き換えてください。
269
+ - 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/best-practice-for-text-component
270
+ - <${asValue}>要素にclassNameを移動してください
271
+ - Textコンポーネントの機能(weight、size、color等)を使用しない場合は、直接HTML要素を使用することでシンプルになります`,
272
+ fix(fixer) {
273
+ const sourceCode = context.sourceCode || context.getSourceCode()
274
+ const asAttrNode = getAttributeNode(openingElement, 'as')
275
+
276
+ // 属性とその前のスペースを含めて削除
277
+ const tokenBefore = sourceCode.getTokenBefore(asAttrNode)
278
+ const rangeStart = tokenBefore.range[1]
279
+ const rangeEnd = asAttrNode.range[1]
280
+
281
+ return [
282
+ fixer.removeRange([rangeStart, rangeEnd]),
283
+ fixer.replaceText(openingElement.name, asValue),
284
+ fixer.replaceText(jsxElement.closingElement.name, asValue)
285
+ ]
286
+ },
287
+ })
288
+ return
289
+ }
290
+
291
+ // 変換可能なクラスがある場合、属性に変換
240
292
  context.report({
241
293
  node: openingElement,
242
294
  message: `classNameで指定されたshr-プレフィックスのクラスは、Textコンポーネントの属性に置き換えてください。
@@ -105,6 +105,11 @@ ruleTester.run('best-practice-for-text-component', rule, {
105
105
  { code: `<Text as="p" className="shr-text-sm custom-class">text</Text>`, output: `<Text as="p" size="S" className="custom-class">text</Text>`, errors: [{ message: errorConvertibleShr('size="S" className="custom-class"', 'shr-text-sm', 'p') }] },
106
106
  { code: `<Text className="shr-text-lg shr-font-bold custom-one custom-two">text</Text>`, output: `<Text size="L" weight="bold" className="custom-one custom-two">text</Text>`, errors: [{ message: errorConvertibleShr('size="L" weight="bold" className="custom-one custom-two"', 'shr-text-lg, shr-font-bold') }] },
107
107
 
108
+ // パターン2-4: shr-プレフィックスがあるが変換不可能なクラスのみ(spanに変換)
109
+ { code: `<Text className="shr-w-[10rem]">text</Text>`, output: `<span className="shr-w-[10rem]">text</span>`, errors: [{ message: errorUnnecessaryClassName('shr-w-[10rem]') }] },
110
+ { code: `<Text className="shr-inline-block shr-mr-0.5">text</Text>`, output: `<span className="shr-inline-block shr-mr-0.5">text</span>`, errors: [{ message: errorUnnecessaryClassName('shr-inline-block shr-mr-0.5') }] },
111
+ { code: `<Text as="p" className="shr-bg-background shr-block">text</Text>`, output: `<p className="shr-bg-background shr-block">text</p>`, errors: [{ message: errorUnnecessaryAsClassName('p') }] },
112
+
108
113
  // パターン3: 属性とclassNameの矛盾
109
114
  { code: `<Text size="M" className="shr-text-sm">text</Text>`, errors: [{ message: errorConflictingProps('shr-text-sm') }] },
110
115
  { code: `<Text weight="bold" className="shr-font-normal">text</Text>`, errors: [{ message: errorConflictingProps('shr-font-normal') }] },