Skip to main content
0.50.0
View Zag.js on Github
Join the Discord server

Clipboard

The clipboard machine allows users to quickly copy content to clipboard.

Properties

Installation

To use the clipboard machine in your project, run the following command in your command line:

npm install @zag-js/clipboard @zag-js/react # or yarn add @zag-js/clipboard @zag-js/react

This command will install the framework agnostic clipboard logic and the reactive utilities for your framework of choice.

Anatomy

To set up the clipboard correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM`.

Usage

First, import the clipboard package into your project

import * as clipboard from "@zag-js/clipboard"

The clipboard package exports two key functions:

  • machine — The state machine logic for the clipboard widget.
  • connect — The function that translates the machine's state to JSX attributes and event handlers.

You'll also need to provide a unique id to the useMachine hook. This is used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the clipboard machine in your project 🔥

import * as clipboard from "@zag-js/clipboard" import { useMachine, normalizeProps } from "@zag-js/react" import { ClipboardCheck, ClipboardCopyIcon } from "lucide-react" import { useId } from "react" function Clipboard() { const [state, send] = useMachine( clipboard.machine({ id: useId(), value: "https://github.com/chakra-ui/zag", }), ) const api = clipboard.connect(state, send, normalizeProps) return ( <div {...api.rootProps}> <label {...api.labelProps}>Copy this link</label> <div {...api.controlProps}> <input {...api.inputProps} /> <button {...api.triggerProps}> {api.isCopied ? <ClipboardCheck /> : <ClipboardCopyIcon />} </button> </div> </div> ) }

Setting the value to copy

You can set the value to copy by passing a value prop to the machine context.

const [state, send] = useMachine( clipboard.machine({ value: "Hello, world!", }), )

Listening to copy events

When the value is copied to the clipboard, the onStatusChange event is fired. You can listen to this event and perform any action you want.

const [state, send] = useMachine( clipboard.machine({ onStatusChange: (details) => { console.log("Copy status changed to", details.copied) }, }), )

Checking if the value is copied

Use the api.copied property to check if the value is copied to the clipboard.

const api = clipboard.connect(state, send) if (api.copied) { console.log("Value is copied to the clipboard") }

Changing the timeout

By default, the clipboard machine will automatically reset the state to idle after 3000ms. You can change this timeout by passing a timeout option to the machine context.

const [state, send] = useMachine( clipboard.machine({ timeout: 5000, }), )

Styling guide

Earlier, we mentioned that each clipboard part has a data-part attribute added to them to select and style them in the DOM.

[data-scope="clipboard"][data-part="root"] { /* styles for the root part */ }

Methods and Properties

Machine Context

The clipboard machine exposes the following context properties:

  • idsPartial<{ root: string; input: string; label: string; }>The ids of the elements in the clipboard. Useful for composition.
  • valuestringThe value to be copied to the clipboard
  • onStatusChange(details: CopyStatusDetails) => voidThe function to be called when the value is copied to the clipboard
  • timeoutnumberThe timeout for the copy operation
  • idstringThe unique identifier of the machine.
  • getRootNode() => ShadowRoot | Node | DocumentA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

Machine API

The clipboard api exposes the following methods:

  • copiedbooleanWhether the value has been copied to the clipboard
  • valuestringThe value to be copied to the clipboard
  • setValue(value: string) => voidSet the value to be copied to the clipboard
  • copy() => voidCopy the value to the clipboard

Edit this page on GitHub

On this page