ashlar_ui/content/
card.rs1use egui::{InnerResponse, Margin, RichText, Stroke, Ui};
4
5use crate::automation::{self, Details, Role};
6use crate::tokens;
7
8pub struct Card<'a> {
10 id: &'a str,
11 title: Option<&'a str>,
12}
13
14impl<'a> Card<'a> {
15 pub fn new(id: &'a str) -> Self {
16 Card { id, title: None }
17 }
18 pub fn title(mut self, title: &'a str) -> Self {
20 self.title = Some(title);
21 self
22 }
23
24 pub fn show<R>(self, ui: &mut Ui, add: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
25 let t = tokens::current(ui.ctx());
26 let title = self.title;
27 let inner = egui::Frame::new()
28 .fill(t.surface.panel)
29 .stroke(Stroke::new(1.0, t.border))
30 .corner_radius(t.radius.lg)
31 .inner_margin(Margin::same(t.space.lg.round().clamp(0.0, 127.0) as i8))
32 .show(ui, |ui| {
33 ui.ctx().accesskit_node_builder(ui.unique_id(), |node| {
34 node.set_role(egui::accesskit::Role::Group);
35 if let Some(title) = title {
36 node.set_label(title);
37 }
38 });
39 if let Some(title) = title {
40 ui.label(RichText::new(title).size(t.type_scale.heading).strong().color(t.text.primary));
41 ui.add_space(t.space.sm);
42 }
43 add(ui)
44 });
45 automation::register_with(ui, &inner.response, self.id, title.unwrap_or_default(), Role::Group, Details::default());
46 inner
47 }
48}