hp-copy
Copy-to-clipboard button primitive. Writes a configured value string to
the system clipboard via the async Clipboard API, dispatches a bubbling
hp-copy-success event on success, and fades a sibling "Copied" toast in
for ~1.5s as feedback. Used internally by
<hp-demo> for its
copy-code action and by
<hp-latex> for the
block-math copy button; available standalone for any consumer needing the same
affordance.
Install
bun add @hexpunk/core lit import "@hexpunk/core"; Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
value | value | string | "" | Text to write to the clipboard on click |
copied | copied | string | "Copied" | Toast text shown briefly after a successful copy (default: "Copied") |
iconOnly | icon-only | boolean | false | Drop the visible text label (still in the a11y tree); show only the icon |
Events
| Event | Type | Description |
|---|---|---|
hp-copy-success | CustomEvent | Bubbling CustomEvent on successful clipboard write; detail = { value } |
hp-copy-error | CustomEvent | Bubbling CustomEvent on failed clipboard write; detail = { error, value } |
Slots
| Slot | Description |
|---|---|
(default) | Idle button text (default: "Copy"). Provide consumer-translated content for i18n: `<hp-copy value="...">Copy code</hp-copy>`. |
CSS Parts
| Part | Description |
|---|---|
button | The internal <button> element |
When to use
copied attribute. Both default to English ("Copy" / "Copied")
when absent.
icon-only for tight chrome (corner buttons, dense toolbars).
The slotted label stays in the accessibility tree via a standard visually-
hidden recipe, so screen readers still announce it.
hp-copy-success event from outside and run side effects there
— hp-copy stays a single-purpose clipboard widget.
Events
Both events bubble + compose, so consumers can listen at any ancestor:
-
hp-copy-success— fired after a successful write.detail = { value }. -
hp-copy-error— fired when the Clipboard API rejects (permission denied, non-secure context, blocked iframe).detail = { error, value }.
Accessibility
The slotted text is the button's accessible name — no aria-label
override needed in the default form. icon-only keeps the slot
content in the a11y tree via visually-hidden styling, so screen readers still
read "Copy" (or the translated label) when navigating to the icon.
The toast uses aria-live="polite" so assistive tech announces
the success state without interrupting the user.
Clipboard API caveats
hp-copy relies exclusively on the async Clipboard API
(navigator.clipboard.writeText). This requires a secure context
(HTTPS or localhost). In non-secure contexts the click is a no-op rather than
falling back to legacy document.execCommand("copy") — that
fallback is sync-only, requires a transient user-activation focus dance, and
silently fails just as often. Consumers can listen for
hp-copy-error to surface a fallback affordance.
- 0.1.0-beta 2026-05-24
Added
- Showcase: home page redesign — hero (
<h1>Hexpunk</h1>+ tagline) + Setup section (copy-paste<head>snippet in<hp-code language="html">with an<hp-copy>button positioned in the top-right corner; the snippet documents the eventual esm.sh CDN surface: two stylesheet links, an importmap, a module script) + Get Started section (5-hex<hp-cluster layout="rosette">: Install centre + Concepts top + Components middle-left + Palette middle-right + GitHub bottom). Drops the old "Spatial primitives" + "Quick links" prose sections. <hp-latex>— render-only LaTeX math primitive. Consumer-registered renderer viaHpLatex.setRenderer((latex, "inline" | "block") => string | null);@hexpunk/corehas zero math-engine dependency.valueattribute carries the LaTeX source (text content fallback captured once on connect). Boolean attributes:block(block/display mode, centred + full-width),background(mounts<hp-background>backdrop inside the element, block mode only),copyable(mounts<hp-copy>source button in the top-right corner, block mode only). Without a renderer, source renders mono-spaced fallback;render-errorCustomEvent dispatches on renderer throw. Only light-DOM hp-\* element in the system — required for KaTeX's class-scoped CSS to cascade into the rendered output (file header explains the rationale). Not SSR-friendly via@lit-labs/ssr; consumers wanting pre-rendered math in MDX use Astro'sremark-math+rehype-katexdirectly.<hp-copy>— copy-to-clipboard button widget. Lucidecopyicon + slotted label (translatable per-instance, default "Copy") + sibling "Copied" toast witharia-live="polite".valueattribute for the text to copy;copiedattribute for the toast text;icon-onlyboolean drops the visible label while keeping it in the a11y tree. Bubblinghp-copy-success/hp-copy-errorevents. Async Clipboard API only — noexecCommandfallback. Now powers<hp-demo>'s copy-code action and<hp-latex>'s source-copy button.- Lucide
copyicon mirrored intosrc/icons/copy.tsviabun run iconsfor use inside<hp-copy>'s shadow root.
Changed
<hp-demo>copy action — replaced the bespoke inline copy button + animated toast with<hp-copy>so the same widget powers both<hp-demo>and<hp-latex>. Slot-text source caching viaslotchangeon the code slot; no behaviour change for consumers.
- Showcase: home page redesign — hero (