1use gpui::{AnyElement, Div, StyleRefinement};
2use smallvec::SmallVec;
3use ui::prelude::*;
4
5#[derive(IntoElement)]
6pub struct FeatureUpsell {
7 base: Div,
8 text: SharedString,
9 docs_url: Option<SharedString>,
10 children: SmallVec<[AnyElement; 2]>,
11}
12
13impl FeatureUpsell {
14 pub fn new(text: impl Into<SharedString>) -> Self {
15 Self {
16 base: h_flex(),
17 text: text.into(),
18 docs_url: None,
19 children: SmallVec::new(),
20 }
21 }
22
23 pub fn docs_url(mut self, docs_url: impl Into<SharedString>) -> Self {
24 self.docs_url = Some(docs_url.into());
25 self
26 }
27}
28
29impl ParentElement for FeatureUpsell {
30 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
31 self.children.extend(elements)
32 }
33}
34
35// Style methods.
36impl FeatureUpsell {
37 fn style(&mut self) -> &mut StyleRefinement {
38 self.base.style()
39 }
40
41 gpui::border_style_methods!({
42 visibility: pub
43 });
44}
45
46impl RenderOnce for FeatureUpsell {
47 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
48 self.base
49 .py_2()
50 .px_4()
51 .justify_between()
52 .flex_wrap()
53 .border_color(cx.theme().colors().border_variant)
54 .child(Label::new(self.text))
55 .child(h_flex().gap_2().children(self.children).when_some(
56 self.docs_url,
57 |el, docs_url| {
58 el.child(
59 Button::new("open_docs", "View Documentation")
60 .icon(IconName::ArrowUpRight)
61 .icon_size(IconSize::Small)
62 .icon_position(IconPosition::End)
63 .on_click({
64 move |_event, _window, cx| {
65 telemetry::event!(
66 "Documentation Viewed",
67 source = "Feature Upsell",
68 url = docs_url,
69 );
70 cx.open_url(&docs_url)
71 }
72 }),
73 )
74 },
75 ))
76 }
77}