2
votes

How can I access the ThemeProvider props in global.js when using styled-components?

For example in theme.js I have ${props => props.theme.fonts.fontSize} calling a default font size of 16px

const theme = {
    fonts: {
        fontSize : '16px',
    }
}

export default theme

This is provided in /layouts/index.js as

import React from 'react'

import { ThemeProvider } from 'styled-components'
import '../style/global';
import theme from '../style/theme'

class Template extends React.Component {
  render() {
    const { children } = this.props

    return (
      <ThemeProvider theme={theme}>
        ...
        {children()}
        ...
      </ThemeProvider>
    )
  }
}

export default Template

From here I can access the ${props => props.theme.fonts.fontSize} within each component or child page.

But how can I pass to global.js in the same way when global is technically a level above theme.js? So that I could create a global style as

injectGlobal`
  html {
    font-size: (${props => props.theme.fonts.fontSize} / 16px) * 1em;
  }
`
2

2 Answers

3
votes

The easiest way off solving this is by creating a top level component that injects your desired styling like this:

import { Children } from 'react';
import { withTheme, injectGlobal } from 'styled-components';

const GlobalComponent = ({ theme, children }) => {
  injectGlobal`
      font-size: ${theme.fonts.fontSize}
    }
  `;
  return Children.only(children);
};

export default withTheme(Global);

This will make sure all Components that have this Component as a parent will have the desired globalStyling. Hope this helped

1
votes

Late but now we can actually create a Global Component and pass it as a child of ThemeProvider. It will allow you to access all the props of current theme.

Example for applying font family:

Your Global.js / Global.ts

import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`

  html,
  body {
    padding: 0;
    margin: 0;
    font-family: ${(props) => props.theme.font.family}
  }

  a {
    color: inherit;
    text-decoration: none;
  }

  * {
    box-sizing: border-box;
  }
`;

export default GlobalStyle;

Your Main component app.tsx / app.jsx

import theme...
import { ThemeProvider } ...
imort GlobalStyle from '../path-to-global-file';

const App ...
.
.
return(
 <>
  <ThemeProvider theme={theme}>
   <GlobalStyle />
   { /* Root component */ }
   <Component/>
  </ThemeProvider>
 </>
);

You can use the props easily now.