Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript with Styled component conditional css for custom props

i have 2 similar questions : I`ve been working with the typescript recently, but i need my styled-component code to be validate to typescript.

1. I need describe custom prop - shadow, because typescript return error

Property 'shadow' does not exist on type 'ThemedStyledProps, HTMLDivElement>, "color" | "style" | "title" | ... 251 more ... | "key"> & { ...; } & { ...; }, DefaultTheme>'. TS2339

 export const InputBlock = styled.div<{height: string}>`
          display: flex;
          width: 100%;
          height: ${props => (props.height ? props.height : "56px")};

          ${props =>
            props.shadow &&
            css`
              box-shadow: ${props =>
                props.shadow ? "4px 4px 10px rgba(31,31,31,0.1)" : "none"};
            `};
        `;

2. how can i describe this props.touched[props.name] in my interface

interface FormSchema {
  errors: {
    [name: string]?: string, // ????
  },
  touched: {
    [propName: string]?: string, // ???
  },
  value: string,
  theme: {
    color: {
      redError?:string,
      inactiveBlue?:string,
      green?:string,
    }
  }
}

const colorStateForm = (props: FormSchema) =>
  props.errors &&
  props.touched &&
  props.errors[props.name] &&
  props.touched[props.name]
    ? props.theme.color.redError
    : !props.value && (!props.value.length || props.value.length === 0)
    ? props.theme.color.inactiveBlue
    : props.theme.color.green;

I used Formik and Yup for my form

like image 588
Роман Гирич Avatar asked Feb 21 '20 16:02

Роман Гирич


People also ask

How to use styled-components with props and typescript?

To use styled-components with props and TypeScript, we can create our own interface and use that as the type argument for the styled element function. interface Props { onPress: any; src: any; width: string; height: string; } const Icon = styled.Image<Props>` width: $ { (p) => p.width}; height: $ { (p) => p.height}; `;

Can you use CSS in typescript?

Using the CSS Prop In the Styled Components documentation, there are a couple of CSS functions. Here specifically is the attribute of CSS that could be utilized on an element when a Babel plugin is enabled. Unfortunately, TypeScript does not know about this CSS property, and makes an error.

How to use CSS-in-JS for styled components?

One of the major advantages of using a CSS-in-JS solution is the ability to pass custom props on runtime and adapt CSS accordingly. Just as in JSX Elements, you can pass the generic type with <> after the component. Now, your styled-component is typed and there would be a static error on the element if you have not passed active prop.

How do I style a prop inside an example component?

We will create a file called styles.ts where our styled components will be, which we will use later inside the Example component. In this step we will use the breakpoints created earlier for the media queries. First we must pass the prop and its value in the styled component call. We simply do a destructuring and use the prop.


Video Answer


1 Answers

I found an answer for my question =)

for first question

we should create type or interface

type ColorStateForm = {
      errors: any,
      touch: any,
      name: string,
      value: string,
      theme: any,
      hideDefault?: boolean
}

than we use this type or interface in our styled component

export const CheckBoxCustom = styled.div<ColorStateForm >`
  width: ${props => (props.width ? props.width : "24px")};
  height: ${props => (props.height ? props.height : "24px")};
  margin: ${props => (props.margin ? props.margin : "0")};
  position: relative;
  overflow: hidden;
  border-radius: 4px;
  flex: 0 0 24px;

  &:before {
    ${props =>
      props.hideDefault &&
      css`
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        display: block;
        width: ${props => (props.width ? props.width : "24px")};
        height: ${props => (props.height ? props.height : "24px")};
        border-style: solid;
        border-width: 2px;
        border-color: ${props =>
          props.errors &&
          props.touched &&
          props.errors[props.name] &&
          props.touched[props.name]
            ? props.theme.color.redError
            : props.theme.color.mainBlue};
        box-sizing: border-box;
      `};
  }

this is where we need to use TypeScript for conditional css on line

 &:before {
    ${props =>
      props.hideDefault &&
      css`

we need to pass our type or interface again. For example:

 &:before {
    ${(props: ColorStateForm ) =>
      props.hideDefault &&
      css`

that`s all, my VS Code is clean and friendly for TypeScript

for second question

First of all I created a type

type ColorStateForm = {
  errors: any,
  touch: any,
  name: string,
  value: string,
  theme: any
}

yes, i know that "any" type is evil, you can write anything instead

than i rewrote my ternary operator like that and added my created type

const colorStateForm = (props: ColorStateForm): string => {
  const {errors, touched, name, value, theme} = props;

  if(errors && touched && errors[name] && touched[name]){
    return theme.coloor.redError;
  }

  if(!value && (!value.length || value.length === 0)) {
    return theme.color.inactiveBlue;
  }  

  return theme.color.green;
}

I hope this info will be useful

like image 132
Роман Гирич Avatar answered Oct 27 '22 11:10

Роман Гирич