shadcn.io is an independent project built on shadcn/ui
Text
ProCopy Text for Svelte
Press to copy: the text slides away as Copied rises, then comes back. For Svelte with Ark UI, when a command, key or link should copy in one press.
Copy Text is a piece of text you press to copy: it goes to the clipboard, the text slides up out of sight as Copied rises in its place and the copy icon turns into a check, then after two seconds the text comes back. If the clipboard refuses, it says so instead.
Use it for an install command, an API key, an order number or a share link set inline, where the text itself is the button. For a copy icon beside a field or a code block, use Copy Button; to hide a secret until it's asked for, Password Text. It wraps the Button, so variant and size work as usual; the state is one data attribute that CSS transitions draw, with no animation library, and with reduced motion the labels only fade.
Installation
Usage
<script lang="ts">
import { CopyText } from "@/components/ui/copy-text";
</script>
<CopyText class="font-mono" text="npx shadcn@latest add button" />
Demos
Content
content is what goes on the clipboard when it isn't the text shown: a whole key behind a shortened one, a full link behind a short one. Give each an aria-label that says what it copies.
Variant
It's a Button underneath, ghost and sm by default, so any variant and size work. copiedLabel is the word that takes the text's place, Copied by default.
Accessibility
It's a real button, named by its text, or by an aria-label when you give one. The sliding labels and the icons are hidden from assistive tech; a polite status inside the button says Copied, or Couldn't copy when the clipboard refuses. Change those words with copiedLabel and failedLabel, which also show on screen. With reduced motion the labels cross-fade without sliding.
- Enter
- Copy the text.
- Space
- Copy the text.
FAQ
Why is there space around a short text?
The text and the labels share one place, and the widest sets its width, so the button never changes size as they swap. Keep copiedLabel and failedLabel about as long as the text, or shorter.
What happens when the copy fails?
Couldn't copy takes the text's place with a cross, for resetDelay, and the status says it. The clipboard refuses when the browser denies access or the page isn't served over HTTPS.
What if someone presses it again while it says Copied?
It copies again and the timer starts over, so the label doesn't flicker back to the text in between.
How do I know it was copied?
onCopiedChange is called with true when the text reaches the clipboard and false when the text comes back. Use it for analytics, or to show a hint elsewhere.
API Reference
CopyText
data-slot="copy-text-label"
textstring
The text shown, and copied unless content says otherwise.
clickEffect?boolean
Apply a click effect to the button.
- Default
true
content?string
What goes on the clipboard when it isn't the text itself, such as a whole key behind a shortened one.
- Default
text
copiedLabel?string
What shows in place of the text once it's copied, and what screen readers hear.
- Default
"Copied"
failedLabel?string
What shows, and what screen readers hear, when the clipboard refuses the text.
- Default
"Couldn't copy"
isLoading?boolean
Show a loading indicator.
- Default
false
onCopiedChange?(copied: boolean) โ void
Called when the copied state starts (true) and when it ends (false).
- Parameters
copiedโ boolean- Returns
void
resetDelay?number
How long the copied (or failed) state stays before the text comes back, in milliseconds.
- Default
2000
asChild?Snippet<[PropsFn]>
Render your own element: a snippet that gets the part's props to spread on it.
- Type
Snippet<[PropsFn]>
class?string
Merged with the part's classes.
data-state?string
Mirrors status.





