Pass through raw numeric and color style values instead of throwing when not found in theme#356
Closed
KAMRONBEK wants to merge 1 commit into
Closed
Conversation
When a theme-key prop received a value that is not a key in the theme scale, getThemeValue threw even for valid raw style values. react-native-reanimated 4.4+ re-renders settled animations with the resolved raw values set as top-level props (e.g. borderRadius: 13, backgroundColor: 'rgba(255, 209, 102, 1)'), crashing animated restyle components. Numeric literals and unambiguous raw color strings (hex / rgb / rgba / hsl / hsla / hwb) now pass through as-is, matching styled-system and dripsy, while unresolvable string keys (likely typos) still throw. Fixes Shopify#355
Author
|
@naqvitalha @gvarandas TL;DR for #355: when a Reanimated 4.4+ animation settles it re-renders with the raw settled value as a prop (e.g. |
Author
|
I have signed the CLA! |
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
Animated restyle components crash under react-native-reanimated 4.4+ (issue #355, two independent reports). Reanimated 4.4 ships the default-on
FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONSflag: when an animation settles, it re-renders the wrapped component with the resolved raw style values spread as top-level props. On anAnimated.createAnimatedComponent(Box)those arrive as theme-key props with raw values, and restyle throws:Root cause
In
src/utilities/getThemeValue.ts, any truthy value that is not a key in the theme scale throws — regardless of whether it is a legitimate literal style value (a raw pixel number, an rgba/hex color string) or a genuine typo'd theme key. Peer theme-prop libraries (styled-system, dripsy) pass unknown values through, so restyle's strictness turns benign upstream behavior into render crashes.Fix
getThemeValuenow passes a value through as-is when it is not a key in the theme scale but is a valid raw style value:borderRadius={13}) — valid for the numeric scales (borderRadii,spacing,zIndices, custom scales), and RN also accepts processed-color ints;#hex(3/4/6/8 digits) andrgb()/rgba()/hsl()/hsla()/hwb()functional notation.Unresolvable string keys (e.g.
backgroundColor="primaryy",borderRadius="xxl") still throw exactly as before, preserving the typo-catching behavior — raw color syntax is never a plausible theme key, so typo detection is not weakened. Named colors ('red','transparent') intentionally do NOT pass through, because they could shadow misspelled theme keys; Reanimated settles colors asrgba()strings, which are covered.The passthrough composes with responsive values for free (
getResponsiveValueresolves the breakpoint value and funnels it throughgetThemeValue), and with the memoization increateRestyleFunction(passthrough results memoize per theme/property/value like any other). It is also consistent with the existing behavior for falsy values (borderRadius={0}already passed through raw). I kept the passthrough silent rather than adding a dev-mode warning since the codebase has noconsole.warn/__DEV__convention anywhere insrc/— happy to add one if preferred.Tests
createRestyleFunction.test.ts: raw numericborderRadius(13) passes through on aborderRadiiscale — plain and inside a{phone: 13}responsive object; rawrgba(...)and#hexstrings pass through on thecolorsscale; misspelled string keys ('xxl'onborderRadii,'primaryy'oncolors) still throw; theme-key lookup ('m'→ 8) unchanged.createRestyleComponent.test.tsx: component-level repros of both reports —<Component borderRadius={13 as never} />and<Component backgroundColor={'rgba(255, 209, 102, 1)' as never} />render with the raw values (the casts mirror Reanimated spreading settled values as props, bypassing TypeScript).All 6 new passthrough tests fail without the fix (verified by temporarily reverting
getThemeValue.ts); full suite is 53/53, andyarn lint(eslint +tsc --noEmit) andyarn buildpass.Fixes #355