R2T8
R2T8

Reputation: 2590

How to theme components with styled-components and Material-UI?

Is there a possibility to use the Material-UI "theme"-prop with styled-components using TypeScript?

Example Material-UI code:

const useStyles = makeStyles((theme: Theme) => ({
  root: {
    background: theme.palette.primary.main,
  },
}));

Now I want to replace this code with styled-components.
I have tested the following implementation (and other similar implementations) without success:

const Wrapper = styled.div`
  background: ${props => props.theme.palette.primary.main};
`;

Upvotes: 4

Views: 4581

Answers (3)

Nathron
Nathron

Reputation: 1649

I wanted a similar set of requirements (MUI, styled-components, theme & typescript). I got it working, but I'm sure it could be prettier:

import React from "react";
import styled from "styled-components";
import { Theme, useTheme } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";

const StyledCustomButton: React.FC<{
  theme: Theme;
}> = styled(({ ...props }) => <Button {...props}>Test</Button>)`
  && {
    padding-bottom: ${(props) => props.theme.spacing(2)}px;
  }
`;

const CustomButton: React.FC = () => {
  const theme: Theme = useTheme();
  return <StyledCustomButton theme={theme} />;
};

export default CustomButton;

Upvotes: 0

Ryan Cogswell
Ryan Cogswell

Reputation: 80976

You can use withTheme to inject the theme as a prop.

import React from "react";
import { withTheme } from "@material-ui/core/styles";
import styled from "styled-components";

const StyledDiv = withTheme(styled.div`
  background: ${props => props.theme.palette.primary.main};
  color: ${props => props.theme.palette.primary.contrastText};
`);
export default function App() {
  return (
    <StyledDiv>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </StyledDiv>
  );
}

Edit Use theme with styled-components

For a start on the TypeScript aspects, see this demo: https://codesandbox.io/s/xyh60

This is from the withTheme HOC portion of the documentation.

Upvotes: 4

Julian Kleine
Julian Kleine

Reputation: 1547

I think no intended way. If you prefer the css way of writing then maybe consider this https://material-ui.com/styles/advanced/#string-templates

The example is

const useStyles = makeStyles({
  root: `
    background: linear-gradient(45deg, #fe6b8b 30%, #ff8e53 90%);
    border-radius: 3px;
    font-size: 16px;
    border: 0;
    color: white;
    height: 48px;
    padding: 0 30px;
    box-shadow: 0 3px 5px 2px rgba(255, 105, 135, 0.3);
  `,
});

Upvotes: -1

Related Questions