Skip to Content
Dashflow Logo

CopyButton Component

A comprehensive guide to using the CopyButton component with examples, props, and best practices.


Overview

The CopyButton component provides a button interface for copying text to the clipboard. It's commonly used for code snippets, URLs, and any text content that users need to copy quickly.

Basic Usage

import { CopyButton } from '@dashflowx/core'
export default function CopyButtonExample() {
return (
<CopyButton
value="Hello, World!"
/>
)
}

Preview:

Props

PropTypeDefaultDescription
valuestring'Copy this text'The text to copy to the clipboard
classNamestring''Additional CSS classes for the button
srcstring-Optional source reference

Examples

Basic Copy Button

<CopyButton
value="Hello, World!"
/>

Preview:

Code Snippet Copy Button

<CopyButton
value="npm install @dashflowx/core"
/>

Preview:

URL Copy Button

<CopyButton
value="https://dashflowx.com"
/>

Preview:

Custom Styled Copy Button

<CopyButton
value="Custom styled copy button"
className="border-2 border-blue-500 rounded-xl"
/>

Preview:

Copy Button with Long Text

<CopyButton
value="This is a very long text that demonstrates how the copy button handles longer content. It should still work perfectly and copy the entire text to the clipboard."
/>

Preview:

Common Use Cases

Code Block Copy Button

const codeSnippet = `import { Button } from '@dashflowx/core'
export default function MyComponent() {
return (
<Button variant="primary">
Click me
</Button>
)
}`;
<div className="relative">
<pre className="bg-gray-100 p-4 rounded-lg overflow-x-auto">
<code>{codeSnippet}</code>
</pre>
<div className="absolute top-2 right-2">
<CopyButton value={codeSnippet} />
</div>
</div>

API Endpoint Copy Button

const apiEndpoints = [
'GET /api/users',
'POST /api/users',
'PUT /api/users/:id',
'DELETE /api/users/:id'
];
<div className="space-y-2">
{apiEndpoints.map((endpoint, index) => (
<div key={index} className="flex items-center justify-between p-3 border rounded-lg">
<code className="text-sm font-mono">{endpoint}</code>
<CopyButton value={endpoint} />
</div>
))}
</div>

Configuration Copy Button

const configExamples = [
{
name: 'Environment Variables',
value: 'NODE_ENV=production\nAPI_URL=https://api.example.com\nDATABASE_URL=postgresql://...'
},
{
name: 'Package.json Scripts',
value: '{\n "scripts": {\n "dev": "next dev",\n "build": "next build",\n "start": "next start"\n }\n}'
},
{
name: 'Docker Compose',
value: 'version: "3.8"\nservices:\n app:\n build: .\n ports:\n - "3000:3000"'
}
];
<div className="space-y-4">
{configExamples.map((config, index) => (
<div key={index} className="border rounded-lg p-4">
<div className="flex items-center justify-between mb-2">
<h3 className="font-semibold">{config.name}</h3>
<CopyButton value={config.value} />
</div>
<pre className="bg-gray-100 p-3 rounded text-sm overflow-x-auto">
<code>{config.value}</code>
</pre>
</div>
))}
</div>

Command Copy Button

const commands = [
'git clone https://github.com/user/repo.git',
'cd repo',
'npm install',
'npm run dev',
'npm run build',
'npm run test'
];
<div className="space-y-2">
<h3 className="font-semibold mb-4">Setup Commands</h3>
{commands.map((command, index) => (
<div key={index} className="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<code className="text-sm font-mono">{command}</code>
<CopyButton value={command} />
</div>
))}
</div>

Package Manager Copy Buttons

const packageCommands = {
npm: 'npm install @dashflowx/core',
yarn: 'yarn add @dashflowx/core',
pnpm: 'pnpm add @dashflowx/core',
bun: 'bun add @dashflowx/core'
};
<div className="space-y-2">
<h3 className="font-semibold mb-4">Installation Commands</h3>
{Object.entries(packageCommands).map(([manager, command]) => (
<div key={manager} className="flex items-center justify-between p-3 border rounded-lg">
<div className="flex items-center space-x-3">
<span className="font-semibold text-sm">{manager}</span>
<code className="text-sm font-mono">{command}</code>
</div>
<CopyButton value={command} />
</div>
))}
</div>

