Skip to content
UI

Class names

Joins class names and resolves Tailwind conflicts, last one wins, knowing the theme's own tokens.

@zenoxai/ui/lib/utils Markdown
Criticalrounded-md border py-1 text-sm border-primary bg-primary-soft text-primary-soft-foreground px-3
function ClassNamesDemo() {
  const [selected, setSelected] = React.useState(true)
  const className = cn(
    "rounded-md border border-border px-2 py-1 text-sm",
    selected && "border-primary bg-primary-soft text-primary-soft-foreground",
    "px-3"
  )

  return (
    <div className="flex flex-col items-start gap-3">
      <div className="flex items-center gap-2">
        <Switch
          id="class-names-selected"
          checked={selected}
          onCheckedChange={setSelected}
        />
        <Label htmlFor="class-names-selected">Selected</Label>
      </div>
      <span className={className}>Critical</span>
      <code className="font-mono text-sm wrap-anywhere text-text-secondary">
        {className}
      </code>
    </div>
  )
}

Usage

import { cn } from "@zenoxai/ui/lib/utils"

<span className={cn("px-2 text-sm", selected && "bg-primary-soft", className)} />

Use cn for every className built from more than one source: a component’s own classes, a condition and the caller’s className. The last class wins a conflict, so the caller can override a padding or a color.

A bare twMerge does not know the tokens this theme adds, such as text-md and text-dense-xs, and drops one of two classes it cannot tell apart. cn registers them.

It is a plain function, with no React and no DOM: it runs in a Server Component too.

API reference

Generated from the TypeScript source and its JSDoc.

cn

cn(...inputs: ClassValue[]): string

cn joins class names and resolves Tailwind conflicts, last one wins: cn("px-2", condition && "px-4", className). Use it for every className that is built from more than one source.

ParameterType
...inputsoptionalClassValue[]

Class names, and falsy values that are skipped, as in clsx.

Returns string
One class string, with the conflicts resolved.