Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[styled] CSS Animations (@keyframes) do not work with the built-in "styled" function #24851

Closed
2 tasks done
roymdavis opened this issue Feb 9, 2021 · 11 comments
Closed
2 tasks done
Labels
docs Improvements or additions to the documentation package: styled-engine Specific to @mui/styled-engine

Comments

@roymdavis
Copy link

  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

I'm trying to add a CSS animation in my styled component using the built in styled function from @material-ui/styles, adding the animation causes an error to be returned. Here's what my code looks like:

import {styled} from "@material-ui/core/styles";

const PulsatingCircle = styled("div")(({
  theme,
}) => ({
  "@keyframes pulsate": {
    from: {
      opacity: 1,
      transform: "scale(1)",
    },
    to: {
      opacity: 0,
      transform: "scale(2)",
    },
  },
  background: theme.palette.primary.main,
  borderRadius: "100%",
  animation: "$plusate 1s infinite ease",
  position: "absolute",
  zIndex: -2,
}));

Error that's returned:

TypeError: container.addRule(...).addRule is not a function
Array.onProcessStyle
src/optimized-frontend/node_modules/jss-plugin-nested/dist/jss-plugin-nested.esm.js:93
  90 |   }));
  91 | } else if (isNestedConditional) {
  92 |   // Place conditional right after the parent rule to ensure right ordering.
> 93 |   container.addRule(prop, {}, options) // Flow expects more options but they aren't required
     | ^  94 |   // And flow doesn't know this will always be a StyleRule which has the addRule method
  95 |   // $FlowFixMe[incompatible-use]
  96 |   // $FlowFixMe[prop-missing]

I also tried "scoping" the animation globally as per some recommend solutions for JSS that I found online, but it still resulted in the same error being thrown. Here's what it looks like when scoped globally:

import {styled} from "@material-ui/core/styles";

const PulsatingCircle = styled("div")(({
  theme,
}) => ({
  "@global": {
    "@keyframes pulsate": {
      from: {
        opacity: 1,
        transform: "scale(1)",
      },
      to: {
        opacity: 0,
        transform: "scale(2)",
      },
    }
  },
  background: theme.palette.primary.main,
  borderRadius: "100%",
  animation: "$plusate 1s infinite ease",
  position: "absolute",
  zIndex: -2,
}));

I believe I'm following the correct format for adding keyframe animations to a JSS object. For reference here's the JSS docs for adding keyframes: https://cssinjs.org/jss-syntax/?v=v10.5.1#keyframes-animation

Expected Behavior 🤔

The keyframe animation should be usable in the styled component.

Steps to Reproduce 🕹

Codesandbox link: https://codesandbox.io/s/material-ui-issue-forked-rj600

See details above. Adding a MUI styled component with a CSS keyframe animation results in the error posted above being thrown.

Context 🔦

I'm attempting to add an animation to my styled component, and this error is not allowing me to.

Your Environment 🌎

I'm developing on Brave Browser Version 1.19.92 (Chromium: 88.0.4324.152 64 bit)

`npx @material-ui/envinfo`
  System:
    OS: Linux 5.10 Artix Linux
  Binaries:
    Node: 15.6.0 - /usr/bin/node
    Yarn: 1.22.10 - /usr/bin/yarn
    npm: 6.14.11 - /usr/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: Not Found
  npmPackages:
    @types/react: ^16.9.0 => 16.9.49
    react: ^16.13.1 => 16.13.1
    react-dom: ^16.13.1 => 16.13.1
    styled-components: ^5.2.0 => 5.2.0
    typescript: ^4.0.2 => 4.0.2

@roymdavis roymdavis added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Feb 9, 2021
@oliviertassinari oliviertassinari removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Feb 9, 2021
@oliviertassinari oliviertassinari changed the title CSS Animations (@keyframes) do not work with the built-in "styled" function [styled] CSS Animations (@keyframes) do not work with the built-in "styled" function Feb 9, 2021
@oliviertassinari oliviertassinari added the package: styled-engine Specific to @mui/styled-engine label Feb 9, 2021
@oliviertassinari
Copy link
Member

oliviertassinari commented Feb 9, 2021

The problem was solved in v5:

import * as React from "react";
import { keyframes } from "@material-ui/styled-engine";
import { experimentalStyled as styled } from "@material-ui/core/styles";

const bounce = keyframes`
  from {
    opacity: 1;
    transform: scale(1);
  }

  to {
    opacity: 0;
    transform: scale(2);
  }
`;

const PulsatingCircle = styled("div")(({ theme }) => ({
  background: theme.palette.primary.main,
  width: 10,
  height: 10,
  borderRadius: "100%",
  animation: `${bounce} 1s infinite ease`,
  position: "absolute",
  zIndex: -2
}));

https://codesandbox.io/s/material-ui-issue-forked-cxkn7?file=/src/Demo.js

cc @mnajdova It seems that the JavaScript syntax for the usage works fine. We might want to document it if we get more questions about it. We didn't with JSS so we might not need it for emotion/sc either

@oliviertassinari oliviertassinari added the docs Improvements or additions to the documentation label Feb 9, 2021
@roymdavis
Copy link
Author

roymdavis commented Feb 9, 2021

@oliviertassinari I need a solution for v4, would it be possible to fix this for v4? If this is not possible then when will v5 be released?

@oliviertassinari
Copy link
Member

oliviertassinari commented Feb 9, 2021

@roymdavis in v4, you can use the makeStyles/withStyles API, the API supports it (not styled). You can check the source components some depend on keyframes.

@roymdavis
Copy link
Author

roymdavis commented Feb 10, 2021

For anyone who's facing the same issue I was able to come up with the following using the withStyles API

const PulsatingCircleComponent = styled("div")(({
  theme,
}) => ({
  background: theme.palette.primary.main,
  borderRadius: "100%",
  animation: "pulsate 1s infinite ease",
  position: "absolute",
  zIndex: -2,
}));

const PulsatingCircle = withStyles({
  "@global @keyframes pulsate": {
    from: {
      opacity: 1,
      transform: "scale(1)",
    },
    to: {
      opacity: 0,
      transform: "scale(2)",
    },
  },
})(() => {
  return (
    <PulsatingCircleComponent />
  );
});

@oliviertassinari This compiles/works, so thanks for pointing me in the right direction. However I don't think this solution is very elegant, would it be possible to add a quick fix for this issue in v4? If it's not possible then would you be open to accepting a pull request with a fix for v4?

@oliviertassinari
Copy link
Member

@roymdavis We don't plan nor will accept fixes for v4. The development of v4 has been paused for almost a year now

@roymdavis
Copy link
Author

@oliviertassinari Got it, thanks for clarifying and the quick response.

@Gungrave223
Copy link

Question....how would this look in v5?

@mnajdova
Copy link
Member

@Gungrave223 take a look at the CircularProgress usage.

@Gungrave223
Copy link

@mnajdova much appreciated....worked perfectly...also... outstanding job on mui.

@david-vendel
Copy link

Just to add to Oliver's answer, keyframes come from styled-engine in v5:
import { keyframes } from '@mui/styled-engine'

@mnajdova
Copy link
Member

@justdvl it will be exported from both the @mui/system as well as the @mui/material/styles with #29035 (the next release)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Improvements or additions to the documentation package: styled-engine Specific to @mui/styled-engine
Projects
None yet
Development

No branches or pull requests

5 participants