Skip to content

Composing with cx()

cx() is the functional composition API. It takes StyleRule objects and plain strings, and returns a space-separated class name string.

Most users will prefer the tw chainable API instead. Use cx() when you need conditional logic, dynamic values, or prefer the functional style.

Standalone utilities support property-access tokens — no strings needed for design tokens:

import { cx, p, bg, rounded } from 'typewritingclass'
// Property-access tokens (recommended)
cx(p(4), bg.blue500, rounded.lg)
// String lookups (equivalent)
cx(p(4), bg('blue-500'), rounded('lg'))

Color utilities are callable for opacity:

cx(bg.blue500(50), rounded.lg, p(4)) // 50% opacity blue

Later arguments win. Typewriting Class uses CSS @layer for deterministic ordering:

cx(p(4), p(8)) // p(8) wins -- padding: 2rem
cx('my-component', p(4), bg.white)
// => "my-component _a1b2c _d3e4f"

Use standard JavaScript for conditional logic:

cx(
p(4),
bg.white,
isActive ? bg.blue50 : '',
isDisabled ? opacity(0.5) : '',
)
import { cx, p, bg, shadow, when, hover, md } from 'typewritingclass'
cx(
p(4),
bg.blue500,
when(hover)(bg.blue600, shadow.lg),
when(md)(p(8)),
)
const cardBase = [p(4), bg.white, rounded.lg, shadow.sm]
const blueCard = cx(...cardBase, bg.blue50)
const dangerCard = cx(...cardBase, bg.red50, textColor.red900)