Command Palette

Search for a command to run...

[ COMPONENTS ]
Tinte

Tinte

tinte components

Overview

Tinte is an AI-powered theme editor that generates beautiful, consistent themes for shadcn/ui using semantic color palettes in OKLCH color space. Live-edit your design tokens with real-time preview, intelligent color format preservation, and AI-assisted theme generation.

🏆 Winner of 3rd Place at Vercel × Midudev Hackathon

Tinte provides a floating ball UI that expands into a full theme editor, supporting HEX, RGB, HSL, OKLCH, and LCH color formats with automatic format preservation.

Components

Theme Editor

Live theme editor with AI generation, format preservation, and real-time preview.

tinte editor

Open in v0
Check the bottom right cornerArrow

Features: AI theme generation, OKLCH/HEX/RGB/HSL/LCH support, live preview, format preservation

import { TinteEditor } from "@elements/tinte";

export default function App() {
  return (
    <div>
      <YourApp />
      <TinteEditor />
    </div>
  );
}

Quick Start

1. Install

bunx shadcn@latest add @elements/tinte-editor

This installs:

  • TinteEditor - Main floating theme editor component
  • ColorInput - Color picker with format switching
  • TinteLogo - Tinte logo component
  • API Routes - Endpoints for reading/writing globals.css

2. Add to Layout

// app/layout.tsx
import { TinteEditor } from "@elements/tinte";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <TinteEditor />
      </body>
    </html>
  );
}

3. Start Editing

Click the floating purple ball in the bottom-right corner to open the theme editor.

Features

🎨 Real-time Color Editing

Edit any shadcn/ui design token with instant visual feedback. Changes apply immediately to your UI.

🌈 Color Format Preservation

Automatically preserves your original color format:

  • OKLCH → stays OKLCH
  • HEX → stays HEX
  • RGB → stays RGB
  • HSL → stays HSL
  • LCH → stays LCH

🎯 Format Switching

Click the format button next to any color input to cycle through formats:

HEX → RGB → HSL → OKLCH → LCH → HEX

🌓 Light/Dark Mode Toggle

Switch between light and dark mode to edit theme variables for each mode independently.

📦 Organized Token Groups

Tokens are organized into semantic groups:

  • Background & Text - Core surface colors
  • Cards & Surfaces - Muted and accent colors
  • Interactive Elements - Primary and secondary colors
  • Forms & States - Input, border, ring, destructive
  • Charts - Data visualization colors
  • Sidebar - Sidebar-specific tokens

💾 Save to globals.css

Save your changes directly to app/globals.css with one click.

🔄 Reload Theme

Reset to the current values in app/globals.css at any time.

Configuration

Conditional Rendering (Recommended)

Only show the theme editor in development:

// app/layout.tsx
import { TinteEditor } from "@elements/tinte";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        {process.env.NODE_ENV === "development" && <TinteEditor />} // [!code
        highlight]
      </body>
    </html>
  );
}

Color Input Component

Use the ColorInput component standalone:

import ColorInput from "@/components/color-input";

export default function CustomForm() {
  const [color, setColor] = useState("oklch(0.7 0.15 180)");

  return (
    <ColorInput
      value={color}
      onChange={setColor}
    />
  );
}

Features:

  • Color wheel picker
  • Text input with validation
  • Format toggle button
  • Click-outside to close

Client-Side Architecture

The theme editor works entirely in the browser without requiring server-side API routes:

  • Read Theme: Reads CSS variables directly from document.documentElement using getComputedStyle()
  • Write Theme: Applies theme changes by injecting a <style> element into the DOM
  • Live Preview: Changes are instantly visible across both light and dark modes
  • No Server Required: Perfect for static sites, v0, and serverless deployments

Token Reference

Background & Text

TokenDescription
--backgroundMain background color
--foregroundMain text color
--cardCard background
--card-foregroundCard text
--popoverPopover background
--popover-foregroundPopover text

Cards & Surfaces

TokenDescription
--mutedMuted background
--muted-foregroundMuted text
--accentAccent background
--accent-foregroundAccent text

Interactive Elements

TokenDescription
--primaryPrimary button background
--primary-foregroundPrimary button text
--secondarySecondary button background
--secondary-foregroundSecondary button text

Forms & States

TokenDescription
--destructiveDestructive action background
--destructive-foregroundDestructive action text
--inputInput border
--ringFocus ring
--borderBorder color

Charts

TokenDescription
--chart-1 through --chart-5Chart data colors

Sidebar

TokenDescription
--sidebar-backgroundSidebar background
--sidebar-foregroundSidebar text
--sidebar-primarySidebar primary background
--sidebar-primary-foregroundSidebar primary text
--sidebar-accentSidebar accent background
--sidebar-accent-foregroundSidebar accent text
--sidebar-borderSidebar border
--sidebar-ringSidebar focus ring

How It Works

  1. Read Theme - Reads CSS variables from DOM using getComputedStyle()
  2. Parse Variables - Extracts all --* CSS custom properties
  3. Live Updates - Changes apply to document.documentElement.style
  4. Save - Injects updated theme as <style> element in DOM

Color Format Details

OKLCH (Recommended)

--primary: oklch(0.7 0.15 270);

Benefits: Perceptually uniform, wide gamut, human-readable

HEX

--primary: #6366f1;

Benefits: Compact, widely supported, familiar

RGB

--primary: rgb(99, 102, 241);

Benefits: Direct browser support, alpha channel

HSL

--primary: hsl(239, 84%, 67%);

Benefits: Intuitive (hue, saturation, lightness)

LCH

--primary: lch(55% 75 270);

Benefits: Perceptually uniform like OKLCH

Best Practices

  1. Test Both Modes - Always verify light and dark mode
  2. Use OKLCH - For consistent color manipulation across modes
  3. Semantic Tokens - Edit tokens, not component colors directly
  4. Export Themes - Copy CSS from Raw CSS tab to save themes
  5. Browser DevTools - Use inspector to verify applied variables

Troubleshooting

Colors not updating: Hard refresh the page (Cmd/Ctrl + Shift + R)

Format not preserved: Ensure color value is valid CSS

Floating ball hidden: Check z-index conflicts (ball uses z-50)

Theme resets on reload: Changes are DOM-only, copy CSS to persist

Production Safe

No Security Concerns: Works entirely in the browser without server access. Safe for production, v0, and static sites.

Keyboard Shortcuts

KeyAction
EscClose theme editor
TabNavigate between inputs
EnterApply color in input field

Dependencies

  • culori - Color conversion and manipulation
  • @uiw/react-color - Color picker wheel component
  • @uiw/color-convert - Color format conversions
  • lucide-react - Icons (X, RotateCw, Save)
  • sonner - Toast notifications

Resources