Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Inputs

Color Picker

Inputs

Color Picker React component for Tailwind CSS v4

CheckboxCombobox
Live props
Field
label
description
error
required
invalid
disabled
readOnly
Content
defaultValue
placeholder
name
sheetTitle
Behavior
format
alpha
responsive
Appearance
showInputs
showFormatSwitch
showEyeDropper
trigger
size
variant
radius
Layout
inline
side
align
State
defaultOpen
Code
import { ColorPicker } from "@/components/ui/color-picker"

<ColorPicker />
  1. Home
  2. Components
  3. Inputs
  4. Color Picker
Pro

Color Picker React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React color picker with a saturation and brightness square, hue and opacity sliders, HEX / RGB / HSL inputs, swatches and an eyedropper.

Click the field (or the round swatch button) to open a panel under it: drag in the square to set saturation (left to right) and brightness (bottom to top), drag the hue bar, and with alpha the opacity bar; the thumb grows a little while you drag and the value updates live, once per frame. Below them the HEX / RGB / HSL switch changes which fields show (the output keeps its format); typed values apply on Enter or when the field loses focus, text that is not a color turns the field red and goes back to the last good color, ArrowUp / ArrowDown in a number field step by 1 (Shift by 10), and a 3-digit hex expands ("F60" is #FF6600). Tap a preset swatch to use it: a ring slides to it. In Chrome and Edge a pipette button picks any pixel on screen. Keyboard: Enter, Space or ArrowDown on the trigger opens the panel with focus in the square; in the square ArrowLeft / ArrowRight change saturation and ArrowUp / ArrowDown brightness by 1% (Shift 10%), PageUp / PageDown step brightness by 10%, Home / End go to no or full saturation; the hue and opacity bars take the arrow keys, Home and End; the swatches are a radio group moved with the arrow keys; Escape closes the panel and returns focus to the trigger. Clicking the label focuses the trigger. On a phone the panel opens in a bottom sheet, full width, with a taller square, 28px thumbs and larger swatches; the changes are a draft until Done, and dragging the sheet away keeps the old color. Disabled and read-only pickers never open. ColorPickerPanel (the panel alone, with the same value, format, alpha, swatches and labels props) is exported for your own popovers and pages, with the helpers parseColor (hex, rgb(), hsl() and the 16 basic CSS names, no canvas), formatColor, hsvaToRgba, rgbaToHsva and COLOR_PICKER_SWATCHES.

Color Picker is a Pro React component in the React input components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add color-picker, together with Button, Drawer, Field, Segmented Control, useControllableState and 3 more and the npm packages @radix-ui/react-popover, @radix-ui/react-slider, motion and lucide-react.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add color-picker

Color Picker is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import ColorPicker from @/components/ui/color-picker.

import { useState } from "react"
import { ColorPicker } from "@/components/ui/color-picker"

export function StoreColor() {
  const [color, setColor] = useState("#FC4C01")
  return (
    <ColorPicker
      label="Primary color"
      description="The store's buttons and links use this color."
      value={color}
      onValueChange={setColor}
      onValueCommit={(saved) => console.log("saved", saved)}
      name="primary_color"
      placeholder="Choose a brand color"
      sheetTitle="Brand color"
      labels={{ swatches: "Brand presets", done: "Apply" }}
    />
  )
}

Props

  • labeldefault ""
    ReactNode

    The field label. The trigger reads it with the value ("Primary color, #FC4C01"); plain text also titles the phone sheet.

  • descriptiondefault ""
    ReactNode

    Helper text under the field, linked with aria-describedby.

  • errordefault ""
    ReactNode

    Replaces the description with an animated error and marks the field invalid.

  • requireddefault false
    boolean

    The red mark after the label and aria-required on the trigger.

  • invaliddefault false
    boolean

    The invalid look and aria-invalid without a message.

  • disableddefault false
    boolean

    Dims the field and never opens the panel; the hidden input is not submitted.

  • readOnlydefault false
    boolean

    The color stays visible and the trigger focusable, but the panel never opens (inline: nothing can change).

  • defaultValuedefault ""
    string

    The starting color while uncontrolled, any CSS color we can read ("#FC4C01", "rgb(252 76 1)", "hsl(18 99% 50%)", "red"). A form reset returns to it.

  • value
    string

    The color, controlled, as a CSS color in format ("" is empty). A value in another format is shown as given and re-emitted in format on the next change.

  • onValueChange
    (value: string) => void

    Called with the new color in format: live while dragging (at most once per frame), after a typed value, a swatch or the eyedropper. On phones only when Done is pressed.

  • onValueCommit
    (value: string) => void

    Called when a change is final: pointer up after a drag, Enter or blur in a field, a swatch, an eyedropper pick, a key in the square, the sheet's Done. Save here.

  • formatdefault "hex"
    "hex" | "rgb" | "hsl"

    The output: "#FC4C01", "rgb(252, 76, 1)" or "hsl(18, 99%, 50%)". Also the fields the panel shows first; the panel's switch only changes the fields. The exported parseColor(text) and formatColor(hsva, format, alpha) do the same conversions for your own code.

  • alphadefault false
    boolean

    An opacity slider and an opacity field. Hex becomes #RRGGBBAA below 100% opacity; rgb and hsl always become rgba() / hsla(). Off, colors are always opaque.

  • swatchesdefault "["#0A0A0A", "#525252", "#A3A3A3", "#FFFFFF", "#EF4444", "#F97316", "#F59E0B", "#EAB308", "#84CC16", "#22C55E", "#14B8A6", "#0EA5E9", "#3B82F6", "#6366F1", "#8B5CF6", "#EC4899"]"
    string[]

    Preset colors in a grid of 8 per row. Defaults to the exported COLOR_PICKER_SWATCHES: 16 colors (neutrals, red, orange, amber, yellow, lime, green, teal, sky, blue, indigo, violet, pink), easy to extend. [] hides the row.

  • showInputsdefault true
    boolean

    The format switch, the text fields and the eyedropper under the sliders.

  • showFormatSwitchdefault true
    boolean

    The HEX / RGB / HSL segmented control above the fields.

  • showEyeDropperdefault true
    boolean

    The pipette button. It only renders where the browser has window.EyeDropper (Chrome and Edge on desktop), so it never appears broken.

  • inlinedefault false
    boolean

    Renders the panel in place (settings pages): no trigger, no popover, no sheet. Changes apply at once.

  • triggerdefault "field"
    "field" | "swatch"

    A field box with a color chip and the value, or a round swatch button sized like an icon button (toolbars, compact forms).

  • placeholderdefault "Pick a color"
    string

    The trigger's text while empty (with a checkerboard chip).

  • labels
    Partial<{ area; saturation; brightness; hue; alpha; hex; red; green; blue; hueInput; lightness; format; eyeDropper; swatches; done; trigger: string }>

    Every spoken and visible string, merged over English defaults ("Saturation and brightness", "Hue", "Opacity", "Done"...). trigger names the trigger when there is no label ("Color, #FC4C01").

  • sizedefault "md"
    "sm" | "md" | "lg"

    Trigger heights of 32, 40 and 48px (md is 44px on touch screens); the swatch button is square at the same sizes.

  • variantdefault "soft"
    "soft" | "outline" | "underline" | "ghost"

    The field box look (trigger field): a tinted fill, a border, a bottom line, or nothing until hover.

  • radiusdefault "md"
    "none" | "sm" | "md" | "lg" | "full"

    Corner radius of the field, scaled per size like the button; full also makes the color chip round. Ignored by underline.

  • namedefault ""
    string

    Renders a hidden input with this name and the color text, for native forms.

  • defaultOpendefault false
    boolean

    Starts with the panel (or the sheet) open. Pass open and onOpenChange to control it.

  • open
    boolean

    Whether the panel or sheet is open, controlled. It never opens while disabled or readOnly.

  • onOpenChange
    (open: boolean) => void

    Called when the panel or sheet opens or closes.

  • responsivedefault true
    boolean

    Below 768px the panel opens in a bottom sheet with a Done button that commits the draft. Off, phones get the popover too.

  • sheetTitledefault "Pick a color"
    string

    The phone sheet's title (and the popover's accessible name) when the label is not plain text or missing.

  • sidedefault "bottom"
    "top" | "right" | "bottom" | "left"

    Where the panel opens; it flips when there is no room.

  • aligndefault "start"
    "start" | "center" | "end"

    How the panel lines up with the trigger.

  • container
    HTMLElement | null

    Portal target of the panel and the sheet; defaults to document.body.

  • fieldProps
    Partial<FieldProps>

    Anything else for the Field wrapper: optional, labelAction, orientation, labelWidth, hideLabel.

  • id
    string

    The trigger's id (the panel's with inline); generated when left out.

  • classNames
    Partial<Record<"field" | "label" | "description" | "error" | "counter" | "trigger" | "swatch" | "value" | "chevron" | "content" | "panel" | "area" | "thumb" | "hue" | "alpha" | "preview" | "inputs" | "format" | "input" | "eyedropper" | "swatches" | "swatchOption" | "footer", string>>

    Extra classes for the inner parts. content is the popover or the sheet, thumb the square's thumb, input every text field in the panel.

  • className
    string

    Extra classes for the outermost element: the Field when there is a label or message, else the trigger (or the inline panel).

  • ref
    Ref<HTMLButtonElement> (a useRef object or an (el) => void callback)

    The trigger button. Other props (onBlur, autoFocus, aria-*, data-*) land on it too.

