# Pixel Prompt Button

> A pill button made of tiny pixels that light up around the pointer and ring out from a press, twinkle while a prompt is written, then copy it to the clipboard and swap in a check.

Source: https://ui.cortexcn.dev/docs/cortex/pixel-prompt-button

## Installation

```bash
npx shadcn@latest add @cortexcn/pixel-prompt-button
```

## Usage

```tsx
import { PixelPromptButton } from "@/components/pixel-prompt-button";
```

```tsx
<PixelPromptButton prompt="Build a pricing page with three plans." />

<PixelPromptButton
  icon="sparkle"
  label="Write a prompt"
  variant="outline"
  prompt={async () => buildPromptFromSettings()}
/>
```

`prompt` is the text to copy, or a function that writes it, and the function may return a promise. Use it beside a template, a component, or a code sample, so people can paste a ready prompt into their AI tool.

## Behavior

- The pill's surface is a grid of tiny pixels drawn on a canvas, faint at rest. Pixels near the pointer light up and fade as it moves on.
- A press rings out from the point pressed, or from the middle for a keyboard press. The pixels twinkle while the prompt is written, for at least `writeMs`.
- Once the prompt is on the clipboard, a check swaps in with `copiedLabel`, a softer ring goes out, and the button resets after `resetMs`. If the clipboard refuses, it says `failedLabel` instead.
- Every label shares one grid cell, so the button keeps its width as the label changes. Screen readers hear the current label, then "Prompt copied".
- The pixels take the button's text color and redraw when the theme changes. With reduced motion enabled, the pixels stay still and the button still copies.
- The canvas only draws while something moves.

## Props

| Prop           | Type                                             | Default            | Description                                           |
| -------------- | ------------------------------------------------ | ------------------ | ----------------------------------------------------- |
| `prompt`       | `string \| () => string \| Promise<string>`      | -                  | The prompt, or a function that writes it              |
| `label`        | `string`                                         | `"Copy prompt"`    | The label at rest                                     |
| `writingLabel` | `string`                                         | `"Writing prompt"` | The label while the prompt is written                 |
| `copiedLabel`  | `string`                                         | `"Copied"`         | The label once it is on the clipboard                 |
| `failedLabel`  | `string`                                         | `"Couldn't copy"`  | The label when the clipboard refuses                  |
| `variant`      | `"ink" \| "outline" \| "soft"`                   | `"ink"`            | A solid, outlined, or soft gray pill                  |
| `size`         | `"sm" \| "md" \| "lg"`                           | `"md"`             | The button's size                                     |
| `icon`         | `"copy" \| "sparkle"`                            | `"copy"`           | The icon at rest                                      |
| `writeMs`      | `number`                                         | `900`              | The shortest twinkle, in milliseconds                 |
| `resetMs`      | `number`                                         | `1800`             | How long the check stays, in milliseconds             |
| `pitch`        | `number`                                         | `5`                | The distance between pixels, in CSS pixels            |
| `onCopied`     | `(prompt: string) => void`                       | -                  | Called with the prompt once it is copied              |

Every other prop is passed to the `button`.