eslint-plugin-primer-react 8.4.0-rc.6ac270a → 8.5.0-rc.1eb9de5

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.
@@ -14,6 +14,6 @@ on:
14
14
  jobs:
15
15
  release-tracking:
16
16
  name: Release Tracking
17
- uses: primer/.github/.github/workflows/release_tracking.yml@v2.2.0
17
+ uses: primer/.github/.github/workflows/release_tracking.yml@v2.2.1
18
18
  secrets:
19
19
  datadog_api_key: ${{ secrets.DATADOG_API_KEY }}
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # eslint-plugin-primer-react
2
2
 
3
+ ## 8.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#443](https://github.com/primer/eslint-plugin-primer-react/pull/443) [`8865e3a`](https://github.com/primer/eslint-plugin-primer-react/commit/8865e3af43dfd302ed345c5b9243c32abe7cebad) Thanks [@hectahertz](https://github.com/hectahertz)! - Add no-use-responsive-value
8
+
3
9
  ## 8.4.0
4
10
 
5
11
  ### Minor Changes
@@ -0,0 +1,102 @@
1
+ # no-use-responsive-value
2
+
3
+ Disallow using `useResponsiveValue` hook from `@primer/react` or local imports.
4
+
5
+ ## Rule Details
6
+
7
+ This rule prevents the use of the `useResponsiveValue` hook from:
8
+
9
+ - `@primer/react` package imports (including `/experimental` and `/deprecated` entrypoints)
10
+ - Local file imports (relative paths containing `useResponsiveValue`)
11
+
12
+ ### Why?
13
+
14
+ This hook is not fully SSR compatible as it relies on `useMediaUnsafeSSR` without a `defaultState`. Using `getResponsiveAttributes` is preferred to avoid hydration mismatches. This rule helps enforce consistent usage of SSR-safe responsive patterns across the codebase.
15
+
16
+ ## Examples
17
+
18
+ ### ❌ Incorrect
19
+
20
+ ```js
21
+ import {useResponsiveValue} from '@primer/react'
22
+
23
+ function Component() {
24
+ const value = useResponsiveValue(['sm', 'md', 'lg'])
25
+ return <div>{value}</div>
26
+ }
27
+ ```
28
+
29
+ ```js
30
+ import {Button, useResponsiveValue} from '@primer/react'
31
+ ```
32
+
33
+ ```js
34
+ import {useResponsiveValue} from '@primer/react/experimental'
35
+ ```
36
+
37
+ ```js
38
+ import {useResponsiveValue} from '../hooks/useResponsiveValue'
39
+ ```
40
+
41
+ ```js
42
+ import useResponsiveValue from '../hooks/useResponsiveValue'
43
+ ```
44
+
45
+ ```js
46
+ import {useResponsiveValue} from './useResponsiveValue'
47
+ ```
48
+
49
+ ### ✅ Correct
50
+
51
+ ```js
52
+ import {Button} from '@primer/react'
53
+
54
+ function Component() {
55
+ // Use alternative responsive patterns
56
+ return <Button>Click me</Button>
57
+ }
58
+ ```
59
+
60
+ ```js
61
+ import {useResponsiveValue} from 'other-library'
62
+
63
+ function Component() {
64
+ // Using useResponsiveValue from a different library is allowed
65
+ const value = useResponsiveValue(['sm', 'md', 'lg'])
66
+ return <div>{value}</div>
67
+ }
68
+ ```
69
+
70
+ ```js
71
+ import {useCustomHook} from '../hooks/useCustomHook'
72
+
73
+ function Component() {
74
+ // Importing other hooks from local paths is allowed
75
+ const value = useCustomHook(['sm', 'md', 'lg'])
76
+ return <div>{value}</div>
77
+ }
78
+ ```
79
+
80
+ ```js
81
+ function useResponsiveValue() {
82
+ // Local function definitions are allowed
83
+ return 'custom implementation'
84
+ }
85
+
86
+ function Component() {
87
+ const value = useResponsiveValue()
88
+ return <div>{value}</div>
89
+ }
90
+ ```
91
+
92
+ ## When Not To Use It
93
+
94
+ If your project needs to use `useResponsiveValue` from `@primer/react`, you can disable this rule:
95
+
96
+ ```js
97
+ /* eslint primer-react/no-use-responsive-value: "off" */
98
+ ```
99
+
100
+ ## Options
101
+
102
+ This rule has no options.
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "eslint-plugin-primer-react",
3
- "version": "8.3.0",
3
+ "version": "8.4.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "eslint-plugin-primer-react",
9
- "version": "8.3.0",
9
+ "version": "8.4.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@styled-system/props": "^5.1.5",
@@ -24,7 +24,7 @@
24
24
  "@github/markdownlint-github": "^0.6.3",
