Styled System
cva()
The css/cva entrypoint — atomic recipes with typed variants, colocated in your component.
File: styled-system/css/cva
Import: import { cva } from '../styled-system/css'
cva() (atomic recipe) defines base styles plus named variants. Call the result with a variant map; get a class
name. Styles stay colocated with the component. Prefer this when variants are local to one file.
import { cva } from '../styled-system/css'
const button = cva({
base: {
display: 'inline-flex',
alignItems: 'center',
rounded: 'md',
fontWeight: 'semibold'
},
variants: {
visual: {
solid: { bg: 'blue.500', color: 'white' },
outline: { borderWidth: '1px', borderColor: 'blue.500' }
},
size: {
sm: { px: '2', py: '1', fontSize: 'sm' },
md: { px: '4', py: '2', fontSize: 'md' }
}
},
defaultVariants: {
visual: 'solid',
size: 'md'
}
})
button({ visual: 'outline', size: 'sm' }) // => class name stringShape
| Key | Role |
|---|---|
base | Always-on styles |
variants | Named axes (size, visual, …) and their style maps |
compoundVariants | Styles for specific combinations of variants |
defaultVariants | Defaults when a variant is omitted |
Types
Generated types come from the recipe definition:
import { cva, type RecipeVariantProps } from '../styled-system/css'
const button = cva({
/* ... */
})
type ButtonProps = RecipeVariantProps<typeof button>Atomic vs config recipes
cva (this file) | Config recipe | |
|---|---|---|
| Defined in | Component file | panda.config.ts / theme |
| Import from | styled-system/css | styled-system/recipes |
| Best for | Local, one-off variants | Shared design-system components |
Full walkthrough: Atomic recipes. Config form: Config recipes. Ladder: Thinking in Panda.
See also
- sva() — multi-part slot recipes
- recipes/ — generated config-recipe folder
- Styled System overview