Back to Styled Components

Styled Theming

sections/tooling/styled-theming.mdx

latest3.7 KB
Original Source

import StyledThemingExample from './styled-theming-example'

Styled Theming

Create themes for your styled components using styled-theming

<StyledThemingExample />

Read the introductory blog post

Install

Install the babel-plugin first:

npm install --save styled-theming

Example

tsx
import React from 'react'
import styled, { ThemeProvider } from 'styled-components'
import theme from 'styled-theming'

const boxBackgroundColor = theme('mode', {
  light: '#fff',
  dark: '#000',
})

const Box = styled.div`
  background-color: ${boxBackgroundColor};
`

export default function App() {
  return (
    <ThemeProvider theme={{ mode: 'light' }}>
      <Box>Hello World</Box>
    </ThemeProvider>
  )
}

API

<ThemeProvider>

See styled-components docs

<ThemeProvider> is part of styled-components, but is required for styled-theming.

tsx
import { ThemeProvider } from 'styled-components'

<ThemeProvider> accepts a single prop theme which you should pass an object with either strings or getter functions. For example:

tsx
<ThemeProvider theme={{ mode: "dark", size: "large" }}>
<ThemeProvider theme={{ mode: modes => modes.dark, size: sizes => sizes.large }}>

You should generally set up a <ThemeProvider> at the root of your app:

tsx
function App() {
  return (
    <ThemeProvider theme={...}>
    </ThemeProvider>
  );
}

theme(name, values)

Most of your theming will be done with this function.

name should match one of the keys in your <ThemeProvider> theme.

tsx
;<ThemeProvider theme={{ whatever: '...' }} />
tsx
theme("whatever", {...});

values should be an object where one of the keys will be selected by the value provided to <ThemeProvider> theme.

tsx
<ThemeProvider theme={{ mode: "light" }} />
<ThemeProvider theme={{ mode: "dark" }} />

theme("mode", {
  light: "...",
  dark: "...",
});

The values of this object can be any CSS value.

tsx
theme("mode", {
  light: "#fff",
  dark: "#000",
});

theme("font", {
  sansSerif: '"Helvetica Neue", Helvetica, Arial, sans-serif',
  serif: 'Georgia, Times, "Times New Roman", serif',
  monoSpaced: "Consolas, monaco, monospace",
});

These values can also be functions that return CSS values.

tsx
theme('mode', {
  light: props => props.theme.userProfileAccentColor.light,
  dark: props => props.theme.userProfileAccentColor.dark,
})

theme will create a function that you can use as a value in styled-component's styled function.

tsx
import styled from 'styled-components'
import theme from 'styled-theming'

const backgroundColor = theme('mode', {
  light: '#fff',
  dark: '#000',
})

const Box = styled.div`
  background-color: ${backgroundColor};
`

theme.variants(name, prop, themes)

It's often useful to create variants of the same component that are selected via an additional prop.

To make this easier with theming, styled-theming provides a theme.variants function.

tsx
import styled from "styled-components";
import theme from "styled-theming";

const backgroundColor = theme.variants("mode", "variant", {
  default: { light: "gray", dark: "darkgray" },
  primary: { light: "blue", dark: "darkblue" },
  success: { light: "green", dark: "darkgreen" },
  warning: { light: "orange", dark: "darkorange" },
});

const Button = styled.button`
  background-color: ${backgroundColor};
`;

Button.propTypes = {
  variant: PropTypes.oneOf(["default", "primary", "success", "warning"])
};

Button.defaultProps = {
  variant: "default",
};

<Button />
<Button variant="primary" />
<Button variant="success" />
<Button variant="warning" />