Documentation Index
Fetch the complete documentation index at: https://mintlify.com/aurelienbobenrieth/gadget/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The gadget-ui library exports utility functions to help with common tasks. These utilities are designed to work seamlessly with the component library.
cn()
The cn() utility function merges and deduplicates Tailwind CSS classes. It combines clsx for conditional class handling with tailwind-merge for intelligent class merging.
Import
import { cn } from "@aurelienbbn/gadget-ui/components";
Usage
The function accepts any number of class values and intelligently merges them:
cn("px-4 py-2", "bg-blue-500")
// Returns: "px-4 py-2 bg-blue-500"
Conditional Classes
Use objects for conditional classes:
cn("base-class", {
"active-class": isActive,
"disabled-class": isDisabled
})
// Returns: "base-class active-class" (if isActive is true)
Class Deduplication
Tailwind-merge handles conflicting utility classes:
cn("px-2 px-4")
// Returns: "px-4" (later value wins)
cn("text-red-500", "text-blue-500")
// Returns: "text-blue-500"
Arrays and Mixed Values
Supports arrays and mixed input types:
cn(["class1", "class2"], "class3", undefined, null, false)
// Returns: "class1 class2 class3"
Type Signature
function cn(...inputs: ClassValue[]): string
The ClassValue type (from clsx) accepts:
- Strings:
"class-name"
- Objects:
{ "class-name": boolean }
- Arrays:
["class1", "class2"]
- Falsy values:
undefined, null, false (ignored)
Examples
Basic Merging
const buttonClasses = cn(
"px-4 py-2 rounded",
"bg-blue-500 text-white",
"hover:bg-blue-600"
);
// "px-4 py-2 rounded bg-blue-500 text-white hover:bg-blue-600"
With Component Props
function MyButton({ className, variant }) {
return (
<button
className={cn(
"base-button-styles",
variant === "primary" && "bg-blue-500",
variant === "secondary" && "bg-gray-500",
className
)}
>
Click me
</button>
);
}
Responsive Classes
cn(
"text-sm md:text-base",
"px-2 md:px-4",
"hidden md:block"
)
// All responsive variants are preserved
With CVA Variants
The cn() function works seamlessly with class-variance-authority (CVA):
import { cva } from "class-variance-authority";
import { cn } from "@aurelienbbn/gadget-ui/components";
const buttonVariants = cva("base-styles", {
variants: {
variant: {
primary: "bg-blue-500",
secondary: "bg-gray-500"
}
}
});
function Button({ variant, className }) {
return (
<button className={cn(buttonVariants({ variant }), className)}>
Click me
</button>
);
}
Override Component Styles
import { Button } from "@aurelienbbn/gadget-ui/components";
// The Button component internally uses cn() to merge custom classes
<Button className="w-full mt-4">
Full Width Button
</Button>
Why cn()?
The cn() utility solves two problems:
-
Conditional classes: Using
clsx makes it easy to apply classes conditionally without string concatenation.
-
Tailwind conflicts: Using
tailwind-merge ensures that conflicting Tailwind utilities are properly resolved (the last one wins).
Without cn():
// Verbose and error-prone
const classes = [
"base-class",
isActive ? "active-class" : "",
isDisabled ? "disabled-class" : "",
className
].filter(Boolean).join(" ");
// Conflicting classes not resolved
"px-2 px-4" // Both classes applied!
With cn():
// Clean and correct
const classes = cn(
"base-class",
isActive && "active-class",
isDisabled && "disabled-class",
className
);
cn("px-2 px-4") // Returns "px-4" (conflict resolved)
Implementation
Location: packages/gadget-ui/src/lib/cn.ts:4
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Dependencies
- clsx - Tiny utility for constructing className strings conditionally
- tailwind-merge - Merge Tailwind CSS classes without style conflicts