Skip to repository content157 lines · 4.9 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T05:39:31.477Z 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
disclosure.rs
1use std::sync::Arc;
2
3use gpui::{AnyView, ClickEvent, SharedString};
4
5use crate::IconButtonShape;
6use crate::prelude::*;
7
8#[derive(IntoElement, RegisterComponent)]
9pub struct Disclosure {
10 id: ElementId,
11 is_open: bool,
12 selected: bool,
13 disabled: bool,
14 closed_icon: IconName,
15 shape: Option<IconButtonShape>,
16 visible_on_hover: Option<SharedString>,
17 tooltip: Option<Box<dyn Fn(&mut Window, &mut App) -> AnyView + 'static>>,
18 on_toggle_expanded: Option<Arc<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
19 opened_icon: IconName,
20}
21
22impl Disclosure {
23 pub fn new(id: impl Into<ElementId>, is_open: bool) -> Self {
24 Self {
25 id: id.into(),
26 is_open,
27 selected: false,
28 disabled: false,
29 on_toggle_expanded: None,
30 opened_icon: IconName::ChevronDown,
31 closed_icon: IconName::ChevronRight,
32 shape: None,
33 visible_on_hover: None,
34 tooltip: None,
35 }
36 }
37
38 pub fn tooltip(mut self, tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static) -> Self {
39 self.tooltip = Some(Box::new(tooltip));
40 self
41 }
42
43 pub fn on_toggle_expanded(
44 mut self,
45 handler: impl Into<Option<Arc<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>>,
46 ) -> Self {
47 self.on_toggle_expanded = handler.into();
48 self
49 }
50
51 pub fn opened_icon(mut self, icon: IconName) -> Self {
52 self.opened_icon = icon;
53 self
54 }
55
56 pub fn closed_icon(mut self, icon: IconName) -> Self {
57 self.closed_icon = icon;
58 self
59 }
60
61 pub fn disabled(mut self, disabled: bool) -> Self {
62 self.disabled = disabled;
63 self
64 }
65
66 /// Sets the shape of the underlying [`IconButton`].
67 pub fn shape(mut self, shape: IconButtonShape) -> Self {
68 self.shape = Some(shape);
69 self
70 }
71
72 /// Alias for [`Self::on_toggle_expanded`].
73 pub fn on_click(self, handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) -> Self {
74 self.on_toggle_expanded(Arc::new(handler) as Arc<_>)
75 }
76}
77
78impl Toggleable for Disclosure {
79 fn toggle_state(mut self, selected: bool) -> Self {
80 self.selected = selected;
81 self
82 }
83}
84
85impl VisibleOnHover for Disclosure {
86 fn visible_on_hover(mut self, group_name: impl Into<SharedString>) -> Self {
87 self.visible_on_hover = Some(group_name.into());
88 self
89 }
90}
91
92impl RenderOnce for Disclosure {
93 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
94 IconButton::new(
95 self.id,
96 match self.is_open {
97 true => self.opened_icon,
98 false => self.closed_icon,
99 },
100 )
101 .icon_color(Color::Muted)
102 .icon_size(IconSize::Small)
103 .aria_label(if self.is_open { "Collapse" } else { "Expand" })
104 .aria_expanded(self.is_open)
105 .disabled(self.disabled)
106 .when_some(self.shape, |this, shape| this.shape(shape))
107 .toggle_state(self.selected)
108 .when_some(self.visible_on_hover.clone(), |this, group_name| {
109 this.visible_on_hover(group_name)
110 })
111 .when_some(self.tooltip, |this, tooltip| this.tooltip(tooltip))
112 .when_some(self.on_toggle_expanded, move |this, on_toggle| {
113 this.on_click(move |event, window, cx| on_toggle(event, window, cx))
114 })
115 }
116}
117
118impl Component for Disclosure {
119 fn scope() -> ComponentScope {
120 ComponentScope::Input
121 }
122
123 fn description() -> &'static str {
124 "An interactive element used to show or hide content, \
125 typically used in expandable sections or tree-like structures."
126 }
127
128 fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
129 v_flex()
130 .gap_6()
131 .children(vec![
132 example_group_with_title(
133 "Disclosure States",
134 vec![
135 single_example(
136 "Closed",
137 Disclosure::new("closed", false).into_any_element(),
138 ),
139 single_example("Open", Disclosure::new("open", true).into_any_element()),
140 ],
141 ),
142 example_group_with_title(
143 "Interactive Example",
144 vec![single_example(
145 "Toggleable",
146 v_flex()
147 .gap_2()
148 .child(Disclosure::new("interactive", false).into_any_element())
149 .child(Label::new("Click to toggle"))
150 .into_any_element(),
151 )],
152 ),
153 ])
154 .into_any_element()
155 }
156}
157