25
25
  "@github/prettier-config": "0.0.6",
26
26
  "@types/jest": "^30.0.0",
27
- "@typescript-eslint/rule-tester": "8.44.1",
27
+ "@typescript-eslint/rule-tester": "8.46.2",
28
28
  "eslint": "^9.0.0",
29
29
  "eslint-plugin-eslint-comments": "^3.2.0",
30
30
  "eslint-plugin-filenames": "^1.3.2",
@@ -568,10 +568,11 @@
568
568
  "license": "MIT"
569
569
  },
570
570
  "node_modules/@changesets/apply-release-plan": {
571
- "version": "7.0.12",
572
- "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.12.tgz",
573
- "integrity": "sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==",
571
+ "version": "7.0.13",
572
+ "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.13.tgz",
573
+ "integrity": "sha512-BIW7bofD2yAWoE8H4V40FikC+1nNFEKBisMECccS16W1rt6qqhNTBDmIw5HaqmMgtLNz9e7oiALiEUuKrQ4oHg==",
574
574
  "dev": true,
575
+ "license": "MIT",
575
576
  "dependencies": {
576
577
  "@changesets/config": "^3.1.1",
577
578
  "@changesets/get-version-range-type": "^0.4.0",
@@ -593,6 +594,7 @@
593
594
  "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
594
595
  "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
595
596
  "dev": true,
597
+ "license": "MIT",
596
598
  "bin": {
597
599
  "prettier": "bin-prettier.js"
598
600
  },
@@ -638,13 +640,13 @@
638
640
  }
639
641
  },
640
642
  "node_modules/@changesets/cli": {
641
- "version": "2.29.6",
642
- "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.29.6.tgz",
643
- "integrity": "sha512-6qCcVsIG1KQLhpQ5zE8N0PckIx4+9QlHK3z6/lwKnw7Tir71Bjw8BeOZaxA/4Jt00pcgCnCSWZnyuZf5Il05QQ==",
643
+ "version": "2.29.7",
644
+ "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.29.7.tgz",
645
+ "integrity": "sha512-R7RqWoaksyyKXbKXBTbT4REdy22yH81mcFK6sWtqSanxUCbUi9Uf+6aqxZtDQouIqPdem2W56CdxXgsxdq7FLQ==",
644
646
  "dev": true,
645
647
  "license": "MIT",
646
648
  "dependencies": {
647
- "@changesets/apply-release-plan": "^7.0.12",
649
+ "@changesets/apply-release-plan": "^7.0.13",
648
650
  "@changesets/assemble-release-plan": "^6.0.9",
649
651
  "@changesets/changelog-git": "^0.2.1",
650
652
  "@changesets/config": "^3.1.1",
@@ -775,7 +777,8 @@
775
777
  "version": "0.4.0",
776
778
  "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz",
777
779
  "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==",
778
- "dev": true
780
+ "dev": true,
781
+ "license": "MIT"
779
782
  },
780
783
  "node_modules/@changesets/git": {
781
784
  "version": "3.0.4",
@@ -2160,15 +2163,15 @@
2160
2163
  }
2161
2164
  },
