Skip to repository content145 lines · 4.7 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:47:16.328Z 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
list_sub_header.rs
1use crate::prelude::*;
2use component::{Component, ComponentScope, example_group_with_title, single_example};
3
4#[derive(IntoElement, RegisterComponent)]
5pub struct ListSubHeader {
6 label: SharedString,
7 start_slot: Option<IconName>,
8 end_slot: Option<AnyElement>,
9 inset: bool,
10 selected: bool,
11}
12
13impl ListSubHeader {
14 pub fn new(label: impl Into<SharedString>) -> Self {
15 Self {
16 label: label.into(),
17 start_slot: None,
18 end_slot: None,
19 inset: false,
20 selected: false,
21 }
22 }
23
24 pub fn left_icon(mut self, left_icon: Option<IconName>) -> Self {
25 self.start_slot = left_icon;
26 self
27 }
28
29 pub fn end_slot(mut self, end_slot: AnyElement) -> Self {
30 self.end_slot = Some(end_slot);
31 self
32 }
33
34 pub fn inset(mut self, inset: bool) -> Self {
35 self.inset = inset;
36 self
37 }
38}
39
40impl Toggleable for ListSubHeader {
41 fn toggle_state(mut self, selected: bool) -> Self {
42 self.selected = selected;
43 self
44 }
45}
46
47impl RenderOnce for ListSubHeader {
48 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
49 h_flex()
50 .flex_1()
51 .w_full()
52 .relative()
53 .pb(DynamicSpacing::Base04.rems(cx))
54 .px(DynamicSpacing::Base02.rems(cx))
55 .child(
56 div()
57 .h_5()
58 .when(self.inset, |this| this.px_2())
59 .when(self.selected, |this| {
60 this.bg(cx.theme().colors().ghost_element_selected)
61 })
62 .flex()
63 .flex_1()
64 .w_full()
65 .gap_1()
66 .items_center()
67 .justify_between()
68 .child(
69 div()
70 .flex()
71 .gap_1()
72 .items_center()
73 .children(
74 self.start_slot.map(|i| {
75 Icon::new(i).color(Color::Muted).size(IconSize::Small)
76 }),
77 )
78 .child(
79 Label::new(self.label.clone())
80 .color(Color::Muted)
81 .size(LabelSize::Small),
82 ),
83 )
84 .children(self.end_slot),
85 )
86 }
87}
88
89impl Component for ListSubHeader {
90 fn scope() -> ComponentScope {
91 ComponentScope::DataDisplay
92 }
93
94 fn description() -> &'static str {
95 "A sub-header component for organizing list content into subsections \
96 with optional icons and end slots."
97 }
98
99 fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
100 v_flex()
101 .gap_6()
102 .children(vec![
103 example_group_with_title(
104 "Basic Sub-headers",
105 vec![
106 single_example(
107 "Simple",
108 ListSubHeader::new("Subsection").into_any_element(),
109 ),
110 single_example(
111 "With Icon",
112 ListSubHeader::new("Documents")
113 .left_icon(Some(IconName::File))
114 .into_any_element(),
115 ),
116 single_example(
117 "With End Slot",
118 ListSubHeader::new("Recent")
119 .end_slot(Label::new("3").color(Color::Muted).into_any_element())
120 .into_any_element(),
121 ),
122 ],
123 ),
124 example_group_with_title(
125 "States",
126 vec![
127 single_example(
128 "Selected",
129 ListSubHeader::new("Selected")
130 .toggle_state(true)
131 .into_any_element(),
132 ),
133 single_example(
134 "Inset",
135 ListSubHeader::new("Inset Sub-header")
136 .inset(true)
137 .into_any_element(),
138 ),
139 ],
140 ),
141 ])
142 .into_any_element()
143 }
144}
145