Skip to main content

gpui_component/input/
token.rs

1use super::InlineTokenContext;
2use crate::{ActiveTheme as _, Icon, StyledExt as _};
3use gpui::{
4    App, InteractiveElement as _, IntoElement, ParentElement as _, RenderOnce, StyleRefinement,
5    Styled, Window, div, prelude::FluentBuilder as _,
6};
7
8/// The element an [`InlineToken`](super::InlineToken) renders as by default. Editing
9/// and activation belong to the input.
10#[derive(IntoElement)]
11pub struct InputToken {
12    context: InlineTokenContext,
13    icon: Option<Icon>,
14    style: StyleRefinement,
15}
16impl InputToken {
17    pub fn new(context: &InlineTokenContext) -> Self {
18        Self {
19            context: context.clone(),
20            icon: None,
21            style: Default::default(),
22        }
23    }
24    pub fn icon(mut self, icon: impl Into<Icon>) -> Self {
25        self.icon = Some(icon.into());
26        self
27    }
28}
29impl Styled for InputToken {
30    fn style(&mut self) -> &mut StyleRefinement {
31        &mut self.style
32    }
33}
34impl RenderOnce for InputToken {
35    fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
36        div()
37            .id("input-token")
38            .flex()
39            .items_center()
40            .gap_1()
41            .px_1()
42            .h(self.context.line_height())
43            .max_w(self.context.available_width())
44            .rounded(cx.theme().radius)
45            .border_1()
46            .map(|this| {
47                // The selection color is translucent as a fill; its opaque form
48                // is the matching border.
49                if self.context.is_selected() {
50                    this.bg(cx.theme().selection)
51                        .border_color(cx.theme().selection.alpha(1.))
52                } else {
53                    this.bg(cx.theme().muted).border_color(cx.theme().border)
54                }
55            })
56            .text_color(cx.theme().foreground)
57            .when(self.context.is_disabled(), |this| this.opacity(0.5))
58            .when_some(self.icon, |this, icon| {
59                this.child(icon.size_3().flex_shrink_0())
60            })
61            .child(
62                div()
63                    .min_w_0()
64                    .text_ellipsis()
65                    .child(self.context.token().label().clone()),
66            )
67            .refine_style(&self.style)
68    }
69}