Copy Button
Copies a value to the clipboard and confirms it, with the outcome spoken to screen readers and a refusal explained.
Rendering Copy Button…
Installation
Copy the source into your project with the CLI. It lands under @/components/ui and is yours to edit.
npx mlola-ui add copy-buttonUsage
import { CopyButton } from "@/components/ui/copy-button";
export default function Example() {
return (
<div className="ml-cluster">
<code>ml_live_4f9a2c</code>
<CopyButton value="ml_live_4f9a2c" label="Copy API key" variant="subtle" />
<CopyButton value="https://ui.mlola.com/invite/3fa9" size="sm">
Copy invite link
</CopyButton>
</div>
);
}Styling comes from the engine stylesheet and the nearest theme. Set it once at the root:
<html data-theme="graphite" data-mode="light">HTML
The markup the example above renders, at rest. The interaction lives in the React component; from another framework, set the attributes below as the state changes.
<div class="ml-cluster">
<code>ml_live_4f9a2c</code>
<button class="ml-button ml-copy-button" type="button" data-variant="subtle" data-size="icon" aria-label="Copy API key" title="Copy API key"><span class="ml-button-label"><svg class="mlola-glyph" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="var(--mlola-glyph-stroke, var(--ml-icon-stroke, 1.75))" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true" data-optical-size="default" style="color:var(--mlola-glyph-color, currentColor);scale:var(--mlola-glyph-optical-scale, 1);transform-origin:center"><rect width="13" height="13" x="9" y="9" rx="2" ry="2" pathLength="1"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" pathLength="1"></path></svg><span class="ml-visually-hidden" role="status"></span></span></button>
<button class="ml-button ml-copy-button" type="button" data-variant="secondary" data-size="sm"><span class="ml-button-label"><svg class="mlola-glyph" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="var(--mlola-glyph-stroke, var(--ml-icon-stroke, 1.75))" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true" data-optical-size="default" style="color:var(--mlola-glyph-color, currentColor);scale:var(--mlola-glyph-optical-scale, 1);transform-origin:center"><rect width="13" height="13" x="9" y="9" rx="2" ry="2" pathLength="1"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" pathLength="1"></path></svg>Copy invite link<span class="ml-visually-hidden" role="status"></span></span></button>
</div>Options
| Prop | Values | Default |
|---|---|---|
size | smmdlgicon | — |
variant | primarysecondarysubtledangeroutlinelink | secondary |
width | autofull | — |
Every prop with a fixed set of values, read from the exported TypeScript types. Open the Code tab above for the rest of the API.
Classes and attributes
A class names each element; data-* and aria-* attributes carry its variant and state. The values listed are the ones the stylesheet draws; the default needs no attribute.
| Class | Attributes |
|---|---|
ml-copy-button | data-status="error" |
Accessibility and theming
- Semantic elements, accessible names and state relationships are part of the contract.
- Keyboard, pointer and touch paths are operable; focus stays visible in every theme.
- Light and dark modes pass WCAG AA contrast in all 5 canonical themes.
- Reduced motion and forced colors keep meaning and operation.
Dependencies
Installed alongside this component. No third-party UI runtime is ever added.
- button
@mlola-ui/icons