styled-components icon indicating copy to clipboard operation
styled-components copied to clipboard

styled-components v6 alpha feedback

Open quantizor opened this issue 3 years ago • 24 comments

Use alpha tag in npm: yarn add styled-components@alpha

Example sandbox: https://codesandbox.io/s/styled-components-v6-alpha-sandbox-05bod1?file=/src/App.tsx

If you run into any bugs, please post reproductions and keep related discourse in this thread, thanks!

quantizor avatar Feb 22 '22 22:02 quantizor

Hey @probablyup , I wonder where is the TypeScript typing? I installed the alpha but didn't find it in the package, though it's mentioned that typing is included in this release :D

Thanks!

binhpv avatar Feb 24 '22 08:02 binhpv

Hey @probablyup , I wonder where is the TypeScript typing? I installed the alpha but didn't find it in the package, though it's mentioned that typing is included in this release :D

Thanks!

Oh weird, will look into that today thanks for flagging!

quantizor avatar Feb 24 '22 12:02 quantizor

@binhpv should be fixed here, thanks: https://github.com/styled-components/styled-components/releases/tag/v6.0.0-alpha.1

quantizor avatar Feb 24 '22 13:02 quantizor

@probablyup Thanks! I believe the "types" field is needed as well in package.json, since the index.d.ts is not at the root level. Ref: https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html#including-declarations-in-your-npm-package

binhpv avatar Feb 27 '22 08:02 binhpv

Oh weird, I thought it autodetected those...

quantizor avatar Feb 28 '22 18:02 quantizor

Just published 6.0.0-alpha.2 with the added "types" fields thank you!

quantizor avatar Mar 24 '22 13:03 quantizor

Updated OP with a code sandbox

quantizor avatar Mar 24 '22 14:03 quantizor

declare module 'styled-components/native' {
  interface DefaultTheme extends Styles.Theme {}
}

