# Pixel colour picker
> Colour picker made of pixel cells with a fisheye under the pointer; a new hue ripples across the grid from where you clicked.
- Element: `<px-color>`
- React: `import { PxColor } from "@/components/lumesec/px-color"`
- Collection: Pixel Lab (https://elements.lumesec.ai/components/pixel-lab)
- Registry item: https://elements.lumesec.ai/r/px-color.json
- Page: https://elements.lumesec.ai/components/pixel-lab/color



Live preview: https://elements.lumesec.ai/view/px-color

```html
<script type="module" src="https://elements.lumesec.ai/cdn/px-color.js"></script>

<px-color></px-color>
```

## Installation

```bash
npx shadcn@latest add @lumesec/px-color
```

First time with the @lumesec registry? Register it once, or install by URL:

```bash
npx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json
npx shadcn@latest add https://elements.lumesec.ai/r/px-color.json
```

## Usage

React:

```tsx
import { PxColor } from "@/components/lumesec/px-color";

export function Example() {
  return (
    <PxColor />
  );
}
```

HTML:

```html
<script type="module" src="https://elements.lumesec.ai/cdn/px-color.js"></script>

<px-color></px-color>
```

## Behaviour

A grid of colour pixels with a fisheye that swells cells under your pointer. Picking a hue sends the new colour rippling across the grid from where you clicked.

## API reference

### Events

Events bubble and cross the shadow boundary unless the description says otherwise.

| Event    | React prop | Detail            | Description                                                                              |
| -------- | ---------- | ----------------- | ---------------------------------------------------------------------------------------- |
| `change` | `onChange` | `{ hex: string }` | Fires when the selected cell or the hue changes, with the colour as lowercase `#rrggbb`. |

### Methods

Call them on the element, for example through a React ref.

| Method                | Description                                                                                   |
| --------------------- | --------------------------------------------------------------------------------------------- |
| `setHue(hue: number)` | Sets the hue in degrees (wrapped to 0 to 359), ripples it across the grid and fires `change`. |

### Properties

| Property | Type     | Description                                                                   |
| -------- | -------- | ----------------------------------------------------------------------------- |
| `hex`    | `string` | Current colour as lowercase `#rrggbb`. Writing it does not update the picker. |

## Keyboard

| Keys              | Action                                   |
| ----------------- | ---------------------------------------- |
| Arrow keys        | Move the selection one cell in the grid. |
| PageUp / PageDown | Shift the hue by +15 or -15 degrees.     |

## Accessibility

* The canvas is focusable with `role="group"` and `aria-label="Colour picker. Arrow keys move in the grid, Page Up and Page Down change the hue."`.
* The hex readout is an `aria-live="polite"` region; the HSL value is shown as plain text beside it.
* Copy is a native button whose text changes to "Copied" or "Select it" for 1.4 seconds.
* Reduced motion: a new hue applies to the whole grid at once and cells do not swell under the pointer.

## Theming

The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from `--lumesec`. See [Theming](/docs/theming).

This component reads `--foreground`, `--lumesec` and `--muted-foreground`.

To restyle only LumeSec elements, set the matching `--ui-*` overrides: `--ui-accent`, `--ui-fg`, `--ui-mono` and `--ui-muted`.

## Notes

* The grid is 16 columns of saturation (15% to 100%) by 9 rows of lightness (88% down to 12%), with a 36-step hue strip below. It starts at hue 262.
* Copy uses `navigator.clipboard.writeText`. The canvas is 196px tall and animates continuously while on screen.


