Clipboard

Copy text to clipboard with visual feedback and multiple style variants, perfect for code blocks, API keys, and shareable content.

Key Features

  • Copy from any element - Works with inputs, textareas, or any HTML element
  • Visual feedback - Icon swap (clipboard → check) and text change for 2 seconds
  • GitHub-style variant - Icon-only compact button perfect for code blocks
  • Toolbar variant - Shows label + icon, turns green on success (like GitHub PR toolbar)
  • Code variant - Flowbite-style icon + text button that turns blue on success
  • Tooltip support - Shows tooltip on hover, changes to "Copied!" on success
  • Multiple variants - default, minimal, github, toolbar, code
  • All semantic colors - primary, success, danger, warning, info, zinc, etc.
  • Auto-detection - Automatically uses input.value or element.textContent
  • Full accessibility - ARIA labels, live regions, keyboard support
  • Modern browsers - Uses Clipboard API (Chrome 66+, Firefox 63+, Safari 13.1+)
  • Accessibility - aria-label, aria-hidden, aria-describedby
  • JavaScript API - Programmatic control with data-action attributes

Basic Usage

Copy text from any element by specifying its ID. The component automatically detects whether to use value (for inputs) or textContent (for other elements).

<div id="text-to-copy">This text will be copied</div>
<%= rui_clipboard(target: "text-to-copy") %>
Hello, World! Click the button below to copy this text.

Variants

Three distinct visual styles to match your UI needs.

Default (Solid)

Bold, prominent button style. Best for primary copy actions.

<%= rui_clipboard(target: "content", variant: :default) %>
Solid variant example

Minimal (Ghost)

Subtle, transparent style. Perfect for inline or secondary copy actions.

<%= rui_clipboard(target: "content", variant: :minimal) %>
Minimal variant example

GitHub (Icon-Only)

Compact, icon-only button. Perfect for code blocks and tight spaces.

<%= rui_clipboard(target: "content", variant: :github) %>
GitHub variant example

Sizes

Five size options from extra small to extra large.

<%= rui_clipboard(target: "content", size: :xs) %>
<%= rui_clipboard(target: "content", size: :sm) %>
<%= rui_clipboard(target: "content", size: :base) %>
<%= rui_clipboard(target: "content", size: :lg) %>
<%= rui_clipboard(target: "content", size: :xl) %>
Size comparison

Colors

Support for all semantic and Tailwind colors.

<%= rui_clipboard(target: "content", color: :primary) %>
<%= rui_clipboard(target: "content", color: :success) %>
<%= rui_clipboard(target: "content", color: :danger) %>
Color examples

Code Blocks

Multiple styles for adding copy buttons to code blocks.

GitHub Style (Icon Only)

gem install rapid_rails_ui

Code Style (Flowbite-like)

Button with icon + text that turns blue on success.

import { Clipboard } from 'rapid_rails_ui'

function CopyButton() {
  return <Clipboard target="code" />
}
<%= rui_clipboard(target: "code-block", variant: :code) %>

With Tooltip

Shows tooltip on hover, changes to "Copied!" on success.

bundle exec rails server
<%= rui_clipboard(target: "cmd", variant: :github, tooltip: "Copy command") %>

Toolbar Variant

GitHub-style toolbar with label showing what's being copied. Perfect for PR diffs, file lists, and commit SHAs.

<%= rui_clipboard(target: "sha", variant: :toolbar, label: "1 file changed") %>
main.yml +6 -2 lines
3e42cc3
feature/clipboard-component
<%# GitHub-style toolbar examples %>

<%# File changes summary %>
<span id="changes">1 file changed, +6 -2 lines</span>
<%= rui_clipboard(target: "changes", variant: :toolbar, label: "1 file changed") %>

<%# Commit SHA %>
<span id="sha">3e42cc3</span>
<%= rui_clipboard(target: "sha", variant: :toolbar, label: "Copy SHA") %>

<%# Branch name %>
<span id="branch">feature/clipboard-component</span>
<%= rui_clipboard(target: "branch", variant: :toolbar, label: "Copy branch") %>

Real-World Examples

API Key Copy

<div class="flex items-center gap-2">
  <input type="text" id="api-key" value="sk_live_..." readonly>
  <%= rui_clipboard(target: "api-key", text: "Copy Key", variant: :minimal, color: :primary) %>
</div>

Share URL

https://example.com/posts/123
<div class="flex items-center gap-2">
  <span id="share-url">https://example.com/posts/123</span>
  <%= rui_clipboard(target: "share-url", text: "Copy Link", size: :sm, color: :success) %>
</div>

Accessibility

The Clipboard component follows WAI-ARIA best practices for interactive buttons.

ARIA Attributes

  • Uses aria-label to describe the copy action
  • Visual feedback indicates success or failure state

Keyboard Navigation

  • Tab focuses the clipboard button
  • Enter or Space triggers the copy action
  • Focus states are clearly visible with ring styles

Semantic HTML

  • Uses native <button> element for proper semantics
  • Button type is type="button" to prevent form submission

Screen Reader Support

  • Button text clearly describes the copy action
  • Icon changes to checkmark on successful copy provide visual confirmation

JavaScript API

The Clipboard component exposes a Stimulus action for copying content to the clipboard.

Stimulus Actions

Use these actions via data-action attributes:

Action Description
clipboard#copy Copies text from target element to clipboard with visual feedback
Using Stimulus Actions
<%# Basic clipboard button %>
<span id="text-to-copy">Copy this text</span>
<button data-controller="clipboard"
        data-clipboard-target-value="text-to-copy"
        data-action="click->clipboard#copy">
  Copy
</button>

<%# With visual feedback targets %>
<button data-controller="clipboard"
        data-clipboard-target-value="my-input"
        data-action="click->clipboard#copy">
  <span data-clipboard-target="defaultMessage">Copy</span>
  <span data-clipboard-target="successMessage" class="opacity-0">Copied!</span>
</button>

Programmatic Control

Copy to clipboard programmatically:

Programmatic Control
// Get the clipboard controller
const clipboardElement = document.querySelector('[data-controller="clipboard"]')
const clipboardController = application.getControllerForElementAndIdentifier(
  clipboardElement,
  "clipboard"
)

// Trigger copy programmatically
clipboardController.copy(new Event("click"))

// Or use the native Clipboard API directly
const text = document.getElementById("my-input").value
navigator.clipboard.writeText(text)

API Reference

rui_clipboard

Copy text to clipboard with visual feedback and multiple style variants

Parameter Type Default Description
target* String ID of element to copy from (positional or keyword)
text String "Copy" Button text to display
label String Label for toolbar variant (shows what's being copied)
tooltip String Tooltip text on hover (changes to 'Copied!' on success)

Appearance

Visual styling options

Parameter Type Default Description
variant Symbol :default Visual style variant
:default :minimal :github :toolbar :code
color Symbol :zinc Button color - semantic or any Tailwind color
size Symbol :base Button size
:xs :sm :base :lg :xl

States

Button state options

Parameter Type Default Description
disabled Boolean false Disable the copy button

Feedback Behavior

How the component provides visual feedback

Parameter Type Default Description
Icon swap Behavior Clipboard icon → check icon on success
Text change Behavior Button text → 'Copied!' for 2 seconds
Tooltip update Behavior Tooltip changes to 'Copied!' when tooltip prop provided

Important Notes

  • Target element MUST have an id attribute
  • For inputs/textareas, copies the .value property
  • For other elements, copies the .textContent property
  • Success feedback shows for 2 seconds then auto-resets
  • Clipboard API requires HTTPS (except localhost)
  • Uses modern Clipboard API (supported in all modern browsers)

Related Components