Gradient picker components

Powerful and customizable React gradient picker components built for modern applications and websites. These gradient pickers are built using React Aria and styled with Tailwind CSS.

Get the code

Stops

Saved

Installation

You can add this gradient picker component using our CLI or manually:

npx untitledui@latest add gradient-picker

Gradient picker examples

Below are examples and variations of this gradient picker component:

Get the code

Stops

Saved

API reference

Import the parts and assemble them:

import { GradientPicker } from "@/components/application/gradient-picker/gradient-picker";
 
<GradientPicker.Provider>
    <GradientPicker />
</GradientPicker.Provider>
 
<GradientPicker.Provider>
    <GradientPicker.Area />
    <GradientPicker.TypeSelect />
    <GradientPicker.Reverse />
    <GradientPicker.Slider />
    <GradientPicker.StopList />
</GradientPicker.Provider>

GradientPicker

All-in-one gradient picker layout: area, type select, slider, and stop list.

Renders a <div> element.

GradientPicker.Area

Interactive 2D gradient area with draggable stop thumbs.The gradient is defined by an explicit 2D line (state.gradientLine) extended to the area edges. Stop positions (0–100%) map to points along this line via lerp.Endpoint drag — moves the thumb freely in 2D. The line through both endpoints is extended to the area edges via extendLineToEdges, and both endpoint positions are re-projected onto it. The other endpoint's 2D position is snapshotted on pointerdown so it never drifts. Inner stop positions stay unchanged.Inner stop drag — slides the stop along the current gradient line by projecting the pointer onto it.

Renders a <div> element.

GradientPicker.Provider

Gradient color state provider.

Import GradientProvider from @/components/application/gradient-picker/gradient-picker-context. Renders GradientColorPickerProvider.

GradientPicker.Provider props
PropTypeDefaultDescription
children* (required)ReactNode—The gradient picker parts that read and update the shared gradient state.
defaultStopsGradientStop[]—Initial gradient stops.
defaultType
"linear""radial""angular""diamond"
"linear"Initial gradient type.
defaultAnglenumber135Initial gradient angle in degrees.
onStopsChange((stops: GradientStop[]) => void)—Called when gradient stops change.
onTypeChange((type: GradientType) => void)—Called when the gradient type changes.
onAngleChange((angle: number) => void)—Called when the gradient angle changes.

GradientPicker.Reverse

Button to reverse the gradient by mirroring all stop colors.

Renders ButtonUtility.

GradientPicker.Slider

Horizontal gradient slider. Stops are draggable thumbs along the track. Clicking an empty area of the track adds a new stop with an interpolated color.

Renders a <div> element.

GradientPicker.StopList

Editable list of gradient stops with add/remove controls.

Renders a <div> element.

GradientPicker.TypeSelect

Dropdown to switch between gradient types (linear, radial, angular, diamond).

Renders Button.

FAQs

Please refer to our frequently asked questions page for more.

The type select offers "linear" (the default), "radial", "angular" and "diamond". Set the starting type with defaultType on GradientPicker.Provider and listen for changes with onTypeChange. Angular and diamond gradients are both output as a CSS conic-gradient().

Click an empty spot on the gradient slider to add a stop there with an interpolated color, or click Add in the stop list to insert one between the last two stops. Remove a stop with its minus button in the stop list, or focus its thumb and press Delete or Backspace; the picker always keeps at least two stops. Arrow keys move a focused stop by 1%.

Users change the angle by dragging the endpoints on GradientPicker.Area. defaultAngle on GradientPicker.Provider only sets the starting angle (default 135), and there is no controlled angle prop. Listen with onAngleChange, or set it from a child component with actions.setAngle() from the useGradientColorPicker() hook.

Yes. Inside GradientPicker.Provider, arrange GradientPicker.Area, GradientPicker.Slider, GradientPicker.StopList, GradientPicker.TypeSelect and GradientPicker.Reverse however you like. The provider is required for these parts and for the all-in-one GradientPicker, because useGradientColorPicker() throws outside it.

Inside the provider, read state from useGradientColorPicker() and pass it to toGradientCSSFromLine(state.gradientStops, state.gradientType, state.gradientLine.start, state.gradientLine.end) from gradient-picker-utils.ts. The area preview uses the same function, so the string matches what users see. toGradientCSS(stops, type, angle) is also exported, but it assumes the gradient line spans the whole area, so it can differ once the endpoints have been dragged.

Parse the CSS string with parseGradientCSS() from gradient-picker-utils.ts, then call actions.setGradientStops(parsed.stops) and actions.setAngle(parsed.angle) from useGradientColorPicker(), as the example does. It reads linear-gradient(), radial-gradient() and conic-gradient() strings with hex or rgb()/rgba() stops, and returns null if it finds fewer than two stops.