Theme types are not working for React Native =(

declare module 'styled-components' {
  interface DefaultTheme extends Styles.Theme {}
}

but works fine for React project

ghost avatar Mar 25 '22 17:03 ghost

import styled, { css, ThemeProvider } from "styled-components/macro";
import Theme from "./theme";

const Container = styled.div`
  ${({ theme }) =>
    css`
      color: ${theme.primary};
    `}
`;

Such construction {using css``} is not working with typescript anymore https://codesandbox.io/s/styled-components-v6-alpha-sandbox-forked-dnxedn?file=/src/App.tsx


(parameter) theme: DefaultTheme Argument of type '({ theme }: ExecutionContext & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>) => TemplateStringsArray | (Interpolation<...> & { ...; })' is not assignable to parameter of type 'Interpolation<ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>>'. Type '({ theme }: ExecutionContext & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement>) => TemplateStringsArray | (Interpolation<...> & { ...; })' is missing the following properties from type 'IStyledComponent<any, any>': $$typeof, componentStyle, foldedComponentIds, target, and 3 more.ts(2345)

ghost avatar Mar 25 '22 18:03 ghost

Thank you! Will add this to my list along with looking into the React native issues

quantizor avatar Mar 26 '22 13:03 quantizor

The quick solution in styled-components.d.ts

...
import { Interpolation, Styles, CSSProp } from 'styled-components/native/dist/types';

declare module 'styled-components/native/dist/types' {
  interface DefaultTheme extends Styles.Theme {}
}

declare module 'styled-components/native' {
  function css<Props>(
    styles: Styles<Props>,
    ...interpolations: Interpolation<Props>[]
  ): Interpolation<CSSProp>[] & string;
}

ghost avatar Mar 26 '22 13:03 ghost

Oh right, I guess for native it would be declare module 'styled-components/native' since it's a different import

quantizor avatar Mar 26 '22 13:03 quantizor

import styled, { css, ThemeProvider } from "styled-components/macro";
import Theme from "./theme";

const Container = styled.div`
  ${({ theme }) =>
    css`
      color: ${theme.primary};
    `}
`;

Such construction {using css``} is not working with typescript anymore https://codesandbox.io/s/styled-components-v6-alpha-sandbox-forked-dnxedn?file=/src/App.tsx

(parameter) theme: DefaultTheme Argument of type '({ theme }: ExecutionContext & ClassAttributes & HTMLAttributes) => TemplateStringsArray | (Interpolation<...> & { ...; })' is not assignable to parameter of type 'Interpolation<ClassAttributes & HTMLAttributes>'. Type '({ theme }: ExecutionContext & ClassAttributes & HTMLAttributes) => TemplateStringsArray | (Interpolation<...> & { ...; })' is missing the following properties from type 'IStyledComponent<any, any>': $$typeof, componentStyle, foldedComponentIds, target, and 3 more.ts(2345)

Has anyone found a solution for this issue which is still present in v6.0.0-alpha.5?

esetnik avatar Apr 18 '22 21:04 esetnik

I think that the DefaultTheme object needs an optional generic adding to it, as i have a load of custom defaultStyles in my theme object and im sure other people would need the ability to add an extra prop or two that dont exist in the defaulttheme

The other thing is this error still exists when using esm and jest

 FAIL  src/atoms/button/__test__/index.test.tsx
  ● Test suite failed to run

    TypeError: styled.div is not a function

      1 | import styled from 'styled-components';
      2 |
    > 3 | export const StyledDiv = styled.div<{ direction: 'row' | 'column' }>`

I think its something to do with

export { default as styled };
i think it needs to be 
export default styled;

The-Code-Monkey avatar May 02 '22 05:05 The-Code-Monkey

import styled, { css, ThemeProvider } from "styled-components/macro";
import Theme from "./theme";

const Container = styled.div`
  ${({ theme }) =>
    css`
      color: ${theme.primary};
    `}
`;

Such construction {using css``} is not working with typescript anymore https://codesandbox.io/s/styled-components-v6-alpha-sandbox-forked-dnxedn?file=/src/App.tsx (parameter) theme: DefaultTheme Argument of type '({ theme }: ExecutionContext & ClassAttributes & HTMLAttributes) => TemplateStringsArray | (Interpolation<...> & { ...; })' is not assignable to parameter of type 'Interpolation<ClassAttributes & HTMLAttributes>'. Type '({ theme }: ExecutionContext & ClassAttributes & HTMLAttributes) => TemplateStringsArray | (Interpolation<...> & { ...; })' is missing the following properties from type 'IStyledComponent<any, any>': $$typeof, componentStyle, foldedComponentIds, target, and 3 more.ts(2345)

Has anyone found a solution for this issue which is still present in v6.0.0-alpha.5?

Nope not currently i think it might just be the types that are off does //@ts-ignore work?

The-Code-Monkey avatar May 02 '22 05:05 The-Code-Monkey

Another issue i have on my mono repo is after updating to the alpha release is that my tests no longer run.

they just sit there

 RUNS  src/atoms/button/__test__/index.test.tsx
 RUNS  src/atoms/checkbox/__test__/index.test.tsx
 RUNS  src/atoms/grid/__test__/index.test.tsx
 RUNS  src/primatives/icon/__test__/index.test.tsx
 RUNS  src/atoms/table/__test__/index.test.tsx
 RUNS  src/atoms/input/__test__/index.test.tsx
 RUNS  src/atoms/divider/__test__/index.test.tsx

Test Suites: 0 of 7 total
Tests:       0 total
Snapshots:   0 total
Time:        168 s

edit: link to the repo https://github.com/The-Code-Monkey/TechStack/tree/dev/packages/components

The-Code-Monkey avatar May 02 '22 06:05 The-Code-Monkey

I'm trying to solve the Component is not a styled component and cannot be referred to via component selector. error.

With this code

const StyledColorBox = styled.div<{
    value: any;
}>`
  background-color: ${(props) => props.value};
`;

const ColorBox = ({
    parentName,
    childName,
}: {
    parentName: keyof GetFilter_getFilter;
    childName: FilterElementChildTypes | undefined;
}): JSX.Element => {
    const value = values[childName];
    const colorBox = <StyledColorBox value={value} />;
    if (parentName === "colors") {
       // Argument of type 'Element' is not assignable to parameter of type 'WebTarget'
        return styled(colorBox)``
    }
    return <></>;
};

I get the TS error Argument of type 'Element' is not assignable to parameter of type 'WebTarget' with styled(colorBox)

sirganya avatar May 04 '22 13:05 sirganya

Error on build or dev of nextjs@12

Build error occurred
TypeError: external_styled_components_.div is not a function
at Object.8689 (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/chunks/529.js:829:58)
at __webpack_require__ (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/webpack-runtime.js:25:42)
at Object.7712 (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:22:11)
at __webpack_require__ (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/webpack-runtime.js:25:42)
at __webpack_exec__ (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:124:39)
at /Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:125:66
at Function.__webpack_require__.X (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/webpack-runtime.js:220:21)
at /Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:125:47
at Object.<anonymous> (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:128:3)
at Module._compile (node:internal/modules/cjs/loader:1103:14) {
type: 'TypeError'
}

im not sure on how to fix this?

The-Code-Monkey avatar May 04 '22 14:05 The-Code-Monkey

I'm extremely excited for this release.

I wanted to take a moment to suggest a drastic change since this is already a breaking change.

Specifically, that styled-components should only export one module: createStyledComponentsConfig. This would be very similar to what Stitches and Vanilla Extract do. There are multiple benefits:

You can have multiple different themes with different keys and multiple theme providers, and NOT lose out on type safety. Today, and with how v6 is shaping out, it's not possible without some extra work. VS Code (and other editors that rely on a TSConfig) can potentially resolve different type definitions, but only in different folders, so if you have 2 theme providers in the same spot (lets say to support... federated modules with webpack module federation or to support multiple micro front-ends with different themes) you can't have typesafety for both of them. The simple fix is to name your themes when you add types for them and when you pass them to the ThemeProvider.

It also means you wouldn't need to maintain this part of the documentation anymore. Setup would be easier because types simply come free of charge with your defined theme.

I'm not sure if this is desired, but it also means styled-components could start to do more opinionated things when people define their theme, like encourage adoption of the SystemUI spec via the theme type. I say encourage, because it can be optional and people can add whatever keys they want or ignore it completely.

This can also remove the need for useTheme. People can simply import the correct theme as the key of the exported object returned by the function. It's a portable object.

kylemh avatar May 26 '22 20:05 kylemh

On ts 4.7.2 ERROR in ./node_modules/styled-components/dist/styled-components.browser.esm.js export '__spreadArray' (imported as 'e') was not found in 'tslib'

popuguytheparrot avatar Jun 06 '22 10:06 popuguytheparrot

It looks like there's a type error with the following pattern:

const Container = styled.div<{ variant: Variant }>`
  // ...

  ${(p) => {
    switch (p.variant) {
      case "X":
        return css`
          --primary-color: green;
          --base-color: white;
        `;

      // ...
    }
  }}
`;
Argument of type '(p: ExecutionContext & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { ...; }) => TemplateStringsArray | ... 1 more ... | undefined' is not assignable to parameter of type 'Interpolation<ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { variant: Variant; }>'.
  Type '(p: ExecutionContext & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { ...; }) => TemplateStringsArray | ... 1 more ... | undefined' is missing the following properties from type 'IStyledComponent<any, any>': $$typeof, componentStyle, foldedComponentIds, target, and 3 more.ts(2345)

But in runtime, it seems to be ok, just like previous versions. Here's a reproduction.

Update:

It seems like this example from the docs doesn't work as well.

Newbie012 avatar Jun 07 '22 06:06 Newbie012

Error on build or dev of nextjs@12

Build error occurred
TypeError: external_styled_components_.div is not a function
at Object.8689 (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/chunks/529.js:829:58)
at __webpack_require__ (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/webpack-runtime.js:25:42)
at Object.7712 (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:22:11)
at __webpack_require__ (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/webpack-runtime.js:25:42)
at __webpack_exec__ (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:124:39)
at /Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:125:66
at Function.__webpack_require__.X (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/webpack-runtime.js:220:21)
at /Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:125:47
at Object.<anonymous> (/Users/iv0706/code/TechStack/platforms/react-cms/.next/server/pages/[table].js:128:3)
at Module._compile (node:internal/modules/cjs/loader:1103:14) {
type: 'TypeError'
}

im not sure on how to fix this?

@The-Code-Monkey I'm getting the exact same issue with Next.js 12.2 and Styled Components 5.3.5 in my monorepo. external_styled_components_ is the entire module instead of the default export.

steve-taylor avatar Jul 04 '22 16:07 steve-taylor

@Newbie012 just pushed a new alpha build that should hopefully fix the type issue you were seeing

quantizor avatar Jul 22 '22 16:07 quantizor

@steve-taylor Have you found a way around this yet as currently it breaks not only my nextjs implementation but also my compiled component library?

The-Code-Monkey avatar Jul 27 '22 10:07 The-Code-Monkey

@probablyup Thanks for all your work on this! I'm finally getting around to trying it with a large codebase.

Here's a problem I'm hitting:

image

Obviously some useless nested css invocations there, but they're not useless in my app, just in the sandbox, which you can find at https://codesandbox.io/s/exciting-lucy-zmrdep?file=/src/App.tsx

The workaround I'm using is

${Inner as any}

Specifically it seems like the inferred props of Inner are interfering with the inferred props of css wrapping it, but I haven't figured out why.

agriffis avatar Sep 04 '22 13:09 agriffis

I'm not sure if this is a bug or intentional:

image

https://codesandbox.io/s/angry-darkness-oyu716?file=/src/App.tsx

I've previously used this sort of construction a lot:

${foo && css`...`}

but it doesn't like when foo is false, so I have to:

${foo ? css`...` : null}

PR for this https://github.com/styled-components/styled-components/pull/3799

agriffis avatar Sep 04 '22 14:09 agriffis

I'm trying React Native + SC v6 but something seems weird. When using the Box component I got no bg prop autocomplete, but if I type the prop name completely then I got autocomplete! It's like bg prop is hidden from the component props and thus does not show up on autocomplete, so I don't know why this is happening. On BoxBase same thing I got no autocomplete on align or justify, but on Box I got justify and align autocomplete but no bg.

https://user-images.githubusercontent.com/13828833/188333923-486f09f8-d36a-43e8-9f59-2941d96d7cee.mov

hadnet avatar Sep 04 '22 21:09 hadnet

I think I found out why the above is happening. In the PolymorphicComponentProps

declare type PolymorphicComponentProps<R extends Runtime, ActualComponent extends StyledTarget<R>,
PropsToBeInjectedIntoActualComponent extends {},
ActualComponentProps = ActualComponent extends KnownTarget ?
 React.ComponentPropsWithRef<ActualComponent> : {}> = React.HTMLAttributes<ActualComponent> & 
// Here I replaced Omit for Exclude in order to work
Exclude<PropsToBeInjectedIntoActualComponent, keyof ActualComponentProps | 'as' | '$as'> & ActualComponentProps & ({
    $as: ActualComponent;
    as?: AnyComponent;
} | {
    as?: ActualComponent;
});

I'm not a TS wizard, but do you think this can be the issue, @probablyup ?

hadnet avatar Sep 04 '22 22:09 hadnet

It looks like styled components don't emit an error on missing props:

import styled from 'styled-components'

type Props = {requiredProp: boolean}

const A = (_props: Props) => <div />
const a = <A />  // error for missing requiredProp ✅

const B = styled.div<Props>``
const b = <B />  // no error for missing requiredProp ❌

Sandbox at https://codesandbox.io/s/blue-mountain-g3vsfr?file=/src/App.tsx


This appears to be caused by

export interface BaseExtensibleObject {
  [key: string]: any;
}

Because of this declaration, styled components will never generate errors for missing props.

The motivation behind this declaration isn't clear to me. When I comment it out, everything seems to work in my limited testing:

export interface BaseExtensibleObject {
  // [key: string]: any;
}

but I'm probably missing something.

agriffis avatar Sep 06 '22 12:09 agriffis

@probablyup Would you prefer separate issues now that we're on beta?

agriffis avatar Sep 06 '22 12:09 agriffis

Seems like styled-components@^6.0.0-beta.2 can't handle "inplace argument extension" (not sure what's the official name for that):

const StyledContainer = styled.div<{ clickable?: boolean }>`
  ${({ clickable }) => clickable && 'cursor: pointer;'}
`

Error:

TS2345: Argument of type '({ clickable }: ExecutionContext & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { ...; }) => false | ... 1 more ... | undefined' is not assignable to parameter of type 'Interpolation<ExecutionContext & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { ...; }>'.   
  Type '({ clickable }: ExecutionContext & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { ...; }) => false | ... 1 more ... | undefined' is missing the following properties from type 'IStyledComponent<"web", any, any>': $$typeof, componentStyle, foldedComponentIds, inlineStyle, and 4 more.

Dependencies:

  • React 18
  • Typescript 4.3.5

TmLev avatar Sep 09 '22 19:09 TmLev

Okay, seems like it doesn't like possible false return value.

Explicit handling prevents Typescript from erroring out:

const StyledContainer = styled.div<{ clickable?: boolean }>`
  ${({ clickable }) => clickable ? 'cursor: pointer;' : ''}
`

Feels like a regression from v5.


But when using .attrs, it definitely refuses to work:

const HideOnMobile = styled(HideOn).attrs({ device: 'mobile' })<{ gridColumn: number }>`
  grid-column: ${({ gridColumn }) => gridColumn};
`

Error:

TS7031: Binding element 'gridColumn' implicitly has an 'any' type.

TmLev avatar Sep 09 '22 19:09 TmLev

Okay, seems like it doesn't like possible false return value.

@TmLev This was mentioned above, see https://github.com/styled-components/styled-components/issues/3696#issuecomment-1236355978

and there is a PR for it, see #3799

agriffis avatar Sep 09 '22 20:09 agriffis

Okay, seems like it doesn't like possible false return value.

@TmLev This was mentioned above, see https://github.com/styled-components/styled-components/issues/3696#issuecomment-1236355978

and there is a PR for it, see #3799

Right, missed that, sorry.

Nevertheless, the latter issue (when using .attrs) persists.

TmLev avatar Sep 09 '22 21:09 TmLev

Hi folks, I've started a new thread for beta at #3800. Going to close this one for now. Thanks!

quantizor avatar Sep 10 '22 14:09 quantizor

(merged @agriffis's fix to allow false again as an interpolation, that'll go out with beta 3)

quantizor avatar Sep 10 '22 14:09 quantizor