Best Practices

1. Clear Copy Targets

Use clear and descriptive text for copy buttons.

// ✅ Good - Clear copy target
<CopyButton value="npm install @dashflowx/core" />
// ❌ Avoid - Unclear copy target
<CopyButton value="install" />

2. Appropriate Button Size

Use appropriate button sizes for different contexts.

// ✅ Good - Appropriate sizing
<div className="flex items-center space-x-2">
<code>npm install package</code>
<CopyButton value="npm install package" className="h-6 w-6" />
</div>

3. Visual Feedback

Provide visual feedback when copying is successful.

// ✅ Good - Visual feedback
const [copied, setCopied] = useState(false);
<CopyButton
value={text}
onClick={() => {
copyToClipboard(text);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}}
/>

4. Accessibility

Ensure copy buttons are accessible to all users.

// ✅ Good - Accessible
<CopyButton
value={text}
aria-label={`Copy ${text}`}
title={`Copy: ${text}`}
/>

5. Error Handling

Handle copy failures gracefully.

// ✅ Good - Error handling
const handleCopy = async (text: string) => {
try {
await navigator.clipboard.writeText(text);
setCopied(true);
} catch (error) {
console.error('Failed to copy:', error);
// Fallback or user notification
}
};

Customization

Custom Styling

You can customize the copy button appearance using CSS classes:

<CopyButton
value="Custom styled"
className="border-2 border-purple-500 rounded-xl bg-purple-50 hover:bg-purple-100"
/>

Different Themes

Use different themes for different contexts:

// Light theme
<CopyButton
value="Light theme"
className="bg-white border-gray-200 hover:bg-gray-50"
/>
// Dark theme
<CopyButton
value="Dark theme"
className="bg-gray-900 border-gray-700 text-white hover:bg-gray-800"
/>

Size Variations

Use different sizes for different emphasis levels:

// Small copy button
<CopyButton
value="Small"
className="h-6 w-6 text-xs"
/>
// Large copy button
<CopyButton
value="Large"
className="h-12 w-12 text-lg"
/>

Advanced Usage

Copy with Toast Notification

const [toast, setToast] = useState('');
const handleCopy = async (text: string) => {
try {
await navigator.clipboard.writeText(text);
setToast('Copied to clipboard!');
setTimeout(() => setToast(''), 3000);
} catch (error) {
setToast('Failed to copy');
setTimeout(() => setToast(''), 3000);
}
};
return (
<div>
<CopyButton value={text} onClick={() => handleCopy(text)} />
{toast && (
<div className="fixed top-4 right-4 bg-green-500 text-white px-4 py-2 rounded">
{toast}
</div>
)}
</div>
);

Copy with Analytics

const handleCopy = async (text: string, context: string) => {
try {
await navigator.clipboard.writeText(text);
// Track copy event
analytics.track('copy_button_clicked', {
context,
text_length: text.length,
timestamp: new Date().toISOString()
});
} catch (error) {
console.error('Copy failed:', error);
}
};

Copy with Fallback

const copyWithFallback = async (text: string) => {
try {
// Try modern clipboard API
await navigator.clipboard.writeText(text);
} catch (error) {
try {
// Fallback to legacy method
const textArea = document.createElement('textarea');
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
} catch (fallbackError) {
console.error('Copy failed:', fallbackError);
// Show user notification
}
}
};

Copy with Formatting

const copyFormatted = async (text: string, format: 'plain' | 'markdown' | 'html') => {
let formattedText = text;
switch (format) {
case 'markdown':
formattedText = `\`\`\`\n${text}\n\`\`\``;
break;
case 'html':
formattedText = `<pre><code>${text}</code></pre>`;
break;
default:
formattedText = text;
}
await navigator.clipboard.writeText(formattedText);
};
  • Button: For general button functionality
  • Toast: For copy notifications
  • Tooltip: For copy button tooltips
  • Code: For code display
  • Input: For text input

API Reference

For the complete API reference and advanced usage patterns, see the CopyButton API documentation.

Edit this page on GitHub