cn
Merge Tailwind class strings, with later conflicting classes winning over earlier ones.
Every spark-ui component takes a className and merges it onto its own base
classes with cn; it's what lets a consumer override a component's default
styling (<Badge className="bg-base-error-soft" />) without fighting
specificity. Re-exported from cn, a
drop-in for the common clsx + tailwind-merge combo (same behavior, no
config changes needed on your side).
Usage
import { cn } from '@epilot/spark-ui/utils/cn'cn('px-2 py-1', condition && 'bg-spark-9', className)Accepts the same inputs as clsx:
| Input | Example | Behavior |
|---|---|---|
string | 'flex gap-2' | included as-is |
| falsy | false, null, undefined | dropped silently, safe in a ternary/&& |
object | { 'bg-spark-9': isActive } | key included when the value is truthy |
array | ['flex', ['gap-2', cond && x]] | flattened, each item follows the same rules |
Later arguments win when two classes target the same CSS property (e.g.
cn('bg-spark-9', 'bg-error') → bg-error); this is what makes
cn(baseClasses, className) a safe override pattern.
Examples
Merge override
The second bg-*/text-* pair replaces the first instead of both applying.
Conditional classes
Notes
- Custom-named font-size tokens don't merge correctly by default: a token
like
text-xxsmerged with atext-{color}utility can silently drop one of them, the same as defaulttailwind-merge. Spark's own font-size tokens use the standard names (text-xs…text-4xl), which are unaffected. If you introduce a custom-named size token downstream, extend the merge config viacreateCninstead of relying on the defaultcnexport.