-
-
Notifications
You must be signed in to change notification settings - Fork 80
BUG: TW4 + TW merge + CVA some base classes are not applied #540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm having the same issue with "leading-" not being set when it's inside the first argument. |
🤔 Given the situation, I added some tests, and it seems TW merge is the problem. I added these 4 simple tests to check the output, and TW merge with some classes looks like it doesn't return the correct ones. describe('Link', () => {
it('clsx returns correct classes', () => {
const classes = 'leading-md font-secondary font-normal tracking-md mb-md'
expect(clsx(classes)).toBe(classes)
})
it('clsx returns correct classes without removal', () => {
const classes =
'leading-md font-secondary font-normal text-sm font-bold text-grey-200 tracking-md mb-md'
expect(clsx(classes)).toBe(classes)
})
it('cn returns correct classes', () => {
const classes = 'leading-md font-secondary font-normal tracking-md mb-md'
expect(cn(classes)).toBe(classes)
})
it('cn returns correct classes without removal', () => {
const classes =
'leading-md font-secondary font-normal text-sm font-bold text-grey-200 tracking-md mb-md'
expect(cn(classes)).toBe(
'leading-md font-secondary text-sm font-bold text-grey-200 tracking-md mb-md'
)
})
}) The last one is the failing one: Expected: "leading-md font-secondary text-sm font-bold text-grey-200 tracking-md mb-md"
Received: "font-secondary text-sm font-bold text-grey-200 tracking-md mb-md" It doesn't matter if you have this configuration or not inside the
|
It depends on the class order. for example, this work:
but this doesn't
The former can be found when you have const titleVariants = cva([], {
variants: {
level: {
1: [
'font-primary',
'text-2xl',
'sm:text-3xl',
'font-bold',
'leading-sm',
'tracking-xs',
'mb-xl',
],
...
compoundVariants: [
{
level: 1,
large: true,
class: ['text-4xl', 'sm:text-landing', 'md:text-2landing'],
},
... or even when you have shared classes like this: className: `${cn('font-secondary font-normal tracking-md leading-md mb-md', typographyVariants({ size, bold, light }), className)}` |
Hey @sebalaini! 👋 The reason why the import { extendTailwindMerge } from 'tailwind-merge'
const twMerge = extendTailwindMerge({
override: {
conflictingClassGroups: {
// In the default config the value is ['leading']
// See https://github.com/dcastil/tailwind-merge/blob/v3.0.2/src/lib/default-config.ts#L2095
'font-size': []
}
},
// … rest of your config
}) |
hey @dcastil ty for your response. With that snippet seems to look properly now :) |
Great! Let me close this issue. If there is still a problem, just let me know and I'll reopen. |
Hi, I have the same issue but it's a bit more complicated. I'd working on a new design system replacing the existing one. In the old system, I have: --text-sm: 0.875rem;
--text-sm--line-height: 1.25rem; i.e. the class In the new design system, I remove that connection to better support CJK languages: --text-75: 0.875rem;
--body-text-sm: var(--text-75); I need to support backward compatibility, so if I do Any suggestion? |
@unional you could create a complete separate class group for your new font-size classes and specify with which other class groups that new group is in conflict. Just keep in mind that when you use import { extendTailwindMerge } from 'tailwind-merge'
const twMerge = extendTailwindMerge<'font-size-new'>({
extend: {
classGroups: {
'font-size-new': ['text-75'],
},
conflictingClassGroups: {
'font-size-new': ['font-size'],
'font-size': ['font-size-new'],
},
},
}) |
Hi @dcastil, I tried what you have suggested. It works for some case but I found it doesn't work for the following: @utility body-emphasized {
font-style: italic;
font-weight: 400;
}
@utility body-strong {
font-style: normal;
font-weight: 700;
} const twMerge = extendTailwindMerge<'font-style-weight'>({
extend: {
classGroups: {
'font-style-weight': ['body-emphasized', 'body-strong']
},
conflictingClassGroups: {
'font-style-weight': ['font-style', 'font-weight'],
'font-style': ['font-style-weight'],
'font-weight': ['font-style-weight']
}
}
} // works: { fontStyle: normal, fontWeight: 400 }
<div className={twMerge('body-emphasized', 'not-italic')}/>
// does not work: { fontStyle: normal, fontWeight: 800 }
<div className={twMerge('body-emphasized', 'font-extrabold')}/>
// does not work: { fontStyle: italic, fontWeight: 400 }
<div className={twMerge('body-strong', 'italic')}/>
// works: { fontStyle: normal, fontWeight: 800 }
<div className={twMerge('body-strong', 'font-extrabold')}/> I am using the latest 4.0.15. Am I defining it wrong? Do you want me to create a new issue? UPDATE: const twMerge = extendTailwindMerge<'font-style-weight'>({
extend: {
classGroups: {
'font-style-weight': ['body-emphasized', 'body-strong']
},
conflictingClassGroups: {
'font-style-weight': ['font-style', 'font-weight']
},
conflictingClassGroupModifiers: {
'font-style-weight': ['font-style', 'font-weight']
}
}
} |
@unional yeah the problem is that with const twMerge = extendTailwindMerge<'font-style-weight'>({
extend: {
// …
conflictingClassGroups: {
'font-style': ['font-style-weight'],
'font-weight': ['font-style-weight'],
// …
}
}
} you define that the I recommend to not create utilities like this that bundle multiple CSS values together when using tailwind-merge and instead use variables in JS that hold multiple classes. Then you don't need to configure tailwind-merge which can become quite cumbersome otherwise. |
Yeah, it is tedious. Thanks for your tips. |
When I want to create fixed groups with certain styles, I create a file like export const TYPOGRAPHY_BODY_SMALL = 'text-sm font-medium …'
export const TYPOGRAPHY_BODY_MEDIUM = 'text-base font-normal …' Imagine that e.g. .body-small {
font-size: …;
font-weight …;
…
} Then in my components, I use the variable instead of the class essentially. import { twMerge } from 'tailwind-merge'
import { TYPOGRAPHY_BODY_SMALL } from '…'
function MyComponent({ className }) {
return <div className={twMerge(TYPOGRAPHY_BODY_SMALL, '…', className)} />
} This way you can still use a predefined set of styles like you would in a design system but don't need to add any config with complex conflict resolution to tailwind-merge. |
Describe the bug
I opened the issue in cva 335 but after some digging, I think is related to TW merge 🤔 looks like some classes are removed from the final class list.
The classes I'm having a problem with are
font-xxx
&leading-xxx
To Reproduce
This is my config:
This is the new way I have to do it to make it work, which doesn't seem correct.
Especially because I can override one of those classes that doesn't work, like this:
Expected behavior
both
font-xxx
&leading-xxx
should be applied to the final class list.The text was updated successfully, but these errors were encountered: