npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lp-labs/react-color-picker

v0.1.0

Published

React color picker with dependency-free HEX, RGB and HSL conversions.

Readme

@lp-labs/react-color-picker

Package version: 0.1.0.

An interactive React color picker with HEX, RGB, HSL, alpha, a native visual color input and selectable palettes. Pure conversion helpers work without a DOM. React 18.2 or 19 is the only peer; no runtime dependency is bundled. ESM, CommonJS and TypeScript declarations are included.

Install and use

npm install @lp-labs/react-color-picker react
import { useState } from "react";
import { ColorPicker, hexToRgb, type RGBA } from "@lp-labs/react-color-picker";
import "@lp-labs/react-color-picker/style.css";

export function ForegroundPicker() {
  const [color, setColor] = useState<RGBA>(() => hexToRgb("#2563ebcc"));
  return (
    <ColorPicker
      value={color}
      onChange={setColor}
      palette={["#2563eb", "#ec4899", "#ffffff00", "hsl(120, 80%, 40%)"]}
    />
  );
}

For uncontrolled use, render <ColorPicker /> or pass defaultValue. Its default is { r: 99, g: 102, b: 241, a: 1 } (#6366f1ff). defaultValue is read on mount only. Do not switch controlled/uncontrolled mode within a mount. In controlled mode callbacks propose a value; the preview and numeric controls change only after the parent supplies it. Text drafts are local and may temporarily differ from that value.

Component API

ColorPicker(props: ColorPickerProps) is a named export.

| Prop | Type | Default / behavior | | --- | --- | --- | | value | RGBA | Omit for internal state | | defaultValue | RGBA | Default above, used once | | onChange | (color: RGBA) => void | Independent copy on valid edit requests; not called on mount | | palette | readonly string[] | ["#ef4444", "#22c55e", "#3b82f6", "#ffffff", "#000000"]; [] hides swatches | | disabled | boolean | false; disables editing | | label | string | "Color picker" | | className | string | ""; appended to root | | style | React.CSSProperties | Optional root styles |

interface RGBA {
  r: number; // 0..255, fractional values allowed
  g: number; // 0..255
  b: number; // 0..255
  a: number; // 0..1
}
interface HSLA {
  h: number; // 0..360 degrees
  s: number; // 0..100 percent
  l: number; // 0..100 percent
  a: number; // 0..1
}

Every channel must be finite. Values are validated, not silently clamped; conversion results are bounded against floating-point rounding error. HSL conversion preserves fractional RGB precision. Hue 360 is equivalent to 0. For achromatic colors, rgbToHsl returns hue 0 and saturation 0.

The text field accepts HEX, comma-separated RGB(A) and HSL(A) and commits on blur or Enter. Escape restores the current canonical HEX value. Invalid drafts show an associated error and do not emit. RGB and HSL number inputs apply valid in-range edits immediately; invalid/empty numeric edits are ignored. RGB UI steps are 1 and HSL steps are 0.1; shown numbers are rounded to two decimals, without rounding the stored model. Alpha uses a 0.01-step range input. The native visual input edits RGB while retaining alpha. Selecting a palette entry replaces all four channels, including that entry's alpha.

Pure helpers and types

All exports are named. Helpers do not mutate inputs.

| Export | Signature / behavior | | --- | --- | | validateRGBA | (value: RGBA) => void; validates all four channels | | validateHSLA | (value: HSLA) => void; validates all four channels | | hexToRgb | (hex: string) => RGBA; strict HEX with leading # | | rgbToHex | (value: RGBA, includeAlpha?: boolean) => string; lowercase HEX; includeAlpha defaults to true | | rgbToHsl | (value: RGBA) => HSLA | | hslToRgb | (value: HSLA) => RGBA | | parseColor | (text: string) => RGBA; trims outer whitespace | | colorToCss | (value: RGBA) => string; rgba(r, g, b, a) |

RGBA, HSLA and ColorPickerProps are exported types. HEX forms are #RGB, #RGBA, #RRGGBB, #RRGGBBAA, case-insensitive. hexToRgb itself does not trim whitespace; parseColor does. RGB(A) channels use absolute numeric values, not percentages. HSL(A) uses degrees without a unit suffix and percentage saturation/lightness:

import {
  parseColor, rgbToHex, rgbToHsl, colorToCss,
} from "@lp-labs/react-color-picker";

const rgba = parseColor("hsla(210, 100%, 50%, 0.5)");
rgbToHex(rgba);        // "#0080ff80"
rgbToHex(rgba, false); // "#0080ff"
rgbToHsl(rgba);        // approximately { h: 210, s: 100, l: 50, a: 0.5 }
colorToCss(rgba);      // "rgba(0, 128, 255, 0.5)"

The parser accepts rgb/rgba or hsl/hsla names with three channels and an optional fourth alpha, regardless of the a suffix. Unsigned plain decimals (including .5) are supported; exponent notation is not. Formatting HEX rounds RGB bytes and alpha to the nearest byte; CSS formatting rounds RGB bytes and alpha to four decimals. Conversion to 8-bit HEX can lose alpha precision. RGB/HSL conversions themselves do not intentionally round.

Helpers throw TypeError for malformed objects, invalid strings or unsupported syntax, and RangeError for non-finite/out-of-range channels. Valid component models and palettes are required; invalid props throw during render. Validation helpers accept typed models; use parseColor to validate external strings rather than casting unknown input to a model.

Customization

Import the optional stylesheet once or provide your own. No unscoped document rules are applied. Public CSS variables:

.my-picker {
  --lp-color-accent: #0369a1;
  --lp-color-surface: #f0f9ff;
  --lp-color-text: #0c4a6e;
  max-width: 32rem;
}

Pass className="my-picker" or inline style. Structural classes use lp-color-picker with __preview, __channels and __palette suffixes.

Accessibility and limitations

Every input has a visible label. Native buttons, a fieldset legend, pressed palette states, visible focus, native range keyboard controls, readable CSS output and linked aria-invalid/alert messages provide keyboard alternatives. The native color input's capabilities and dialog accessibility vary by browser. No global keyboard or pointer listeners are installed.

This is an sRGB picker, not a color-management suite. It does not support named colors, CSS variables, modern space/slash CSS syntax, RGB percentages, LAB, OKLCH, wide gamut, gradients, eyedroppers, contrast audits, or a custom saturation/value drag surface. HSL is derived from RGB, so a chosen hue is not retained for black/white/gray until saturation and lightness permit it. Palette equality uses rounded 8-bit HEX. Translucent previews depend on their background. Accessibility and browser coverage have not been independently certified.

Helpers and edits are synchronous; there is no persistence, subscription, worker, or cancellation API. Import does not access browser globals. The native color control requires a browser when mounted; root imports still resolve the React peer even for helper-only use. Palette parsing/rendering visits every entry on each render, so bound custom palettes rather than assuming virtualization.

License

MIT.

Support

If this library is useful to you, consider supporting its maintenance with a donation via PayPal.

Author

Created by Libin Prasanth. Connect on LinkedIn for updates and discussion.