2162
2165
  "node_modules/@typescript-eslint/rule-tester": {
2163
- "version": "8.44.1",
2164
- "resolved": "https://registry.npmjs.org/@typescript-eslint/rule-tester/-/rule-tester-8.44.1.tgz",
2165
- "integrity": "sha512-yzqJhTLrbXCdEZhO9cuasGLZixWWx11/uFn6Leuu0p1PeW97wDy9JhiaAOl45TFrv5f67qwWdrzM5PMIuIu4vw==",
2166
+ "version": "8.46.2",
2167
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/rule-tester/-/rule-tester-8.46.2.tgz",
2168
+ "integrity": "sha512-95F3U8JcJmQEvMyD/VH88c96EWTg3d5F7iIb7puZPowweIArCiVFHbnBJVXw7nhJGsCFMG6LavdMWkkJaOxBdw==",
2166
2169
  "dev": true,
2167
2170
  "license": "MIT",
2168
2171
  "dependencies": {
2169
- "@typescript-eslint/parser": "8.44.1",
2170
- "@typescript-eslint/typescript-estree": "8.44.1",
2171
- "@typescript-eslint/utils": "8.44.1",
2172
+ "@typescript-eslint/parser": "8.46.2",
2173
+ "@typescript-eslint/typescript-estree": "8.46.2",
2174
+ "@typescript-eslint/utils": "8.46.2",
2172
2175
  "ajv": "^6.12.6",
2173
2176
  "json-stable-stringify-without-jsonify": "^1.0.1",
2174
2177
  "lodash.merge": "4.6.2",
@@ -2186,16 +2189,16 @@
2186
2189
  }
2187
2190
  },
2188
2191
  "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/parser": {
2189
- "version": "8.44.1",
2190
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.1.tgz",
2191
- "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==",
2192
+ "version": "8.46.2",
2193
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz",
2194
+ "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
2192
2195
  "dev": true,
2193
2196
  "license": "MIT",
2194
2197
  "dependencies": {
2195
- "@typescript-eslint/scope-manager": "8.44.1",
2196
- "@typescript-eslint/types": "8.44.1",
2197
- "@typescript-eslint/typescript-estree": "8.44.1",
2198
- "@typescript-eslint/visitor-keys": "8.44.1",
2198
+ "@typescript-eslint/scope-manager": "8.46.2",
2199
+ "@typescript-eslint/types": "8.46.2",
2200
+ "@typescript-eslint/typescript-estree": "8.46.2",
2201
+ "@typescript-eslint/visitor-keys": "8.46.2",
2199
2202
  "debug": "^4.3.4"
2200
2203
  },
2201
2204
  "engines": {
@@ -2211,14 +2214,14 @@
2211
2214
  }
2212
2215
  },
2213
2216
  "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/project-service": {
2214
- "version": "8.44.1",
2215
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.1.tgz",
2216
- "integrity": "sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==",
2217
+ "version": "8.46.2",
2218
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz",
2219
+ "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==",
2217
2220
  "dev": true,
2218
2221
  "license": "MIT",
2219
2222
  "dependencies": {
2220
- "@typescript-eslint/tsconfig-utils": "^8.44.1",
2221
- "@typescript-eslint/types": "^8.44.1",
2223
+ "@typescript-eslint/tsconfig-utils": "^8.46.2",
2224
+ "@typescript-eslint/types": "^8.46.2",
2222
2225
  "debug": "^4.3.4"
2223
2226
  },
2224
2227
  "engines": {
@@ -2233,14 +2236,14 @@
2233
2236
  }
2234
2237
  },
2235
2238
  "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/scope-manager": {
2236
- "version": "8.44.1",
2237
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz",
2238
- "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==",
2239
+ "version": "8.46.2",
2240
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz",
2241
+ "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==",
2239
2242
  "dev": true,
2240
2243
  "license": "MIT",
2241
2244
  "dependencies": {
2242
- "@typescript-eslint/types": "8.44.1",
2243
- "@typescript-eslint/visitor-keys": "8.44.1"
2245
+ "@typescript-eslint/types": "8.46.2",
2246
+ "@typescript-eslint/visitor-keys": "8.46.2"
2244
2247
  },
2245
2248
  "engines": {
2246
2249
  "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2251,9 +2254,9 @@
2251
2254
  }
2252
2255
  },
2253
2256
  "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/tsconfig-utils": {
2254
- "version": "8.44.1",
2255
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.1.tgz",
2256
- "integrity": "sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==",
2257
+ "version": "8.46.2",
2258
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz",
2259
+ "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==",
2257
2260
  "dev": true,
2258
2261
  "license": "MIT",
2259
2262
  "engines": {
@@ -2268,9 +2271,9 @@
2268
2271
  }
2269
2272
  },
