# Copyable

A button that allows users to quickly and easily copy content to their clipboard.

Tabs: [Guidelines](/components/web/copyable/copyable.guidelines.md) · [Code](/components/web/copyable/copyable.code.md)

## Basic usage

`Copyable` copies `valueToCopy` to the clipboard when it is activated. It does not show a toast by itself, so pass a `callback` and show the feedback in your own code. The callback receives `{isSuccess, message}`.

```tsx
import {Copyable, useToaster} from '@pleo-io/telescope'

const ApiKeyCopy = ({apiKey}: {apiKey: string}) => {
    const {showToast} = useToaster()

    return (
        <Copyable
            text="Copy API key"
            valueToCopy={apiKey}
            callback={({isSuccess, message}) =>
                showToast(message, {variant: isSuccess ? 'positive' : 'negative'})
            }
        />
    )
}
```

## Variants

By default `Copyable` renders a button with a copy icon. Use `text` to show a label, or `children` to render your own content, for example a Tooltip.

```tsx
<Copyable text="Copy email" valueToCopy="john.doe@pleo.io" callback={handleCallback} />
<Copyable text="Copy email" valueToCopy="john.doe@pleo.io" callback={handleCallback} isWithoutIcon />
<Copyable text="Copy email" valueToCopy="john.doe@pleo.io" callback={handleCallback} iconPosition="right" />
```

Set `isInline` to render the component as an inline element instead of a button. Inline copies are focusable and can be activated with Enter or Space.

```tsx
<Copyable
    text="john.doe@pleo.io"
    valueToCopy="john.doe@pleo.io"
    callback={handleCallback}
    isInline
/>
```

Set `asIconButton` to render an icon-only `IconButton`. Its `variant`, `size` and `tooltipProps` are passed through to the IconButton.

```tsx
<Copyable
    valueToCopy="john.doe@pleo.io"
    callback={handleCallback}
    asIconButton={{variant: 'quiet', size: 'small', tooltipProps: {content: 'Copy'}}}
/>
```

Use `CustomIcon` to replace the copy icon with another Telescope icon. It also works with `asIconButton`.

```tsx
import {Email} from '@pleo-io/telescope-icons'
;<Copyable
    text="Copy email"
    valueToCopy="john.doe@pleo.io"
    callback={handleCallback}
    CustomIcon={Email}
/>
```

Set `disabled` to block the copy action and apply the disabled style.

```tsx
<Copyable text="Copy email" valueToCopy="john.doe@pleo.io" callback={handleCallback} disabled />
```

## Callback

`callback` is called after every copy attempt with:

- `isSuccess`: `true` when the value was copied, `false` otherwise
- `message`: the localised success or error message, unless overridden

Use `successMessage` and `errorMessage` to override the message passed to the callback.

```tsx
<Copyable
    text="Copy reference"
    valueToCopy={reference}
    successMessage="Reference copied"
    errorMessage="Could not copy the reference"
    callback={handleCallback}
/>
```

## Localisation

The labels come from the `TelescopeProvider` translations under `Copyable`:

- `Copyable.CopyButton`: the accessible name of the component, for example "Copy to clipboard"
- `Copyable.CopySuccess`: the default success message passed to the callback
- `Copyable.CopyError`: the default error message passed to the callback

## Accessibility

- The accessible name is always `Copyable.CopyButton`, even when `text` or `children` are shown.
- Inline copyables have `role="button"`, are focusable and can be activated with Enter or Space.
- When `disabled`, clicks and keyboard activation do not copy.
- Feedback is delivered through the `callback`, so show it with a toast or another live region.

## API reference

#### `asIconButton`

Type: `enum`

##### Allowed values

- `{ variant: "primary" | "secondary" | "quiet"; size: "small" | "medium" | "large" | "extraSmall" | undefined; tooltipProps: IconButtonTooltipProps; }`

Default: -

Renders an icon-only IconButton instead of a button or inline element

#### `callback` (required)

Type: `(result: CopyResult) => void`

Default: -

Called after the copy attempt with whether it succeeded and a message

#### `children`

Type: `ReactNode`

##### Allowed values

- `null`
- `string`
- `number`
- `bigint`
- `false`
- `true`
- `ReactElement<unknown, string | JSXElementConstructor<any>>`
- `Iterable<ReactNode>`
- `ReactPortal`
- `Promise<AwaitedReactNode>`

Default: -

Content rendered when `text` is not provided, e.g. a Tooltip

#### `CustomIcon`

Type: `IconComponent | undefined`

Default: -

Telescope icon rendered instead of the copy icon

#### `dataTestId`

Type: `string | undefined`

Default: -

Overrides the default data-testid

#### `disabled`

Type: `boolean`

Default: -

Disables the copy action and applies the disabled style

#### `errorMessage`

Type: `string | undefined`

Default: -

Overrides the message passed to `callback` when the copy fails

#### `iconPosition`

Type: `"left" | "right" | undefined`

Default: `left`

Position of the copy icon, defaults to left

#### `isInline`

Type: `boolean`

Default: -

Renders the component as an inline element instead of a button

#### `isWithoutIcon`

Type: `boolean`

Default: -

Removes the copy icon

#### `successMessage`

Type: `string | undefined`

Default: -

Overrides the message passed to `callback` when the copy succeeds

#### `text`

Type: `string | undefined`

Default: -

Text to display inside a span instead of children

#### `valueToCopy` (required)

Type: `string`

Default: -

Value copied to the clipboard when activated
