npm package: @polarityio/pi-copy-button
Description: Clipboard copy button with rich text support and lifecycle hooks
Latest version: 1.0.3

# Polarity Integration Component Library

## Copy Button Component

A button component that copies text or HTML content to the clipboard with lifecycle hooks, success feedback, and support for both static strings and DOM element content.

## Installation

```bash
npm install @polarityio/pi-copy-button
```

### Peer Dependencies

- [lit](https://lit.dev/) ^3.0.0

## Usage

```javascript
import '@polarityio/pi-copy-button';
```

```html
<!-- Copy a static string -->
<pi-copy-button copy-data="Hello, World!"></pi-copy-button>

<!-- Copy content from a DOM element (preserves HTML formatting) -->
<div id="my-content">
  <strong>Important</strong> data in a <em>table</em>.
</div>
<pi-copy-button copy-content-id="my-content" copy-format="html" button-text="Copy HTML"></pi-copy-button>

<!-- Copy as plain text from a DOM element -->
<pi-copy-button copy-content-id="my-content" copy-format="text" button-text="Copy Text"></pi-copy-button>

<!-- Icon-only compact button -->
<pi-copy-button copy-data="Copied!" button-text="" condensed></pi-copy-button>
```

### Copy Lifecycle

The copy operation follows a defined lifecycle:

1. **`pi-copy-before`** event fires (cancelable — call `preventDefault()` to abort)
2. **`beforeCopy`** hook runs (async supported — throwing aborts the copy)
3. Clipboard write operation executes
4. **`pi-copy-success`** or **`pi-copy-error`** event fires
5. **`afterCopy`** hook runs (on both success and error)

```javascript
const copyBtn = document.querySelector('pi-copy-button');

// Lifecycle hooks
copyBtn.beforeCopy = async (context) => {
  // Prepare content before copying (e.g., expand collapsed sections)
  await expandContent();
};

copyBtn.afterCopy = (context) => {
  if (context.success) {
    console.log('Copied:', context.copiedData);
  } else {
    console.error('Copy failed:', context.error);
  }
};

// Programmatic copy
const result = await copyBtn.copy();
console.log(result.success, result.copiedData);
```

### Copy Modes

| Mode | Source | Behavior |
| --- | --- | --- |
| **Text** (`copyData`) | Static string property | Copies plain text via `navigator.clipboard.writeText()` |
| **HTML** (`copyContentId` + `copy-format="html"`) | DOM element | Preserves rich formatting via browser Selection API |
| **Text** (`copyContentId` + `copy-format="text"`) | DOM element | Copies `innerText` as plain text |

> **Priority:** `copyContentId` takes precedence over `copyData` when both are set.

## API Reference

### Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `copyData` | `string` | `''` | Static string data to copy to the clipboard |
| `copyContentId` | `string` | `''` | ID of a DOM element whose content will be copied |
| `copyFormat` | `'html' \| 'text'` | `'html'` | Format when copying from a `copyContentId` element |
| `buttonText` | `string` | `'Copy'` | Text displayed on the button. Set to `''` for icon-only. |
| `buttonType` | `string` | `'primary'` | Visual style of the inner button (`'primary'`, `'secondary'`, `'tertiary'`) |
| `condensed` | `boolean` | `false` | Reduces button padding for compact layouts |
| `successMessage` | `string` | `'Copied Information'` | Tooltip message shown after a successful copy (auto-hides after 2 seconds) |
| `disabled` | `boolean` | `false` | Disables the button. Also auto-disabled when no copy source is set. |
| `beforeCopy` | `(context: PiCopyContext) => void \| Promise<void>` | `undefined` | Async hook that runs before the copy. Throwing aborts the copy. |
| `afterCopy` | `(context: PiCopyResultContext) => void \| Promise<void>` | `undefined` | Hook that runs after copy completes (on both success and error). |

### Events

| Event Name | Detail | Description |
| --- | --- | --- |
| `pi-copy-before` | `PiCopyContext` | Fired before the copy starts. **Cancelable** — call `preventDefault()` to abort. |
| `pi-copy-success` | `PiCopyResultContext` | Fired on a successful copy. |
| `pi-copy-error` | `PiCopyResultContext` | Fired when the copy fails. |

#### Event Detail Types

```typescript
interface PiCopyContext {
  component: PiCopyButton;
  trigger: 'click' | 'programmatic';
  sourceEvent?: Event;
}

interface PiCopyResultContext extends PiCopyContext {
  success: boolean;
  copiedData: string;
  error?: unknown;
}
```

### CSS Custom Properties

| Property | Default | Description |
| --- | --- | --- |
| `--pi-tooltip-background` | `var(--pi-color-font-success)` | Success tooltip background color |
| `--pi-tooltip-color` | `var(--pi-color-font-inverse)` | Success tooltip text color |

### Public Methods

| Method | Description |
| --- | --- |
| `copy(trigger?: 'click' \| 'programmatic', sourceEvent?: Event): Promise<PiCopyResult>` | Starts the copy flow programmatically. Returns `{ success, copiedData?, error? }`. |

#### Return Type

```typescript
interface PiCopyResult {
  success: boolean;
  copiedData?: string;
  error?: unknown;
}
```

## Theming

Customize the appearance using CSS custom properties. This component uses design tokens from `@polarityio/pi-shared` for consistent theming across the component library.

## License

MIT