Vize

Copy Button

Accessible, unstyled clipboard copy button primitive.

Package @vizejs/ui/copy-button
Maturity stable
Own the source vize lib pull copy-button
Requires —
Aliases copy button, clipboard button, copy to clipboard, clipboard action
Covers shadcn/ui Copy Button, React Aria Button, WAI-ARIA Button

Usage

import { CopyButton } from "@vizejs/ui/copy-button";

Or copy the source into your project with vize lib pull copy-button (see Source Distribution).

API

CopyButton

Source: src/families/actions/copy-button/copy-button.vue

Props

Prop Type Default Description
as PrimitiveAs "button" Native element, custom element, or component to render.
native boolean true when as is "button"; otherwise false Whether the rendered target already implements native button semantics.
type CopyButtonType "button" Native button submission behavior.
value (required) string required Plain string copied to the system clipboard on activation.
disabled boolean false Remove the control from activation and sequential keyboard focus.
idleLabel string "Copy" Idle fallback text rendered when no default slot is supplied.
copiedLabel string "Copied" Success fallback text rendered when no default slot is supplied.
errorLabel string "Copy failed" Failure fallback text rendered when no default slot is supplied.
ariaLabel string undefined Accessible name when no visible label or aria-labelledby supplies one.
ariaLabelledby string undefined Space-separated ids that label the button.
ariaDescribedby string undefined Space-separated ids that describe the button.
writer CopyButtonWriter navigator.clipboard.writeText Test or platform hook for writing clipboard text.

Events

Event Payload Description
copy [value: string, nativeEvent: MouseEvent] Fired after the configured writer accepts the value.
error [error: unknown, value: string, nativeEvent: MouseEvent] Fired after the configured writer rejects the value.

Slots

Slot Slot props Description
default CopyButtonSlotState Renders button contents with the current copy state.

Exposed

Member Type Description
value string Plain string that will be passed to the writer on activation.
disabled boolean Whether the control suppresses user activation.
writing boolean Whether an async write is already in flight.
unavailable boolean Whether activation is currently unavailable.
state CopyButtonState Stable copy result token for styling and tests.
label string Resolved fallback text for the current state.
element CopyButtonElement | null Rendered root element or component instance.
focus (options?: FocusOptions) => void Move focus to the rendered control.

Behavior

Normative state × input → outcome table for copy-button.vue.

ID Scenario Behavior Assertion
C1 native render renders a native button with type="button", part="root", label part, and idle state renders deterministic native button semantics and default label
C2 default clipboard activation writes the string through navigator.clipboard.writeText when available uses navigator.clipboard.writeText by default
C3 successful write accepts the configured writer, emits copy, and exposes data-state="copied" copies the configured value and exposes copied state
C4 rejected write catches writer failures, emits error, and exposes data-state="error" captures writer failures without throwing out of activation
C5 disabled native disabled removes activation; non-native disabled leaves tab order with ARIA state disabled copy buttons suppress writes and keep platform semantics
C6 labels and slots label props and default slot receive the same strict idle | copied | error state supports custom labels and slot rendering
C7 duplicate activation a write in flight sets busy hooks and suppresses additional accidental writes suppresses duplicate writes while a copy is in flight
C8 non-native activation non-native hosts expose button semantics and emulate native Enter/Space timing non-native hosts preserve keyboard button activation
C9 public instance exposes live state, writing, unavailable, value, element, label, and focus() exposes live state and focus without broad clipboard abstractions
C10 SSR and hydration setup never touches browser globals; server markup is stable and hydrates without warnings copy-button-ssr.test.ts and runtime conformance fixtures

Contract

CopyButton is a headless action primitive for copying one plain string value. It intentionally owns only a narrow clipboard write: the default writer calls navigator.clipboard.writeText(value) at activation time, and tests or SSR consumers may inject a writer prop. Component setup, SSR rendering, and hydration do not access navigator, window, timers, or document globals.

The result state is closed to idle, copied, and error. Disabled and in-flight writes are separate availability hooks through data-disabled, data-writing, aria-disabled, aria-busy, slot state, and the public expose contract. In-flight writes preserve focus rather than applying native disabled.

The rendered DOM exposes part="root" on the host and part="label" on the fallback label span. Stable selectors are data-vize-ui="copy-button" and data-vize-ui="copy-button-label". No CSS classes, runtime styles, CSS custom properties, runtime CSS-in-JS, or copied value data attributes are emitted; all visual styling remains consumer-owned.