pmndrs / react-spring

✌️ A spring physics based React animation library
http://www.react-spring.dev/
MIT License
27.93k stars 1.19k forks source link

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

Open ivantm opened 2 years ago

ivantm commented 2 years ago

Which react-spring target are you using?

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 :smile: .

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

Yovach commented 10 months ago

Hi, I'm currently using @react-spring/web with something like this :

function MyComponent() {
  return (
    <div>
      <ul className="[--from-bg:#000] [--to-bg:#fff] md:[--from-bg:#5f5]"></ul> {/* with tailwindcss */}
      <ul style={{ "--from-x": "#000" } as CSSProperties}></ul> {/* without tailwindcss */}
    </div>
  );
}

I just found this issue and I can't do something as above because it seems that the properties must be on the :root.

There's a way to bypass this ?

Emiliano-Bucci commented 9 months ago

@joshuaellis Hi! Is there a way to define the css variable outside the root, or this is mandatory to work?

Emiliano-Bucci commented 7 months ago

@ivantm Hi! I can reproduce this error in Nextjs when notFound() is called; did you find any solution to this? Is a pretty annoying issue :/

AlexandrMers commented 4 months ago

Hi. I faced the same problem. When I try to use CSS-variables from outside provider (theme provider of ui-kit) I get this kind of error as above. It seems to me that it shouldn't provide error at all in such a case, it should be just ignored I think))

filippovamaria commented 4 months ago

Hi! I have the same problem, too. We used CSS-variables from ui-kit and get same error. I hope you can solve it