oklch-pickerPlaygroundGitHub

Qwik

Everything the picker does, in Qwik, on one page. The value binding is value and onChange$, the QRL form Qwik uses for every handler.

Install

npm install @oklch-picker/qwik

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 { component$, useSignal } from "@builder.io/qwik";
import { ColourPicker } from "@oklch-picker/qwik";
import "@oklch-picker/core/styles.css";

export const Example = component$(() => {
  const colour = useSignal("oklch(0.7 0.15 255)");
  return (
    <ColourPicker
      value={colour.value}
      onChange$={(c) => {
        colour.value = c;
      }}
    />
  );
});

Presets

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

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

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.

// An id, not the gamut object. Qwik serialises props to resume a
// component, and a Gamut carries a function, so the id crosses the
// boundary where the object cannot.
<ColourPicker value={colour.value} gamut="p3" onChange$={(c) => (colour.value = c)} />

Letting the user switch space

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

<ColourPicker
  value={colour.value}
  gamut={gamut.value}
  gamutChoices={["srgb", "p3", "rec2020"]}
  parts={{ gamutSwitch: true }}
  onChange$={(c) => (colour.value = c)}
  onGamutChange$={(g) => (gamut.value = g)}
/>

Alpha

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

<ColourPicker value={colour.value} parts={{ alpha: false }} onChange$={(c) => (colour.value = c)} />

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.

<ColourPicker
  value={colour.value}
  recents={recents.value}
  onChange$={(c) => (colour.value = c)}
  onRecentsChange$={(next) => (recents.value = next)}
/>

On a server

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

import { renderToString } from "@builder.io/qwik/server";

// Resumability is the point: the server sends the finished picker and the
// client resumes it rather than re-running the component.
await renderToString(<Example />);

Where next