react-spring icon indicating copy to clipboard operation
react-spring copied to clipboard

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

Open ivantm opened this issue 3 years ago • 5 comments

Which react-spring target are you using?

  • [X] @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 :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

ivantm avatar Jul 25 '22 05:07 ivantm

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 ?

Yovach avatar Oct 20 '23 16:10 Yovach

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

Emiliano-Bucci avatar Nov 21 '23 09:11 Emiliano-Bucci

@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 :/

Emiliano-Bucci avatar Jan 07 '24 19:01 Emiliano-Bucci

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))

AlexandrMers avatar Apr 22 '24 14:04 AlexandrMers

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

filippovamaria avatar Apr 22 '24 14:04 filippovamaria