ben-rogerson / twin.macro

🦹‍♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components, solid-styled-components, stitches and goober) at build time.
MIT License
7.95k stars 183 forks source link

Unable to clone and style existing components with Stitches using standard syntax #824

Open wmcb91 opened 1 year ago

wmcb91 commented 1 year ago

When trying to clone and style an existing twin/styled component, I am getting this error while using Next.js and Stitches.

error - Error [TypeError]: (0 , _stitches_config_ts__WEBPACK_IMPORTED_MODULE_1__.styled)(...) is not a function
...

To recreate, you can use the next-stitches-typescript project from twin.examples. twin.examples/next-stitches-typescript/src/pages/index.tsx

const ButtonBox = tw.div`flex flex-col justify-center h-full gap-y-5`
const MyCustomButtonBox = tw(ButtonBox)`bg-red-500`

Currently, a workaround is to use Stitches' styled import.

const MyCustomButtonBox = styled(ButtonBox, {
  ...tw`bg-red-500`,
})

Without much knowledge of the codebase, an oversimplified solution appears to be calling handleStyledFunction when tw(Component) is called with Stitches.

ben-rogerson commented 1 year ago

Thanks for the examples - I also replicated it in the stitches example.

Looking at the generated code, it all looks okay and no different than what's generated for emotion/styled-components and both I've tested and don't cause that webpack error.

Will have to look into this further.

wmcb91 commented 1 year ago

I've include the a full error dump below. Also here is a repo where the bug should be able to be replicated.

event - compiled client and server successfully in 819 ms (180 modules)
error - src/pages/index.tsx (15:37) @ eval
error - Error [TypeError]: (0 , _stitches_config_ts__WEBPACK_IMPORTED_MODULE_1__.styled)(...) is not a function
    at eval (webpack-internal:///./src/pages/index.tsx:43:95)
    at Function.__webpack_require__.a (/Users/will/Development/next-stitches-typescript-bug-example/.next/server/webpack-runtime.js:97:13)
    at eval (webpack-internal:///./src/pages/index.tsx:1:21)
    at Object../src/pages/index.tsx (/Users/will/Development/next-stitches-typescript-bug-example/.next/server/pages/index.js:52:1)
    at __webpack_require__ (/Users/will/Development/next-stitches-typescript-bug-example/.next/server/webpack-runtime.js:33:42)
    at __webpack_exec__ (/Users/will/Development/next-stitches-typescript-bug-example/.next/server/pages/index.js:92:39)
    at /Users/will/Development/next-stitches-typescript-bug-example/.next/server/pages/index.js:93:28
    at Object.<anonymous> (/Users/will/Development/next-stitches-typescript-bug-example/.next/server/pages/index.js:96:3)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.requirePage (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/require.js:134:12)
    at /Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/load-components.js:51:73
    at async Object.loadComponentsImpl [as loadComponents] (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/load-components.js:51:26)
    at async DevServer.findPageComponentsImpl (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/next-server.js:667:36)
    at async DevServer.findPageComponents (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/dev/next-dev-server.js:1248:20)
    at async DevServer.renderPageComponent (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/base-server.js:1187:24)
    at async DevServer.renderToResponseImpl (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/base-server.js:1230:32)
    at async DevServer.pipeImpl (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/base-server.js:548:25)
    at async Object.fn (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/next-server.js:1030:21)
    at async Router.execute (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/router.js:297:32)
    at async DevServer.runImpl (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/base-server.js:522:29)
    at async DevServer.run (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/dev/next-dev-server.js:869:20)
    at async DevServer.handleRequestImpl (/Users/will/Development/next-stitches-typescript-bug-example/node_modules/next/dist/server/base-server.js:456:20) {
  digest: undefined
}
  13 | const ButtonBox = tw.div`flex flex-col justify-center h-full gap-y-5`
  14 | 
> 15 | const CustomButtonBox = tw(ButtonBox)`bg-black`
     |                                     ^
  16 | 
  17 | const IndexPage = () => (
  18 |   <Container hasBackground>
zax-xyz commented 1 year ago

Looking at the generated code, it all looks okay and no different than what's generated for emotion/styled-components

@ben-rogerson It does generate similar code to with emotion/styled-components, but this is also the problem - Stitches doesn't use the same syntax here, it doesn't support using styled(Component) as a function (as in styled(Component)(styles). You can only use syntax similar to the workaround mentioned by @wmcb91 using 2 parameters: styled(Component, styles).

It looks like you've already took note of this for the dot syntax: https://github.com/ben-rogerson/twin.macro/blob/b1258e71defc4de70e381d569fc2254f1094affa/src/macro/twin.ts#L35 so I think a similar approach should probably be able to be taken here? But I haven't looked too deeply into it either