Skip to main content

gpui_kit/overlay/
panel.rs

1//! The parts a modal surface and a drawer build from.
2//!
3//! [`Dialog`](crate::overlay::Dialog) and [`Drawer`](crate::overlay::Drawer)
4//! differ in where they sit and how they arrive, not in what they are made of,
5//! so the body callback and the two pieces of copy above it live here.
6
7use std::rc::Rc;
8
9use gpui::{AnyElement, App, ParentElement, SharedString, Styled, Window, div, px};
10use gpui_kit_semantics::{NodeSpec, Role, Semantic};
11use gpui_kit_theme::Theme;
12
13use crate::foundation::Ident;
14
15/// Builds a surface body for one frame.
16///
17/// An `AnyElement` can be consumed once, while an open surface re-renders for
18/// as long as it stays open, so the caller supplies a builder instead.
19pub type Body = Rc<dyn Fn(&mut Window, &mut App) -> AnyElement>;
20
21/// The title of a surface, published as its first-level heading.
22pub fn heading(
23    ident: &Ident,
24    theme: &Theme,
25    title: SharedString,
26    cx: &App,
27) -> gpui::Stateful<gpui::Div> {
28    div()
29        .text_size(px(theme.typography.title.size))
30        .line_height(px(theme.typography.title.line_height))
31        .font_weight(gpui::FontWeight(theme.typography.title.weight))
32        .child(title.clone())
33        .semantic_in(
34            cx,
35            NodeSpec::new(ident.child("title").semantic_id(), Role::Heading)
36                .parent(ident.semantic_id())
37                .level(1)
38                .text(title),
39        )
40}
41
42/// Secondary copy under the title.
43pub fn description(
44    ident: &Ident,
45    theme: &Theme,
46    description: SharedString,
47    cx: &App,
48) -> gpui::Stateful<gpui::Div> {
49    div()
50        .text_size(px(theme.typography.body.size))
51        .line_height(px(theme.typography.body.line_height))
52        .text_color(theme.colors.text_muted)
53        .child(description.clone())
54        .semantic_in(
55            cx,
56            NodeSpec::new(ident.child("description").semantic_id(), Role::Text)
57                .parent(ident.semantic_id())
58                .text(description),
59        )
60}