CopyButton

Writes a piece of text to the clipboard and confirms the result.

pnpm add @hina-ui/vue
<script setup lang="ts">
  import { Code, CopyButton, Inline } from '@hina-ui/vue'
</script>

<template>
  <Inline align="center">
    <Code>pnpm add @hina-ui/vue</Code>
    <CopyButton text="pnpm add @hina-ui/vue" />
  </Inline>
</template>
vue

Usage

import { CopyButton } from '@hina-ui/vue'
ts

text is required and its content is written to the clipboard. On success the icon turns from a copy glyph into a check, the name becomes “Copied”, and both revert after two seconds.

<script setup lang="ts">
  import { CopyButton } from '@hina-ui/vue'
</script>

<template>
  <CopyButton text="Hina UI" />
</template>
vue

Examples

Sizes

Defaults to sm. A copy button usually follows a piece of text or a command, where sm matches the height of the neighbouring text most closely.

<script setup lang="ts">
  import { CopyButton, Inline } from '@hina-ui/vue'
</script>

<template>
  <Inline align="center">
    <CopyButton size="sm" text="Small" />
    <CopyButton size="md" text="Medium" />
    <CopyButton size="lg" text="Large" />
  </Inline>
</template>
vue

Name and tooltip

The default name is “Copy”. Where a page has several copy buttons, use label to say what each one copies and turn on tooltip, so they can be told apart before clicking.

Once copying succeeds the name always switches to “Copied”, and the custom name is not shown during that time.

<script setup lang="ts">
  import { CopyButton, Inline } from '@hina-ui/vue'
</script>

<template>
  <Inline align="center">
    <CopyButton text="ssh://git@example.com/hina.git" label="Copy repository URL" tooltip />
    <CopyButton text="hina-2f9c41" label="Copy order number" tooltip />
  </Inline>
</template>
vue

Reset delay

timeout sets how long the success state lasts, defaulting to 2000 milliseconds. Lengthen it where the button sits inside a long form or at the edge of the page, so the feedback is easier to notice.

<script setup lang="ts">
  import { CopyButton, Inline } from '@hina-ui/vue'
</script>

<template>
  <Inline align="center">
    <CopyButton text="Two seconds by default" />
    <CopyButton text="Resets after five seconds" :timeout="5000" />
  </Inline>
</template>
vue

The copied event

On success the component emits copied with the text that was written. Nothing is emitted on failure.

Copied 0 times

<script setup lang="ts">
  import { ref } from 'vue'
  import { CopyButton, Inline, Text } from '@hina-ui/vue'

  const count = ref(0)
</script>

<template>
  <Inline align="center">
    <CopyButton text="hina@example.com" @copied="count++" />
    <Text tone="muted">Copied {{ count }} times</Text>
  </Inline>
</template>
vue

Clipboard limits

Browsers only expose the clipboard in a secure context, so the page has to be served over HTTPS or from localhost. Pages opened through file:// and some embedded pages have writes rejected.

When a write fails the button does not enter the success state, the icon and name stay as they are, and no copied event is emitted.

Accessibility

  • The default name is “Copy” and becomes “Copied” on success, a change screen readers announce.
  • The button renders a native button, takes keyboard focus, and responds to both Enter and Space.
  • The tooltip is off by default and can be turned on with tooltip.

API

Props

Prop
Type
Default
Description
text
string
—
Required. The text written to the clipboard
label
string
Copy
Accessible name of the button
size
'xs' | 'sm' | 'md' | 'lg'
'sm'
Size
timeout
number
2000
How long the success state lasts, in ms
tooltip
boolean
false
Whether to show a tooltip
disabled
boolean
false
Whether the button is unavailable
class
string
—
Classes appended to the button

Events

Event
Payload
Description
copied
text: string
Emitted when the write succeeds