pmndrs / pmndrs/react-spring

[bug]: Better error message when CSS variable cannot be resolved

Open
#1,952 5 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind: bug
Dominant language
TypeScript
Stars
29.1k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

Which react-spring target are you using?
  • @react-spring/web
  • @react-spring/three
  • @react-spring/native
  • @react-spring/konva
  • @react-spring/zdog
What version of react-spring are you using?

9.5.2

What's Wrong?

When a CSS variable is unavailable, the output of this code in the variableToRgba function inside variableToRgba.ts is an empty string:

  const value = window
    .getComputedStyle(document.documentElement)
    .getPropertyValue(token)

If value is falsy, the initial value (the name of the CSS variable as a string) is returned.

In stringInterpolation.ts, this value falls through to:

  // Convert ["1px 2px", "0px 0px"] into [[1, 2], [0, 0]]
  const keyframes = output.map(value => value.match(numberRegex)!.map(Number))

where value.match returns null, and it tries to essentially do (null).map(Number)

The error reported is rather cryptic, especially when it happens in production in minified code:

TypeError: cannot read properties of null (reading 'map')
  at [....]

A much better developer experience would be for react-spring to throw an error, similar to what it does a little further below in the createStringInterpolator code when it checks the arity of values.

To Reproduce

The obvious fix is for the consumer to ensure the CSS variables are defined 😄 .

However, under certain circumstances and despite the developer's best intentions, this can occur. It happened to me on a non-trivial Next.js app that used Emotion's <Global> component to define CSS variables on :root. When performing a client-side route change from a page with a react-spring animation to another page (causing the Global component to unmount) and then navigating back. The Next.js application is non-trivial and I have had difficulty reproducing a simple case as it seems multiple factors are at play, such as the time taken to render a page on the client and the server.

Expected Behaviour

Throw a more meaningful error if the return value of variableToRgba is still a CSS variable (explicit).

An alternative could be to default to what CSS defaults to when a variable cannot be resolved on an element's CSS property - instead of an empty string, it defaults to rgba(0, 0, 0, 0) (to reproduce: create an element with a bogus css variable as its background color, then run window.getComputedStyle(element).backgroundColor). This is less explicit, but it would not throw an error.

Link to repo

N/A

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read variableToRgba.ts and follow its output into stringInterpolation.ts; compare the existing createStringInterpolator arity error for the project's error style. Reproduce the unresolved-CSS-variable path, then add a meaningful failure when resolution remains unavailable and cover the behavior with a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, react, typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.