Explore the enhanced Monaco Editor with integrated copy-to-clipboard functionality. This demonstrates TASK-020 implementation with visual feedback and multiple positioning options.
The copy button appears in the top-right corner by default when enabled.
JavaScript is required to use the interactive code editor.
// Click the copy button in the top-right corner!
const message: string = 'Hello, Sparkle!'
const features: string[] = [
'TypeScript Support',
'Copy to Clipboard',
'Visual Feedback',
'Multiple Positions'
]
function displayFeatures(features: string[]): void {
console.log('Sparkle Features:')
features.forEach((feature, index) => {
console.log(`${index + 1}. ${feature}`)
})
}
displayFeatures(features)
console.log(message)
When using a header, the copy button integrates seamlessly with the title bar.
React Counter Component JavaScript is required to use the interactive code editor.
// React component example with copy functionality
import React, { useState } from 'react'
interface CounterProps {
initialValue?: number
step?: number
}
export const Counter: React.FC<CounterProps> = ({
initialValue = 0,
step = 1
}) => {
const [count, setCount] = useState(initialValue)
const increment = () => setCount(prev => prev + step)
const decrement = () => setCount(prev => prev - step)
const reset = () => setCount(initialValue)
return (
<div className="counter">
<p>Count: {count}</p>
<button onClick={increment}>+{step}</button>
<button onClick={decrement}>-{step}</button>
<button onClick={reset}>Reset</button>
</div>
)
}
Copy button positioned at the bottom-right corner.
JavaScript is required to use the interactive code editor.
// Utility functions with TypeScript
export const StringUtils = {
capitalize: (str: string): string =>
str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(),
truncate: (str: string, maxLength: number): string =>
str.length > maxLength ? str.slice(0, maxLength) + '...' : str,
slugify: (str: string): string =>
str.toLowerCase()
.replace(/[^a-z0-9 -]/g, '')
.replace(/s+/g, '-')
.replace(/-+/g, '-'),
isEmail: (str: string): boolean => {
const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/
return emailRegex.test(str)
}
}
// Usage examples
console.log(StringUtils.capitalize('hello world'))
console.log(StringUtils.truncate('This is a long text', 10))
console.log(StringUtils.slugify('Hello World 123!'))
console.log(StringUtils.isEmail('user@example.com'))
Copy button positioned at the bottom-left corner.
JavaScript is required to use the interactive code editor.
// API client with error handling
class ApiClient {
private baseUrl: string
private defaultHeaders: Record<string, string>
constructor(baseUrl: string, apiKey?: string) {
this.baseUrl = baseUrl.replace(//$/, '')
this.defaultHeaders = {
'Content-Type': 'application/json',
...(apiKey && { 'Authorization': `Bearer ${apiKey}` })
}
}
async get<T>(endpoint: string): Promise<T> {
return this.request<T>('GET', endpoint)
}
async post<T>(endpoint: string, data?: unknown): Promise<T> {
return this.request<T>('POST', endpoint, data)
}
private async request<T>(
method: string,
endpoint: string,
data?: unknown
): Promise<T> {
const url = `${this.baseUrl}${endpoint}`
try {
const response = await fetch(url, {
method,
headers: this.defaultHeaders,
...(data && { body: JSON.stringify(data) })
})
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
return await response.json()
} catch (error) {
console.error('API request failed:', error)
throw error
}
}
}
Different styling options for the copy button:
JavaScript is required to use the interactive code editor.
const example = 'Default button style with solid background'
JavaScript is required to use the interactive code editor.
const example = 'Outline button style with border'
JavaScript is required to use the interactive code editor.
const example = 'Ghost button style with subtle background'
JavaScript is required to use the interactive code editor.
const example = 'Minimal button style, very subtle'
✅ Copy to Clipboard : Click any copy button to copy the code content
✅ Visual Feedback : Button states change to show copy progress (copying → copied → back to idle)
✅ Error Handling : Graceful fallback for older browsers
✅ Flexible Positioning : Top/bottom, left/right corner options
✅ Style Variants : Default, outline, ghost, and minimal button styles
✅ Size Options : Small, medium, and large button sizes
✅ Header Integration : Copy button can be integrated into a title header
✅ Accessibility : Proper ARIA labels and keyboard support
This copy functionality is implemented as part of TASK-020 in the Astro Starlight documentation site. The implementation includes:
useCopyToClipboard Hook : Manages clipboard operations with fallback support
CopyButton Component : Reusable button with visual feedback states
Enhanced CodeEditor : Monaco Editor with integrated copy functionality
Astro Integration : Seamless integration with Astro Starlight
The copy functionality uses the modern Clipboard API when available and falls back to the legacy execCommand method for broader browser support.