Ark UI Logo
Components
Clipboard

Clipboard

A component to copy text to the clipboard

Loading...

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.

Examples

Learn how to use the Clipboard component in your project. Let's take a look at the most basic example:

import { Clipboard } from '@ark-ui/react/clipboard'
import { CheckIcon, ClipboardCopyIcon } from 'lucide-react'

export const Basic = () => {
  return (
    <Clipboard.Root value="https://ark-ui.com">
      <Clipboard.Label>Copy this link</Clipboard.Label>
      <Clipboard.Control>
        <Clipboard.Input />
        <Clipboard.Trigger>
          <Clipboard.Indicator copied={<CheckIcon />}>
            <ClipboardCopyIcon />
          </Clipboard.Indicator>
        </Clipboard.Trigger>
      </Clipboard.Control>
    </Clipboard.Root>
  )
}

Using Context

Access the clipboard state and methods using Clipboard.Context. This provides access to properties like copied, value, and setValue

Alternatively, you can use the useClipboardContext hook to access the clipboard context.

import { Clipboard } from '@ark-ui/react/clipboard'
import { CheckIcon, ClipboardCopyIcon } from 'lucide-react'

export const Context = () => {
  return (
    <Clipboard.Root value="https://ark-ui.com">
      <Clipboard.Label>Copy this link</Clipboard.Label>
      <Clipboard.Control>
        <Clipboard.Trigger>
          <Clipboard.Context>
            {(clipboard) => (
              <div>
                {clipboard.copied ? <CheckIcon /> : <ClipboardCopyIcon />}
                <span>{clipboard.copied ? 'Copied!' : 'Copy'}</span>
                <small>Value: {clipboard.value}</small>
              </div>
            )}
          </Clipboard.Context>
        </Clipboard.Trigger>
      </Clipboard.Control>
    </Clipboard.Root>
  )
}

Copy Status

Use the onStatusChange prop to listen for copy operations. It exposes a copied property that you can use to display a success message.

import { Clipboard } from '@ark-ui/react/clipboard'
import { CheckIcon, ClipboardCopyIcon } from 'lucide-react'
import { useState } from 'react'

export const CopyStatus = () => {
  const [copyCount, setCopyCount] = useState(0)

  return (
    <Clipboard.Root
      value="https://ark-ui.com"
      onStatusChange={(details) => {
        if (details.copied) {
          setCopyCount((prev) => prev + 1)
        }
      }}
    >
      <Clipboard.Trigger>
        <Clipboard.Indicator copied={<CheckIcon />}>
          <ClipboardCopyIcon />
        </Clipboard.Indicator>
        Copy
      </Clipboard.Trigger>
      <p>Copied {copyCount} times</p>
    </Clipboard.Root>
  )
}

Controlled

Control the clipboard value externally by managing the state yourself and using onValueChange to handle updates.

import { Clipboard } from '@ark-ui/react/clipboard'
import { CheckIcon, ClipboardCopyIcon } from 'lucide-react'
import { useState } from 'react'

export const Controlled = () => {
  const [url, setUrl] = useState('https://ark-ui.com')

  const handleUrlChange = () => {
    setUrl('https://chakra-ui.com')
  }

  return (
    <Clipboard.Root value={url} onValueChange={({ value }) => setUrl(value)}>
      <Clipboard.Label>Copy this link</Clipboard.Label>
      <Clipboard.Control>
        <Clipboard.Input />
        <Clipboard.Trigger>
          <Clipboard.Indicator copied={<CheckIcon />}>
            <ClipboardCopyIcon />
          </Clipboard.Indicator>
        </Clipboard.Trigger>
      </Clipboard.Control>

      <button onClick={handleUrlChange}>Change Url</button>
    </Clipboard.Root>
  )
}

Root Provider

Use the useClipboard hook to create the clipboard store and pass it to the Clipboard.RootProvider component. This allows you to have maximum control over the clipboard programmatically.

