Add clipboard (#105)
This commit is contained in:
parent
48c452e6f6
commit
12b5d1b501
6 changed files with 96 additions and 1 deletions
1
assets/icons/copy.svg
Normal file
1
assets/icons/copy.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
|
||||
|
After Width: | Height: | Size: 337 B |
|
|
@ -177,7 +177,7 @@ impl StoryWorkspace {
|
|||
|
||||
StoryContainer::add_pane(
|
||||
"Scrollable",
|
||||
"A scrollable area with scroll bar",
|
||||
"A scrollable area with scroll bar.",
|
||||
ScrollableStory::view(cx).into(),
|
||||
workspace.clone(),
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use gpui::{
|
|||
use ui::{
|
||||
button::{Button, ButtonStyle},
|
||||
checkbox::Checkbox,
|
||||
clipboard::Clipboard,
|
||||
h_flex,
|
||||
label::Label,
|
||||
link::Link,
|
||||
|
|
@ -213,5 +214,25 @@ impl Render for TextStory {
|
|||
)
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section("Clipboard", cx).child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_4()
|
||||
.items_start()
|
||||
.child(
|
||||
Clipboard::new("clipboard1")
|
||||
.content(|_| Label::new("Click icon to copy"))
|
||||
.value("Copied!")
|
||||
.on_copied(|value, _| println!("Copied value: {}", value)),
|
||||
)
|
||||
.child(
|
||||
Clipboard::new("clipboard2")
|
||||
.content(|_| Link::new("link1").href("https://github.com").child("GitHub"))
|
||||
.value("https://github.com")
|
||||
.on_copied(|value, _| println!("Copied value: {}", value)),
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
70
crates/ui/src/clipboard.rs
Normal file
70
crates/ui/src/clipboard.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use gpui::{
|
||||
prelude::FluentBuilder, AnyElement, ClipboardItem, ElementId, IntoElement, ParentElement,
|
||||
RenderOnce, SharedString, Styled, WindowContext,
|
||||
};
|
||||
|
||||
use crate::{button::Button, h_flex, Clickable, IconName};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct Clipboard {
|
||||
id: ElementId,
|
||||
value: SharedString,
|
||||
content_builder: Option<Box<dyn Fn(&mut WindowContext) -> AnyElement>>,
|
||||
copied_callback: Option<Box<dyn Fn(SharedString, &mut WindowContext)>>,
|
||||
}
|
||||
|
||||
impl Clipboard {
|
||||
pub fn new(id: impl Into<ElementId>) -> Self {
|
||||
Self {
|
||||
id: id.into(),
|
||||
value: "".into(),
|
||||
content_builder: None,
|
||||
copied_callback: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value(mut self, value: impl Into<SharedString>) -> Self {
|
||||
self.value = value.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn content<E, F>(mut self, element_builder: F) -> Self
|
||||
where
|
||||
E: IntoElement,
|
||||
F: Fn(&mut WindowContext) -> E + 'static,
|
||||
{
|
||||
self.content_builder = Some(Box::new(move |cx| element_builder(cx).into_any_element()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn on_copied<F>(mut self, handler: F) -> Self
|
||||
where
|
||||
F: Fn(SharedString, &mut WindowContext) + 'static,
|
||||
{
|
||||
self.copied_callback = Some(Box::new(handler));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for Clipboard {
|
||||
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
||||
h_flex()
|
||||
.gap_0p5()
|
||||
.when_some(self.content_builder, |this, builder| {
|
||||
this.child(builder(cx))
|
||||
})
|
||||
.child(
|
||||
Button::new(self.id, cx)
|
||||
.icon(IconName::Copy)
|
||||
.ghost()
|
||||
.on_click(move |_, cx| {
|
||||
cx.stop_propagation();
|
||||
cx.write_to_clipboard(ClipboardItem::new(self.value.to_string()));
|
||||
|
||||
if let Some(copied) = &self.copied_callback {
|
||||
copied(self.value.clone(), cx);
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,7 @@ pub enum IconName {
|
|||
ThumbsDown,
|
||||
ThumbsUp,
|
||||
Menu,
|
||||
Copy,
|
||||
}
|
||||
|
||||
impl IconName {
|
||||
|
|
@ -89,6 +90,7 @@ impl IconName {
|
|||
IconName::ThumbsDown => "icons/thumbs-down.svg",
|
||||
IconName::ThumbsUp => "icons/thumbs-up.svg",
|
||||
IconName::Menu => "icons/menu.svg",
|
||||
IconName::Copy => "icons/copy.svg",
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ mod svg_img;
|
|||
|
||||
pub mod button;
|
||||
pub mod checkbox;
|
||||
pub mod clipboard;
|
||||
pub mod divider;
|
||||
pub mod dropdown;
|
||||
pub mod indicator;
|
||||
|
|
|
|||
Loading…
Reference in a new issue