React Styled Components — Animation and Theming
Tags: react, webdev, programming, javascript
Published: 2021-01-23 19:50:43

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at how to create styled-components with animation and theming with `styled-components` .

### Animations

We can use CSS animations to animate styled-components with `styled-components`. For instance, we can write the following code to do that:

```
import React from "react";
import styled, { keyframes } from "styled-components";

const rotate = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`;

const Rotate = styled.div`
  display: inline-block;
  animation: ${rotate} 2s linear infinite;
  padding: 5px;
  font-size: 1.2rem;
`;

export default function App() {
  return (
    <div className="App">
      <Rotate>foo</Rotate>
    </div>
  );
}
```

In the code above, we create the `rotate` animation with the `keyframes` function. We just pass in animation code as we do with normal CSS animations.

To rotation is 360-degree rotation.

Then we include `rotate` inside the template string where would normally put our animation definition. We specified it to run forever.

Finally, we put `Rotate` in `App` with the text that we want to rotate inside to rotate it.

### Theming

We can theme by exporting using the`ThemeProvider` component. For instance, we can use it as follows:

```
import React from "react";
import styled, { ThemeProvider } from "styled-components";

const Button = styled.button`
  font-size: 1em;
  margin: 1em;
  padding: 5px;
  color: ${props => props.theme.main};
  border: 2px solid ${props => props.theme.main};
`;
Button.defaultProps = {
  theme: {
    main: "red"
  }
};

const theme = {
  main: "green"
};

export default function App() {
  return (
    <div className="App">
      <Button>Normal</Button>
      <ThemeProvider theme={theme}>
        <Button>Themed</Button>
      </ThemeProvider>
    </div>
  );
}
```

In the code above, we have the `ThemeProvider` component that’s provided by `styled-components` .

We then defined a styled button with:

```
const Button = styled.button`
  font-size: 1em;
  margin: 1em;
  padding: 5px;
  color: ${props => props.theme.main};
  border: 2px solid ${props => props.theme.main};
`;
Button.defaultProps = {
  theme: {
    main: "red"
  }
};
```

We take the `theme.main` property to which has the color to apply the color selectively. If it’s not defined, then we set the button color to red.

Then the button that’s added outside the `ThemeProvider` has a red border and text. The button inside the `ThemeProvider` is green as we defined in:

```
const theme = {
  main: "green"
};
```

### Function Themes

We can also define functions for theming purposes. For instance, we can define a base theme and a theme based off of it by writing the following code:

```
import React from "react";
import styled, { ThemeProvider } from "styled-components";

const Button = styled.button`
  font-size: 1em;
  margin: 1em;
  padding: 5px;
  color: ${props => props.theme.fg};
  background-color: ${props => props.theme.bg};
`;

const baseTheme = {
  fg: "green",
  bg: "white"
};

const theme = ({ fg, bg }) => ({
  fg: bg,
  bg: fg
});

export default function App() {
  return (
    <ThemeProvider theme={baseTheme}>
      <Button>Normal</Button>
      <ThemeProvider theme={theme}>
        <Button>Inverted</Button>
      </ThemeProvider>
    </ThemeProvider>
  );
}
```

In the code above, we have a styled `Button` component that takes variable styling from the theme. We access the theme variables in the `theme` property.

Then we defined a `baseTheme` , which has the foreground and background colors of the button.

Then we defined `theme` , which invert the colors from the base theme by flipping the foreground and background colors.

Therefore, the Normal button has green text and white background, and the Inverted button has a green background with white text.

### Getting the Theme Without Styled Components

We can use themes without applying them to styled-components. To do this, we use the `withTheme` function.

For instance, we can use it as follows:

```
import React from "react";
import { ThemeProvider, withTheme } from "styled-components";

const baseTheme = {
  color: "green",
  backgroundColor: "white"
};

let Foo = ({ theme, children }) => {
  return <div style={theme}>{children}</div>;
};

Foo = withTheme(Foo);

export default function App() {
  return (
    <div>
      <ThemeProvider theme={baseTheme}>
        <Foo>foo</Foo>
      </ThemeProvider>
    </div>
  );
}
```

In the code above, we defined the `Foo` component, which takes the `theme` prop to get the styles from the `baseTheme` object.

Then since we wrapped `ThemeProvider` around the `Foo` component, we can get the styles in `baseTheme` with the `theme` prop.

In `Foo` , we passed it straight into the `style` prop to style our `Foo` component.

Therefore, we’ll see ‘foo’ displayed in green on the screen.

### Conclusion

We can create animations with CSS animation. To create one, we use the `keyframe` tag with the animation put in the string. Then we put the returned animation code in our CSS where the animation-name would be.

`styled-components` supports theming. We can theme it with the `ThemeProvider` component. Then we can pass the styles to components with `styled-components` or the components that we defined without it.