twind
twind copied to clipboard
tw`bg-white` at use tw variable with template string it is not work!
I get an error:
Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'StringLike'. Type 'TemplateStringsArray' is not assignable to type 'string'.
Without some code it is difficult to help.
What twind version are you using?
Without some code it is difficult to help.
What twind version are you using?
I using: "twind": "^1.0.0-next.37" and "@twind/with-next": "^1.0.0-next.37" for nextjs
I get the error when using tw``
without Parentheses, It is work fine when use with parentheses like this tw(``)
tw accepts only a string: tw(„…“) or use tx that is an alias for tw(cx…) and works as template literal.
In v0.16, tw took a template string.
https://twind.dev/api/interfaces/twind.tw.html#callable
The documentation for v1 migration says the following. It makes it sound like we can use it the same as we were in v0.16.
tw as known from twind v0.16
https://twind.style/docs/migration
The readme on GitHub says the same.
https://github.com/tw-in-js/twind/blob/next/website/pages/docs/migration.md#notable-changes
It looks like the equivalent of v0.16 tw is tx.bind(tw). That's not clear from the documentation. I found out about tx from the following reference page but it just says that it is shorthand for tw(cx(...args))
. Coming from v0.16, it wasn't clear what cx does, so I didn't realize tx would get me the same behavior. I didn't make the connection until reading your comment on this issue.
https://twind.style/docs/reference#utilities
I think it would help if migration docs were updated to reflect that tx is the equivalent of v0.16 tw and that v1 tw is different.
Any insight into why the call signature of tw was changed in V1?
In v0.16, tw took a template string.
twind.dev/api/interfaces/twind.tw.html#callable
The documentation for v1 migration says the following. It makes it sound like we can use it the same as we were in v0.16.
tw as known from twind v0.16
The readme on GitHub says the same.
https://github.com/tw-in-js/twind/blob/next/website/pages/docs/migration.md#notable-changes
You are right that's a mistake in the docs.
It looks like the equivalent of v0.16 tw is tx.bind(tw). That's not clear from the documentation. I found out about tx from the following reference page but it just says that it is shorthand for
tw(cx(...args))
. Coming from v0.16, it wasn't clear what cx does, so I didn't realize tx would get me the same behavior. I didn't make the connection until reading your comment on this issue.twind.style/docs/reference#utilities
I think it would help if migration docs were updated to reflect that tx is the equivalent of v0.16 tw and that v1 tw is different.
Yep. I must adjust this.
Any insight into why the call signature of tw was changed in V1?
The main reason is performance. Interpolating a template string array takes some time. By accepting only a string we can boost the performance for many cases (like transforming the class name attribute).
The main reason is performance. Interpolating a template string array takes some time. By accepting only a string we can boost the performance for many cases (like transforming the class name attribute).
In that case, I've decided not to use tx. My main use case for tx was being able to have conditional classes. Below is an example.
<NavLink
key={item.name}
to={item.to}
end
className={({ isActive }) => tx`
${isActive
? "bg-gray-900 text-white"
: "text-gray-300 hover:bg-gray-700 hover:text-white"}
px-3 py-2 rounded-md text-sm font-medium
`}
>
{item.name}
</NavLink>
I decided to just make a thin wrapper around tw that allows it to take multiple arguments and will join them together with space separators. That way I can get the performance benefit of not interpolating a template string array but am still able to add conditional classes easily.
const _tw = twind.setup(twindConfig, sheet)
export const tw = (...tokens: string[]) => _tw(tokens.filter(Boolean).join(" "))
Below is what the NavLink looks like using my tw wrapper.
<NavLink
key={item.name}
to={item.to}
end
className={({ isActive }) => tw(
isActive
? "bg-gray-900 text-white"
: "text-gray-300 hover:bg-gray-700 hover:text-white",
"px-3 py-2 rounded-md text-sm font-medium",
)}
>
{item.name}
</NavLink>
@KyleJune You could use the style helper which provides a stitches like API. Docs are missing but here are the tests: https://github.com/tw-in-js/twind/blob/next/packages/twind/src/tests/style.test.ts#L61
import { style } from 'twind'
const navLinkStyle = style({
label: 'NavLink', // optional
// the classes to always use
base: `px-3 py-2 rounded-md text-sm font-medium`,
// only needed in cases there is no isActive in the props
defaults: {
isActive: false,
},
// define the props the navLinkStyle function accepts
props: {
isActive: {
true: `bg-gray-900 text-white`,
false: `text-gray-300 hover:bg-gray-700 hover:text-white`,
},
},
})
// Usage
function Component({ item }) {
return (<NavLink
key={item.name}
to={item.to}
end
className={navLinkStyle}
// or explicit
className={({ isActive }) => navLinkStyle({ isActive })}
>
{item.name}
</NavLink>)
Your example could use the builtin tx
method. It does not need to be called as tagged template function.
<NavLink
key={item.name}
to={item.to}
end
className={({ isActive }) => tx(
isActive
? "bg-gray-900 text-white"
: "text-gray-300 hover:bg-gray-700 hover:text-white",
"px-3 py-2 rounded-md text-sm font-medium",
)}
>
{item.name}
</NavLink>
or using an object:
<NavLink
key={item.name}
to={item.to}
end
className={({ isActive }) => tx({
"bg-gray-900 text-white": isActive,
"text-gray-300 hover:bg-gray-700 hover:text-white": !isActive,
},
"px-3 py-2 rounded-md text-sm font-medium"
)}
>
{item.name}
</NavLink>