akashtdev/halo-color-picker

A beautiful, animated radial color picker for React.

TypeScript

2

2 commits

updated Aug 23, 2026

See the code

See what people are saying (2)

SourceMessageScoreDate

I built a tactile, spring-animated radial color picker for React (r/SideProject)

I couldn't find a color picker that actually felt good to use, most of the ones out there are pretty clunky. So, I built a radial, spring-animated one myself and decided to open-source it. It’s made for React, has full TypeScript support, and keeps things minimal. **GitHub:**…

0

Sep 19, 2026

I built a tactile, spring-animated radial color picker for React (r/reactjs)

I couldn't find a color picker that actually felt good to use, most of the ones out there are pretty clunky. So, I built a radial, spring-animated one myself and decided to open-source it. It’s made for React, has full TypeScript support, and keeps things minimal. GitHub:…

0

Sep 19, 2026

README

Halo Color Picker

NPM Version Bundle Size License: MIT

A tiny, beautiful, animated radial color picker for React. Tap the core and watch a beautifully animated disc spring open into a radiant color wheel.

Extracted from stele.so
I couldn't find a color picker with the exact radial physics and premium feel I needed for my spatial UI canvas. So, I reverse-engineered the best one I'd ever seen and open-sourced it for the community.

🎨 Features at a glance

  • Fluid Animations: Beautiful fisheye magnification and spring physics.
  • Zero Dependencies: Exceptionally lightweight.
  • Universal Compatibility: Flawlessly supports all React versions >=16.8.0
  • Beautiful by Default: Auto-arranges swatches into a geometric flower pattern.
  • Fully Accessible: Keyboard navigation, focus trapping, and smooth mobile touch interactions out of the box.
  • Strictly Typed: Built with TypeScript for a flawless developer experience.

Getting Started

Install the package using your favorite package manager:

bun add halo-color-picker
# or
npm install halo-color-picker
# or
yarn add halo-color-picker
# or
pnpm add halo-color-picker

Quick Integration

Integrating Halo into your React application takes only a few lines of code.

import { useState } from 'react';
import { HaloColorPicker, type HaloColor } from 'halo-color-picker';
import 'halo-color-picker/styles.css'; // Import the minimal stylesheet once

export default function App() {
  const [color, setColor] = useState<HaloColor>();

  return (
    <HaloColorPicker
      defaultValue="#3b82f6"
      onChange={setColor}
    />
  );
}

Usage Guide

Halo Color Picker is designed to be highly flexible while keeping the API surface minimal.

Controlled State

If you need to strictly control the color or the open/closed state of the picker, use the value and open props.

const [hexString, setHexString] = useState('#22c55e');
const [isOpen, setIsOpen] = useState(false);

<HaloColorPicker
  value={hexString}
  onChange={(color) => setHexString(color.hex)}
  open={isOpen}
  onOpenChange={setIsOpen}
/>

Custom Color Swatches

You can provide your own curated palette instead of the default spectrum. Halo intelligently accepts Hex, RGB(A), HSL(A) strings, or raw color objects.

<HaloColorPicker
  swatches={[
    '#0ea5e9',
    '#6366f1',
    '#ec4899',
    { h: 140, s: 70, l: 50 } // Objects are supported too!
  ]}
/>

AI Assistance

Want to use an AI assistant to build with this library? We provide a standard llms.txt file optimized for LLMs.

Just feed this URL to Claude, or Cursor to give it instant, perfect context on how to use halo-color-picker:

https://akashtdev.github.io/halo-color-picker/llms.txt

API Reference

Component Props

Configure the look and feel of your color picker using these properties.

