Skip to main content

guise/
anchor.rs

1//! `Anchor` — a clickable, colored text link.
2
3use 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/// A text link. The Mantine `Anchor`.
10#[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}