General · astro-ui · Clipboard
ClipboardJS
Icon-first copy-to-clipboard trigger with copied-state check.
Clipboard renders an icon-first trigger button carrying its value in data-aui-clipboard. On success the copy icon swaps to a green check and a polite live region confirms. Ships zero JS by default — wire it app-side, or set auto to opt into a ~10-line built-in handler using the async Clipboard API. onlyIcon renders a square icon-only trigger for code blocks.
Features
- Copy icon swaps to a green check when copied
- onlyIcon square trigger for code blocks and toolbars
- Zero-JS core: value travels in data-aui-clipboard
- auto mode adds a tiny built-in handler (no hydration)
- Polite live-region copy feedback
- 3 trigger styles, 2 sizes, disabled state
Usage
---
import { Clipboard } from "astro-ui";
---
<Clipboard value="npm install astro-ui" auto />
<!-- or wire it yourself -->
<Clipboard value="npx astro add" />
<script>
// read data-aui-clipboard and call the async clipboard API
</script>Demos
Icon trigger
Click either — the copy icon swaps to a green check for 1.5s.
<Clipboard value="npm install astro-ui" auto />
<!-- icon=false falls back to a text-only trigger -->
<Clipboard value="npm install astro-ui" auto icon={false} />Icon only
The accessible name derives from the value: aria-label="Copy npx astro add".
<Clipboard value="npx astro add" auto onlyIcon />
<Clipboard value="npx astro add" auto onlyIcon variant="soft" />
<Clipboard value="npx astro add" auto onlyIcon variant="ghost" />
<!-- accessible name derives from the value: aria-label="Copy npx astro add" -->Variants
<Clipboard value="outline" auto variant="outline" label="Outline" />
<Clipboard value="ghost" auto variant="ghost" label="Ghost" />
<Clipboard value="soft" auto variant="soft" label="Soft" />Sizes
<Clipboard value="small command" auto size="sm" />
<Clipboard value="regular command" auto size="md" />Custom feedback
feedback= skips the text entirely — the check icon alone confirms.
<Clipboard
value="pnpm add astro-ui"
auto
feedback="Install command copied"
/>
<!-- feedback={null} hides the live-region text entirely —
the icon swap alone carries the confirmation -->
<Clipboard value="pnpm add astro-ui" auto feedback={null} />Disabled
<Clipboard value="locked" auto disabled label="Copy" />
<Clipboard value="locked" auto disabled onlyIcon />Manual wiring (zero JS)
This instance ships no script — the docs page wires data-aui-clipboard globally, exactly as the copy source shows.
<Clipboard value="npx astro add" />
<script>
document.addEventListener("click", (event) => {
const btn = event.target.closest("[data-aui-clipboard]");
if (!btn) return;
navigator.clipboard?.writeText(btn.dataset.auiClipboard);
});
</script>In a code block
npm install astro-ui<div class="aui-code-pill">
<code>npm install astro-ui</code>
<Clipboard value="npm install astro-ui" auto onlyIcon variant="ghost" size="sm" />
</div>
<style>
.aui-code-pill {
display: inline-flex; align-items: center; gap: 0.5rem;
padding: 0.375rem 0.375rem 0.375rem 0.75rem;
background: var(--ui-muted); border-radius: var(--ui-radius-md);
font-family: var(--ui-font-mono); font-size: var(--ui-text-sm);
}
</style>API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | required | Text placed on the clipboard. |
label | string | "Copy" | Trigger label (hidden when onlyIcon). |
icon | boolean | true | Lead with the copy icon; swaps to a check when copied. |
onlyIcon | boolean | false | Square icon-only trigger; aria-label derives from value. |
auto | boolean | false | Opt into the built-in clipboard handler. |
feedback | string | "Copied!" | Live-region success message. |
variant | "outline" | "ghost" | "soft" | "outline" | Trigger style. |
size | "sm" | "md" | "md" | Trigger scale. |
class | string | — | Merged via cn(); Tailwind classes welcome. |
id | string | — | Element id. |
ariaLabel | string | — | Accessible name. |
Accessibility
Implemented accessibility features — semantics, ARIA wiring, and keyboard behavior that ship with the component.
- Copied confirmation is announced via
role="status"witharia-live="polite" - Real button with an
aria-label; iconsaria-hidden
FAQ
Why is JS optional here?
The web platform has no script-free clipboard write, so the component keeps its core markup zero-JS and makes the (tiny) script opt-in via auto.
How does the copied state work?
The success handler toggles an is-copied class on the root for 1.5s; CSS swaps the copy icon for a green check. With manual wiring, toggle the class yourself.
Is the icon-only trigger accessible?
Yes — it renders a real button whose aria-label defaults to Copy <value> (override with ariaLabel), and copy success is announced via the live region.
Changelog
Version history mentioning Clipboard.
- General (7): Button, ButtonGroup, Command, Carousel, Clipboard, Kbd, Link.