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
|
@ -173,6 +173,7 @@ fn generate_custom_value_setter(
|
||||||
method
|
method
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a vec of (Property name, has 'auto' suffix, tokens for accessing the property, documentation)
|
||||||
fn box_prefixes() -> Vec<(&'static str, bool, Vec<TokenStream2>, &'static str)> {
|
fn box_prefixes() -> Vec<(&'static str, bool, Vec<TokenStream2>, &'static str)> {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
|
@ -188,24 +189,32 @@ fn box_prefixes() -> Vec<(&'static str, bool, Vec<TokenStream2>, &'static str)>
|
||||||
vec![quote! {size.width}, quote! {size.height}],
|
vec![quote! {size.width}, quote! {size.height}],
|
||||||
"Sets the width and height of the element."
|
"Sets the width and height of the element."
|
||||||
),
|
),
|
||||||
|
// TODO: These don't use the same size ramp as the others
|
||||||
|
// see https://tailwindcss.com/docs/max-width
|
||||||
(
|
(
|
||||||
"min_w",
|
"min_w",
|
||||||
true,
|
true,
|
||||||
vec![quote! { min_size.width }],
|
vec![quote! { min_size.width }],
|
||||||
"Sets the minimum width of the element. [Docs](https://tailwindcss.com/docs/min-width)",
|
"Sets the minimum width of the element. [Docs](https://tailwindcss.com/docs/min-width)",
|
||||||
),
|
),
|
||||||
|
// TODO: These don't use the same size ramp as the others
|
||||||
|
// see https://tailwindcss.com/docs/max-width
|
||||||
(
|
(
|
||||||
"min_h",
|
"min_h",
|
||||||
true,
|
true,
|
||||||
vec![quote! { min_size.height }],
|
vec![quote! { min_size.height }],
|
||||||
"Sets the minimum height of the element. [Docs](https://tailwindcss.com/docs/min-height)",
|
"Sets the minimum height of the element. [Docs](https://tailwindcss.com/docs/min-height)",
|
||||||
),
|
),
|
||||||
|
// TODO: These don't use the same size ramp as the others
|
||||||
|
// see https://tailwindcss.com/docs/max-width
|
||||||
(
|
(
|
||||||
"max_w",
|
"max_w",
|
||||||
true,
|
true,
|
||||||
vec![quote! { max_size.width }],
|
vec![quote! { max_size.width }],
|
||||||
"Sets the maximum width of the element. [Docs](https://tailwindcss.com/docs/max-width)",
|
"Sets the maximum width of the element. [Docs](https://tailwindcss.com/docs/max-width)",
|
||||||
),
|
),
|
||||||
|
// TODO: These don't use the same size ramp as the others
|
||||||
|
// see https://tailwindcss.com/docs/max-width
|
||||||
(
|
(
|
||||||
"max_h",
|
"max_h",
|
||||||
true,
|
true,
|
||||||
|
@ -336,6 +345,7 @@ fn box_prefixes() -> Vec<(&'static str, bool, Vec<TokenStream2>, &'static str)>
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a vec of (Suffix size, tokens that correspond to this size, documentation)
|
||||||
fn box_suffixes() -> Vec<(&'static str, TokenStream2, &'static str)> {
|
fn box_suffixes() -> Vec<(&'static str, TokenStream2, &'static str)> {
|
||||||
vec![
|
vec![
|
||||||
("0", quote! { px(0.) }, "0px"),
|
("0", quote! { px(0.) }, "0px"),
|
||||||
|
|
|
@ -65,6 +65,7 @@ pub enum ComponentStory {
|
||||||
ChatPanel,
|
ChatPanel,
|
||||||
CollabPanel,
|
CollabPanel,
|
||||||
CommandPalette,
|
CommandPalette,
|
||||||
|
Copilot,
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
Facepile,
|
Facepile,
|
||||||
Keybinding,
|
Keybinding,
|
||||||
|
@ -170,6 +171,10 @@ impl ComponentStory {
|
||||||
ui::TrafficLightsStory::new().into_any()
|
ui::TrafficLightsStory::new().into_any()
|
||||||
})
|
})
|
||||||
.into_any(),
|
.into_any(),
|
||||||
|
Self::Copilot => view(cx.entity(|cx| ()), |_, _| {
|
||||||
|
ui::CopilotModalStory::new().into_any()
|
||||||
|
})
|
||||||
|
.into_any(),
|
||||||
Self::Workspace => ui::WorkspaceStory::view(cx).into_any(),
|
Self::Workspace => ui::WorkspaceStory::view(cx).into_any(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,14 @@ mod chat_panel;
|
||||||
mod collab_panel;
|
mod collab_panel;
|
||||||
mod command_palette;
|
mod command_palette;
|
||||||
mod context_menu;
|
mod context_menu;
|
||||||
|
mod copilot;
|
||||||
mod editor_pane;
|
mod editor_pane;
|
||||||
mod facepile;
|
mod facepile;
|
||||||
mod icon_button;
|
mod icon_button;
|
||||||
mod keybinding;
|
mod keybinding;
|
||||||
mod language_selector;
|
mod language_selector;
|
||||||
mod list;
|
mod list;
|
||||||
|
mod modal;
|
||||||
mod multi_buffer;
|
mod multi_buffer;
|
||||||
mod notification_toast;
|
mod notification_toast;
|
||||||
mod notifications_panel;
|
mod notifications_panel;
|
||||||
|
@ -40,12 +42,14 @@ pub use chat_panel::*;
|
||||||
pub use collab_panel::*;
|
pub use collab_panel::*;
|
||||||
pub use command_palette::*;
|
pub use command_palette::*;
|
||||||
pub use context_menu::*;
|
pub use context_menu::*;
|
||||||
|
pub use copilot::*;
|
||||||
pub use editor_pane::*;
|
pub use editor_pane::*;
|
||||||
pub use facepile::*;
|
pub use facepile::*;
|
||||||
pub use icon_button::*;
|
pub use icon_button::*;
|
||||||
pub use keybinding::*;
|
pub use keybinding::*;
|
||||||
pub use language_selector::*;
|
pub use language_selector::*;
|
||||||
pub use list::*;
|
pub use list::*;
|
||||||
|
pub use modal::*;
|
||||||
pub use multi_buffer::*;
|
pub use multi_buffer::*;
|
||||||
pub use notification_toast::*;
|
pub use notification_toast::*;
|
||||||
pub use notifications_panel::*;
|
pub use notifications_panel::*;
|
||||||
|
|
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))
|
this.child(Label::new(self.meta.clone().unwrap()).color(LabelColor::Muted))
|
||||||
})
|
})
|
||||||
.child(
|
.child(
|
||||||
h_stack().gap_1().justify_end().children(
|
h_stack()
|
||||||
self.actions
|
.gap_1()
|
||||||
.take()
|
.justify_end()
|
||||||
.unwrap_or_default()
|
.children(self.actions.take().unwrap_or_default().into_iter()),
|
||||||
.into_iter()
|
|
||||||
.map(|action| action),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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
|
||||||
|
}
|
||||||
|
}
|
|
@ -146,7 +146,11 @@ impl<S: 'static + Send + Sync> Button<S> {
|
||||||
self.icon.map(|i| IconElement::new(i).color(icon_color))
|
self.icon.map(|i| IconElement::new(i).color(icon_color))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
|
pub fn render(
|
||||||
|
&mut self,
|
||||||
|
_view: &mut S,
|
||||||
|
cx: &mut ViewContext<S>,
|
||||||
|
) -> impl Element<ViewState = S> {
|
||||||
let icon_color = self.icon_color();
|
let icon_color = self.icon_color();
|
||||||
let border_color = self.border_color(cx);
|
let border_color = self.border_color(cx);
|
||||||
let settings = user_settings(cx);
|
let settings = user_settings(cx);
|
||||||
|
|
|
@ -110,7 +110,7 @@ pub struct ThemeColor {
|
||||||
/// The background color of an elevated surface, like a modal, tooltip or toast.
|
/// The background color of an elevated surface, like a modal, tooltip or toast.
|
||||||
pub elevated_surface: Hsla,
|
pub elevated_surface: Hsla,
|
||||||
pub surface: Hsla,
|
pub surface: Hsla,
|
||||||
/// Window background color
|
/// Window background color of the base app
|
||||||
pub background: Hsla,
|
pub background: Hsla,
|
||||||
/// Default background for elements like filled buttons,
|
/// Default background for elements like filled buttons,
|
||||||
/// text fields, checkboxes, radio buttons, etc.
|
/// text fields, checkboxes, radio buttons, etc.
|
||||||
|
@ -149,6 +149,7 @@ pub struct ThemeColor {
|
||||||
pub title_bar: Hsla,
|
pub title_bar: Hsla,
|
||||||
pub toolbar: Hsla,
|
pub toolbar: Hsla,
|
||||||
pub tab_bar: Hsla,
|
pub tab_bar: Hsla,
|
||||||
|
/// The background of the editor
|
||||||
pub editor: Hsla,
|
pub editor: Hsla,
|
||||||
pub editor_subheader: Hsla,
|
pub editor_subheader: Hsla,
|
||||||
pub editor_active_line: Hsla,
|
pub editor_active_line: Hsla,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue