---
title: "tva"
description: "Builds a variant resolver modeled on [cva](https://cva.style). Where cva composes class strings, `tva` composes brand-enforced style objects into a `mix`-ready descriptor."
url: "https://pitlane.tools/package/theme/function/tva"
---

# tva

```ts
import { tva } from "@pitlane/theme";
```

```ts
function tva<V>(config): TVAFn<V>;
```

Builds a variant resolver modeled on [cva](https://cva.style). Where cva composes class strings, `tva` composes brand-enforced style objects into a `mix`-ready descriptor.

Each invocation resolves the selection by deep-merging `base`, then every matching variant in declaration order, then every matching compound variant in array order, and feeds the result to a single [css](https://pitlane.tools/package/theme/function/css.md) call. `defaultVariants` fills in unset axes, and boolean axes come from options named `true` and `false`.

## Type Parameters

### V

`V` _extends_ `VariantShape`

## Parameters

### config

[`TVAConfig`](https://pitlane.tools/package/theme/interface/TVAConfig.md)\<`V`>

## Returns

[`TVAFn`](https://pitlane.tools/package/theme/interface/TVAFn.md)\<`V`>

## See

- [TVAConfig](https://pitlane.tools/package/theme/interface/TVAConfig.md) for the configuration shape.
- [TVAProps](https://pitlane.tools/package/theme/type/TVAProps.md) to extract the props type.
- [Theme guide: Variants with Theme Variance Authority](https://pitlane.tools/guides/theme.md#variants-with-theme-variance-authority)

## Example

```ts
export let button = tva({
    base: { borderRadius: t.radius.md },
    variants: {
        intent: {
            primary: { backgroundColor: t.color.accent },
            secondary: { backgroundColor: "transparent" },
        },
        size: { sm: { fontSize: t.text.sm }, md: { fontSize: t.text.md } },
        block: { true: { display: "flex" } },
    },
    compoundVariants: [
        { intent: "secondary", size: "md", css: { fontSize: t.text.lg } },
    ],
    defaultVariants: { intent: "primary", size: "md" },
});

<button mix={button({ intent: "secondary", block: true })} />;
```
