Start scaffolding out the Copilot Modal UI
Co-Authored-By: Mikayla Maki <mikayla.c.maki@gmail.com>
This commit is contained in:
parent
4e6fb9034d
commit
cc445f7cef
8 changed files with 180 additions and 9 deletions
63
crates/ui2/src/components/copilot.rs
Normal file
63
crates/ui2/src/components/copilot.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{prelude::*, Button, Label, LabelColor, Modal};
|
||||
|
||||
#[derive(Element)]
|
||||
pub struct CopilotModal<S: 'static + Send + Sync + Clone> {
|
||||
id: ElementId,
|
||||
state_type: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S: 'static + Send + Sync + Clone> CopilotModal<S> {
|
||||
pub fn new(id: impl Into<ElementId>) -> Self {
|
||||
Self {
|
||||
id: id.into(),
|
||||
state_type: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
|
||||
let color = ThemeColor::new(cx);
|
||||
|
||||
div().id(self.id.clone()).child(
|
||||
Modal::new("some-id")
|
||||
.title("Connect Copilot to Zed")
|
||||
.child(Label::new("You can update your settings or sign out from the Copilot menu in the status bar.").color(LabelColor::Muted))
|
||||
.primary_action(Button::new("Connect to Github").variant(ButtonVariant::Filled)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "stories")]
|
||||
pub use stories::*;
|
||||
|
||||
#[cfg(feature = "stories")]
|
||||
mod stories {
|
||||
use crate::Story;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Element)]
|
||||
pub struct CopilotModalStory<S: 'static + Send + Sync + Clone> {
|
||||
state_type: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S: 'static + Send + Sync + Clone> CopilotModalStory<S> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
state_type: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
_view: &mut S,
|
||||
cx: &mut ViewContext<S>,
|
||||
) -> impl Element<ViewState = S> {
|
||||
Story::container(cx)
|
||||
.child(Story::title_for::<_, CopilotModal<S>>(cx))
|
||||
.child(Story::label(cx, "Default"))
|
||||
.child(CopilotModal::new("copilot-modal"))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -518,13 +518,10 @@ impl<S: 'static + Send + Sync> ListDetailsEntry<S> {
|
|||
this.child(Label::new(self.meta.clone().unwrap()).color(LabelColor::Muted))
|
||||
})
|
||||
.child(
|
||||
h_stack().gap_1().justify_end().children(
|
||||
self.actions
|
||||
.take()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|action| action),
|
||||
),
|
||||
h_stack()
|
||||
.gap_1()
|
||||
.justify_end()
|
||||
.children(self.actions.take().unwrap_or_default().into_iter()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
87
crates/ui2/src/components/modal.rs
Normal file
87
crates/ui2/src/components/modal.rs
Normal file
|
@ -0,0 +1,87 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use gpui2::AnyElement;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{h_stack, prelude::*, v_stack, Button, Icon, IconButton, Label};
|
||||
|
||||
#[derive(Element)]
|
||||
pub struct Modal<S: 'static + Send + Sync> {
|
||||
id: ElementId,
|
||||
state_type: PhantomData<S>,
|
||||
title: Option<SharedString>,
|
||||
primary_action: Option<Button<S>>,
|
||||
secondary_action: Option<Button<S>>,
|
||||
children: SmallVec<[AnyElement<S>; 2]>,
|
||||
}
|
||||
|
||||
impl<S: 'static + Send + Sync> Modal<S> {
|
||||
pub fn new(id: impl Into<ElementId>) -> Self {
|
||||
Self {
|
||||
id: id.into(),
|
||||
state_type: PhantomData,
|
||||
title: None,
|
||||
primary_action: None,
|
||||
secondary_action: None,
|
||||
children: SmallVec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn title(mut self, title: impl Into<SharedString>) -> Self {
|
||||
self.title = Some(title.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn primary_action(mut self, action: Button<S>) -> Self {
|
||||
self.primary_action = Some(action);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn secondary_action(mut self, action: Button<S>) -> Self {
|
||||
self.secondary_action = Some(action);
|
||||
self
|
||||
}
|
||||
|
||||
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
|
||||
let color = ThemeColor::new(cx);
|
||||
|
||||
v_stack()
|
||||
.id(self.id.clone())
|
||||
.w_96()
|
||||
// .rounded_xl()
|
||||
.bg(color.background)
|
||||
.border()
|
||||
.border_color(color.border)
|
||||
.shadow_2xl()
|
||||
.child(
|
||||
h_stack()
|
||||
.justify_between()
|
||||
.p_1()
|
||||
.border_b()
|
||||
.border_color(color.border)
|
||||
.child(div().children(self.title.clone().map(|t| Label::new(t))))
|
||||
.child(IconButton::new(Icon::Close)),
|
||||
)
|
||||
.child(v_stack().p_1().children(self.children.drain(..)))
|
||||
.when(
|
||||
self.primary_action.is_some() || self.secondary_action.is_some(),
|
||||
|this| {
|
||||
this.child(
|
||||
h_stack()
|
||||
.border_t()
|
||||
.border_color(color.border)
|
||||
.p_1()
|
||||
.justify_end()
|
||||
.children(self.secondary_action.take())
|
||||
.children(self.primary_action.take()),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: 'static + Send + Sync> ParentElement for Modal<S> {
|
||||
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::ViewState>; 2]> {
|
||||
&mut self.children
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue