Closed bebbi closed 2 years ago
Hey there, thanks for bringing up this issue and posting this detailed report.
This reminds me of a styled bug I've also been trying to pinpoint, maybe it's the same one!
It seems to manifest when you use a mixture of the css/tw props and the styled
import but I'm having trouble tracking it down again also.
What I think might be happening is that Babel usually renames styled to _styled
to avoid conflicting with user imports. Then sometime after that, the styled
import tries to get used and isn't found.
I'll circle back to this after the next twin release is out, then maybe we can crack the case on this one :)
Barring unforeseen codebase changes, I should be able to reproduce this anytime. Happy to assist when you're ready!
Hey @bebbi, let's do this ๐
I can still repro this. You have the lead :)
sounds like you're able to pinpoint it now, you could either post the steps here or jump into our discord to discuss ๐
1+ on this issue. also in a nextjs setup. will investigate my setup
Module '"../../../node_modules/twin.macro/types"' has no exported member 'styled'. Did you mean to use 'import styled from "../../../node_modules/twin.macro/types"' instead?
import tw, { css, styled, theme } from 'twin.macro'
interface ButtonProps {
isPrimary?: boolean
isSecondary?: boolean
isSmall?: boolean
}
const Button = styled.button(
({ isPrimary, isSecondary, isSmall }: ButtonProps) => [
// The common button styles
tw`text-lg px-8 py-2 rounded focus:outline-none`,
tw`transform transition-transform duration-75`,
// Use the variant grouping feature to add variants to multiple classes
tw`hocus:(scale-105 text-yellow-400)`,
// Use props to conditionally style your components
isPrimary && tw`bg-black text-white border-black`,
// Combine regular css with tailwind classes within backticks
isSecondary && [
css`
box-shadow: 0 0.1em 0 0 rgba(0, 0, 0, 0.25);
`,
tw`border-2 border-yellow-600`,
],
// Conditional props can be added
isSmall ? tw`text-sm` : tw`text-lg`,
// The theme import can supply values from your tailwind.config.js
css`
color: ${theme`colors.white`};
`,
],
)
export default Button
@denu5 I think you might have a separate issue there.
Check you have typescript setup and make sure @types/react
is installed (I need to add this step to the docs as it's a new requirement).
The issue above is due to a custom twin import config that no longer works - it's triggered when the styled
import isn't imported from styled-components/macro
, like this:
// package.json
"babelMacros": {
"twin": {
"styled": {
"import": "default",
"from": "styled-components"
},
"css": {
"import": "css",
"from": "styled-components/macro"
},
"global": {
"import": "createGlobalStyle",
"from": "styled-components"
}
}
},
The new preset does this for you, so the config should be changed to this:
// package.json
"babelMacros": {
"twin": {
"preset": "styled-components"
}
},
Hi @ben-rogerson - my bad, I naively copied the button.tsx without reading the docs about the ts config. works! @types/react was already installed. moving on with tw now, wohoo! ๐ : Thanks a lot for the quick answer.
This should be fixed with the new import presets now, feel free to reopen if it's still an issue ๐
I fixed this error, try this
babel-plugin-macros.config.js
twin: {
styled: "styled-components",
config: "./tailwind.config.js",
format: "auto"
}
};
OR
package.json
"babelMacros": {
"twin": {
"styled": "styled-components",
"config": "./tailwind.config.js",
"format": "auto"
}
}
Twin doesn't have an item called format
in it's config.
Try this config and see if it still fixes your issue @najathi:
"babelMacros": {
"twin": {
"preset": "styled-components",
}
}
yeah, it works @ben-rogerson. Thanks
I'm still getting this error (following the vite example). It seems to happen whenever use the tw prop. Any help would be greatly appreciated.
@qscacheri I just tested both of the vite examples (emotion / styled-components) out with a fresh yarn
install, which use the tw prop with no issues. You could compare your setup with one of those examples or drop a link to a repo so I can take a look?
Seems like it could be user error, but I cloned the styled-components example, and only modified App.tsx to be the following and I am still getting the error.
import React from 'react'
import { Logo } from './components'
import tw, { styled, TwStyle } from 'twin.macro'
type ButtonVariant = 'green' | 'blue' | 'red' | 'gray'
interface ButtonProps {
variant?: ButtonVariant
}
const buttonVariants: Record<ButtonVariant, TwStyle> = {
blue: tw`bg-blue-400 focus:ring-blue-400 hover:bg-blue-500 disabled:bg-blue-400`,
green: tw`bg-green-400 focus:ring-green-400 hover:bg-green-500 disabled:bg-green-400`,
red: tw`bg-red-400 focus:ring-red-400 hover:bg-red-500 disabled:bg-red-400`,
gray: tw`text-black bg-gray-200 focus:ring-gray-200 hover:bg-gray-300 disabled:bg-gray-200`,
}
export const Button = styled.button<ButtonProps>(() => [
tw`h-10 px-4 py-2 mx-2 my-auto text-sm text-white transition-all rounded-lg focus:outline-none focus:ring-2 focus:ring-opacity-75 disabled:opacity-50 disabled:cursor-default`,
({ variant = 'blue' }) => buttonVariants[variant],
])
const App = () => (
<div>
<div tw="flex flex-col justify-center h-full gap-y-5"></div>
<Button variant="blue" tw="bg-red-500">
Click me
</Button>
</div>
)
export default App
@qscacheri Which example did you use - so I can look into this?
I see the issue mentioned, let me look into this.
_styled is not defined
I've taken a look into this error and found that it happens when we add a tw prop on a styled component using the styled-components
library, eg:
import tw from "twin.macro";
const Test = tw.div`mt-5`;
<Test tw="block" />;
The styled-components preset defined a default styled import of import styled from "styled-components/macro
.
The problem is that their macro doesn't preserve the _styled
import twin.macro adds for the tw prop.
To avoid this, the solution is to switch to the non-macro import import styled from "styled-components
.
Edit: twin.macro@2.8.2 fixed the error by updating the preset to use the updated import.
In the same version twin had to remove the css prop feature and now it should be added by babel-plugin-styled-components
.
Hereโs the minimum config youโll now need:
// package.json
"babelMacros": {
"twin": {
"preset": "styled-components"
}
},
I've now added a patch for the _styled is not defined error
in twin.macro@2.8.2 ๐
Awesome thanks!
@ben-rogerson The problem still occurs in a quite peculiar case when the styled
import is used together with this syntax:
const Component = tw['p']`text-base`
Take a look on this React component:
import { ElementType, PropsWithChildren, ComponentPropsWithoutRef, ReactElement } from 'react'
import tw, { styled } from 'twin.macro'
const Container = styled.div(() => [
// some tyles here
])
export type TextProps<T extends ElementType> = PropsWithChildren<{
as?: T
}>
export default function Text<T extends ElementType = 'p'>({
as,
children,
...rest
}: TextProps<T> & Omit<ComponentPropsWithoutRef<T>, keyof TextProps<T>>): ReactElement {
// WARNING!: This is the problematic syntax:
const Component = tw[(as || 'p') as string]`text-base`
return <Component {...rest}>{children}</Component>
}
The returned error visible below:
points to the problematic line from the component source code above:
const Component = tw[(as || 'p') as string]`text-base`
However this syntax is processed correctly and runs without errors:
const Component = tw.p`text-base`
Dependencies:
react v17.0.2
,twin.macro v2.8.2
,@emotion/babel-plugin v11.7.2
,vite v2.7.13
.A workaround I came up with for this problem is to manually save lost reference to the styled
import in the local variable called styledRef
and create a styled element using that variable:
import { ElementType, PropsWithChildren, ComponentPropsWithoutRef, ReactElement } from 'react'
import tw, { styled } from 'twin.macro'
// Reference is preserved in the local variable during bundle processing:
const styledRef = styled
const Container = styledRef.div(() => [
// some tyles here
])
// ...
// rest of the component code remains unchanged
I hope that my solution help to find the root cause and unblock the community while waiting for the fix.
@ben-rogerson I appreciate all the work you have done to create this macro. Thank you! ๐
@mszmida Twin 's tw function can't support a dynamic as
due to babel limitations, but using styled will work:
import tw, { styled } from 'twin.macro'
const as = 'dialog'
const Component = styled(as)(() => [tw`text-base`])
This should help
declare module "twin.macro" {
// The styled and css imports
const styled: typeof styledImport;
const css: typeof cssImport;
}
In an otherwise well-working project with gatsby + styled-components (using
tw
prop,css
prop, andtw
import is working fine), I randomly can't get thestyled
import to work and getReferenceError: styled is not defined
if I try.The error doesn't come up always. First I've managed to get it to work somehow. After that, I could get it to fail again with above error by:
Sorry I can't pin it down more precisely.
The setup: gatsby 2.26.1, styled-components 5.2.1, twin.macro 1.12.1. (But playing with some earlier twin version didn't appear to change the behaviour). Running in a yarn workspaces setting if that matters.
package.json:
I've tried replacing the preset with
but that didn't change the outcome.
Btw: I love the twin project, your pace of adding new goodies is addictive..