If you're using the Clipboard.RootProvider component, you don't need to use the Clipboard.Root component.

import { Clipboard, useClipboard } from '@ark-ui/react/clipboard'
import { CheckIcon, ClipboardCopyIcon } from 'lucide-react'

export const RootProvider = () => {
  const clipboard = useClipboard({ value: 'https://ark-ui.com' })

  return (
    <>
      <button onClick={() => clipboard.copy()}>Copy</button>

      <Clipboard.RootProvider value={clipboard}>
        <Clipboard.Label>Copy this link</Clipboard.Label>
        <Clipboard.Control>
          <Clipboard.Input />
          <Clipboard.Trigger>
            <Clipboard.Indicator copied={<CheckIcon />}>
              <ClipboardCopyIcon />
            </Clipboard.Indicator>
          </Clipboard.Trigger>
        </Clipboard.Control>
      </Clipboard.RootProvider>
    </>
  )
}

Custom Timeout

Configure the copy status timeout duration using the timeout prop. Default is 3000ms (3 seconds).

import { Clipboard } from '@ark-ui/react/clipboard'
import { CheckIcon, ClipboardCopyIcon } from 'lucide-react'

export const CustomTimeout = () => {
  return (
    <Clipboard.Root value="https://ark-ui.com" timeout={5000}>
      <Clipboard.Label>Copy this link (5 second timeout)</Clipboard.Label>
      <Clipboard.Control>
        <Clipboard.Input />
        <Clipboard.Trigger>
          <Clipboard.Indicator copied={<CheckIcon />}>
            <ClipboardCopyIcon />
          </Clipboard.Indicator>
        </Clipboard.Trigger>
      </Clipboard.Control>
    </Clipboard.Root>
  )
}

Programmatic Copy

Trigger copy operations programmatically using the context's copy() method.

import { Clipboard } from '@ark-ui/react/clipboard'

export const Programmatic = () => {
  return (
    <Clipboard.Root value="https://ark-ui.com">
      <Clipboard.Context>
        {(clipboard) => <button onClick={() => clipboard.copy()}>{clipboard.copied ? 'Copied!' : 'Copy URL'}</button>}
      </Clipboard.Context>
    </Clipboard.Root>
  )
}

Value Text

Use Clipboard.ValueText to display the current clipboard value.

import { Clipboard } from '@ark-ui/react/clipboard'
import { CheckIcon, ClipboardCopyIcon } from 'lucide-react'

export const ValueText = () => {
  return (
    <Clipboard.Root value="https://ark-ui.com">
      <Clipboard.ValueText />
      <Clipboard.Trigger>
        <Clipboard.Indicator copied={<CheckIcon />}>
          <ClipboardCopyIcon />
        </Clipboard.Indicator>
        Copy
      </Clipboard.Trigger>
    </Clipboard.Root>
  )
}

API Reference

Root

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
defaultValue
string

The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard.

id
string

The unique identifier of the machine.

ids
Partial<{ root: string; input: string; label: string }>

The ids of the elements in the clipboard. Useful for composition.

onStatusChange
(details: CopyStatusDetails) => void

The function to be called when the value is copied to the clipboard

onValueChange
(details: ValueChangeDetails) => void

The function to be called when the value changes

timeout3000
number

The timeout for the copy operation

value
string

The controlled value of the clipboard

Data AttributeValue
[data-scope]clipboard
[data-part]root
[data-copied]Present when copied state is true

Control

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]clipboard
[data-part]control
[data-copied]Present when copied state is true

Indicator

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
copied
string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<...>

Input

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]clipboard
[data-part]input
[data-copied]Present when copied state is true
[data-readonly]Present when read-only

Label

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]clipboard
[data-part]label
[data-copied]Present when copied state is true

RootProvider

PropDefaultType
value
UseClipboardReturn

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Trigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]clipboard
[data-part]trigger
[data-copied]Present when copied state is true

ValueText

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Design System Support

Expert design system support from the creators of Ark UI

Get Support