# Clipboard

**A component to copy text to the clipboard.**

**Reference:** [View Source](https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Primitives/Clipboard) · [Zag.js Docs](https://zagjs.com/components/react/clipboard)

**Clipboard.html**

```html
<ui:clipboard.root value="composer require jramke/fluid-primitives">
    <ui:clipboard.label>Copy to clipboard</ui:clipboard.label>
    <ui:clipboard.control class="flex items-center gap-2">
        <ui:clipboard.input class="field-sizing-content" />
        <ui:clipboard.trigger asChild="{true}">
            <ui:button>
                <ui:clipboard.indicator state="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ClipboardIndicatorState::Idle')}">Copy</ui:clipboard.indicator>
                <ui:clipboard.indicator state="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ClipboardIndicatorState::Copied')}">Copied!</ui:clipboard.indicator>
            </ui:button>
        </ui:clipboard.trigger>
    </ui:clipboard.control>
</ui:clipboard.root>

```

**Clipboard.ts**

```ts
import { mountAll } from 'fluid-primitives';
import { Clipboard } from 'fluid-primitives/clipboard';

mountAll('clipboard', ({ props }) => {
    const clipboard = new Clipboard(props);
    clipboard.init();
    return clipboard;
});

```

## Features

- Supports copying text to the clipboard
- Visual feedback when copying is successful
- Supports custom timeout for the copied state

## Installation

```bash
typo3 ui:add clipboard
```

Or copy the files manually from GitHub (https://github.com/jramke/fluid-primitives.com/tree/main/packages/docs/Resources/Private/Registry/Clipboard) into your project.

Read more about installing [Components and Primitives](/docs/core-concepts/primitives.md).

## Examples

### Copy Button Only

Display only a copy button without the input field.

**Clipboard.html**

```html
<ui:clipboard.root value="https://example.com/share/abc123">
    <ui:clipboard.trigger>
        <ui:clipboard.indicator state="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ClipboardIndicatorState::Idle')}">Copy Link</ui:clipboard.indicator>
        <ui:clipboard.indicator state="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ClipboardIndicatorState::Copied')}">Link Copied!</ui:clipboard.indicator>
    </ui:clipboard.trigger>
</ui:clipboard.root>

```

### Custom Timeout

Set a custom duration for how long the "copied" state is shown.

**Clipboard.html**

```html
<ui:clipboard.root value="Copy me!" timeout="5000">
    <ui:clipboard.control class="flex items-center gap-2">
        <ui:clipboard.input class="w-32" />
        <ui:clipboard.trigger asChild="{true}">
            <ui:button>
                <ui:clipboard.indicator state="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ClipboardIndicatorState::Idle')}">Copy</ui:clipboard.indicator>
                <ui:clipboard.indicator state="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ClipboardIndicatorState::Copied')}">Copied for 5 seconds!</ui:clipboard.indicator>
            </ui:button>
        </ui:clipboard.trigger>
    </ui:clipboard.control>
</ui:clipboard.root>

```

### Localization

Default clipboard trigger labels are shipped via XLF and follow the current Site Language. For per-template overrides, pass translated strings through the `translations` prop. Set a translation entry to `{false}` or an empty string to omit the corresponding `aria-label`.

Note that Zag.js uses a function for the trigger label to allow dynamic labels based on the copied state. Fluid Primitives simplifies this by accepting static strings for both states, which are then merged into the appropriate function internally.

```html
<f:variable
    name="clipboardTranslations"
    value="{
        triggerLabelIdle: '{f:translate(key: \'LLL:EXT:site_package/Resources/Private/Language/locallang.xlf:clipboard.copy\')}',
        triggerLabelCopied: '{f:translate(key: \'LLL:EXT:site_package/Resources/Private/Language/locallang.xlf:clipboard.copied\')}'
    }"
/>

<ui:clipboard.root value="Copy me" translations="{clipboardTranslations}"> ... </ui:clipboard.root>
```

## API Reference

### clipboard.root

Provides the clipboard state and shared context for the composed parts. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `value` | `string` | Yes | `-` | The value to copy to the clipboard. |
| `timeout` | `integer` | No | `3000` | The timeout for the copied state in milliseconds. |
| `translations` | `array` | No | `-` | Localized clipboard trigger labels. Set entries to `` to omit the corresponding `aria-label`. Use `f:translate` for per-template localization overrides when needed. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `rootId` | `string` | No | `-` | The root ID of the component, used for hydration and identification. |
| `ids` | `array` | No | `[]` | The IDs of of the component parts for composition. |
| `controlled` | `boolean` | No | `false` | If true, the component is meant to be initialized manually inside another component |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | clipboard |
| `data-part` | root |
| `data-copied` | Present when copied state is true |

### clipboard.label

Labels the clipboard input. Renders a `<label>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | clipboard |
| `data-part` | label |
| `data-copied` | Present when copied state is true |

### clipboard.control

Groups the input and trigger into a single layout container. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | clipboard |
| `data-part` | control |
| `data-copied` | Present when copied state is true |

### clipboard.input

Displays the text value that can be copied. Renders an `<input>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | clipboard |
| `data-part` | input |
| `data-copied` | Present when copied state is true |
| `data-readonly` | Present when read-only |

### clipboard.trigger

Copies the current value to the clipboard when activated. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | clipboard |
| `data-part` | trigger |
| `data-copied` | Present when copied state is true |

### clipboard.indicator

Displays UI for a specific clipboard state like `idle` or `copied`. Renders a `<span>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `state` | `Enum\ClipboardIndicatorState` | Yes | `-` | The indicator state to render. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

### Machine JavaScript API

| Name | Type | Description |
| --- | --- | --- |
| `copied` | `boolean` | Whether the value has been copied to the clipboard |
| `value` | `string` | The value to be copied to the clipboard |
| `setValue` | `(value: string) => void` | Set the value to be copied to the clipboard |
| `copy` | `VoidFunction` | Copy the value to the clipboard |

## Anatomy

```html
<primitives:clipboard.root>
    <primitives:clipboard.label />
    <primitives:clipboard.control>
        <primitives:clipboard.input />
        <primitives:clipboard.trigger>
            <primitives:clipboard.indicator />
        </primitives:clipboard.trigger>
    </primitives:clipboard.control>
</primitives:clipboard.root>
```
