Skip to main content

guise/
mark.rs

1//! `Mark` — an inline highlighted span of text.
2//!
3//! ```ignore
4//! Group::new()
5//!     .gap(Size::Xs)
6//!     .child(Text::new("Highlight the"))
7//!     .child(Mark::new("important part"))
8//!     .child(Text::new("of a sentence."))
9//! ```
10
11use gpui::prelude::*;
12use gpui::{div, px, App, IntoElement, SharedString, Window};
13
14use crate::devtools::Probed;
15use crate::theme::{theme, ColorName, Size};
16
17/// A highlighter-pen span.
18///
19/// Inherits the surrounding font size unless [`Mark::size`] is set, so it
20/// drops into a `Group` next to `Text` runs.
21#[derive(IntoElement)]
22pub struct Mark {
23  content: SharedString,
24  color: ColorName,
25  size: Option<Size>,
26}
27
28impl Mark {
29  pub fn new(content: impl Into<SharedString>) -> Self {
30    Mark {
31      content: content.into(),
32      color: ColorName::Yellow,
33      size: None,
34    }
35  }
36
37  /// The highlight tint (default `Yellow`).
38  pub fn color(mut self, color: ColorName) -> Self {
39    self.color = color;
40    self
41  }
42
43  /// Explicit font size; unset inherits from the parent.
44  pub fn size(mut self, size: Size) -> Self {
45    self.size = Some(size);
46    self
47  }
48}
49
50impl RenderOnce for Mark {
51  fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
52    let t = theme(cx);
53    // A light shade-2 wash in light mode, a translucent shade-5 tint in
54    // dark mode; text stays the theme text color.
55    let bg = if t.scheme.is_dark() {
56      t.color(self.color, 5).alpha(0.35)
57    } else {
58      t.color(self.color, 2).hsla()
59    };
60    let fg = t.text().hsla();
61
62    let mut el = div()
63      .px(px(4.0))
64      .rounded(px(t.radius(Size::Xs)))
65      .bg(bg)
66      .text_color(fg)
67      .child(self.content);
68    if let Some(size) = self.size {
69      el = el.text_size(px(t.font_size(size)));
70    }
71    el.probe("Mark")
72  }
73}