Skip to repository content150 lines · 4.6 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:43:57.195Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
agent_setup_button.rs
1use crate::prelude::*;
2use gpui::{ClickEvent, Role, SharedString};
3
4#[derive(IntoElement, RegisterComponent)]
5pub struct AgentSetupButton {
6 id: ElementId,
7 icon: Option<Icon>,
8 name: Option<SharedString>,
9 state: Option<AnyElement>,
10 aria_label: Option<SharedString>,
11 tab_index: Option<isize>,
12 disabled: bool,
13 on_click: Option<Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
14}
15
16impl AgentSetupButton {
17 pub fn new(id: impl Into<ElementId>) -> Self {
18 Self {
19 id: id.into(),
20 icon: None,
21 name: None,
22 state: None,
23 aria_label: None,
24 tab_index: None,
25 disabled: false,
26 on_click: None,
27 }
28 }
29
30 pub fn icon(mut self, icon: Icon) -> Self {
31 self.icon = Some(icon);
32 self
33 }
34
35 pub fn name(mut self, name: impl Into<SharedString>) -> Self {
36 self.name = Some(name.into());
37 self
38 }
39
40 pub fn state(mut self, element: impl IntoElement) -> Self {
41 self.state = Some(element.into_any_element());
42 self
43 }
44
45 pub fn aria_label(mut self, label: impl Into<SharedString>) -> Self {
46 self.aria_label = Some(label.into());
47 self
48 }
49
50 pub fn tab_index(mut self, tab_index: isize) -> Self {
51 self.tab_index = Some(tab_index);
52 self
53 }
54
55 pub fn disabled(mut self, disabled: bool) -> Self {
56 self.disabled = disabled;
57 self
58 }
59
60 pub fn on_click(
61 mut self,
62 handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
63 ) -> Self {
64 self.on_click = Some(Box::new(handler));
65 self
66 }
67}
68
69impl Component for AgentSetupButton {
70 fn scope() -> ComponentScope {
71 ComponentScope::Agent
72 }
73
74 fn description() -> &'static str {
75 "A large, two-section button used in agent onboarding flows \
76 to launch the setup of a provider or tool, showing an icon, name, \
77 and current setup state."
78 }
79
80 fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
81 single_example(
82 "Default",
83 AgentSetupButton::new("preview")
84 .icon(Icon::new(IconName::OmegaAgent))
85 .name("Omega Agent")
86 .into_any_element(),
87 )
88 .into_any_element()
89 }
90}
91
92impl RenderOnce for AgentSetupButton {
93 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
94 let is_clickable = !self.disabled && self.on_click.is_some();
95
96 let has_top_section = self.icon.is_some() || self.name.is_some();
97 let top_section = has_top_section.then(|| {
98 h_flex()
99 .p_1p5()
100 .gap_1()
101 .justify_center()
102 .when_some(self.icon, |this, icon| this.child(icon))
103 .when_some(self.name, |this, name| {
104 this.child(Label::new(name).size(LabelSize::Small))
105 })
106 });
107
108 let bottom_section = self.state.map(|state_element| {
109 h_flex()
110 .p_0p5()
111 .h_full()
112 .justify_center()
113 .border_t_1()
114 .border_color(cx.theme().colors().border_variant)
115 .bg(cx.theme().colors().element_background.opacity(0.5))
116 .child(state_element)
117 });
118
119 v_flex()
120 .id(self.id)
121 .role(if is_clickable {
122 Role::Button
123 } else {
124 Role::Label
125 })
126 .when_some(self.aria_label, |this, label| this.aria_label(label))
127 .when_some(
128 self.tab_index.filter(|_| is_clickable),
129 |this, tab_index| this.tab_index(tab_index),
130 )
131 .border_1()
132 .border_color(cx.theme().colors().border_variant)
133 .rounded_sm()
134 .when(is_clickable, |this| {
135 this.cursor_pointer()
136 .focus_visible(|style| style.border_color(cx.theme().colors().border_focused))
137 .hover(|style| {
138 style
139 .bg(cx.theme().colors().element_hover)
140 .border_color(cx.theme().colors().border)
141 })
142 })
143 .when_some(top_section, |this, section| this.child(section))
144 .when_some(bottom_section, |this, section| this.child(section))
145 .when_some(self.on_click.filter(|_| is_clickable), |this, on_click| {
146 this.on_click(on_click)
147 })
148 }
149}
150