PropertyTypeDefaultDescription
valueColorInputThe controlled color value.
defaultValueColorInput'#3b82f6'The initial color when uncontrolled.
swatchesColorInput[](Default Wheel)Array of colors to display in the radial disc.
onChange(color: HaloColor) => voidCallback fired when a color is selected.
openbooleanControlled visibility state of the disc.
defaultOpenbooleanfalseInitial visibility state when uncontrolled.
onOpenChange(open: boolean) => voidCallback fired when the disc opens or closes.
trigger'click' | 'hover''click'Interaction required to open the disc.
closeOnSelectbooleantrueAutomatically collapse the disc after selection.
disabledbooleanfalseDisables interaction and dims the trigger.
coreSizenumber36Diameter of the center trigger button (in px).
swatchSizenumber30Diameter of each individual swatch (in px).
durationnumber260Animation duration for opening/closing (in ms).
glowbooleantrueEnables a soft colored glow under the hovered swatch.
magnify'none' | 'focus' | 'dock''focus'Hover effect style. 'focus' enlarges the single hovered swatch, 'dock' swells the surrounding area (like macOS dock), 'none' disables it.
placement'top' | 'bottom' | 'auto''auto'Origin point where the disc expands relative to the trigger.
morphbooleanfalseExpands the trigger into the disc center.
liftOnHoverbooleanfalseBrings the hovered swatch to the top layer.
portalbooleantrueRenders the popover in a React Portal (document.body) so it's never cut off by parent containers.
gapnumber0Spacing between swatches. 0 allows slight overlap.
labelstring'Choose a color'ARIA label for screen readers.
classNamestringExtra CSS class applied to the root element.
styleCSSPropertiesInline style applied to the root element.

The HaloColor Object

When a selection is made, the onChange callback provides a comprehensive HaloColor object, giving you the exact format you need instantly without external converters.

interface HaloColor {
  hex: string;   // e.g. "#3b82f6"
  rgb: string;   // e.g. "rgb(59, 130, 246)"
  rgba: string;  // e.g. "rgba(59, 130, 246, 1)"
  hsl: string;   // e.g. "hsl(217, 91%, 60%)"
  hsla: string;  // e.g. "hsla(217, 91%, 60%, 1)"
  r: number; g: number; b: number; a: number; // Channels (a is 0-1)
  h: number; s: number; l: number;
}

License

MIT © Akash T

Contributors

akashtdev

2 commits

akashtdev/halo-color-picker

A beautiful, animated radial color picker for React.

TypeScript

2

2 commits

updated Aug 23, 2026

See the code

See what people are saying (2)

SourceMessageScoreDate

I built a tactile, spring-animated radial color picker for React (r/SideProject)

I couldn't find a color picker that actually felt good to use, most of the ones out there are pretty clunky. So, I built a radial, spring-animated one myself and decided to open-source it. It’s made for React, has full TypeScript support, and keeps things minimal. **GitHub:**…

0

Sep 19, 2026

I built a tactile, spring-animated radial color picker for React (r/reactjs)

I couldn't find a color picker that actually felt good to use, most of the ones out there are pretty clunky. So, I built a radial, spring-animated one myself and decided to open-source it. It’s made for React, has full TypeScript support, and keeps things minimal. GitHub:…

0

Sep 19, 2026

README

Halo Color Picker

NPM Version Bundle Size License: MIT

A tiny, beautiful, animated radial color picker for React. Tap the core and watch a beautifully animated disc spring open into a radiant color wheel.

Extracted from stele.so
I couldn't find a color picker with the exact radial physics and premium feel I needed for my spatial UI canvas. So, I reverse-engineered the best one I'd ever seen and open-sourced it for the community.

🎨 Features at a glance

  • Fluid Animations: Beautiful fisheye magnification and spring physics.
  • Zero Dependencies: Exceptionally lightweight.
  • Universal Compatibility: Flawlessly supports all React versions >=16.8.0
  • Beautiful by Default: Auto-arranges swatches into a geometric flower pattern.
  • Fully Accessible: Keyboard navigation, focus trapping, and smooth mobile touch interactions out of the box.
  • Strictly Typed: Built with TypeScript for a flawless developer experience.

Getting Started

Install the package using your favorite package manager:

bun add halo-color-picker
# or
npm install halo-color-picker
# or
yarn add halo-color-picker
# or
pnpm add halo-color-picker

Quick Integration

Integrating Halo into your React application takes only a few lines of code.