2270
2273
  "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/types": {
2271
- "version": "8.44.1",
2272
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz",
2273
- "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==",
2274
+ "version": "8.46.2",
2275
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz",
2276
+ "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==",
2274
2277
  "dev": true,
2275
2278
  "license": "MIT",
2276
2279
  "engines": {
@@ -2282,16 +2285,16 @@
2282
2285
  }
2283
2286
  },
2284
2287
  "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/typescript-estree": {
2285
- "version": "8.44.1",
2286
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz",
2287
- "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==",
2288
+ "version": "8.46.2",
2289
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz",
2290
+ "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==",
2288
2291
  "dev": true,
2289
2292
  "license": "MIT",
2290
2293
  "dependencies": {
2291
- "@typescript-eslint/project-service": "8.44.1",
2292
- "@typescript-eslint/tsconfig-utils": "8.44.1",
2293
- "@typescript-eslint/types": "8.44.1",
2294
- "@typescript-eslint/visitor-keys": "8.44.1",
2294
+ "@typescript-eslint/project-service": "8.46.2",
2295
+ "@typescript-eslint/tsconfig-utils": "8.46.2",
2296
+ "@typescript-eslint/types": "8.46.2",
2297
+ "@typescript-eslint/visitor-keys": "8.46.2",
2295
2298
  "debug": "^4.3.4",
2296
2299
  "fast-glob": "^3.3.2",
2297
2300
  "is-glob": "^4.0.3",
@@ -2310,38 +2313,14 @@
2310
2313
  "typescript": ">=4.8.4 <6.0.0"
2311
2314
  }
2312
2315
  },
2313
- "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/utils": {
2314
- "version": "8.44.1",
2315
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz",
2316
- "integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==",
2317
- "dev": true,
2318
- "license": "MIT",
2319
- "dependencies": {
2320
- "@eslint-community/eslint-utils": "^4.7.0",
2321
- "@typescript-eslint/scope-manager": "8.44.1",
2322
- "@typescript-eslint/types": "8.44.1",
2323
- "@typescript-eslint/typescript-estree": "8.44.1"
2324
- },
2325
- "engines": {
2326
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2327
- },
2328
- "funding": {
2329
- "type": "opencollective",
2330
- "url": "https://opencollective.com/typescript-eslint"
2331
- },
2332
- "peerDependencies": {
2333
- "eslint": "^8.57.0 || ^9.0.0",
2334
- "typescript": ">=4.8.4 <6.0.0"
2335
- }
2336
- },
2337
2316
  "node_modules/@typescript-eslint/rule-tester/node_modules/@typescript-eslint/visitor-keys": {
2338
- "version": "8.44.1",
2339
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz",
2340
- "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==",
2317
+ "version": "8.46.2",
2318
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz",
2319
+ "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==",
2341
2320
  "dev": true,
2342
2321
  "license": "MIT",
2343
2322
  "dependencies": {
2344
- "@typescript-eslint/types": "8.44.1",
2323
+ "@typescript-eslint/types": "8.46.2",
2345
2324
  "eslint-visitor-keys": "^4.2.1"
2346
2325
  },
2347
2326
  "engines": {
@@ -3847,6 +3826,7 @@
3847
3826
  "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
3848
3827
  "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
3849
3828
  "dev": true,
3829
+ "license": "MIT",
3850
3830
  "engines": {
3851
3831
  "node": ">=8"
3852
3832
  }
@@ -5194,9 +5174,9 @@
5194
5174
  }
5195
5175
  },