Parts

  • ColorPickerPanel

    component

    The picker panel on its own (square, hue and opacity bars, fields, format switch, swatches, eyedropper) for your own popover, sheet or settings page. Takes value / defaultValue, onValueChange, onValueCommit, format, alpha, swatches, showInputs, showFormatSwitch, showEyeDropper, labels, disabled, readOnly, autoFocus and classNames, the same as ColorPicker.

  • parseColor

    function

    Reads hex (3, 4, 6 or 8 digits), rgb() / rgba(), hsl() / hsla() and the 16 basic CSS color names into an Hsva, without a canvas. Returns null for text that is not a color. Signature: (text: string | null | undefined) => Hsva | null.

  • formatColor

    function

    Writes an Hsva as "#FC4C01", "rgb(252, 76, 1)" or "hsl(18, 99%, 50%)", with the alpha channel when alpha is true. Signature: (hsva: Hsva, format?: ColorFormat, alpha?: boolean) => string.

  • hsvaToRgba

    function

    Converts hue / saturation / value / alpha to red / green / blue / alpha (0-255 channels). Signature: (hsva: Hsva) => Rgba.

  • rgbaToHsva

    function

    Converts red / green / blue / alpha (0-255 channels) to hue / saturation / value / alpha. Signature: (rgba: Rgba) => Hsva.

  • COLOR_PICKER_SWATCHES

    constant

    The 16 default preset colors as hex strings: neutrals, then red through pink. Spread it to add your brand colors.

  • ColorPickerPanelProps

    type

    Props of ColorPickerPanel.

  • ColorFormat

    type

    "hex" | "rgb" | "hsl", the output format and the fields the panel shows first.

  • Hsva

    type

    { h, s, v, a }: hue 0-360, saturation and value 0-100, alpha 0-1. The internal color model.

