70

Here is my styled component.

import * as React from 'react';
import styled from 'styled-components';
import { ComponentChildren } from 'app-types';

interface Props {
    children: ComponentChildren;
    emphasized: boolean;
}

const HeadingStyled = styled.h2`
    ${props => props.emphasized && css`
        display: inline;
        padding-top: 10px;
        padding-right: 30px;
  `}
`;

const Heading = (props: Props) => (
    <HeadingStyled>
        {props.children}
    </HeadingStyled>
);

export default Heading;

I get warnings that:

  • Property 'emphasized' does not exist on type 'ThemedStyledProps<DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, any>'.
  • Cannot find name 'css'. Did you mean 'CSS'?

How can I get this to work?

user1283776
  • 19,640
  • 49
  • 136
  • 276

5 Answers5

127
  • The styled component will have to specify the prop to pass to the component like styled("h2")<IProps>. You can read more about the pattern from documentation
  • css is not required here, it is added as a helper when you need to actually return CSS from a function. Check out conditional rendering.

Taking these into account, the component becomes:

const HeadingStyled = styled("h2")<{emphasized: boolean}>`
  ${props => props.emphasized && `
    display: inline;
    padding-top: 10px;
    padding-right: 30px;
  `}
`;

A use-case for css

Agney
  • 18,522
  • 7
  • 57
  • 75
  • The documentation is different from your example and also the _use-case for css_ is not working any more. Could you please investigate? I am lost. – Qwerty Feb 06 '19 at 19:14
  • 1
    The typings has changed after I had written the answer, updated answer with the recent changes – Agney Feb 07 '19 at 08:11
  • I would just like to add another thing that was missing for me: you also need to pass the `emphasized` prop to `HeadingStyled`, like so: ` {props.children} `. Might be obvious for some but wanted to point it out – Phlame Aug 18 '21 at 02:30
14

The previous answer worked for me, but just to add some information that was also helpful in my case:

StyledComponents uses a "ThemedStyledFunction" interface that allows the user to define additional Prop Types.

That means you could create an interface like:

interface IHeadingStyled {
   emphasized: boolean;
}

And use it on the component:

const HeadingStyled = styled("h2")<IHeadingStyled>`
  ${props => props.emphasized && `
    display: inline;
    padding-top: 10px;
    padding-right: 30px;
  `}
`;

(Which is a cleaner way to implement what @BoyWithSilverWings suggested, in case you have multiple props)


Check this discussion for more complete information:

https://github.com/styled-components/styled-components/issues/1428#issuecomment-358621605

Bruno Monteiro
  • 4,153
  • 5
  • 29
  • 48
6

This solution also works with emotion, maybe cause both of them uses stylis as a preprocessor?

interface ButtonProps {
  width: string;
}

const Button = styled("button")<ButtonProps>((props) => {
  return `width: ${props.width};`;
});

or different flavour same thing

interface ButtonProps {
  width: string;
}

const Button = styled("button")<ButtonProps>`
  width: ${props => props.width};
`;

or

interface ButtonProps {
  width: string;
}

const Button = styled.button<ButtonProps>`
  width: ${props => props.width};
`;
ncubica
  • 8,169
  • 9
  • 54
  • 72
1

When using styled components in a diferent sheet, I was having the same error.

I had to do this in index.tsx:

 export interface RadioBoxProps {
    isActive: boolean;
}

Then, in the styling sheet:

 import { RadioBoxProps } from "./index";

export const RadioBox = styled.button<RadioBoxProps>`

background: ${(props) => props.isActive ? '#eee' : 'transparent'};

`

In the tutorial I was watching, the person passes without exporting the interface and importing in the styling sheet. For him, it was working just fine. However, for me I wasn't and just worked when I did what I shown above.

-1
   /** In App.tsx **/

      <div className="App">
          <Button>Register</Button>
          <Button primary="primary">Register</Button>
     </div>


    /*In your functional component*/
    import styled from "styled-components";
    
    interface IButtonPropsType {
      primary: string;
    }
    
    export const Button = styled.button<IButtonPropsType>`
    background: ${(props) => (props.primary ? "palevioletred" : "white")}
    color: ${(props) => (props.primary ? "white" : "palevioletred")}
    font-size: 1.5em
    margin: 1em;
    padding: 0.25em 1em;
    border: 2px solid palevioletred;
    border-radius: 3px;
    `;
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 15 '22 at 11:55