Skip to Content
styled-cva 0.7.1 is available 🎉
API Reference

API Reference

tw

The main export from @styled-cva/react. It’s a function that can be used to create styled components.

Basic Usage

import tw from "@styled-cva/react"; const Button = tw.button`bg-blue-500 text-white`;

With Element Types

You can use tw with any HTML element:

const Div = tw.div`container mx-auto`; const Input = tw.input`border rounded`; const A = tw.a`text-blue-500 hover:underline`;

With Custom Components

You can also wrap custom components:

import MyComponent from "./MyComponent"; const StyledComponent = tw(MyComponent)`bg-gray-100 p-4`;

Extending Styled Components

You can extend existing styled components to add additional styles:

const BaseButton = tw.button`btn-base`; // Extend with additional classes const ExtendedButton = tw(BaseButton)`bg-green-500 hover:bg-green-600`; // This works with CVA components too const VariantButton = tw.button("btn-base", { variants: { $variant: { primary: "btn-primary", secondary: "btn-secondary", }, }, }); const ExtendedVariantButton = tw(VariantButton)`rounded-lg`;

.cva()

⚠️

Deprecated on intrinsic elements (tw.button, tw.div, …): prefer tw.element(base, config) — same types and runtime as tw.element.cva(base, config). The .cva() member remains available but may be removed in a future major version.

Creates a styled component with variant support using class-variance-authority.

Signature

Preferred for intrinsics (see above):

tw.element(baseClasses, config);

Equivalent legacy form:

tw.element.cva(baseClasses, config);

Parameters

  • baseClasses (string): Base CSS classes that are always applied
  • config (object): CVA configuration object
    • variants (object): Variant definitions
    • defaultVariants (object, optional): Default variant values
    • compoundVariants (array, optional): Compound variant definitions

Example

const Button = tw.button("btn-base", { variants: { $variant: { primary: "btn-primary", secondary: "btn-secondary", }, $size: { sm: "btn-sm", md: "btn-md", lg: "btn-lg", }, }, defaultVariants: { $variant: "primary", $size: "md", }, compoundVariants: [ { $variant: "primary", $size: "lg", className: "btn-primary-lg", }, ], }); // Using default variants - they're applied automatically <Button>Click me</Button>; // Uses primary variant and md size // Override defaults <Button $variant="secondary" $size="sm"> Small Secondary </Button>;

Transient Props

đź’ˇ

Variant keys starting with $ are transient props that won’t be passed to the DOM element. This prevents React warnings about unknown props.

Intrinsic shorthand (tw.element(base, config))

For intrinsic factories (tw.button, tw.a, tw.div, …), omit .cva and pass the same arguments (preferred; .cva() on intrinsics is deprecated — see above):

tw.element(baseClasses, cvaConfig); // equivalent to: tw.element.cva(baseClasses, cvaConfig);

Tagged templates (tw.div\classes`) are unchanged. Dispatch treats the first argument as CVA config when it is not a tagged-template receiver. See **isTaggedTemplateArg`** under Utilities.

.withProps()

Sets default props for a component. User-provided props will override these defaults.

Signature

Component.withProps(defaultProps);

Parameters

  • defaultProps (object): An object containing default props to apply

Example

const Button = tw.button("btn", { variants: { $variant: { primary: "btn-primary", secondary: "btn-secondary", }, }, }) .withProps({ type: "button", "data-testid": "button", $variant: "primary", });

$as Prop

The $as prop allows you to render a component as a different element or component.

Example

const Button = tw.button`btn`; // Render as an anchor tag <Button $as="a" href="/link"> Link Button </Button>; // Render as a custom component <Button $as={Link} href="/link"> Next.js Link </Button>; // Works with CVA components too const VariantButton = tw.button("btn", { variants: { $variant: { primary: "btn-primary", secondary: "btn-secondary", }, }, }); <VariantButton $as="a" href="/link" $variant="primary"> Link Button </VariantButton>;

PolymorphicComponentProps

Utility type for rendering CVA components as custom React components (TanStack Router Link, Next.js Link, etc.) while preserving every $-prefixed variant prop ($variant, $size, $tone, …) from the source component.

Use it when the runtime $as={SomeComponent} form needs explicit typing (e.g. when wrapping in your own component):

import { Link, type LinkProps } from "@tanstack/react-router"; import tw, { type PolymorphicComponentProps } from "@styled-cva/react"; const Button = tw.button("btn", { variants: { $variant: { primary: "btn-primary", secondary: "btn-secondary" }, $size: { sm: "px-2", md: "px-3" }, }, }); type ButtonLinkProps = PolymorphicComponentProps<typeof Button, typeof Link> & LinkProps; const ButtonLink = (props: ButtonLinkProps) => ( <Button {...props} $as={Link} /> ); // Now type-safe end-to-end: <ButtonLink to="/about" $variant="primary" $size="md"> About </ButtonLink>;

For intrinsic elements ($as="a", $as="button", …) the typing already works without this utility — it’s only needed when $as is a custom component.

Utilities

cn

A utility function for combining Tailwind CSS classnames. It uses clsx and tailwind-merge to intelligently merge classes.

import { cn } from "@styled-cva/react"; const className = cn("text-red-500", "bg-blue-500"); // className = "text-red-500 bg-blue-500"

isTaggedTemplateArg

From @styled-cva/core, re-exported by framework packages: true when the value is a tagged-template TemplateStringsArray (has raw). Used internally to distinguish tw.div\…`fromtw.div(base, config)`.

import { isTaggedTemplateArg } from "@styled-cva/react";

cva

The underlying class-variance-authority function. You can use it directly if needed:

import { cva } from "@styled-cva/react"; const buttonVariants = cva("btn-base", { variants: { variant: { primary: "btn-primary", secondary: "btn-secondary", }, }, }); // Use with className <button className={buttonVariants({ variant: "primary" })}>Click me</button>;
⚠️

When using cva directly (not through tw.element.cva()), variant keys don’t need the $ prefix since they’re not passed as props to components. The $ prefix is only needed when using tw.element.cva() to prevent props from being passed to the DOM.

TypeScript Types

TailwindComponent<P, O>

The base type for all styled components.

  • P: The base React props
  • O: Additional props added by the template function

VariantProps<T>

Extracts variant props from a CVA configuration.

import { cva, type VariantProps } from "@styled-cva/react"; const buttonVariants = cva("btn", { variants: { $variant: { primary: "btn-primary", secondary: "btn-secondary", }, }, }); type ButtonVariants = VariantProps<typeof buttonVariants>; // { $variant?: 'primary' | 'secondary' }

Advanced: .withStyle()

For additional flexibility, basic styled components (not CVA components) support .withStyle() to add inline styles:

const Button = tw.button`btn`.withStyle({ transition: "all 0.2s", });
⚠️

This is only available on basic styled components created with template literals. CVA components do not support this method.

Last updated on