Upsell built-in features on the extensions page (#14516)

This PR extends the extensions page with support for upselling built-in
Zed features when certain keywords are searched for.

This should help inform users about features that Zed has out-of-the-box
when they go looking for them as extensions.

For example, when someone searches "vim":

<img width="1341" alt="Screenshot 2024-07-15 at 4 58 44 PM"
src="https://github.com/user-attachments/assets/b256d07a-559a-43c2-b491-3eca5bff436e">

Here are more examples of what the upsells can look like:

<img width="1341" alt="Screenshot 2024-07-15 at 4 54 39 PM"
src="https://github.com/user-attachments/assets/1f453132-ac14-4884-afc4-7c12db47ad1d">

Release Notes:

- Added banners for built-in Zed features when corresponding keywords
are used in the extension search.
This commit is contained in:
Marshall Bowers 2024-07-15 17:10:01 -04:00 committed by GitHub
parent d7a25c1696
commit 2ae1a472e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 205 additions and 9 deletions

View file

@ -0,0 +1,72 @@
use gpui::{AnyElement, Div, StyleRefinement};
use smallvec::SmallVec;
use ui::{prelude::*, ButtonLike};
#[derive(IntoElement)]
pub struct FeatureUpsell {
base: Div,
text: SharedString,
docs_url: Option<SharedString>,
children: SmallVec<[AnyElement; 2]>,
}
impl FeatureUpsell {
pub fn new(text: impl Into<SharedString>) -> Self {
Self {
base: h_flex(),
text: text.into(),
docs_url: None,
children: SmallVec::new(),
}
}
pub fn docs_url(mut self, docs_url: impl Into<SharedString>) -> Self {
self.docs_url = Some(docs_url.into());
self
}
}
impl ParentElement for FeatureUpsell {
fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
self.children.extend(elements)
}
}
// Style methods.
impl FeatureUpsell {
fn style(&mut self) -> &mut StyleRefinement {
self.base.style()
}
gpui::border_style_methods!({
visibility: pub
});
}
impl RenderOnce for FeatureUpsell {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
self.base
.p_4()
.justify_between()
.border_color(cx.theme().colors().border)
.child(v_flex().overflow_hidden().child(Label::new(self.text)))
.child(h_flex().gap_2().children(self.children).when_some(
self.docs_url,
|el, docs_url| {
el.child(
ButtonLike::new("open_docs")
.child(
h_flex()
.gap_2()
.child(Label::new("View docs"))
.child(Icon::new(IconName::ArrowUpRight)),
)
.on_click({
let docs_url = docs_url.clone();
move |_event, cx| cx.open_url(&docs_url)
}),
)
},
))
}
}