import { useState } from 'react';
import { HaloColorPicker, type HaloColor } from 'halo-color-picker';
import 'halo-color-picker/styles.css'; // Import the minimal stylesheet once

export default function App() {
  const [color, setColor] = useState<HaloColor>();

  return (
    <HaloColorPicker
      defaultValue="#3b82f6"
      onChange={setColor}
    />
  );
}

Usage Guide

Halo Color Picker is designed to be highly flexible while keeping the API surface minimal.

Controlled State

If you need to strictly control the color or the open/closed state of the picker, use the value and open props.

const [hexString, setHexString] = useState('#22c55e');
const [isOpen, setIsOpen] = useState(false);

<HaloColorPicker
  value={hexString}
  onChange={(color) => setHexString(color.hex)}
  open={isOpen}
  onOpenChange={setIsOpen}
/>

Custom Color Swatches

You can provide your own curated palette instead of the default spectrum. Halo intelligently accepts Hex, RGB(A), HSL(A) strings, or raw color objects.

<HaloColorPicker
  swatches={[
    '#0ea5e9',
    '#6366f1',
    '#ec4899',
    { h: 140, s: 70, l: 50 } // Objects are supported too!
  ]}
/>

AI Assistance

Want to use an AI assistant to build with this library? We provide a standard llms.txt file optimized for LLMs.

Just feed this URL to Claude, or Cursor to give it instant, perfect context on how to use halo-color-picker:

https://akashtdev.github.io/halo-color-picker/llms.txt

API Reference

Component Props

Configure the look and feel of your color picker using these properties.

PropertyTypeDefaultDescription
valueColorInputThe controlled color value.
defaultValueColorInput'#3b82f6'The initial color when uncontrolled.
swatchesColorInput[](Default Wheel)Array of colors to display in the radial disc.
onChange(color: HaloColor) => voidCallback fired when a color is selected.
openbooleanControlled visibility state of the disc.
defaultOpenbooleanfalseInitial visibility state when uncontrolled.
onOpenChange(open: boolean) => voidCallback fired when the disc opens or closes.
trigger'click' | 'hover''click'Interaction required to open the disc.
closeOnSelectbooleantrueAutomatically collapse the disc after selection.
disabledbooleanfalseDisables interaction and dims the trigger.
coreSizenumber36Diameter of the center trigger button (in px).
swatchSizenumber30Diameter of each individual swatch (in px).
durationnumber260Animation duration for opening/closing (in ms).
glowbooleantrueEnables a soft colored glow under the hovered swatch.
magnify'none' | 'focus' | 'dock''focus'Hover effect style. 'focus' enlarges the single hovered swatch, 'dock' swells the surrounding area (like macOS dock), 'none' disables it.
placement'top' | 'bottom' | 'auto''auto'Origin point where the disc expands relative to the trigger.
morphbooleanfalseExpands the trigger into the disc center.
liftOnHoverbooleanfalseBrings the hovered swatch to the top layer.
portalbooleantrueRenders the popover in a React Portal (document.body) so it's never cut off by parent containers.
gapnumber0Spacing between swatches. 0 allows slight overlap.
labelstring'Choose a color'ARIA label for screen readers.
classNamestringExtra CSS class applied to the root element.
styleCSSPropertiesInline style applied to the root element.

The HaloColor Object

When a selection is made, the onChange callback provides a comprehensive HaloColor object, giving you the exact format you need instantly without external converters.

interface HaloColor {
  hex: string;   // e.g. "#3b82f6"
  rgb: string;   // e.g. "rgb(59, 130, 246)"
  rgba: string;  // e.g. "rgba(59, 130, 246, 1)"
  hsl: string;   // e.g. "hsl(217, 91%, 60%)"
  hsla: string;  // e.g. "hsla(217, 91%, 60%, 1)"
  r: number; g: number; b: number; a: number; // Channels (a is 0-1)
  h: number; s: number; l: number;
}

License

MIT © Akash T

Contributors

akashtdev

2 commits

Languages

TypeScript

80.4%

CSS

18.3%

HTML

1.3%