1use gpui::{
4 AnyElement, App, Axis, Div, ElementId, Interactivity, IntoElement, Refineable, RenderOnce,
5 ScrollHandle, Stateful, StyleRefinement, Window, div, prelude::*, px,
6};
7
8use crate::scroll;
9
10#[derive(IntoElement)]
11pub struct TabBar {
12 id: ElementId,
13 row: Stateful<Div>,
14 viewport: Option<AnyElement>,
15 handle: Option<ScrollHandle>,
16 style: StyleRefinement,
17}
18
19impl TabBar {
20 pub(super) fn new(id: ElementId) -> Self {
21 Self {
22 id,
23 row: div()
24 .id("tab-row")
25 .min_w_0()
26 .flex()
27 .flex_row()
28 .items_center()
29 .gap(px(super::GAP))
30 .overflow_x_scroll(),
31 viewport: None,
32 handle: None,
33 style: StyleRefinement::default(),
34 }
35 }
36
37 pub fn track_scroll(mut self, handle: &ScrollHandle) -> Self {
39 self.handle = Some(handle.clone());
40 self
41 }
42
43 pub(super) fn viewport(mut self, viewport: AnyElement, handle: &ScrollHandle) -> Self {
44 self.viewport = Some(viewport);
45 self.track_scroll(handle)
46 }
47}
48
49impl ParentElement for TabBar {
50 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
51 self.row.extend(elements);
52 }
53}
54
55impl Styled for TabBar {
56 fn style(&mut self) -> &mut StyleRefinement {
57 &mut self.style
58 }
59}
60
61impl InteractiveElement for TabBar {
62 fn interactivity(&mut self) -> &mut Interactivity {
63 self.row.interactivity()
64 }
65}
66
67impl StatefulInteractiveElement for TabBar {}
68
69impl RenderOnce for TabBar {
70 fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
71 let handle = self.handle.unwrap_or_else(|| {
72 window
73 .use_keyed_state(self.id.clone(), cx, |_, _| ScrollHandle::new())
74 .read(cx)
75 .clone()
76 });
77 let viewport = self
78 .viewport
79 .unwrap_or_else(|| self.row.flex_1().track_scroll(&handle).into_any_element());
80 let mut frame = div()
81 .id(self.id)
82 .relative()
83 .min_w_0()
84 .min_h_0()
85 .flex()
86 .flex_1();
87 frame.style().refine(&self.style);
88 frame.child(viewport).child(scroll::Overlay::new(
89 "tab-scrollbar",
90 &handle,
91 Axis::Horizontal,
92 ))
93 }
94}