Clipboard
The Clipboard component provides an easy way to copy text or other data to the user's clipboard. It renders as a button with a copy icon that changes to a checkmark when content is successfully copied. The component supports both static values and dynamic content through callback functions.
Import
use gpui_component::clipboard::Clipboard;
Usage
Basic Clipboard
Clipboard::new("my-clipboard")
.value("Text to copy")
.on_copied(|value, window, cx| {
window.push_notification(format!("Copied: {}", value), cx)
})
With Dynamic Content
Clipboard::new("clipboard")
.content(|_, _| Label::new("Copy this text"))
.value("Hello, World!")
Using Value Function
For dynamic values that should be computed when the copy action occurs:
let state = some_state.clone();
Clipboard::new("dynamic-clipboard")
.value_fn(move |_, cx| {
state.read(cx).get_current_value()
})
.on_copied(|value, window, cx| {
window.push_notification(format!("Copied: {}", value), cx)
})
With Custom Content
use gpui_component::label::Label;
Clipboard::new("custom-clipboard")
.content(|_, _|
h_flex()
.gap_2()
.child(Label::new("Share URL"))
.child(Icon::new(IconName::Share))
)
.value("https://example.com")
In Input Fields
The Clipboard component is commonly used as a suffix in input fields:
use gpui_component::input::{InputState, TextInput};
let url_state = cx.new(|cx| InputState::new(window, cx).default_value("https://github.com"));
TextInput::new(&url_state)
.suffix(
Clipboard::new("url-clipboard")
.value_fn({
let state = url_state.clone();
move |_, cx| state.read(cx).value()
})
.on_copied(|value, window, cx| {
window.push_notification(format!("URL copied: {}", value), cx)
})
)
API Reference
Clipboard
Method | Description |
---|---|
new(id) | Create a new clipboard component with the given ID |
value(str) | Set static text to copy to clipboard |
value_fn(fn) | Set dynamic function that returns the value to copy |
content(fn) | Set custom content to display alongside the copy button |
on_copied(fn) | Callback executed when content is successfully copied |
Method Details
value(value: impl Into<SharedString>)
Sets a static value that will be copied to the clipboard when the button is clicked.
Clipboard::new("static")
.value("Static text to copy")
value_fn(fn: impl Fn(&mut Window, &mut App) -> SharedString + 'static)
Sets a function that will be called to get the value when the copy action occurs. This is useful for dynamic content that may change over time.
Clipboard::new("dynamic")
.value_fn(|_, cx| {
format!("Current time: {}", SystemTime::now())
})
content(fn: impl Fn(&mut Window, &mut App) -> E + 'static)
Sets custom content to display before the copy button. The content can be any element that implements IntoElement
.
Clipboard::new("with-content")
.content(|_, _| Label::new("Copy me"))
.value("Hello")
on_copied(fn: impl Fn(SharedString, &mut Window, &mut App) + 'static)
Sets a callback that is executed when content is successfully copied. Receives the copied value as the first parameter.
Clipboard::new("with-callback")
.value("Hello")
.on_copied(|value, window, cx| {
println!("Copied: {}", value);
window.push_notification("Copied to clipboard!", cx);
})
Behavior
Visual States
The clipboard button has two visual states:
- Default State: Shows a copy icon (IconName::Copy)
- Copied State: Shows a checkmark icon (IconName::Check) for 2 seconds after successful copy
Copy Process
- User clicks the clipboard button
- The component determines the value to copy:
- If
value_fn
is set, calls the function to get the current value - Otherwise, uses the static
value
- If
- Writes the value to the system clipboard using
ClipboardItem::new_string()
- Changes the button icon to a checkmark
- Calls the
on_copied
callback if provided - After 2 seconds, resets the icon back to the copy icon
Event Handling
- Click events are handled internally and call
cx.stop_propagation()
to prevent bubbling - The component is disabled (unclickable) while in the "copied" state
- Uses GPUI's clipboard API (
cx.write_to_clipboard()
) for system integration
Examples
Simple Text Copy
Clipboard::new("simple")
.value("Hello, World!")
With User Feedback
Clipboard::new("feedback")
.content(|_, _| Label::new("API Key"))
.value("sk-1234567890abcdef")
.on_copied(|_, window, cx| {
window.push_notification("API key copied to clipboard", cx)
})
Form Field Integration
use gpui_component::{
input::{InputState, TextInput},
h_flex, label::Label
};
let api_key = "sk-1234567890abcdef";
h_flex()
.gap_2()
.items_center()
.child(Label::new("API Key:"))
.child(
TextInput::new(&input_state)
.value(api_key)
.readonly(true)
.suffix(
Clipboard::new("api-key-copy")
.value(api_key)
.on_copied(|_, window, cx| {
window.push_notification("API key copied!", cx)
})
)
)
Dynamic Content Copy
struct AppState {
current_url: String,
}
let app_state = cx.new(|_| AppState {
current_url: "https://example.com".to_string()
});
Clipboard::new("current-url")
.content(|_, _| Label::new("Share current page"))
.value_fn({
let state = app_state.clone();
move |_, cx| {
SharedString::from(state.read(cx).current_url.clone())
}
})
.on_copied(|url, window, cx| {
window.push_notification(format!("Shared: {}", url), cx)
})
Data Types
The Clipboard component currently supports copying text strings to the clipboard. It uses GPUI's ClipboardItem::new_string()
method, which handles:
- Plain text strings
- UTF-8 encoded content
- Cross-platform clipboard integration
Accessibility
- Keyboard Navigation: The clipboard button can be focused and activated using keyboard navigation
- Visual Feedback: Clear visual state changes (copy icon → checkmark) indicate successful operations
- Screen Reader Support: The button state changes are announced to assistive technologies
- Focus Management: Proper focus handling through GPUI's focus system
- Semantic Markup: Uses proper button semantics for screen reader compatibility
Accessibility Best Practices
- Provide Clear Labels: Use descriptive content or ensure the context makes the copy action clear
- User Feedback: Always provide feedback when copy operations succeed
- Keyboard Support: Ensure the component works with keyboard-only navigation
- Error Handling: Consider providing feedback if copy operations fail
// Good: Clear context and feedback
Clipboard::new("email-copy")
.content(|_, _| Label::new("Copy email address"))
.value("user@example.com")
.on_copied(|_, window, cx| {
window.push_notification("Email address copied to clipboard", cx)
})