Using Material Icons with Styled Components

14.1k views Asked by At

Just started playing around with Styled Components. Is there a way to style third party icons such as Material Design Icons? This is the code I have so far but obviously it isn't working. Relavant code is below Content component Thanks!

const MaterialIcon = (props) => <i className="material-icons">account_balance</i>;

const Icon = styled(MaterialIcon)`
  background-color: green;
  font-size: 50px;
`;

const CheckThisOut = props => (
  <Wrapper>
    <Header>
      <h5>{props.title}</h5>
      <Icon />
    </Header>
    <Divider />
    <Content>
      <p>5% of all participants in this campaign were first time users.</p>
    </Content>
  </Wrapper>
);

export default CheckThisOut;

enter image description here

2

There are 2 answers

0
mxstbr On BEST ANSWER

For the styled(AnyComp) notation to work AnyComp needs to accept the incoming className prop and attach it to a DOM node.

For your example to work MaterialIcon has to use the passed in className, otherwise the styles are injected but no DOM node is targeted:

const MaterialIcon = (props) => (
  <i className={`material-icons ${props.className}`}>account_balance</i>
);

// WORKS 
const Icon = styled(MaterialIcon)`
  background-color: green;
  font-size: 50px;
`;

See our documentation page about styling any component for more information!

0
jngrt On

I know this is an old post, but here's another way to write it as a single expression. Using styled components' .attrs() (see docs) for the class name and the CSS ::after selector for the icon name.

const ThumbUp = styled.i.attrs(() => ({ className: "material-icons" }))`
  background-color: green;
  font-size: 50px;
  &:after {
    content: "thumb_up";
  }
`;

Writing this in a more generic way will allow you to use it for any of the available icons. This makes use of styled component ability to adapt based on props (see styled components docs for more info).

const MaterialIcon = styled.i.attrs(() => ({ className: "material-icons" }))`
  background-color: green;
  font-size: 50px;
  &:after {
    content: ${props => props.iconName || "help"};
  }
`;

Which you could then use like this:

<MaterialIcon iconName="check" />