nextui-org / tailwind-variants

🦄 Tailwindcss first-class variant API
https://tailwind-variants.org
MIT License
2.42k stars 70 forks source link

TypeScript Variants Type Information Lost When Extending #185

Open ryanelian opened 7 months ago

ryanelian commented 7 months ago

Describe the bug

variants declared in a variant is not carried over to subsequent variants when extended.

Before I get chastised for doing this, I want to let everyone know that the reason I'm doing this is because Tailwind VS Code Intellisense breaks down and stop working when your variant gets too big, and I don't know how to fix it.

To Reproduce

Steps to reproduce the behavior:

import { VariantProps, tv } from 'tailwind-variants';

export const buttonBaseVariants = tv({
  base: '',
  variants: {
    mode: {
      contained: '',
      text: '',
    },
  },
});

export const buttonIntentVariants = tv({
  extend: buttonBaseVariants,
  variants: {
    intent: {
      primary: '',
      secondary: '',
      danger: '',
    },
  },
});

export const buttonVariants = tv({
  extend: buttonIntentVariants,
  variants: {
    size: {
      small: '',
      medium: '',
      large: '',
    },
  },
});

Expected behavior I expect the final function to contain the variants extended from the original and subsequent variants. Note below that mode is missing from the type information:

Screenshots

image

Additional context

Using Visual Studio Code with TypeScript 5.4.5 in the project package.json

Version: 1.88.1 (Universal)
Commit: e170252f762678dec6ca2cc69aba1570769a5d39
Date: 2024-04-10T17:42:52.765Z
Electron: 28.2.8
ElectronBuildId: 27744544
Chromium: 120.0.6099.291
Node.js: 18.18.2
V8: 12.0.267.19-electron.0
OS: Darwin arm64 23.4.0
mskelton commented 7 months ago

@ryanelian This is a known issue that I'm still trying to decide how to solve. There is a way I know fixes it, but sadly that's a breaking change to how extending works, so I'm not yet sure if that's the route I want to go, but we'll see.

Razinsky commented 6 months ago

We have the same issue. Multiple levels of inheritance seem like a pretty important use case; our case is also for buttons.

w0ofy commented 6 months ago

I too have this same issue. Would be great to get >1 level of inheritance for extended components.

will be watching this thread

ian-os commented 4 months ago

Any advice on an interim solution?

blowsie commented 4 months ago

Any advice on an interim solution?

My only advice here would be to extend plain objects before finally passing to tv

gregoryporebski commented 3 months ago

We had a similar issue with extending, and one way of patching it for now was spread

image

gregoryporebski commented 3 months ago

@ryanelian This is a known issue that I'm still trying to decide how to solve. There is a way I know fixes it, but sadly that's a breaking change to how extending works, so I'm not yet sure if that's the route I want to go, but we'll see.

Would be nice to have an option to pass a custom extend function, similar to how you can pass a custom twMergeConfig into createTV

dvzrd commented 1 week ago

@ryanelian This is a known issue that I'm still trying to decide how to solve. There is a way I know fixes it, but sadly that's a breaking change to how extending works, so I'm not yet sure if that's the route I want to go, but we'll see.

Would you like some help with this? I'm willing to contribute some time to spike on some more backwards compatible solutions, but I'd like to sync up first to understand the full scope of this issue.