Examples

Inline panel

inline renders the panel in a settings card; changes apply at once.

Opacity

alpha adds the opacity slider and field; format rgb emits rgba().

Swatch triggers

trigger="swatch" round buttons in an editor toolbar.

Formats

One color emitted as hex, rgb and hsl, converted with parseColor / formatColor.

Eyedropper

The pipette picks any pixel on screen where the browser supports it.

Brand palette

Custom swatches only, without the fields.

Sizes and states

sm / md / lg, empty, error and disabled.

Dependencies

@radix-ui/react-popover@radix-ui/react-slidermotionlucide-reactbuttondrawerfieldsegmented-controluse-controllable-stateuse-media-querymotionui-config

Files

  • components/ui/color-picker.tsx

FAQ

Is the React Color Picker component free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Color Picker?

Run npx wingo-ui@latest add color-picker. It also adds the Wingo UI items it builds on (Button, Drawer, Field, Segmented Control, useControllableState and 3 more) and the npm packages @radix-ui/react-popover, @radix-ui/react-slider, motion and lucide-react. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/color-picker.

How does Color Picker behave on phones?

Below 768px the panel opens in a bottom sheet with a Done button that commits the draft. Off, phones get the popover too. The responsive prop controls this and is on by default.

See also

FieldSliderSegmented ControlDrawerInput

Used in

DOCX Editor

More React input components

CalendarSwitchMasked InputDate Range PickerCheckboxCombobox
All 40 React input components

Articles using this component

  • React Color Picker: HEX, RGB, HSL, Eyedropper and OKLCH

    Component guides · Oct 16, 2026 · 9 min read

PreviousCheckboxNext Combobox

Customize your store

Mara Studio · how the storefront looks

AMMara Studio

Oslo sofa, 3 seats

$990 · free delivery

value: "#FC4C01" · onValueCommit: "#FC4C01"

format hex · fields, HEX/RGB/HSL, eyedropper · field · phone sheet “Pick a color”