Repository navigation
refactor(native): combine two values of a style prop in one place - #487
Open
YevheniiKotyrlo wants to merge 5 commits into
Open
YevheniiKotyrlo wants to merge 5 commits into
YevheniiKotyrlo wants to merge 5 commits into
Conversation
…tton family Gesture Handler's Pressable, its button family and PureNativeButton render GestureHandlerButton, a codegen'd native view the react-native rewrite never reaches, so className fell onto a view that declares no such prop. DrawerLayoutAndroid wraps react-native's component, which has no styled twin, and the Android GestureHandlerRootView renders a native view too. react-native-css/components/react-native-gesture-handler re-declares these with className mapped to the style each forwards, and the Metro resolver routes react-native-gesture-handler to it. GestureHandlerRootView keeps its flex: 1 default, which a resolved class would otherwise displace. The resolver anchors its own-package check on the layout segment, since it runs from src/metro under the source condition and from dist/<format>/metro once built; a fixed level count sent this package's own components back through the wrapper. Pressable calls a function style with its pressed state, so the className merge keeps a callback a callback on every merge path rather than merging it into an array, where it never runs. The inline branch of the style-target merge is removed: the length-one target merge after it always decides the inline style.
…er suite Jest's teardown reads every global, and expo's lazy fetch then loads the renderer through the suite's react-native mock. With nativeFabricUIManager still cleared, that throws, and on Linux Jest reports the suite as failed to run.
…s flex:1 default Gesture Handler's root falls back to `flex: 1` while no style is given, and the re-declaration kept that default under every class. Yoga reads a positive flex over an explicit or absent basis, so a root a class sizes to its content — `grow-0`, `shrink-0`, `basis-*`, `flex-none` — collapsed or stretched instead. The default now yields to a class that states its own flex sizing, and an inline style still displaces it, as Gesture Handler's own does.
… modules The resolver computed the package root and the own-module test the babel import plugin already computes, and its copy dropped the trailing path separator, so a directory beside the package whose name merely begins with dist or src counted as the package's own and its imports were left unrewritten. Both now import one isFromThisModule.
deepMergeConfig combined a computed style value with another one three ways: flattened for
important styles, an array collapsed to the inline value when it overrides every computed key
for a one-segment array target, and a plain array for a one-segment string target. A new kind
of style value had to be taught to all three, as the callback styles were.
combineStyleValues is the one combination: a callback composes, a value that overrides every key
of the other replaces it, and otherwise the two are flattened when this library computed both or
layered when one came from the element. A one-segment string target now collapses as its array
spelling does, so `{ target: "style" }` and `"style"` combine an inline style the same way.
YevheniiKotyrlo
marked this pull request as ready for review
October 16, 2026 08:36
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
deepMergeConfigcombines a computed style value with another one in three places, three ways:"style","contentContainerStyle"): the inline value alone when it overrides every computed key, otherwise both in an array;{ target: "style" }): always both in an array.So
{ className: "style" }and{ className: { target: "style" } }, two spellings of one mapping, combinestyle={{ backgroundColor: "blue" }}overbg-reddifferently: the first gives{ backgroundColor: "blue" }, the second[{ backgroundColor: "#f00" }, { backgroundColor: "blue" }]. And a new kind of style value has to be handled in all three places, as #416 does for a Pressable's callback style.Solution
combineStyleValues(left, right, layering)is the one combination: a callback composes with the other value, a value that overrides every key of the other replaces it, and otherwise the two are flattened when this library computed both (important styles) or layered when one came from the element, since an inline style object can carry an identity a copy would lose. The three sites call it, so the string target collapses as its array spelling does; the important and array-target paths combine as before.Tests
src/__tests__/native/className-with-style.test.tsx: both spellings of a style target, with an inline style that sets every property the class sets (it replaces the class's value) and one that sets other properties (the two are layered). Onmainthe object form returns both values in an array where the shorthand returns the inline value alone. The existing suites hold the other two paths and #416's callback styles.Verification
On Ubuntu with the workflow's steps - build, lint, typecheck,
yarn test,node --test node/__tests__/*.mjs, both library builds, the web export, the unstaged-changes checks and commitlint - everything passes.Not run: the iOS and Android example builds.
Merge order