# OKLCH theme token

> Lightness, chroma and hue sliders for a --primary token, with a live Button and Badge preview.

A shadcn/ui block from the [@reui](https://reui.io) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/reui/c-color-picker-6).

- Page, with a live preview: https://shadcn.exchange/r/reui/c-color-picker-6
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/reui/c-color-picker-6-light-15771d9fcee90524.png
- Registry item: https://reui.io/r/new-york-v4/c-color-picker-6.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://reui.io/r/new-york-v4/c-color-picker-6.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `@reui/badge`, `button`, `card`, `checkbox`, `@reui/color-picker`, `input-group`, `label`

## Files

### `c-color-picker-6.tsx`

```tsx
"use client"

import { useState } from "react"
import type { CSSProperties } from "react"
import { Badge } from "@/components/reui/badge"
import {
  ColorPicker,
  ColorPickerChannelInput,
  ColorPickerCopy,
  ColorPickerSlider,
  getForegroundColor,
  isColorInSrgb,
  parseColor,
} from "@/components/reui/color-picker"

import { Button } from "@/components/ui/button"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { Checkbox } from "@/components/ui/checkbox"
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@/components/ui/input-group"
import { Label } from "@/components/ui/label"

const CHANNELS = [
  { channel: "lightness", short: "L" },
  { channel: "chroma", short: "C" },
  { channel: "hue", short: "H" },
] as const

export function Pattern() {
  /* Tailwind's blue-500, a P3 color: its chroma runs past sRGB. */
  const [primary, setPrimary] = useState<string | null>(
    "oklch(62.3% 0.214 259.815)"
  )
  const color = parseColor(primary)
  const foreground = color ? getForegroundColor(color) : null
  /* The preview re-points the theme tokens themselves, so the Button and the
     Badge below render exactly as they would with this --primary. */
  const theme =
    primary && foreground
      ? ({
          "--primary": primary,
          "--primary-foreground": foreground,
        } as CSSProperties)
      : undefined

  return (
    <Card className="w-full max-w-md">
      <CardHeader>
        <CardTitle>Primary color</CardTitle>
        <CardDescription>
          Tune the --primary token in OKLCH, the format shadcn and Tailwind v4
          themes use.
        </CardDescription>
      </CardHeader>
      <CardContent>
        <div className="flex flex-col gap-5">
          <ColorPicker
            value={primary}
            onValueChange={setPrimary}
            format="oklch"
            aria-label="Primary color"
          >
            <div className="grid gap-3">
              {CHANNELS.map(({ channel, short }) => (
                <div
                  key={channel}
                  className="grid grid-cols-[1rem_1fr_4.5rem] items-center gap-3"
                >
                  <span
                    aria-hidden="true"
                    className="text-muted-foreground text-xs font-medium"
                  >
                    {short}
                  </span>
                  <ColorPickerSlider channel={channel} colorSpace="oklch" />
                  <InputGroup>
                    <ColorPickerChannelInput
                      channel={channel}
                      colorSpace="oklch"
                    />
                  </InputGroup>
                </div>
              ))}
            </div>
            <InputGroup>
              <InputGroupInput
                readOnly
                value={`--primary: ${primary ?? "none"};`}
                aria-label="CSS variable"
              />
              <InputGroupAddon align="inline-end">
                <ColorPickerCopy size="icon-xs" />
              </InputGroupAddon>
            </InputGroup>
          </ColorPicker>
          <div className="flex flex-wrap items-center gap-3" style={theme}>
            {/* Each fills with --primary and draws on --primary-foreground,
                so all three follow the picked color. */}
            <Button>Save changes</Button>
            <Badge>New</Badge>
            <div className="flex items-center gap-2">
              <Checkbox id="primary-notify" defaultChecked />
              <Label htmlFor="primary-notify">Notify team</Label>
            </div>
            {color && !isColorInSrgb(color) && (
              <Badge variant="warning-light" className="ms-auto">
                Outside sRGB
              </Badge>
            )}
          </div>
        </div>
      </CardContent>
    </Card>
  )
}
```
