Skip to repository content240 lines · 7.7 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T05:38:07.508Z 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
divider.rs
1use gpui::{Hsla, IntoElement, PathBuilder, Refineable as _, StyleRefinement, canvas, point};
2
3use crate::prelude::*;
4
5#[derive(Clone, Copy, PartialEq)]
6enum DividerStyle {
7 Solid,
8 Dashed,
9}
10
11#[derive(Clone, Copy, PartialEq)]
12enum DividerDirection {
13 Horizontal,
14 Vertical,
15}
16
17/// The color of a [`Divider`].
18#[derive(Default)]
19pub enum DividerColor {
20 Border,
21 BorderFaded,
22 #[default]
23 BorderVariant,
24}
25
26impl DividerColor {
27 pub fn hsla(self, cx: &mut App) -> Hsla {
28 match self {
29 DividerColor::Border => cx.theme().colors().border,
30 DividerColor::BorderFaded => cx.theme().colors().border.opacity(0.6),
31 DividerColor::BorderVariant => cx.theme().colors().border_variant,
32 }
33 }
34}
35
36#[derive(IntoElement, RegisterComponent)]
37pub struct Divider {
38 line_style: DividerStyle,
39 direction: DividerDirection,
40 color: DividerColor,
41 style: StyleRefinement,
42 inset: bool,
43}
44
45impl Divider {
46 pub fn horizontal() -> Self {
47 Self {
48 line_style: DividerStyle::Solid,
49 direction: DividerDirection::Horizontal,
50 color: DividerColor::default(),
51 style: StyleRefinement::default(),
52 inset: false,
53 }
54 }
55
56 pub fn vertical() -> Self {
57 Self {
58 line_style: DividerStyle::Solid,
59 direction: DividerDirection::Vertical,
60 color: DividerColor::default(),
61 style: StyleRefinement::default(),
62 inset: false,
63 }
64 }
65
66 pub fn horizontal_dashed() -> Self {
67 Self {
68 line_style: DividerStyle::Dashed,
69 direction: DividerDirection::Horizontal,
70 color: DividerColor::default(),
71 style: StyleRefinement::default(),
72 inset: false,
73 }
74 }
75
76 pub fn vertical_dashed() -> Self {
77 Self {
78 line_style: DividerStyle::Dashed,
79 direction: DividerDirection::Vertical,
80 color: DividerColor::default(),
81 style: StyleRefinement::default(),
82 inset: false,
83 }
84 }
85
86 pub fn inset(mut self) -> Self {
87 self.inset = true;
88 self
89 }
90
91 pub fn color(mut self, color: DividerColor) -> Self {
92 self.color = color;
93 self
94 }
95
96 pub fn render_solid(self, base: Div, cx: &mut App) -> impl IntoElement {
97 base.bg(self.color.hsla(cx))
98 }
99
100 pub fn render_dashed(self, base: Div) -> impl IntoElement {
101 base.relative().child(
102 canvas(
103 |_, _, _| {},
104 move |bounds, _, window, cx| {
105 let mut builder = PathBuilder::stroke(px(1.)).dash_array(&[px(4.), px(2.)]);
106 let (start, end) = match self.direction {
107 DividerDirection::Horizontal => {
108 let x = bounds.origin.x;
109 let y = bounds.origin.y + px(0.5);
110 (point(x, y), point(x + bounds.size.width, y))
111 }
112 DividerDirection::Vertical => {
113 let x = bounds.origin.x + px(0.5);
114 let y = bounds.origin.y;
115 (point(x, y), point(x, y + bounds.size.height))
116 }
117 };
118 builder.move_to(start);
119 builder.line_to(end);
120 if let Ok(line) = builder.build() {
121 window.paint_path(line, self.color.hsla(cx));
122 }
123 },
124 )
125 .absolute()
126 .size_full(),
127 )
128 }
129}
130
131impl Styled for Divider {
132 fn style(&mut self) -> &mut StyleRefinement {
133 &mut self.style
134 }
135}
136
137impl RenderOnce for Divider {
138 fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
139 let mut base = match self.direction {
140 DividerDirection::Horizontal => div()
141 .min_w_0()
142 .h_px()
143 .max_h_px()
144 .w_full()
145 .when(self.inset, |this| this.mx_1p5()),
146 DividerDirection::Vertical => div()
147 .min_w_0()
148 .w_px()
149 .h_4()
150 .when(self.inset, |this| this.my_1p5()),
151 };
152
153 base.style().refine(&self.style);
154
155 match self.line_style {
156 DividerStyle::Solid => self.render_solid(base, cx).into_any_element(),
157 DividerStyle::Dashed => self.render_dashed(base).into_any_element(),
158 }
159 }
160}
161
162impl Component for Divider {
163 fn scope() -> ComponentScope {
164 ComponentScope::Layout
165 }
166
167 fn description() -> &'static str {
168 "Visual separator used to create divisions between groups of content \
169 or sections in a layout."
170 }
171
172 fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
173 v_flex()
174 .gap_6()
175 .children(vec![
176 example_group_with_title(
177 "Horizontal Dividers",
178 vec![
179 single_example("Default", Divider::horizontal().into_any_element()),
180 single_example(
181 "Border Color",
182 Divider::horizontal()
183 .color(DividerColor::Border)
184 .into_any_element(),
185 ),
186 single_example("Inset", Divider::horizontal().inset().into_any_element()),
187 single_example("Dashed", Divider::horizontal_dashed().into_any_element()),
188 ],
189 ),
190 example_group_with_title(
191 "Vertical Dividers",
192 vec![
193 single_example(
194 "Default",
195 div().h_16().child(Divider::vertical()).into_any_element(),
196 ),
197 single_example(
198 "Border Color",
199 div()
200 .h_16()
201 .child(Divider::vertical().color(DividerColor::Border))
202 .into_any_element(),
203 ),
204 single_example(
205 "Inset",
206 div()
207 .h_16()
208 .child(Divider::vertical().inset())
209 .into_any_element(),
210 ),
211 single_example(
212 "Dashed",
213 div()
214 .h_16()
215 .child(Divider::vertical_dashed())
216 .into_any_element(),
217 ),
218 ],
219 ),
220 example_group_with_title(
221 "Example Usage",
222 vec![single_example(
223 "Between Content",
224 v_flex()
225 .w_full()
226 .gap_4()
227 .px_4()
228 .child(Label::new("Section One"))
229 .child(Divider::horizontal())
230 .child(Label::new("Section Two"))
231 .child(Divider::horizontal_dashed())
232 .child(Label::new("Section Three"))
233 .into_any_element(),
234 )],
235 ),
236 ])
237 .into_any_element()
238 }
239}
240