Skip to main content

glassy_ui/
kbd.rs

1use crate::motion::StyledSlot;
2use crate::theme::ActiveTheme;
3use gpui::{
4    div, prelude::*, px, App, FontWeight, IntoElement, RenderOnce, SharedString, StyleRefinement,
5    Styled, Window,
6};
7
8use crate::button::ButtonVariant;
9use crate::chrome::{box_shadow, button_chrome};
10
11/// Ghost glass chip matching Paper `Glassy UI` → Kbd. Not a button.
12#[derive(IntoElement)]
13pub struct Kbd {
14    keys: SharedString,
15    style: StyleRefinement,
16}
17
18impl Kbd {
19    pub fn new(keys: impl Into<SharedString>) -> Self {
20        Self {
21            keys: keys.into(),
22            style: StyleRefinement::default(),
23        }
24    }
25}
26
27impl Styled for Kbd {
28    fn style(&mut self) -> &mut StyleRefinement {
29        &mut self.style
30    }
31}
32
33impl RenderOnce for Kbd {
34    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
35        let theme = cx.theme();
36        let chrome = button_chrome(theme, ButtonVariant::Ghost);
37
38        div()
39            .flex()
40            .items_center()
41            .justify_center()
42            .h(px(22.))
43            .min_w(px(22.))
44            .flex_shrink_0()
45            .px(px(6.))
46            .rounded(px(6.))
47            .border_1()
48            .border_color(chrome.border)
49            .bg(chrome.bg)
50            .shadow(vec![box_shadow(0., 1., chrome.inset, 0., 0.)])
51            .cursor_default()
52            .refine_style(&self.style)
53            .child(
54                div()
55                    .font_family(theme.font_family)
56                    .font_weight(FontWeight::MEDIUM)
57                    .text_size(px(12.))
58                    .line_height(px(16.))
59                    .text_color(chrome.fg)
60                    .child(self.keys),
61            )
62    }
63}