onboarding: Add the AI page (#35351)
This PR starts the work on the AI onboarding page as well as the configuration modal Release Notes: - N/A --------- Co-authored-by: Danilo Leal <daniloleal09@gmail.com> Co-authored-by: Anthony <anthony@zed.dev>
This commit is contained in:
parent
e5c6a596a9
commit
b01d1872cc
12 changed files with 550 additions and 63 deletions
|
@ -1,4 +1,5 @@
|
|||
mod avatar;
|
||||
mod badge;
|
||||
mod banner;
|
||||
mod button;
|
||||
mod callout;
|
||||
|
@ -41,6 +42,7 @@ mod tooltip;
|
|||
mod stories;
|
||||
|
||||
pub use avatar::*;
|
||||
pub use badge::*;
|
||||
pub use banner::*;
|
||||
pub use button::*;
|
||||
pub use callout::*;
|
||||
|
|
71
crates/ui/src/components/badge.rs
Normal file
71
crates/ui/src/components/badge.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
use crate::Divider;
|
||||
use crate::DividerColor;
|
||||
use crate::component_prelude::*;
|
||||
use crate::prelude::*;
|
||||
use gpui::{AnyElement, IntoElement, SharedString, Window};
|
||||
|
||||
#[derive(IntoElement, RegisterComponent)]
|
||||
pub struct Badge {
|
||||
label: SharedString,
|
||||
icon: IconName,
|
||||
}
|
||||
|
||||
impl Badge {
|
||||
pub fn new(label: impl Into<SharedString>) -> Self {
|
||||
Self {
|
||||
label: label.into(),
|
||||
icon: IconName::Check,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn icon(mut self, icon: IconName) -> Self {
|
||||
self.icon = icon;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for Badge {
|
||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
h_flex()
|
||||
.h_full()
|
||||
.gap_1()
|
||||
.pl_1()
|
||||
.pr_2()
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.bg(cx.theme().colors().element_background)
|
||||
.rounded_sm()
|
||||
.overflow_hidden()
|
||||
.child(
|
||||
Icon::new(self.icon)
|
||||
.size(IconSize::XSmall)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(Divider::vertical().color(DividerColor::Border))
|
||||
.child(
|
||||
Label::new(self.label.clone())
|
||||
.size(LabelSize::XSmall)
|
||||
.buffer_font(cx)
|
||||
.ml_1(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Badge {
|
||||
fn scope() -> ComponentScope {
|
||||
ComponentScope::DataDisplay
|
||||
}
|
||||
|
||||
fn description() -> Option<&'static str> {
|
||||
Some(
|
||||
"A compact, labeled component with optional icon for displaying status, categories, or metadata.",
|
||||
)
|
||||
}
|
||||
|
||||
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
|
||||
Some(
|
||||
single_example("Basic Badge", Badge::new("Default").into_any_element())
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
Clickable, Color, DynamicSpacing, Headline, HeadlineSize, IconButton, IconButtonShape,
|
||||
Clickable, Color, DynamicSpacing, Headline, HeadlineSize, Icon, IconButton, IconButtonShape,
|
||||
IconName, Label, LabelCommon, LabelSize, h_flex, v_flex,
|
||||
};
|
||||
use gpui::{prelude::FluentBuilder, *};
|
||||
|
@ -92,6 +92,7 @@ impl RenderOnce for Modal {
|
|||
|
||||
#[derive(IntoElement)]
|
||||
pub struct ModalHeader {
|
||||
icon: Option<Icon>,
|
||||
headline: Option<SharedString>,
|
||||
description: Option<SharedString>,
|
||||
children: SmallVec<[AnyElement; 2]>,
|
||||
|
@ -108,6 +109,7 @@ impl Default for ModalHeader {
|
|||
impl ModalHeader {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
icon: None,
|
||||
headline: None,
|
||||
description: None,
|
||||
children: SmallVec::new(),
|
||||
|
@ -116,6 +118,11 @@ impl ModalHeader {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn icon(mut self, icon: Icon) -> Self {
|
||||
self.icon = Some(icon);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the headline of the modal.
|
||||
///
|
||||
/// This will insert the headline as the first item
|
||||
|
@ -179,12 +186,17 @@ impl RenderOnce for ModalHeader {
|
|||
)
|
||||
})
|
||||
.child(
|
||||
v_flex().flex_1().children(children).when_some(
|
||||
self.description,
|
||||
|this, description| {
|
||||
v_flex()
|
||||
.flex_1()
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.when_some(self.icon, |this, icon| this.child(icon))
|
||||
.children(children),
|
||||
)
|
||||
.when_some(self.description, |this, description| {
|
||||
this.child(Label::new(description).color(Color::Muted).mb_2())
|
||||
},
|
||||
),
|
||||
}),
|
||||
)
|
||||
.when(self.show_dismiss_button, |this| {
|
||||
this.child(
|
||||
|
|
|
@ -566,7 +566,7 @@ impl RenderOnce for Switch {
|
|||
pub struct SwitchField {
|
||||
id: ElementId,
|
||||
label: SharedString,
|
||||
description: SharedString,
|
||||
description: Option<SharedString>,
|
||||
toggle_state: ToggleState,
|
||||
on_click: Arc<dyn Fn(&ToggleState, &mut Window, &mut App) + 'static>,
|
||||
disabled: bool,
|
||||
|
@ -577,14 +577,14 @@ impl SwitchField {
|
|||
pub fn new(
|
||||
id: impl Into<ElementId>,
|
||||
label: impl Into<SharedString>,
|
||||
description: impl Into<SharedString>,
|
||||
description: Option<SharedString>,
|
||||
toggle_state: impl Into<ToggleState>,
|
||||
on_click: impl Fn(&ToggleState, &mut Window, &mut App) + 'static,
|
||||
) -> Self {
|
||||
Self {
|
||||
id: id.into(),
|
||||
label: label.into(),
|
||||
description: description.into(),
|
||||
description: description,
|
||||
toggle_state: toggle_state.into(),
|
||||
on_click: Arc::new(on_click),
|
||||
disabled: false,
|
||||
|
@ -592,6 +592,11 @@ impl SwitchField {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn description(mut self, description: impl Into<SharedString>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn disabled(mut self, disabled: bool) -> Self {
|
||||
self.disabled = disabled;
|
||||
self
|
||||
|
@ -616,13 +621,15 @@ impl RenderOnce for SwitchField {
|
|||
.gap_4()
|
||||
.justify_between()
|
||||
.flex_wrap()
|
||||
.child(
|
||||
v_flex()
|
||||
.child(match &self.description {
|
||||
Some(description) => v_flex()
|
||||
.gap_0p5()
|
||||
.max_w_5_6()
|
||||
.child(Label::new(self.label))
|
||||
.child(Label::new(self.description).color(Color::Muted)),
|
||||
)
|
||||
.child(Label::new(self.label.clone()))
|
||||
.child(Label::new(description.clone()).color(Color::Muted))
|
||||
.into_any_element(),
|
||||
None => Label::new(self.label.clone()).into_any_element(),
|
||||
})
|
||||
.child(
|
||||
Switch::new(
|
||||
SharedString::from(format!("{}-switch", self.id)),
|
||||
|
@ -671,7 +678,7 @@ impl Component for SwitchField {
|
|||
SwitchField::new(
|
||||
"switch_field_unselected",
|
||||
"Enable notifications",
|
||||
"Receive notifications when new messages arrive.",
|
||||
Some("Receive notifications when new messages arrive.".into()),
|
||||
ToggleState::Unselected,
|
||||
|_, _, _| {},
|
||||
)
|
||||
|
@ -682,7 +689,7 @@ impl Component for SwitchField {
|
|||
SwitchField::new(
|
||||
"switch_field_selected",
|
||||
"Enable notifications",
|
||||
"Receive notifications when new messages arrive.",
|
||||
Some("Receive notifications when new messages arrive.".into()),
|
||||
ToggleState::Selected,
|
||||
|_, _, _| {},
|
||||
)
|
||||
|
@ -698,7 +705,7 @@ impl Component for SwitchField {
|
|||
SwitchField::new(
|
||||
"switch_field_default",
|
||||
"Default color",
|
||||
"This uses the default switch color.",
|
||||
Some("This uses the default switch color.".into()),
|
||||
ToggleState::Selected,
|
||||
|_, _, _| {},
|
||||
)
|
||||
|
@ -709,7 +716,7 @@ impl Component for SwitchField {
|
|||
SwitchField::new(
|
||||
"switch_field_accent",
|
||||
"Accent color",
|
||||
"This uses the accent color scheme.",
|
||||
Some("This uses the accent color scheme.".into()),
|
||||
ToggleState::Selected,
|
||||
|_, _, _| {},
|
||||
)
|
||||
|
@ -725,7 +732,7 @@ impl Component for SwitchField {
|
|||
SwitchField::new(
|
||||
"switch_field_disabled",
|
||||
"Disabled field",
|
||||
"This field is disabled and cannot be toggled.",
|
||||
Some("This field is disabled and cannot be toggled.".into()),
|
||||
ToggleState::Selected,
|
||||
|_, _, _| {},
|
||||
)
|
||||
|
@ -733,6 +740,20 @@ impl Component for SwitchField {
|
|||
.into_any_element(),
|
||||
)],
|
||||
),
|
||||
example_group_with_title(
|
||||
"No Description",
|
||||
vec![single_example(
|
||||
"No Description",
|
||||
SwitchField::new(
|
||||
"switch_field_disabled",
|
||||
"Disabled field",
|
||||
None,
|
||||
ToggleState::Selected,
|
||||
|_, _, _| {},
|
||||
)
|
||||
.into_any_element(),
|
||||
)],
|
||||
),
|
||||
])
|
||||
.into_any_element(),
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue