fix(shared): parse negative decimals without integer part in numberRegex (#2397) - #2561
Open
ErfanBagheri404 wants to merge 6 commits into
Open
fix(shared): parse negative decimals without integer part in numberRegex (#2397)#2561ErfanBagheri404 wants to merge 6 commits into
ErfanBagheri404 wants to merge 6 commits into
Conversation
When the parent update has immediate: true and to is an array (chain), each step in the chain should also start immediately. Previously, the immediate flag was only checked in SpringValue.start(), where it short-circuits to skip the animation. But when to is an array, SpringValue.start() delegates to runAsync(), which iterates through the queue and calls animate() for each step. The immediate flag was not propagated to each step, so the chain would animate each step sequentially instead of jumping immediately to the final value. Fixes pmndrs#2204
…mponents On React Native (Hermes), host components become non-extensible after the first render. previously stashed the animated wrapper directly on the component via , which threw when the component was loaded lazily (e.g. via Metro inlineRequires). Replace the per-component property with a module-level WeakMap so we never mutate the original component. Fixes pmndrs#2533
… enabled (pmndrs#2409) When skipAnimation is true, _resume() calls finish() synchronously, resolving the promise immediately. The .then() callback then re-enters the loop via _update(), which calls _start() -> _resume() -> finish() again. Since there is no frame deferral, this creates a synchronous infinite loop that hangs the tab. Skip the loop re-trigger when G.skipAnimation is enabled. Fixes pmndrs#2409
… cleanup
addEventListener calls in onScroll were invoked with `{ passive: true }` but
removeEventListener was called with no options. Per the DOM spec, removeEventListener
must receive options with the same capture flag for the listener to be matched and
removed. While `{ passive: true }` defaults capture to false (same as no options),
some strict environments track add/remove options as an opaque object. The mismatch
causes removeEventListener to silently no-op, leaking listeners.
Use a shared options object for both add and remove calls, satisfying the DOM
spec's matching requirement and fixing useScroll cleanup.
Fixes pmndrs#2384
…er part The number regex `[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?` requires at least one digit before the decimal point (`0` or `[1-9]\d*`). Negative decimals without an integer part like `-.0000298023` (which browsers produce for lab/oklch colors via Chrome/Tailwind) are split into multiple fragments (`0`, `0`, `0`, `0`, `298023`) instead of a single token. This breaks arity checks in createStringInterpolator when the other keyframe has a different token count. Replace the regex with `[+\-]?(?:(?:\d*\.\d+)|\d+)(?:[eE][+\-]?\d+)?` which matches the decimal part independently of having an integer prefix, correctly handling inputs like `-.5`, `-.0000298023`, `+1.5e-3`, and all previously supported formats. Fixes pmndrs#2397
🦋 Changeset detectedLatest commit: 7d78a5b The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 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 |
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.
Summary
Transitioning between certain CSS color formats throws
"The arity of each output value must be equal". The crash happens when a color string contains a decimal without an integer part, such as-.0000298023(produced by Chrome/Tailwind foroklch(0.81 0 255 / 1)→lab(77.96% -.0000298023 0)).Root cause
numberRegexinpackages/shared/src/regexs.tsrequires at least one digit before the decimal point ((?:0|[1-9]\d*)). Input-.0000298023is split into fragments0, 0, 0, 0, 0, 298023instead of a single token, giving 7 numbers vs the other keyframe's 4 → arity check fails.Fix
Replace the regex with one that matches the fractional part independently of having an integer prefix:
This correctly handles
-.5,-.0000298023,+1.5e-3, and all previously supported formats (verified against 14 test inputs).Test plan
createStringInterpolator({output: ['lab(77.96% -.0000298023 0)', 'oklch(0.4 0.2639 271.35 / 1)']})— works.stringInterpolation.test.tsfor lab() colors.-.5pxnegative decimals.@react-spring/sharedbuilds clean (turbo).Fixes #2397