oklch-pickerPlaygroundGitHub

React

Everything the picker does, in React, on one page. The value binding is value and onChange, the usual controlled pair.

Install

npm install @oklch-picker/react

The stylesheet lives in the shared core, which the adapter already depends on. Import it once, anywhere.

import "@oklch-picker/core/styles.css";
This is the result, feel free to drag and experiment

The basics

A controlled picker. The value you get back is always canonical and always in gamut.

import { useState } from "react";
import { ColourPicker } from "@oklch-picker/react";
import "@oklch-picker/core/styles.css";

export function Example() {
  const [colour, setColour] = useState("oklch(0.7 0.15 255)");
  return <ColourPicker value={colour} onChange={setColour} />;
}

Presets

Swatches under the sliders. Clicking one commits it, so it joins the recent colours too.

<ColourPicker
  value={colour}
  onChange={setColour}
  presets={["oklch(0.75 0.16 145)", "oklch(0.7 0.15 255)"]}
/>

A wider gamut

P3 and Rec. 2020 as output spaces, not decoration: the slider reaches further and the value is clamped to the space you chose.

import { P3 } from "@oklch-picker/core/gamuts";

<ColourPicker value={colour} onChange={setColour} gamut={P3} />

Letting the user switch space

A segmented control over the output space. Off by default, since most pickers target one.

const [gamut, setGamut] = useState(SRGB);

<ColourPicker
  value={colour}
  onChange={setColour}
  gamut={gamut}
  onGamutChange={setGamut}
  gamutChoices={[SRGB, P3, REC2020]}
  parts={{ gamutSwitch: true }}
/>

Alpha

On by default. An opaque colour is unchanged in every format, so the alpha forms appear only when a colour is actually transparent.

// Arrives transparent, comes back transparent.
<ColourPicker value="oklch(0.7 0.15 255 / 0.4)" onChange={setColour} />

// Or drop the slider entirely.
<ColourPicker value={colour} onChange={setColour} parts={{ alpha: false }} />

Storing recent colours yourself

The picker keeps a list per session. Pass one in to store them in a backend or share them between pickers.

const [recents, setRecents] = useState(loadFromServer);

<ColourPicker
  value={colour}
  onChange={setColour}
  recents={recents}
  onRecentsChange={(next) => {
    setRecents(next);
    save(next);
  }}
/>

On a server

The markup the server sends is the finished picker, not a shell that fills in on hydration.

import { renderToString } from "react-dom/server";

renderToString(<ColourPicker value={colour} onChange={setColour} />);

Where next