ColorPicker
neon-ui/color-pickerFreeComponent
Swatch-and-hex trigger opening an HSV field, hue rail, hex input, and preset swatches.
Install it
npx shadcn@latest add https://ui.neon.com/r/color-picker.jsonSource
1"use client";23/* oxlint-disable jsx-a11y/prefer-tag-over-role -- the 2D saturation/brightness plane and styled hue rail have no native input equivalent; both implement the full slider keyboard contract */45import { Popover } from "@base-ui/react/popover";6import {7 ColorPickerIcon,8 Copy01Icon,9 Tick02Icon,10} from "@hugeicons/core-free-icons";11import { HugeiconsIcon } from "@hugeicons/react";12import type { CSSProperties, KeyboardEvent, PointerEvent } from "react";13import { useState } from "react";1415import { cn } from "@/lib/utils";1617export interface ColorPickerProps {18 /** Controlled hex value, e.g. "#00e599". */19 value?: string;20 /** Uncontrolled initial hex value. */21 defaultValue?: string;22 onValueChange?: (hex: string) => void;23 /** Preset swatches rendered under the field. */24 swatches?: string[];25 disabled?: boolean;26 className?: string;27 /** Accessible label for the trigger. */28 label?: string;29}3031/* ─────────────────────────────────────────────────────────32 * COLOR MATH — HSV internally, hex at the edges. Hue is33 * kept in state (not re-derived) so the rail doesn't snap34 * to 0 when saturation or value hit their extremes.35 * ───────────────────────────────────────────────────────── */36export interface Hsv {37 h: number;38 s: number;39 v: number;40}4142const HEX_RE = /^#?(?<hex>[0-9a-f]{6})$/iu;4344const clamp01 = (x: number) => Math.min(1, Math.max(0, x));4546export const hexToHsv = (hex: string): Hsv | null => {47 const match = HEX_RE.exec(hex.trim());4849 if (!match?.groups?.hex) {50 return null;51 }5253 const int = Number.parseInt(match.groups.hex, 16);54 const r = Math.floor(int / 65_536) / 255;55 const g = Math.floor((int % 65_536) / 256) / 255;56 const b = (int % 256) / 255;57 const max = Math.max(r, g, b);58 const min = Math.min(r, g, b);59 const delta = max - min;60 let h = 0;6162 if (delta > 0) {63 if (max === r) {64 h = 60 * (((g - b) / delta) % 6);65 } else if (max === g) {66 h = 60 * ((b - r) / delta + 2);67 } else {68 h = 60 * ((r - g) / delta + 4);69 }70 }7172 return {73 h: (h + 360) % 360,74 s: max === 0 ? 0 : delta / max,75 v: max,76 };77};7879export const hsvToHex = ({ h, s, v }: Hsv): string => {80 const f = (n: number) => {81 const k = (n + h / 60) % 6;82// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from neon-ui
All 77 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ActivityFeedactivity-feed | neon-ui | Components | Free | 2 deps | |
| AgentChatagent-chat | neon-ui | Components | Free | 6 deps | |
| AnimatedWashanimated-wash | neon-ui | Components | Free | no deps · 2 files | |
| ApiKeyListapi-key-list | neon-ui | Components | Free | 2 deps | |
| AppCardapp-card | neon-ui | Components | Free | 2 deps | |
| AppCreatorapp-creator | neon-ui | Components | Free | 2 deps | |
| AuthFormauth-form | neon-ui | Components | Free | no deps | |
| AutoscaleChartautoscale-chart | neon-ui | Components | Free | 1 dep |
