Search code examples
javascriptreactjsstyled-components

How to supply objects to styled components


How can you supply objects to styled components for simplicity. This way, I have access to the theme for all my properties, importantly do not have to use - and can supply ints rather than everything being a string.

const Div = styled.div(() => ({
  padding: 20,
  border: '1px solid #c6d4df',
  boxSizing: 'border-box'
}))

Rrror

TypeScript error in /var/www/property-estimating/frontend/claim-handler/src/components/Overview/index.tsx(13,35):
No overload matches this call.
  Overload 1 of 3, '(first: TemplateStringsArray): StyledComponent<"div", any, {}, never>', gave the following error.
    Argument of type '() => { padding: number; border: string; boxSizing: string; }' is not assignable to parameter of type 'TemplateStringsArray'.
      Type '() => { padding: number; border: string; boxSizing: string; }' is missing the following properties from type 'TemplateStringsArray': raw, concat, join, slice, and 18 more.
  Overload 2 of 3, '(first: TemplateStringsArray | CSSObject | InterpolationFunction<ThemedStyledProps<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; }, any>>, ...rest: Interpolation<...>[]): StyledComponent<...>', gave the following error.
    Argument of type '() => { padding: number; border: string; boxSizing: string; }' is not assignable to parameter of type 'TemplateStringsArray | CSSObject | InterpolationFunction<ThemedStyledProps<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; }, any>>'.
      Type '() => { padding: number; border: string; boxSizing: string; }' is not assignable to type 'InterpolationFunction<ThemedStyledProps<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, any>>'.
        Type '{ padding: number; border: string; boxSizing: string; }' is not assignable to type 'Interpolation<ThemedStyledProps<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; }, any>>'.
          Type '{ padding: number; border: string; boxSizing: string; }' is not assignable to type 'CSSObject'.
            Types of property 'boxSizing' are incompatible.
              Type 'string' is not assignable to type 'BoxSizing | undefined'.
  Overload 3 of 3, '(first: TemplateStringsArray | CSSObject | InterpolationFunction<ThemedStyledProps<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; } & object, any>>, ...rest: Interpolation<...>[]): StyledComponent<...>', gave the following error.
    Argument of type '() => { padding: number; border: string; boxSizing: string; }' is not assignable to parameter of type 'TemplateStringsArray | CSSObject | InterpolationFunction<ThemedStyledProps<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; } & object, any>>'.
      Type '() => { padding: number; border: string; boxSizing: string; }' is not assignable to type 'InterpolationFunction<ThemedStyledProps<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; } & object, any>>'.
        Type '{ padding: number; border: string; boxSizing: string; }' is not assignable to type 'Interpolation<ThemedStyledProps<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; } & object, any>>'.
          Type '{ padding: number; border: string; boxSizing: string; }' is not assignable to type 'CSSObject'.  TS2769

    11 | }
    12 | 
  > 13 | const OverviewStyled = styled.div(() => ({
       |                                   ^
    14 |   padding: 20,
    15 |   border: '1px solid #c6d4df',
    16 |   boxSizing: 'border-box'

Solution

  • styled-components use Tagged Template Literals to configure a component, see: https://styled-components.com/docs/advanced#tagged-template-literals

    But, the first argument for a styled-component can either be a interpolated template string, a string array, or a CSSObject. See this post for the latter, which will apply in your case: https://paulie.dev/posts/2020/08/styled-components-style-objects/

    You should be able to do:

    const Div = styled.div({
      padding: 20,
      border: '1px solid #c6d4df',
      boxSizing: 'border-box'
    })
    

    See CodeSandbox: https://codesandbox.io/s/gracious-morning-yx6ht