feat(lint): add useReactNativePlatformComponents rule and options#10033
Conversation
🦋 Changeset detectedLatest commit: 3f32ff2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughAdds a new nursery lint rule Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/biome_rule_options/src/use_react_native_platform_components.rs (1)
9-17: Consider wrapping fields inOption<_>for merging semantics.Per coding guidelines, rule option fields should be wrapped in
Option<_>to distinguish user-set values from defaults during configuration merging. Currently, if a user specifies onlyandroidPathRegex, theiosPathRegexwill silently use the default rather than being recognised as unset.This may be acceptable for this rule since regex patterns are unlikely to need "unsetting", but worth considering for consistency with other options structs.
🔧 Optional refactor to use Option wrappers
pub struct UseReactNativePlatformComponentsOptions { /// A regular expression pattern to identify Android-specific files. /// Defaults to `.*[.]android[.][jt]sx?`. - pub android_path_regex: RestrictedRegex, + #[serde(skip_serializing_if = "Option::is_none")] + pub android_path_regex: Option<RestrictedRegex>, /// A regular expression pattern to identify iOS-specific files. /// Defaults to `.*[.]ios[.][jt]sx?`. - pub ios_path_regex: RestrictedRegex, + #[serde(skip_serializing_if = "Option::is_none")] + pub ios_path_regex: Option<RestrictedRegex>, }Then in the rule, use
options.android_path_regex.as_ref().unwrap_or(&default)or similar.As per coding guidelines: "Wrap all rule option fields in
Option<_>to properly track which options are set vs unset during configuration merging".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_rule_options/src/use_react_native_platform_components.rs` around lines 9 - 17, The struct UseReactNativePlatformComponentsOptions currently uses concrete RestrictedRegex fields (android_path_regex, ios_path_regex) which prevents distinguishing user-set vs default values during config merging; change each field to Option<RestrictedRegex> (android_path_regex: Option<RestrictedRegex>, ios_path_regex: Option<RestrictedRegex>) and update any consumers (rule code that reads these fields) to use as_ref().map(|r| r) or as_ref().unwrap_or(&default_pattern) / unwrap_or_else to fall back to the rule defaults during evaluation so merging logic can detect unset vs explicitly provided values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@crates/biome_rule_options/src/use_react_native_platform_components.rs`:
- Around line 9-17: The struct UseReactNativePlatformComponentsOptions currently
uses concrete RestrictedRegex fields (android_path_regex, ios_path_regex) which
prevents distinguishing user-set vs default values during config merging; change
each field to Option<RestrictedRegex> (android_path_regex:
Option<RestrictedRegex>, ios_path_regex: Option<RestrictedRegex>) and update any
consumers (rule code that reads these fields) to use as_ref().map(|r| r) or
as_ref().unwrap_or(&default_pattern) / unwrap_or_else to fall back to the rule
defaults during evaluation so merging logic can detect unset vs explicitly
provided values.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e5ac23c4-4290-4301-ab4c-f84b6c970b07
⛔ Files ignored due to path filters (8)
crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/src/lint/nursery.rsis excluded by!**/nursery.rsand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalidWithOptions/invalid.jsx.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.android.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.ios.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/validWithOptions/valid.jsx.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (12)
.changeset/vast-phones-argue.mdcrates/biome_js_analyze/src/lint/nursery/use_react_native_platform_components.rscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalid.jscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalidWithOptions/invalid.jsxcrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalidWithOptions/invalid.options.jsoncrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.android.jscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.ios.jscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.jscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/validWithOptions/valid.jsxcrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/validWithOptions/valid.options.jsoncrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/use_react_native_platform_components.rs
Merging this PR will not alter performance
Comparing Footnotes
|
|
Wow, huge regression. Will look into it. |
dyc3
left a comment
There was a problem hiding this comment.
My biggest concern is the options
7490e01 to
6ebc2fd
Compare
fc06750 to
7c7e8ca
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@crates/biome_js_analyze/src/lint/nursery/use_react_native_platform_components.rs`:
- Around line 59-65: The JSON examples in
use_react_native_platform_components.rs incorrectly wrap rule-specific settings
inside a nested "options" object; update the `json,options` code blocks (the
examples showing androidPathPatterns and iosPathPatterns) to remove the extra
"options" wrapper so the blocks contain the rule options directly (e.g., replace
{ "options": { "androidPathPatterns": [...] } } with { "androidPathPatterns":
[...] }) and make the same change for the second example referenced around the
other block.
- Around line 136-140: The is_ios_file check is incorrectly gated by
!is_android_file causing overlapping globs to hide iOS matches; change the logic
to compute Android and iOS matches independently by removing the
!is_android_file condition and evaluating
options.ios_path_patterns.as_ref().is_some_and(|patterns|
patterns.iter().any(|glob| glob.is_match(file_path))) directly (similar to how
is_android_file is computed), so both is_android_file and is_ios_file are set
based solely on their respective pattern checks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e824b4ba-7bd0-4c12-8d0e-1c112b8784a7
⛔ Files ignored due to path filters (13)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_configuration/src/generated/domain_selector.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_configuration/src/generated/linter_options_check.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalidWithOptions/invalid.jsx.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.android.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.ios.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.js.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/validWithOptions/valid.jsx.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (12)
.changeset/vast-phones-argue.mdcrates/biome_js_analyze/src/lint/nursery/use_react_native_platform_components.rscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalid.jscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalidWithOptions/invalid.jsxcrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalidWithOptions/invalid.options.jsoncrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.android.jscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.ios.jscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.jscrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/validWithOptions/valid.jsxcrates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/validWithOptions/valid.options.jsoncrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/use_react_native_platform_components.rs
✅ Files skipped from review due to trivial changes (9)
- crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.ios.js
- crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.android.js
- crates/biome_rule_options/src/lib.rs
- crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalid.js
- crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/validWithOptions/valid.options.json
- crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/validWithOptions/valid.jsx
- crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalidWithOptions/invalid.options.json
- .changeset/vast-phones-argue.md
- crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/valid.js
🚧 Files skipped from review as they are similar to previous changes (1)
- crates/biome_js_analyze/tests/specs/nursery/useReactNativePlatformComponents/invalidWithOptions/invalid.jsx
dyc3
left a comment
There was a problem hiding this comment.
some possible areas that could've caused the perf regression. it could also be just evaluating globs so much.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
crates/biome_js_analyze/src/lint/nursery/use_react_native_platform_components.rs (2)
132-140:⚠️ Potential issue | 🟠 MajorMatch Android and iOS globs independently.
The
!is_android_fileguard means overlapping custom patterns can never count as iOS matches. If a file matches both globs, iOS-only imports are reported anyway, which is a bit too enthusiastic.🐛 Minimal fix
- let is_ios_file = !is_android_file - && options - .ios_path_patterns() - .iter() - .any(|glob| glob.is_match(file_path)); + let is_ios_file = options + .ios_path_patterns() + .iter() + .any(|glob| glob.is_match(file_path));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/use_react_native_platform_components.rs` around lines 132 - 140, The iOS match is incorrectly gated by !is_android_file so overlapping custom globs never allow an iOS match; change the is_ios_file computation to check ioS globs independently (call options.ios_path_patterns().iter().any(|glob| glob.is_match(file_path)) without the !is_android_file guard) so a file can be matched as both Android and iOS when patterns overlap; update any logic that relied on the previous exclusivity if necessary.
59-65:⚠️ Potential issue | 🟡 MinorDrop the extra
"options"wrapper in thesejson,optionsexamples.These blocks are meant to show rule-local options, so the extra nesting is a tiny docs trap for the next person copying and pasting at speed.
📝 Suggested doc fix
/// ```json,options /// { -/// "options": { -/// "androidPathPatterns": ["**/*.droid.jsx"] -/// } +/// "androidPathPatterns": ["**/*.droid.jsx"] /// } /// ``` @@ /// ```json,options /// { -/// "options": { -/// "iosPathPatterns": ["**/*.apple.jsx"] -/// } +/// "iosPathPatterns": ["**/*.apple.jsx"] /// } /// ```Based on learnings: Use
optionscode block property for configuration option snippets containing only rule-specific options.Also applies to: 83-89
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/use_react_native_platform_components.rs` around lines 59 - 65, In the doc comments inside use_react_native_platform_components.rs, remove the extra "options" wrapper from the json,options examples so the rule-local options are shown directly; specifically update the example objects that currently contain "options": { "androidPathPatterns": [...] } and "options": { "iosPathPatterns": [...] } to instead be { "androidPathPatterns": [...] } and { "iosPathPatterns": [...] } respectively (both example blocks in the file).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In
`@crates/biome_js_analyze/src/lint/nursery/use_react_native_platform_components.rs`:
- Around line 132-140: The iOS match is incorrectly gated by !is_android_file so
overlapping custom globs never allow an iOS match; change the is_ios_file
computation to check ioS globs independently (call
options.ios_path_patterns().iter().any(|glob| glob.is_match(file_path)) without
the !is_android_file guard) so a file can be matched as both Android and iOS
when patterns overlap; update any logic that relied on the previous exclusivity
if necessary.
- Around line 59-65: In the doc comments inside
use_react_native_platform_components.rs, remove the extra "options" wrapper from
the json,options examples so the rule-local options are shown directly;
specifically update the example objects that currently contain "options": {
"androidPathPatterns": [...] } and "options": { "iosPathPatterns": [...] } to
instead be { "androidPathPatterns": [...] } and { "iosPathPatterns": [...] }
respectively (both example blocks in the file).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ef18f534-9d4d-490d-88d5-9bb3e3a2b556
⛔ Files ignored due to path filters (1)
packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (2)
crates/biome_js_analyze/src/lint/nursery/use_react_native_platform_components.rscrates/biome_rule_options/src/use_react_native_platform_components.rs
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | patch | `2.4.12` → `2.4.13` | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.4.13`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#2413) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.12...@biomejs/biome@2.4.13) ##### Patch Changes - [#​9969](biomejs/biome#9969) [`c5eb92b`](biomejs/biome@c5eb92b) Thanks [@​officialasishkumar](https://github.com/officialasishkumar)! - Added the nursery rule [`noUnnecessaryTemplateExpression`](https://biomejs.dev/linter/rules/no-unnecessary-template-expression/), which disallows template literals that only contain string literal expressions. These can be replaced with a simpler string literal. For example, the following code triggers the rule: ```js const a = `${"hello"}`; // can be 'hello' const b = `${"prefix"}_suffix`; // can be 'prefix_suffix' const c = `${"a"}${"b"}`; // can be 'ab' ``` - [#​10037](biomejs/biome#10037) [`f785e8c`](biomejs/biome@f785e8c) Thanks [@​minseong0324](https://github.com/minseong0324)! - Fixed [#​9810](biomejs/biome#9810): [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) no longer reports false positives on a getter with a matching setter in the same namespace. ```ts class Store { get status(): string { if (Math.random() > 0.5) return "loading"; return "idle"; } set status(v: string) {} } ``` - [#​10084](biomejs/biome#10084) [`5e2f90c`](biomejs/biome@5e2f90c) Thanks [@​jiwon79](https://github.com/jiwon79)! - Fixed [#​10034](biomejs/biome#10034): [`noUselessEscapeInRegex`](https://biomejs.dev/linter/rules/no-useless-escape-in-regex/) no longer flags escapes of `ClassSetReservedPunctuator` characters (`&`, `!`, `#`, `%`, `,`, `:`, `;`, `<`, `=`, `>`, `@`, `` ` ``, `~`) inside `v`-flag character classes as useless. These characters are reserved as individual code points in `v`-mode, so the escape is required. The following pattern is now considered valid: ```js /[a-z\&]/v; ``` - [#​10063](biomejs/biome#10063) [`c9ffa16`](biomejs/biome@c9ffa16) Thanks [@​Netail](https://github.com/Netail)! - Added extra rule sources from ESLint CSS. `biome migrate eslint` should do a bit better detecting rules in your eslint configurations. - [#​10035](biomejs/biome#10035) [`946b50e`](biomejs/biome@946b50e) Thanks [@​Netail](https://github.com/Netail)! - Fixed [#​10032](biomejs/biome#10032): [useIframeSandbox](https://biomejs.dev/linter/rules/use-iframe-sandbox/) now flags if there's no initializer value. - [#​9865](biomejs/biome#9865) [`68fb8d4`](biomejs/biome@68fb8d4) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useDomNodeTextContent`](https://biomejs.dev/linter/rules/use-dom-node-text-content/), which prefers `textContent` over `innerText` for DOM node text access and destructuring. For example, the following snippet triggers the rule: ```js const foo = node.innerText; ``` - [#​10023](biomejs/biome#10023) [`bd1e74f`](biomejs/biome@bd1e74f) Thanks [@​ematipico](https://github.com/ematipico)! - Added a new nursery rule [`noReactNativeDeepImports`](https://biomejs.dev/linter/rules/no-react-native-deep-imports/) that disallows deep imports from the `react-native` package. Internal paths like `react-native/Libraries/...` are not part of the public API and may change between versions. For example, the following code triggers the rule: ```js import View from "react-native/Libraries/Components/View/View"; ``` - [#​9885](biomejs/biome#9885) [`3dce737`](biomejs/biome@3dce737) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useDomQuerySelector`](https://biomejs.dev/linter/rules/use-dom-query-selector/) that prefers `querySelector()` and `querySelectorAll()` over older DOM query methods such as `getElementById()` and `getElementsByClassName()`. - [#​9995](biomejs/biome#9995) [`4da9caf`](biomejs/biome@4da9caf) Thanks [@​siketyan](https://github.com/siketyan)! - Fixed [#​9994](biomejs/biome#9994): Biome now parses nested CSS rules correctly when declarations follow them inside embedded snippets. - [#​10009](biomejs/biome#10009) [`b41cc5a`](biomejs/biome@b41cc5a) Thanks [@​Jayllyz](https://github.com/Jayllyz)! - Fixed [#​10004](biomejs/biome#10004): [`noComponentHookFactories`](https://biomejs.dev/linter/rules/no-component-hook-factories/) no longer reports false positives for object methods and class methods. - [#​9988](biomejs/biome#9988) [`eabf54a`](biomejs/biome@eabf54a) Thanks [@​Netail](https://github.com/Netail)! - Tweaked the diagnostics range for [useAltText](https://biomejs.dev/linter/rules/use-alt-text), [useButtonType](https://biomejs.dev/linter/rules/use-button-type), [useHtmlLang](https://biomejs.dev/linter/rules/use-html-lang), [useIframeTitle](https://biomejs.dev/linter/rules/use-iframe-title), [useValidAriaRole](https://biomejs.dev/linter/rules/use-valid-aria-role) & [useIfameSandbox](https://biomejs.dev/linter/rules/use-iframe-sandbox) to report on the opening tag instead of the full tag. - [#​10043](biomejs/biome#10043) [`fc65902`](biomejs/biome@fc65902) Thanks [@​mujpao](https://github.com/mujpao)! - Fixed [#​10003](biomejs/biome#10003): Biome no longer panics when parsing Svelte files containing `{#}`. - [#​9815](biomejs/biome#9815) [`5cc83b1`](biomejs/biome@5cc83b1) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`noLoopFunc`](https://biomejs.dev/linter/rules/no-loop-func/). When enabled, it warns when a function declared inside a loop captures outer variables that can change across iterations. - [#​9702](biomejs/biome#9702) [`ef470ba`](biomejs/biome@ef470ba) Thanks [@​ryan-m-walker](https://github.com/ryan-m-walker)! - Added the nursery rule [`useRegexpTest`](https://biomejs.dev/linter/rules/use-regexp-test/) that enforces `RegExp.prototype.test()` over `String.prototype.match()` and `RegExp.prototype.exec()` in boolean contexts. `test()` returns a boolean directly, avoiding unnecessary computation of match results. **Invalid** ```js if ("hello world".match(/hello/)) { } ``` **Valid** ```js if (/hello/.test("hello world")) { } ``` - [#​9743](biomejs/biome#9743) [`245307d`](biomejs/biome@245307d) Thanks [@​leetdavid](https://github.com/leetdavid)! - Fixed [#​2245](biomejs/biome#2245): Svelte `<script>` tag language detection when the `generics` attribute contains `>` characters (e.g., `<script lang="ts" generics="T extends Record<string, unknown>">`). Biome now correctly recognizes TypeScript in such script blocks. - [#​10046](biomejs/biome#10046) [`0707de7`](biomejs/biome@0707de7) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​10038](biomejs/biome#10038): [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) now sorts imports in TypeScript modules and declaration files. ```diff declare module "mymodule" { - import type { B } from "b"; import type { A } from "a"; + import type { B } from "b"; } ``` - [#​10012](biomejs/biome#10012) [`94ccca9`](biomejs/biome@94ccca9) Thanks [@​ematipico](https://github.com/ematipico)! - Added the nursery rule [`noReactNativeLiteralColors`](https://biomejs.dev/linter/rules/no-react-native-literal-colors/), which disallows color literals inside React Native styles. The rule belongs to the `reactNative` domain. It reports properties whose name contains `color` and whose value is a string literal when they appear inside a `StyleSheet.create(...)` call or inside a JSX attribute whose name contains `style`. ```jsx // Invalid const Hello = () => <Text style={{ backgroundColor: "#FFFFFF" }}>hi</Text>; const styles = StyleSheet.create({ text: { color: "red" }, }); ``` ```jsx // Valid const red = "#f00"; const styles = StyleSheet.create({ text: { color: red }, }); ``` - [#​10005](biomejs/biome#10005) [`131019e`](biomejs/biome@131019e) Thanks [@​ematipico](https://github.com/ematipico)! - Added the nursery rule [`noReactNativeRawText`](https://biomejs.dev/linter/rules/no-react-native-raw-text/), which disallows raw text outside of `<Text>` components in React Native. The rule belongs to the new `reactNative` domain. ```jsx // Invalid <View>some text</View> <View>{'some text'}</View> ``` ```jsx // Valid <View> <Text>some text</Text> </View> ``` Additional components can be allowlisted through the `skip` option: ```json { "options": { "skip": ["Title"] } } ``` - [#​9911](biomejs/biome#9911) [`1603f78`](biomejs/biome@1603f78) Thanks [@​Netail](https://github.com/Netail)! - Added the nursery rule [`noJsxLeakedDollar`](https://biomejs.dev/linter/rules/no-jsx-leaked-dollar), which flags text nodes with a trailing `$` if the next sibling node is a JSX expression. This could be an unintentional mistake, resulting in a '$' being rendered as text in the output. **Invalid**: ```jsx function MyComponent({ user }) { return <div>Hello ${user.name}</div>; } ``` - [#​9999](biomejs/biome#9999) [`f42405f`](biomejs/biome@f42405f) Thanks [@​minseong0324](https://github.com/minseong0324)! - Fixed `noMisleadingReturnType` incorrectly flagging functions with reassigned `let` variables. - [#​10075](biomejs/biome#10075) [`295f97f`](biomejs/biome@295f97f) Thanks [@​ematipico](https://github.com/ematipico)! - Fixed [`#9983`](biomejs/biome#9983): Biome now parses functions declared inside Svelte `#snippet` blocks without throwing errors. - [#​10006](biomejs/biome#10006) [`cf4c1c9`](biomejs/biome@cf4c1c9) Thanks [@​minseong0324](https://github.com/minseong0324)! - Fixed [#​9810](biomejs/biome#9810): `noMisleadingReturnType` incorrectly flagging nested object literals with widened properties. - [#​10033](biomejs/biome#10033) [`11ddc05`](biomejs/biome@11ddc05) Thanks [@​ematipico](https://github.com/ematipico)! - Added the nursery rule [`useReactNativePlatformComponents`](https://biomejs.dev/linter/rules/use-react-native-platform-components/) that ensures platform-specific React Native components (e.g. `ProgressBarAndroid`, `ActivityIndicatorIOS`) are only imported in files with a matching platform suffix. It also reports when Android and iOS components are mixed in the same file. The following code triggers the rule when the file does not have an `.android.js` suffix: ```js // file.js import { ProgressBarAndroid } from "react-native"; ``` </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMzkuNiIsInVwZGF0ZWRJblZlciI6IjQzLjEzOS42IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Server/pulls/1
Summary
This PR adds the rule
split-platform-componentsto the react native domain.Generated via Claude Code. It went through different iterations.
The rule basically says that components that belong to a specific platform must be imported into files that match that platform, it's a bug (rule triggered). That's why it's an error, and recommended.
Test Plan
Added tests
Docs
Part of the rule