React Styled Components — Animation and Theming

John Au-Yeung - Jul 28 '20 - - Dev Community

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 theThemeProvider 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.

The post React Styled Components — Animation and Theming appeared first on The Web Dev.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .