1use gpui::prelude::*;
4use gpui::{div, px, App, ClickEvent, ElementId, IntoElement, SharedString, Window};
5
6use crate::input::ClickHandler;
7use crate::theme::{theme, ColorName, Size};
8
9#[derive(IntoElement)]
11pub struct Anchor {
12 id: ElementId,
13 label: SharedString,
14 color: ColorName,
15 size: Size,
16 on_click: Option<ClickHandler>,
17}
18
19impl Anchor {
20 pub fn new(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
21 Anchor {
22 id: id.into(),
23 label: label.into(),
24 color: ColorName::Blue,
25 size: Size::Md,
26 on_click: None,
27 }
28 }
29
30 pub fn color(mut self, color: ColorName) -> Self {
31 self.color = color;
32 self
33 }
34
35 pub fn size(mut self, size: Size) -> Self {
36 self.size = size;
37 self
38 }
39
40 pub fn on_click(
41 mut self,
42 handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
43 ) -> Self {
44 self.on_click = Some(Box::new(handler));
45 self
46 }
47}
48
49impl RenderOnce for Anchor {
50 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
51 let t = theme(cx);
52 let color = t
53 .color(self.color, if t.scheme.is_dark() { 4 } else { 6 })
54 .hsla();
55 let hover = t
56 .color(self.color, if t.scheme.is_dark() { 3 } else { 7 })
57 .hsla();
58
59 let mut el = div()
60 .id(self.id)
61 .text_size(px(t.font_size(self.size)))
62 .text_color(color)
63 .hover(move |s| s.text_color(hover))
64 .child(self.label);
65 if let Some(handler) = self.on_click {
66 el = el.on_click(handler);
67 }
68 el
69 }
70}