diff --git a/crates/storybook/src/component/icon_button.rs b/crates/storybook/src/component/icon_button.rs index 9e8df098be..50241acbe8 100644 --- a/crates/storybook/src/component/icon_button.rs +++ b/crates/storybook/src/component/icon_button.rs @@ -7,16 +7,16 @@ use gpui2::{Element, ParentElement, ViewContext}; #[derive(Element)] struct IconButton { path: &'static str, - variant: Variant, + variant: ButtonVariant, } #[derive(PartialEq)] -pub enum Variant { +pub enum ButtonVariant { Ghost, Filled, } -pub fn icon_button(path: &'static str, variant: Variant) -> impl Element { +pub fn icon_button(path: &'static str, variant: ButtonVariant) -> impl Element { IconButton { path, variant } } @@ -25,8 +25,8 @@ impl IconButton { let theme = theme(cx); let mut div = div(); - if self.variant == Variant::Filled { - div = div.fill(theme.middle.base.default.background); + if self.variant == ButtonVariant::Filled { + div = div.fill(theme.highest.base.default.background); } div.w_7() @@ -35,20 +35,16 @@ impl IconButton { .items_center() .justify_center() .rounded_md() - .border() - .border_color(theme.middle.base.default.background) .hover() - .fill(theme.middle.base.hovered.background) - .border_color(theme.middle.variant.hovered.border) + .fill(theme.highest.base.hovered.background) .active() - .fill(theme.middle.base.pressed.background) - .border_color(theme.middle.variant.pressed.border) + .fill(theme.highest.base.pressed.background) .child( svg() .path(self.path) .w_4() .h_4() - .fill(theme.middle.variant.default.foreground), + .fill(theme.highest.variant.default.foreground), ) } } diff --git a/crates/storybook/src/component/mod.rs b/crates/storybook/src/component/mod.rs index e26b06c8dd..c45b936e96 100644 --- a/crates/storybook/src/component/mod.rs +++ b/crates/storybook/src/component/mod.rs @@ -1 +1,2 @@ pub(crate) mod icon_button; +pub(crate) mod tab; diff --git a/crates/storybook/src/component/tab.rs b/crates/storybook/src/component/tab.rs new file mode 100644 index 0000000000..91a0fb1be1 --- /dev/null +++ b/crates/storybook/src/component/tab.rs @@ -0,0 +1,56 @@ +use crate::theme::theme; +use gpui2::elements::svg; +use gpui2::style::{StyleHelpers, Styleable}; +use gpui2::{elements::div, IntoElement}; +use gpui2::{Element, ParentElement, ViewContext}; + +#[derive(Element)] +struct Tab { + title: &'static str, + active: bool, +} + +pub fn tab(title: &'static str, active: bool) -> impl Element { + Tab { title, active } +} + +impl Tab { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + + div() + .px_2() + .py_0p5() + .flex() + .items_center() + .justify_center() + .rounded_lg() + .fill(if self.active { + theme.highest.on.default.background + } else { + theme.highest.base.default.background + }) + .hover() + .fill(if self.active { + theme.highest.on.hovered.background + } else { + theme.highest.base.hovered.background + }) + .active() + .fill(if self.active { + theme.highest.on.pressed.background + } else { + theme.highest.base.pressed.background + }) + .child( + div() + .text_sm() + .text_color(if self.active { + theme.highest.base.default.foreground + } else { + theme.highest.variant.default.foreground + }) + .child(self.title), + ) + } +} diff --git a/crates/storybook/src/module/mod.rs b/crates/storybook/src/module/mod.rs new file mode 100644 index 0000000000..078db8e167 --- /dev/null +++ b/crates/storybook/src/module/mod.rs @@ -0,0 +1 @@ +pub(crate) mod tab_bar; diff --git a/crates/storybook/src/module/tab_bar.rs b/crates/storybook/src/module/tab_bar.rs new file mode 100644 index 0000000000..24f96337a0 --- /dev/null +++ b/crates/storybook/src/module/tab_bar.rs @@ -0,0 +1,89 @@ +use std::marker::PhantomData; + +use crate::component::icon_button::{icon_button, ButtonVariant}; +use crate::component::tab::tab; +use crate::theme::theme; +use gpui2::elements::div::ScrollState; +use gpui2::style::StyleHelpers; +use gpui2::{elements::div, IntoElement}; +use gpui2::{Element, ParentElement, ViewContext}; + +#[derive(Element)] +pub struct TabBar { + view_type: PhantomData, + scroll_state: ScrollState, +} + +pub fn tab_bar(scroll_state: ScrollState) -> TabBar { + TabBar { + view_type: PhantomData, + scroll_state, + } +} + +impl TabBar { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + + div() + .w_full() + .flex() + .items_center() + .fill(theme.highest.base.default.background) + // Left Side + .child( + div() + .px_1() + .flex() + // Nate + // This isn't what I wanted, but I wanted to try to get at least SOME x overflow scroll working + // Ideally this should be on the "Tabs" div below + // So only the tabs scroll, and the nav buttons stay pinned left, and the other controls stay pinned right + .overflow_x_scroll(self.scroll_state.clone()) + .gap_2() + // Nav Buttons + .child( + div() + .flex() + .items_center() + .gap_px() + .child(icon_button("icons/arrow_left.svg", ButtonVariant::Ghost)) + .child(icon_button("icons/arrow_right.svg", ButtonVariant::Ghost)), + ) + // Tabs + .child( + div() + .py_1() + .flex() + .items_center() + .gap_px() + .child(tab("Cargo.toml", false)) + .child(tab("Channels Panel", true)) + .child(tab("channels_panel.rs", false)) + .child(tab("workspace.rs", false)) + .child(tab("icon_button.rs", false)) + .child(tab("storybook.rs", false)) + .child(tab("theme.rs", false)) + .child(tab("theme_registry.rs", false)) + .child(tab("styleable_helpers.rs", false)), + ), + ) + // Right Side + .child( + div() + .px_1() + .flex() + .flex_initial() + .gap_2() + // Nav Buttons + .child( + div() + .flex() + .items_center() + .gap_px() + .child(icon_button("icons/plus.svg", ButtonVariant::Ghost)) + .child(icon_button("icons/split.svg", ButtonVariant::Ghost)), + ), + ) + } +} diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index 7f9aa86672..ed6f11e074 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -11,6 +11,7 @@ use simplelog::SimpleLogger; mod collab_panel; mod component; +mod module; mod components; mod element_ext; mod theme; diff --git a/crates/storybook/src/workspace.rs b/crates/storybook/src/workspace.rs index 441a4c68fa..bbdfb22788 100644 --- a/crates/storybook/src/workspace.rs +++ b/crates/storybook/src/workspace.rs @@ -1,8 +1,4 @@ -use crate::{ - collab_panel::collab_panel, - component::icon_button::{icon_button, Variant}, - theme::theme, -}; +use crate::{collab_panel::collab_panel, module::tab_bar::tab_bar, theme::theme}; use gpui2::{ elements::{div, div::ScrollState, img, svg}, style::{StyleHelpers, Styleable}, @@ -13,6 +9,7 @@ use gpui2::{ struct WorkspaceElement { left_scroll_state: ScrollState, right_scroll_state: ScrollState, + tab_bar_scroll_state: ScrollState, } pub fn workspace() -> impl Element { @@ -41,17 +38,20 @@ impl WorkspaceElement { .flex() .flex_row() .overflow_hidden() - .child(collab_panel(self.left_scroll_state.clone())) + // .child(collab_panel(self.left_scroll_state.clone())) .child( - div().h_full().flex_1().child( - div() - .w_24() - .h_24() - .child(icon_button("icons/plus.svg", Variant::Ghost)) - .child(icon_button("icons/x.svg", Variant::Filled)), - ), - ) - .child(collab_panel(self.right_scroll_state.clone())), + div() + .h_full() + .flex_1() + .fill(theme.highest.base.default.background) + .child( + div() + .flex() + .flex_col() + .flex_1() + .child(tab_bar(self.tab_bar_scroll_state.clone())), + ), + ), // .child(collab_panel(self.right_scroll_state.clone())), ) .child(statusbar()) }