joe-bell / cva

Class Variance Authority
https://cva.style
Apache License 2.0
5.46k stars 107 forks source link

feat: export ClassProp and ClassValue #229

Closed imcvampire closed 8 months ago

imcvampire commented 8 months ago

Description

ClassProp and ClassValue are not exported. As a result, users need to import them from clsx.

Additional context


What is the purpose of this pull request?

Before submitting the PR, please make sure you do the following

vercel[bot] commented 8 months ago

@imcvampire is attempting to deploy a commit to the cva Team on Vercel.

A member of the Team first needs to authorize it.

joe-bell commented 8 months ago

Hey!

Appreciate the PR but not sure I understand the need for this — my preference is to keep these types coupled with the component constructor

Keen to hear your thoughts 🙏🏼

imcvampire commented 8 months ago

@joe-bell

Hi,

My use case is that I would like to extend the functionality of cva. Currently, I'm having this code:

import { twMerge } from 'tailwind-merge'
import { cx } from 'class-variance-authority'

export const cn: typeof cx = (...inputs) => {
  return twMerge(cx(inputs))
}

It isn't the best IMO. Instead of typeof, I would like to import ClassValue to define my param.

joe-bell commented 8 months ago

Gotcha, thanks @imcvampire

Please can you instead try out cva@beta? There's a new defineConfig feature that allows you to extend upon cx without exposing types 😊

Example

// cva.config.ts
import { defineConfig } from "cva";
import { twMerge } from "tailwind-merge";

export const { cva, cx, compose } = defineConfig({
  hooks: {
    onComplete: (className) => twMerge(className),
  },
});
// components/button.ts
import { cx, cva } from "../cva.config";

export const button = cva({
  // 1. `twMerge` strips out `bg-gray-200`…
  base: "font-semibold bg-gray-200 border rounded",
  variants: {
    // 2. …as variant `bg-*` values take precedence
    primary: "bg-blue-500 text-white border-transparent hover:bg-blue-600",
    secondary: "bg-white text-gray-800 border-gray-400 hover:bg-gray-100",
  },
  defaultVariants: {
    intent: "primary",
  },
});

button();
// => "font-semibold border rounded bg-blue-500 text-white border-transparent hover:bg-blue-600 text-base py-2 px-4 uppercase"

cx("bg-gray-200", "bg-blue-500");
// => "bg-blue-500"

This aims to solve the exact issue you're facing, so for now I'll close this issue 🙏