Styles
cn
1.0.0- Dependencies:
- ∟Direct: 1
- ∟Peer: 1
- Source code ↗
- Check on NPM ↗
Hidden
Overview
Section titled “Overview”Merges and deduplicates CSS class names with intelligent Tailwind CSS class handling. Combines clsx for conditional classes and tailwind-merge for Tailwind-specific merging, then deduplicates classes while preserving order.
cn(/inputs/);Features
Section titled “Features”- Merges CSS classes intelligently with Tailwind support
- Deduplicates classes while preserving order
- Handles conditional classes via clsx
- Resolves Tailwind class conflicts via tailwind-merge
- Supports arrays, objects, and conditional expressions
- Filters out falsy values automatically
- Default export available for convenience
- Comprehensive class processing pipeline
Arguments
Section titled “Arguments”| Arg | Type | Default Value | Required |
...inputs | ClassValue[] | - | No |
Use the cn() function to merge and deduplicate CSS class names.
import { cn } from '@inpulse-ui/utils';
const result = cn('btn', 'btn-primary', 'w-full');console.log(result); // "btn btn-primary w-full"Handles conditional classes:
const isActive = true;const isDisabled = false;
const classes = cn( 'btn', 'btn-primary', isActive && 'active', isDisabled && 'disabled');
console.log(classes); // "btn btn-primary active"Merges Tailwind classes intelligently:
// Tailwind classes with conflictsconst classes = cn( 'bg-red-500', 'bg-blue-500', // This will override bg-red-500 'p-4', 'px-6' // This will override px part of p-4);
console.log(classes); // "bg-blue-500 py-4 px-6"Deduplicates identical classes:
const classes = cn( 'btn btn-primary', 'btn text-white', 'btn-primary hover:bg-blue-600');
console.log(classes); // "btn btn-primary text-white hover:bg-blue-600"Works with arrays and objects:
const baseClasses = ['flex', 'items-center'];const conditionalClasses = { 'justify-center': true, 'justify-between': false, 'space-x-2': true};
const classes = cn(baseClasses, conditionalClasses, 'p-4');console.log(classes); // "flex items-center justify-center space-x-2 p-4"Examples
Section titled “Examples”Form input component - building a flexible input with multiple variants and states:
import { cn } from '@inpulse-ui/utils';
function Input({ variant = 'default', size = 'md', error, disabled, className, ...props}) { const inputClasses = cn( // Base styles 'w-full rounded-md border transition-colors focus:outline-none focus:ring-2',
// Size variants { 'px-2 py-1 text-sm': size === 'sm', 'px-3 py-2 text-base': size === 'md', 'px-4 py-3 text-lg': size === 'lg' },
// Variant styles { 'border-gray-300 bg-white focus:border-blue-500 focus:ring-blue-500': variant === 'default', 'border-gray-400 bg-gray-100 focus:border-gray-600 focus:ring-gray-600': variant === 'filled', 'border-0 border-b-2 border-gray-300 bg-transparent rounded-none focus:border-blue-500': variant === 'underline' },
// Error state error && [ 'border-red-500 bg-red-50 focus:border-red-500 focus:ring-red-500', variant === 'underline' && 'bg-transparent' ],
// Disabled state disabled && 'opacity-50 cursor-not-allowed bg-gray-100',
// Custom classes className );
return ( <input className={inputClasses} disabled={disabled} {...props} /> );}
// Usage examplesconst examples = [ <Input placeholder="Default input" />, <Input variant="filled" size="lg" placeholder="Large filled input" />, <Input variant="underline" error placeholder="Underline with error" />, <Input disabled placeholder="Disabled input" className="font-mono" />];React component styling:
// Button component with variantsfunction Button({ variant = 'primary', size = 'md', disabled, className, children }) { const buttonClasses = cn( // Base styles 'inline-flex items-center justify-center rounded-md font-medium transition-colors',
// Size variants { 'px-3 py-2 text-sm': size === 'sm', 'px-4 py-2 text-base': size === 'md', 'px-6 py-3 text-lg': size === 'lg' },
// Color variants { 'bg-blue-600 text-white hover:bg-blue-700': variant === 'primary', 'bg-gray-200 text-gray-900 hover:bg-gray-300': variant === 'secondary', 'border border-gray-300 bg-white text-gray-700 hover:bg-gray-50': variant === 'outline' },
// States disabled && 'opacity-50 cursor-not-allowed',
// Custom classes className );
return <button className={buttonClasses}>{children}</button>;}Complex conditional styling:
function Card({ highlighted, error, loading, size, className }) { const cardClasses = cn( // Base styles 'rounded-lg border shadow-sm',
// Size variants size === 'sm' && 'p-3', size === 'md' && 'p-4', size === 'lg' && 'p-6',
// State styles highlighted && 'border-blue-500 bg-blue-50', error && 'border-red-500 bg-red-50', loading && 'animate-pulse',
// Default styles when no state !highlighted && !error && 'border-gray-200 bg-white',
// Custom classes className );
return <div className={cardClasses}>Card content</div>;}Theme-based styling:
function ThemeProvider({ theme, children }) { const themeClasses = cn( // Base theme 'min-h-screen transition-colors',
// Theme variants { 'bg-white text-gray-900': theme === 'light', 'bg-gray-900 text-white': theme === 'dark', 'bg-blue-50 text-blue-900': theme === 'blue' } );
return <div className={themeClasses}>{children}</div>;}Built with by Jo Santana in Brazil.
© 2026 Inpulse. All rights reserved.