5196
5176
  "node_modules/globals": {
5197
- "version": "16.4.0",
5198
- "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
5199
- "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
5177
+ "version": "16.5.0",
5178
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
5179
+ "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
5200
5180
  "license": "MIT",
5201
5181
  "engines": {
5202
5182
  "node": ">=18"
@@ -6902,7 +6882,8 @@
6902
6882
  "version": "4.4.0",
6903
6883
  "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
6904
6884
  "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
6905
- "dev": true
6885
+ "dev": true,
6886
+ "license": "MIT"
6906
6887
  },
6907
6888
  "node_modules/lodash.upperfirst": {
6908
6889
  "version": "4.3.1",
@@ -7953,7 +7934,8 @@
7953
7934
  "version": "0.5.0",
7954
7935
  "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz",
7955
7936
  "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==",
7956
- "dev": true
7937
+ "dev": true,
7938
+ "license": "MIT"
7957
7939
  },
7958
7940
  "node_modules/own-keys": {
7959
7941
  "version": "1.0.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-primer-react",
3
- "version": "8.4.0-rc.6ac270a",
3
+ "version": "8.5.0-rc.1eb9de5",
4
4
  "description": "ESLint rules for Primer React",
5
5
  "main": "src/index.js",
6
6
  "engines": {
@@ -46,7 +46,7 @@
46
46
  "@github/markdownlint-github": "^0.6.3",
47
47
  "@github/prettier-config": "0.0.6",
48
48
  "@types/jest": "^30.0.0",
49
- "@typescript-eslint/rule-tester": "8.44.1",
49
+ "@typescript-eslint/rule-tester": "8.46.2",
50
50
  "eslint": "^9.0.0",
51
51
  "eslint-plugin-eslint-comments": "^3.2.0",
52
52
  "eslint-plugin-filenames": "^1.3.2",
@@ -23,6 +23,7 @@ module.exports = {
23
23
  'primer-react/a11y-use-accessible-tooltip': 'error',
24
24
  'primer-react/no-unnecessary-components': 'error',
25
25
  'primer-react/prefer-action-list-item-onselect': 'error',
26
+ 'primer-react/no-use-responsive-value': 'error',
26
27
  },
27
28
  settings: {
28
29
  github: {
package/src/index.js CHANGED
@@ -21,6 +21,7 @@ module.exports = {
21
21
  'enforce-css-module-default-import': require('./rules/enforce-css-module-default-import'),
22
22
  'use-styled-react-import': require('./rules/use-styled-react-import'),
23
23
  'spread-props-first': require('./rules/spread-props-first'),
24
+ 'no-use-responsive-value': require('./rules/no-use-responsive-value'),
24
25
  },
25
26
  configs: {
26
27
  recommended: require('./configs/recommended'),
@@ -0,0 +1,133 @@
1
+ 'use strict'
2
+
3
+ const {RuleTester} = require('eslint')
4
+ const rule = require('../no-use-responsive-value')
5
+
6
+ const ruleTester = new RuleTester({
7
+ languageOptions: {
8
+ ecmaVersion: 'latest',
9
+ sourceType: 'module',
10
+ parserOptions: {
11
+ ecmaFeatures: {
12
+ jsx: true,
13
+ },
14
+ },
15
+ },
16
+ })
17
+
18
+ ruleTester.run('no-use-responsive-value', rule, {
19
+ valid: [
20
+ // Valid - not importing useResponsiveValue
21
+ `import { Button } from '@primer/react'`,
22
+
23
+ // Valid - importing from other modules
24
+ `import { useResponsiveValue } from 'other-module'`,
25
+
26
+ // Valid - using other hooks from @primer/react
27
+ `import { useTheme } from '@primer/react'`,
28
+
29
+ // Valid - function with same name but not imported from @primer/react
30
+ `function useResponsiveValue() { return 'custom' }`,
31
+
32
+ // Valid - importing from unrelated local paths
33
+ `import { something } from '../utils/helpers'`,
34
+
35
+ // Valid - importing other hooks from local paths
36
+ `import { useCustomHook } from '../hooks/useCustomHook'`,
37
+ ],
38
+ invalid: [
39
+ // Invalid - importing useResponsiveValue from @primer/react
40
+ {
41
+ code: `import { useResponsiveValue } from '@primer/react'`,
42
+ errors: [
43
+ {
44
+ messageId: 'noUseResponsiveValue',
45
+ },
46
+ ],
47
+ },
48
+
49
+ // Invalid - importing with other imports
50
+ {
51
+ code: `import { Button, useResponsiveValue, Box } from '@primer/react'`,
52
+ errors: [
53
+ {
54
+ messageId: 'noUseResponsiveValue',
55
+ },
56
+ ],
57
+ },
58
+
59
+ // Invalid - importing as named import with alias
60
+ {
61
+ code: `import { useResponsiveValue as useRV } from '@primer/react'
62
+ function Component() {
63
+ const value = useRV(['sm', 'md'])
64
+ return <div>{value}</div>
65
+ }`,
66
+ errors: [
67
+ {
68
+ messageId: 'noUseResponsiveValue',
69
+ },
70
+ ],
71
+ },
72
+
73
+ // Invalid - importing from experimental entrypoint
74
+ {
75
+ code: `import { useResponsiveValue } from '@primer/react/experimental'`,
76
+ errors: [
77
+ {
78
+ messageId: 'noUseResponsiveValue',
79
+ },
80
+ ],
81
+ },
82
+
83
+ // Invalid - importing from deprecated entrypoint
84
+ {
85
+ code: `import { useResponsiveValue } from '@primer/react/deprecated'`,
86
+ errors: [
87
+ {
88
+ messageId: 'noUseResponsiveValue',
89
+ },
90
+ ],
91
+ },
92
+
93
+ // Invalid - importing from local hooks path
94
+ {
95
+ code: `import { useResponsiveValue } from '../hooks/useResponsiveValue'`,
96
+ errors: [
97
+ {
98
+ messageId: 'noUseResponsiveValue',
99
+ },
100
+ ],
101
+ },
102
+
103
+ // Invalid - importing default from local useResponsiveValue file
104
+ {
105
+ code: `import useResponsiveValue from '../hooks/useResponsiveValue'`,
106
+ errors: [
107
+ {
108
+ messageId: 'noUseResponsiveValue',
109
+ },
110
+ ],
111
+ },
112
+
113
+ // Invalid - importing from nested path containing useResponsiveValue
114
+ {
115
+ code: `import { useResponsiveValue } from '../../src/hooks/useResponsiveValue'`,
116
+ errors: [
117
+ {
118
+ messageId: 'noUseResponsiveValue',
119
+ },
120
+ ],
121
+ },
122
+
123
+ // Invalid - importing from lib path containing useResponsiveValue
124
+ {
125
+ code: `import { useResponsiveValue } from './useResponsiveValue'`,
126
+ errors: [
127
+ {
128
+ messageId: 'noUseResponsiveValue',
129
+ },
130
+ ],
131
+ },
132
+ ],
133
+ })
@@ -0,0 +1,53 @@
1
+ 'use strict'
2
+
3
+ const url = require('../url')
4
+
5
+ /**
6
+ * @type {import('eslint').Rule.RuleModule}
7
+ */
8
+ module.exports = {
9
+ meta: {
10
+ type: 'problem',
11
+ docs: {
12
+ description: 'Disallow using useResponsiveValue hook',
13
+ recommended: true,
14
+ url: url(module),
15
+ },
16
+ schema: [],
17
+ messages: {
18
+ noUseResponsiveValue: 'useResponsiveValue is not allowed. Use alternative responsive patterns instead.',
19
+ },
20
+ },
21
+ create(context) {
22
+ return {
23
+ // Check for import declarations
24
+ ImportDeclaration(node) {
25
+ // Check for @primer/react imports
26
+ const isPrimerImport = /@primer\/react/.test(node.source.value)
27
+ // Check for local imports that might be useResponsiveValue hook
28
+ const isLocalUseResponsiveValueImport =
29
+ node.source.value.includes('useResponsiveValue') || node.source.value.includes('/hooks/useResponsiveValue')
30
+
31
+ if (!isPrimerImport && !isLocalUseResponsiveValueImport) {
32
+ return
33
+ }
34
+
35
+ for (const specifier of node.specifiers) {
36
+ if (specifier.type === 'ImportSpecifier' && specifier.imported.name === 'useResponsiveValue') {
37
+ context.report({
38
+ node: specifier,
39
+ messageId: 'noUseResponsiveValue',
40
+ })
41
+ }
42
+ // Also check for default imports from useResponsiveValue files
43
+ if (specifier.type === 'ImportDefaultSpecifier' && isLocalUseResponsiveValueImport) {
44
+ context.report({
45
+ node: specifier,
46
+ messageId: 'noUseResponsiveValue',
47
+ })
48
+ }
49
+ }
50
+ },
51
+ }
52
+ },
53
+ }