Search code examples
reactjsstyled-components

How to set customized color for a Text component with styled-components?


I want to set a Text component's color dynamically. When there is a disable condition then change to another color.

import React from "react";
import styled, { css } from "styled-components";

type TextType = {
  text: string;
  disable: string;
};

export const Text: React.FC<TextType> = ({ text, disable }) => {
  return <TextStyle disable>{text}</TextStyle>;
};

const TextStyle = styled.span`
  ${({ theme }) => css`
    color: ${(props) =>
      props.disable ? theme.color.text : theme.color.disable};
  `}
`;

The props.disable got error

Property 'disable' does not exist on type 'ThemeProps<DefaultTheme>'. [2339]

The theme is

export const theme = {
  color: {
    text: black,
    disable: blue,
  },
};

I want to use it as

<Text disable text={text} />

Or

<Text text={text} disable={disable} />

Is it necessary to define a disable property in theme const?


Solution

  • i think it is because the first argument in your styled component Text is 'theme', while it should be props. so in your case there is a confusion between theme and props. try this see if it works :

    import React from "react";
    import styled, { css } from "styled-components";
    
    type TextType = {
      text: string;
      disable: string;
    };
    
    export const Text: React.FC<TextType> = ({ text, disable }) => {
      return <TextStyle disable={disable} >{text}</TextStyle>;
    };
    
    const TextStyle = styled.span`
      ${(props) => css`
        color: ${ props.disable ? props.theme.color.text : props.theme.color.disable};
      `}
    `;
    

    Also, the disable prop that you are passing in your component is not the same as the disable property in your theme. If you do not wish to have a different name for each as to avoid confusion, may be you should at least say that the disable you are passing into your component as a prop is of type boolean, like so :

    type TextType = {
      text: string;
      disable: boolean;
    };