cn
The class merger every component in this package uses, so an override actually overrides.
Quick Preview
cn(BASE, OVERRIDE)[BASE, OVERRIDE].join(" ")Both were handed the same override. Only the merged one takes it: the concatenated one still carries the base's radius, background, and font size alongside, and source order decides.
Usage
Every component here merges its own classes with yours through cn. Published so you can do the same when you build on top of them.
import { cn } from "@giddaa-housing/ui/utils/cn";
<Badge className={cn("rounded-none", isActive && "bg-surface-accent")} />;It is clsx for conditional classes and tailwind-merge for conflicting ones, configured for this package's tokens.
That configuration is the reason to import it rather than roll your own. A stock tailwind-merge does not know that text-gdt-sm and text-gdt-lg are the same font-size scale, so it keeps both and lets whichever Tailwind emitted last win — which is not the one you wrote. This one is told about the text-gdt-* scale, so the last class wins the way you meant it to.
The same applies to plain concatenation, which keeps everything:
// Both classes survive; source order decides which applies.
<span className={`text-gdt-sm ${override}`} />
// The override wins.
<span className={cn("text-gdt-sm", override)} />Examples
Overriding a component's own classes
Both badges below were handed the same override. Only the merged one takes it.
cn(BASE, OVERRIDE)[BASE, OVERRIDE].join(" ")Both were handed the same override. Only the merged one takes it: the concatenated one still carries the base's radius, background, and font size alongside, and source order decides.
Building a component on top of one
The pattern every component in this package follows: your classes last, so a call site can override anything you set.
function ListingBadge({ className, ...props }: React.ComponentProps<typeof Badge>) {
return (
<Badge
variant="success"
className={cn("gap-1.5 uppercase", className)}
{...props}
/>
);
}Props
| Prop/API | Type | Default | Description |
|---|---|---|---|
cn | (...inputs: ClassValue[]) => string | - | Merges class names, resolving Tailwind conflicts in favour of the last one. Accepts anything clsx does: strings, arrays, objects, false, undefined. |
Accessibility
- Nothing here affects the accessibility tree.
cnreturns a string and reads no state. - Take care when overriding classes that carry meaning rather than decoration — a
sr-onlyor a focus ring dropped by an override is a regression that looks like a style change.