Clipboard
View as MarkdownA component to copy text to the clipboard.
<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>
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
typo3 ui:add clipboard
Please copy the files manually from GitHub into your project.
Read more about installing Components and Primitives.
Examples
Copy Button Only
Display only a copy button without the input field.
<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.
<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.
<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
The following tables cover the available props of the Fluid Primitives. For a full list of available client side props and methods, see the Zag.js Machine API.
clipboard.root
Provides the clipboard state and shared context for the composed parts. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
value | stringThe value to copy to the clipboard. | Yes | - |
timeout | integerThe timeout for the copied state in milliseconds. | No | 3000 |
translations | arrayLocalized clipboard trigger labels. Set entries to `` to omit the corresponding `aria-label`. Use `f:translate` for per-template localization overrides when needed. | No | - |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
rootId | stringThe root ID of the component, used for hydration and identification. | No | - |
ids | arrayThe IDs of of the component parts for composition. | No | [] |
controlled | booleanIf true, the component is meant to be initialized manually inside another component | No | false |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
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 | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
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 | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
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 | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
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 | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
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 | Description | Required | Default |
|---|---|---|---|
state | Enum\ClipboardIndicatorStateThe indicator state to render. | Yes | - |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
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
<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>