From f798b193d0d40c91abcc67a57e571ae744a33e15 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 7 Dec 2023 01:46:28 -0500 Subject: [PATCH] WIP --- crates/feedback2/src/feedback_modal.rs | 65 ++++++++++--------- crates/ui2/src/components/button/button.rs | 48 +++++++++----- .../ui2/src/components/button/button_like.rs | 8 +++ crates/ui2/src/components/icon.rs | 3 +- crates/ui2/src/prelude.rs | 2 +- 5 files changed, 79 insertions(+), 47 deletions(-) diff --git a/crates/feedback2/src/feedback_modal.rs b/crates/feedback2/src/feedback_modal.rs index b4d4b08d54..aa6f3910a1 100644 --- a/crates/feedback2/src/feedback_modal.rs +++ b/crates/feedback2/src/feedback_modal.rs @@ -6,15 +6,15 @@ use db::kvp::KEY_VALUE_STORE; use editor::{Editor, EditorEvent}; use futures::AsyncReadExt; use gpui::{ - div, red, rems, serde_json, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, - FocusableView, Model, PromptLevel, Render, Task, View, ViewContext, + div, rems, serde_json, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, + Model, PromptLevel, Render, Task, View, ViewContext, }; use isahc::Request; use language::Buffer; use project::Project; use regex::Regex; use serde_derive::Serialize; -use ui::{prelude::*, Button, ButtonStyle, Label, Tooltip}; +use ui::{prelude::*, Button, ButtonStyle, IconPosition, Label, Tooltip}; use util::ResultExt; use workspace::Workspace; @@ -285,29 +285,22 @@ impl Render for FeedbackModal { let open_community_repo = cx.listener(|_, _, cx| cx.dispatch_action(Box::new(OpenZedCommunityRepo))); - // TODO: Nate UI pass v_stack() .elevation_3(cx) .key_context("GiveFeedback") .on_action(cx.listener(Self::cancel)) .min_w(rems(40.)) .max_w(rems(96.)) - .min_h(rems(24.)) - .max_h(rems(42.)) - .gap_2() + .h(rems(32.)) .child( v_stack() - .p_4() - .child( - div() - .size_full() - .child(Label::new("Give Feedback").color(Color::Default)) - .child(Label::new("This editor supports markdown").color(Color::Muted)), - ), + .px_4() + .pt_4() + .pb_2() + .child(Label::new("Give Feedback").color(Color::Default)) + .child(Label::new("This editor supports markdown").color(Color::Muted)), ) - .child(v_stack() - .p_4() - .child( + .child( div() .flex_1() .bg(cx.theme().colors().editor_background) @@ -317,37 +310,49 @@ impl Render for FeedbackModal { ) .child( div().child( - Label::new(format!( - "Characters: {}", - characters_remaining - )) + Label::new( + if !valid_character_count && characters_remaining < 0 { + "Feedback must be at least 10 characters.".to_string() + } else if !valid_character_count && characters_remaining > 5000 { + "Feedback must be less than 5000 characters.".to_string() + } else { + format!( + "Characters: {}", + characters_remaining + ) + } + ) .map(|this| if valid_character_count { this.color(Color::Success) } else { this.color(Color::Error) - } ) - ), - ) - .child( - div() + ) + .child( + v_stack() + .p_4() + .child( + h_stack() .bg(cx.theme().colors().editor_background) .border() .border_color(cx.theme().colors().border) - .child(self.email_address_editor.clone()) + .child(self.email_address_editor.clone())) ) .child( h_stack() + .p_4() .justify_between() .gap_1() .child(Button::new("community_repo", "Community Repo") - .style(ButtonStyle::Filled) - .color(Color::Muted) + .style(ButtonStyle::Transparent) + .icon(Icon::ExternalLink) + .icon_position(IconPosition::End) + .icon_size(IconSize::Small) .on_click(open_community_repo) ) - .child(h_stack().justify_between().gap_1() + .child(h_stack().gap_1() .child( Button::new("cancel_feedback", "Cancel") .style(ButtonStyle::Subtle) diff --git a/crates/ui2/src/components/button/button.rs b/crates/ui2/src/components/button/button.rs index c1262321ce..607b6c8a61 100644 --- a/crates/ui2/src/components/button/button.rs +++ b/crates/ui2/src/components/button/button.rs @@ -1,6 +1,6 @@ use gpui::{AnyView, DefiniteLength}; -use crate::prelude::*; +use crate::{prelude::*, IconPosition}; use crate::{ ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, Icon, IconSize, Label, LineHeightStyle, }; @@ -14,6 +14,7 @@ pub struct Button { label_color: Option, selected_label: Option, icon: Option, + icon_position: Option, icon_size: Option, icon_color: Option, selected_icon: Option, @@ -27,6 +28,7 @@ impl Button { label_color: None, selected_label: None, icon: None, + icon_position: None, icon_size: None, icon_color: None, selected_icon: None, @@ -48,6 +50,11 @@ impl Button { self } + pub fn icon_position(mut self, icon_position: impl Into>) -> Self { + self.icon_position = icon_position.into(); + self + } + pub fn icon_size(mut self, icon_size: impl Into>) -> Self { self.icon_size = icon_size.into(); self @@ -141,19 +148,30 @@ impl RenderOnce for Button { self.label_color.unwrap_or_default() }; - self.base - .children(self.icon.map(|icon| { - ButtonIcon::new(icon) - .disabled(is_disabled) - .selected(is_selected) - .selected_icon(self.selected_icon) - .size(self.icon_size) - .color(self.icon_color) - })) - .child( - Label::new(label) - .color(label_color) - .line_height_style(LineHeightStyle::UILabel), - ) + self.base.child( + h_stack() + .gap_1() + .map(|this| { + if self.icon_position == Some(IconPosition::End) { + this.flex_row_reverse() + } else { + this + } + }) + .flex_row_reverse() + .child( + Label::new(label) + .color(label_color) + .line_height_style(LineHeightStyle::UILabel), + ) + .children(self.icon.map(|icon| { + ButtonIcon::new(icon) + .disabled(is_disabled) + .selected(is_selected) + .selected_icon(self.selected_icon) + .size(self.icon_size) + .color(self.icon_color) + })), + ) } } diff --git a/crates/ui2/src/components/button/button_like.rs b/crates/ui2/src/components/button/button_like.rs index 1a33eb2845..9f42c95e7e 100644 --- a/crates/ui2/src/components/button/button_like.rs +++ b/crates/ui2/src/components/button/button_like.rs @@ -30,6 +30,13 @@ pub trait ButtonCommon: Clickable + Disableable { fn tooltip(self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self; } +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)] +pub enum IconPosition { + #[default] + Start, + End, +} + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)] pub enum ButtonStyle { /// A filled button with a solid background color. Provides emphasis versus @@ -344,6 +351,7 @@ impl RenderOnce for ButtonLike { .gap_1() .px_1() .bg(self.style.enabled(cx).background) + .when(self.disabled, |this| this.cursor_not_allowed()) .when(!self.disabled, |this| { this.cursor_pointer() .hover(|hover| hover.bg(self.style.hovered(cx).background)) diff --git a/crates/ui2/src/components/icon.rs b/crates/ui2/src/components/icon.rs index a5b09782f5..88af3847f5 100644 --- a/crates/ui2/src/components/icon.rs +++ b/crates/ui2/src/components/icon.rs @@ -51,6 +51,7 @@ pub enum Icon { CopilotDisabled, Dash, Envelope, + ExternalLink, ExclamationTriangle, Exit, File, @@ -122,13 +123,13 @@ impl Icon { Icon::Close => "icons/x.svg", Icon::Collab => "icons/user_group_16.svg", Icon::Copilot => "icons/copilot.svg", - Icon::CopilotInit => "icons/copilot_init.svg", Icon::CopilotError => "icons/copilot_error.svg", Icon::CopilotDisabled => "icons/copilot_disabled.svg", Icon::Dash => "icons/dash.svg", Icon::Envelope => "icons/feedback.svg", Icon::ExclamationTriangle => "icons/warning.svg", + Icon::ExternalLink => "icons/external_link.svg", Icon::Exit => "icons/exit.svg", Icon::File => "icons/file.svg", Icon::FileDoc => "icons/file_icons/book.svg", diff --git a/crates/ui2/src/prelude.rs b/crates/ui2/src/prelude.rs index 42fb44ed4d..076d34644c 100644 --- a/crates/ui2/src/prelude.rs +++ b/crates/ui2/src/prelude.rs @@ -12,6 +12,6 @@ pub use crate::selectable::*; pub use crate::{h_stack, v_stack}; pub use crate::{Button, ButtonSize, ButtonStyle, IconButton}; pub use crate::{ButtonCommon, Color, StyledExt}; -pub use crate::{Icon, IconElement, IconSize}; +pub use crate::{Icon, IconElement, IconPosition, IconSize}; pub use crate::{Label, LabelCommon, LabelSize, LineHeightStyle}; pub use theme::ActiveTheme;