BeniUI

Customization

Learn how to customize BeniUI components to match your brand and design system.

Since you own the component code, customization is straightforward — you can modify any part of the components directly. This guide covers common customization patterns.

Customizing Colors

BeniUI components use Tailwind's default color palette. You can change colors by modifying the class names in the component code.

Method 1: Direct Modification

Simply replace the color classes in your component:

// Before: Blue primary button
const variants = {
  primary: "bg-blue-600 text-white hover:bg-blue-700",
};

// After: Green primary button
const variants = {
  primary: "bg-green-600 text-white hover:bg-green-700",
};

// Or use your brand color
const variants = {
  primary: "bg-indigo-600 text-white hover:bg-indigo-700",
};

Method 2: Using CSS Variables

For more flexibility, define CSS variables and reference them in Tailwind:

/* globals.css */
:root {
  --color-primary: 79 70 229;       /* indigo-600 */
  --color-primary-hover: 67 56 202; /* indigo-700 */
  --color-secondary: 229 231 235;   /* gray-200 */
}

.dark {
  --color-primary: 129 140 248;     /* indigo-400 */
  --color-primary-hover: 99 102 241; /* indigo-500 */
  --color-secondary: 55 65 81;      /* gray-700 */
}
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          DEFAULT: "rgb(var(--color-primary) / <alpha-value>)",
          hover: "rgb(var(--color-primary-hover) / <alpha-value>)",
        },
      },
    },
  },
};

// Then use in your component
const variants = {
  primary: "bg-primary text-white hover:bg-primary-hover",
};

💡 Tip

Using CSS variables makes it easy to support dark mode and allows you to change colors globally without modifying each component.

Changing Sizes

Most components include size variants. You can modify existing sizes or add new ones.

Modifying Size Variants

// Button sizes example
const sizes = {
  sm: "h-8 px-3 text-sm",
  md: "h-10 px-4 text-sm",    // default
  lg: "h-12 px-6 text-base",
  
  // Add a new extra-large size
  xl: "h-14 px-8 text-lg",
  
  // Or an icon-only size
  icon: "h-10 w-10 p-0",
};

Global Size Adjustments

If you need to adjust sizes globally (e.g., for a more compact UI), modify the Tailwind config:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      fontSize: {
        // Make all text slightly smaller
        sm: ['0.8125rem', { lineHeight: '1.25rem' }],
        base: ['0.875rem', { lineHeight: '1.375rem' }],
        lg: ['1rem', { lineHeight: '1.5rem' }],
      },
      spacing: {
        // Compact spacing scale
        '3.5': '0.875rem',
        '4.5': '1.125rem',
      },
    },
  },
};

Modifying Variants

BeniUI components use a variant pattern for different visual styles. You can modify existing variants or add new ones.

Adding New Variants

// Add a "success" variant to Button
const variants = {
  primary: "bg-blue-600 text-white hover:bg-blue-700",
  secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200",
  ghost: "text-gray-600 hover:bg-gray-100 hover:text-gray-900",
  destructive: "bg-red-600 text-white hover:bg-red-700",
  
  // New success variant
  success: "bg-green-600 text-white hover:bg-green-700",
  
  // New outline variant
  outline: "border-2 border-gray-300 text-gray-700 hover:border-gray-400",
};

// Don't forget to update the TypeScript type
type ButtonVariant = "primary" | "secondary" | "ghost" | "destructive" | "success" | "outline";

Creating Compound Variants

For more complex styling that depends on multiple props:

function getButtonClasses(variant: string, size: string, isDisabled: boolean) {
  const base = "inline-flex items-center justify-center rounded-lg font-medium transition-colors";
  
  const variantClasses = variants[variant];
  const sizeClasses = sizes[size];
  const disabledClasses = isDisabled ? "opacity-50 cursor-not-allowed" : "";
  
  return cn(base, variantClasses, sizeClasses, disabledClasses);
}

Tips for Extending Components

1. Keep the base component generic

Instead of modifying the base Button, create specialized versions:

// components/ui/icon-button.tsx
import { Button, ButtonProps } from "./button";

export function IconButton({ icon, ...props }: ButtonProps & { icon: ReactNode }) {
  return (
    <Button size="icon" {...props}>
      {icon}
    </Button>
  );
}

2. Use composition over modification

Build complex components by combining simpler ones:

// A form field that combines Input with Label and error message
function FormField({ label, error, ...inputProps }) {
  return (
    <div className="space-y-1">
      <Label>{label}</Label>
      <Input error={!!error} {...inputProps} />
      {error && <p className="text-sm text-red-500">{error}</p>}
    </div>
  );
}

3. Allow className overrides

Always merge incoming className with internal classes using cn():

function Button({ className, variant, ...props }) {
  return (
    <button
      className={cn(
        baseStyles,
        variants[variant],
        className // This allows users to override styles
      )}
      {...props}
    />
  );
}

// Now users can customize individual instances
<Button className="rounded-full">Pill Button</Button>

4. Document your customizations

Add comments to your modified components explaining what was changed and why. This helps team members understand your design system decisions.

Dark Mode Support

All BeniUI components include dark mode variants using Tailwind's dark: prefix.

// Example: Button with dark mode support
const variants = {
  primary: "bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600",
  secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-100 dark:hover:bg-gray-700",
  ghost: "text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-800",
};

Enable dark mode in your Tailwind config:

// tailwind.config.js
module.exports = {
  darkMode: 'class', // or 'media' for system preference
  // ...
};

Start Building

Now that you know how to customize components, explore the component library and start building your UI.